tjs-lang 0.9.0 → 0.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CLAUDE.md +7 -1
- package/dist/index.js +111 -107
- package/dist/index.js.map +3 -3
- package/dist/src/lang/emitters/js-wasm.d.ts +2 -0
- package/dist/src/lang/parser-types.d.ts +7 -0
- package/dist/tjs-browser-from-ts.js +1 -1
- package/dist/tjs-browser-from-ts.js.map +1 -1
- package/dist/tjs-browser.js +93 -89
- package/dist/tjs-browser.js.map +3 -3
- package/dist/tjs-eval.js +14 -14
- package/dist/tjs-eval.js.map +2 -2
- package/dist/tjs-from-ts.js +1 -1
- package/dist/tjs-from-ts.js.map +1 -1
- package/dist/tjs-lang.js +94 -90
- package/dist/tjs-lang.js.map +3 -3
- package/dist/tjs-runtime.js +1 -1
- package/dist/tjs-runtime.js.map +1 -1
- package/dist/tjs-vm.js +2 -2
- package/dist/tjs-vm.js.map +2 -2
- package/docs/type-system-north-star.md +100 -0
- package/package.json +1 -1
- package/src/lang/emitters/js-wasm.ts +8 -4
- package/src/lang/emitters/js.ts +36 -11
- package/src/lang/parser-transforms.ts +4 -1
- package/src/lang/parser-types.ts +7 -0
- package/src/lang/parser.ts +9 -1
- package/src/lang/predicate-report.test.ts +24 -0
- package/src/lang/wasm-fallback-warning.test.ts +50 -0
- package/src/lang/wasm-intdiv-lint.test.ts +45 -0
- package/src/lang/wasm-ready.test.ts +94 -0
- package/src/lang/wasm-simd-ops.test.ts +84 -0
- package/src/lang/wasm.ts +61 -2
package/dist/tjs-runtime.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../package.json", "../src/lang/runtime.ts", "../src/lang/json-schema.ts", "../src/types/Type.ts"],
|
|
4
|
-
"sourcesContent": ["{\n \"name\": \"tjs-lang\",\n \"version\": \"0.9.0\",\n \"description\": \"Type-safe JavaScript dialect with runtime validation, sandboxed VM execution, and AI agent orchestration. Transpiles TypeScript to validated JS with fuel-metered execution for untrusted code.\",\n \"keywords\": [\n \"typescript\",\n \"transpiler\",\n \"runtime-validation\",\n \"type-safety\",\n \"sandbox\",\n \"virtual-machine\",\n \"wasm-alternative\",\n \"ai-agents\",\n \"llm\",\n \"orchestration\",\n \"security\",\n \"fuel-metering\",\n \"capability-based\",\n \"json-ast\",\n \"untrusted-code\"\n ],\n \"license\": \"Apache-2.0\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/src/index.d.ts\",\n \"typesVersions\": {\n \"*\": {\n \"eval\": [\n \"./dist/src/lang/eval.d.ts\"\n ],\n \"lang\": [\n \"./dist/src/lang/transpiler.d.ts\"\n ],\n \"lang/from-ts\": [\n \"./dist/src/lang/emitters/from-ts.d.ts\"\n ],\n \"browser\": [\n \"./dist/src/lang/browser.d.ts\"\n ],\n \"browser/from-ts\": [\n \"./dist/src/lang/browser-from-ts.d.ts\"\n ],\n \"vm\": [\n \"./dist/src/vm/index.d.ts\"\n ],\n \"batteries\": [\n \"./dist/src/batteries/index.d.ts\"\n ],\n \"css\": [\n \"./dist/src/css/index.d.ts\"\n ],\n \"schema\": [\n \"./dist/src/schema/index.d.ts\"\n ],\n \"runtime\": [\n \"./dist/src/lang/runtime.d.ts\"\n ]\n }\n },\n \"exports\": {\n \".\": {\n \"bun\": \"./src/index.ts\",\n \"types\": \"./dist/src/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"./eval\": {\n \"bun\": \"./src/lang/eval.ts\",\n \"types\": \"./dist/src/lang/eval.d.ts\",\n \"default\": \"./dist/tjs-eval.js\"\n },\n \"./lang\": {\n \"bun\": \"./src/lang/transpiler.ts\",\n \"types\": \"./dist/src/lang/transpiler.d.ts\",\n \"default\": \"./dist/tjs-lang.js\"\n },\n \"./lang/from-ts\": {\n \"bun\": \"./src/lang/emitters/from-ts.ts\",\n \"types\": \"./dist/src/lang/emitters/from-ts.d.ts\",\n \"default\": \"./dist/tjs-from-ts.js\"\n },\n \"./browser\": {\n \"types\": \"./dist/src/lang/browser.d.ts\",\n \"default\": \"./dist/tjs-browser.js\"\n },\n \"./browser/from-ts\": {\n \"types\": \"./dist/src/lang/browser-from-ts.d.ts\",\n \"default\": \"./dist/tjs-browser-from-ts.js\"\n },\n \"./vm\": {\n \"bun\": \"./src/vm/index.ts\",\n \"types\": \"./dist/src/vm/index.d.ts\",\n \"default\": \"./dist/tjs-vm.js\"\n },\n \"./batteries\": {\n \"bun\": \"./src/batteries/index.ts\",\n \"types\": \"./dist/src/batteries/index.d.ts\",\n \"default\": \"./dist/tjs-batteries.js\"\n },\n \"./linalg\": {\n \"bun\": \"./src/linalg/index.tjs\",\n \"default\": \"./dist/tjs-linalg.js\"\n },\n \"./css\": {\n \"bun\": \"./src/css/index.ts\",\n \"types\": \"./dist/src/css/index.d.ts\",\n \"default\": \"./dist/tjs-css.js\"\n },\n \"./schema\": {\n \"bun\": \"./src/schema/index.ts\",\n \"types\": \"./dist/src/schema/index.d.ts\",\n \"default\": \"./dist/tjs-schema.js\"\n },\n \"./runtime\": {\n \"bun\": \"./src/lang/runtime.ts\",\n \"types\": \"./dist/src/lang/runtime.d.ts\",\n \"default\": \"./dist/tjs-runtime.js\"\n },\n \"./bun-plugin\": {\n \"bun\": \"./src/bun-plugin/tjs-plugin.ts\"\n },\n \"./src\": \"./src/index.ts\",\n \"./editors/monaco\": \"./editors/monaco/ajs-monarch.js\",\n \"./editors/codemirror\": \"./editors/codemirror/ajs-language.js\",\n \"./editors/ace\": \"./editors/ace/ajs-mode.js\"\n },\n \"bin\": {\n \"tjs\": \"./src/cli/tjs.ts\",\n \"tjsx\": \"./src/cli/tjsx.ts\",\n \"tjs-playground\": \"./src/cli/playground.ts\",\n \"create-tjs-app\": \"./src/cli/create-app.ts\",\n \"ajs-install-vscode\": \"./bin/install-vscode.sh\",\n \"ajs-install-cursor\": \"./bin/install-cursor.sh\"\n },\n \"type\": \"module\",\n \"files\": [\n \"dist\",\n \"src\",\n \"docs\",\n \"editors\",\n \"bin\",\n \"demo\",\n \"tjs-lang.svg\",\n \"CONTEXT.md\",\n \"CLAUDE.md\",\n \"llms.txt\"\n ],\n \"sideEffects\": [\n \"./src/schema/index.ts\",\n \"./dist/tjs-schema.js\"\n ],\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/tonioloewald/tjs-lang.git\"\n },\n \"devDependencies\": {\n \"@codemirror/lang-css\": \"^6.3.1\",\n \"@codemirror/lang-html\": \"^6.4.11\",\n \"@codemirror/lang-javascript\": \"^6.2.4\",\n \"@codemirror/lang-markdown\": \"^6.5.0\",\n \"@codemirror/state\": \"^6.5.3\",\n \"@codemirror/theme-one-dark\": \"^6.1.3\",\n \"@codemirror/view\": \"^6.39.9\",\n \"@eslint/js\": \"^10.0.1\",\n \"@happy-dom/global-registrator\": \"^20.1.0\",\n \"@types/bun\": \"latest\",\n \"@types/jsdom\": \"^21.1.7\",\n \"acorn-walk\": \"^8.3.4\",\n \"chokidar\": \"^4.0.3\",\n \"codemirror\": \"^6.0.2\",\n \"esbuild\": \"^0.28.0\",\n \"eslint\": \"^10.4.1\",\n \"firebase\": \"^10.12.0\",\n \"firebase-admin\": \"^13.6.0\",\n \"firebase-functions\": \"^7.0.5\",\n \"globals\": \"^17.6.0\",\n \"marked\": \"^9.1.6\",\n \"prettier\": \"^2.8.8\",\n \"tosijs\": \"^1.5.6\",\n \"tosijs-ui\": \"^1.4.7\",\n \"typescript\": \"^5.6.2\",\n \"typescript-eslint\": \"^8.61.0\",\n \"valibot\": \"^0.36.0\",\n \"vitest\": \"^2.0.5\"\n },\n \"scripts\": {\n \"format\": \"bun eslint src --fix && bun prettier --write .\",\n \"lint\": \"eslint src\",\n \"build:grammars\": \"bun editors/build-grammars.ts\",\n \"build:editors\": \"bun scripts/build-editors.ts\",\n \"test:fast\": \"SKIP_LLM_TESTS=1 SKIP_BENCHMARKS=1 bun test\",\n \"test:llm\": \"bun test src/batteries/models.integration.test.ts\",\n \"bench\": \"bun bin/benchmarks.ts\",\n \"make\": \"rm -rf dist && bun format && bun run build:grammars && bun run build:editors && tsc -p tsconfig.build.json && bun scripts/build.ts\",\n \"build:bundles\": \"bun scripts/build.ts\",\n \"typecheck\": \"tsc --noEmit\",\n \"latest\": \"rm -rf node_modules && bun install\",\n \"docs\": \"node bin/docs.js\",\n \"dev\": \"bun run bin/dev.ts\",\n \"build:demo\": \"bun scripts/build-demo.ts\",\n \"build:cli\": \"bun build src/cli/tjs.ts --compile --outfile=dist/tjs && bun build src/cli/tjsx.ts --compile --outfile=dist/tjsx\",\n \"functions:build\": \"cd functions && npm run build\",\n \"functions:deploy\": \"cd functions && npm run deploy\",\n \"functions:serve\": \"cd functions && npm run serve\",\n \"deploy:hosting\": \"bun run build:demo && firebase deploy --only hosting\",\n \"deploy\": \"bun run build:demo && bun run functions:deploy && firebase deploy --only hosting\",\n \"start\": \"bun run build:demo && bun run dev\"\n },\n \"dependencies\": {\n \"acorn\": \"^8.15.0\",\n \"acorn-loose\": \"^8.5.2\",\n \"acorn-walk\": \"^8.3.4\",\n \"tosijs-schema\": \"^1.4.0\"\n }\n}\n", "/**\n * TJS Runtime\n *\n * Monadic type checking at runtime:\n * - Functions validate inputs against __tjs metadata\n * - If any input is an error, pass it through (no work)\n * - Type mismatches return error objects\n * - Errors propagate through call chains\n *\n * This runtime is attached to globalThis.__tjs and shared across modules.\n */\n\nimport { validate, s } from 'tosijs-schema'\nimport { functionMetaToJSONSchema } from './json-schema'\nimport {\n Type,\n isRuntimeType,\n Union,\n Generic,\n Enum,\n FunctionPredicate,\n Nullable,\n Optional,\n TArray,\n // Built-in types\n TString,\n TNumber,\n TBoolean,\n TInteger,\n TPositiveInt,\n TNonEmptyString,\n TEmail,\n TUrl,\n TUuid,\n Timestamp,\n LegalDate,\n // Built-in generics\n TPair,\n TRecord,\n // Portable predicate helpers (future AJS builtins)\n isValidUrl,\n isValidTimestamp,\n isValidLegalDate,\n} from '../types/Type'\n\n// Re-export Type utilities for consumers\nexport {\n Type,\n isRuntimeType,\n Union,\n Generic,\n Enum,\n FunctionPredicate,\n Nullable,\n Optional,\n TArray,\n TString,\n TNumber,\n TBoolean,\n TInteger,\n TPositiveInt,\n TNonEmptyString,\n TEmail,\n TUrl,\n TUuid,\n Timestamp,\n LegalDate,\n TPair,\n TRecord,\n isValidUrl,\n isValidTimestamp,\n isValidLegalDate,\n}\n\n// Version from package.json - injected at build time or imported\nconst pkg = require('../../package.json') as { version: string }\n\nexport const TJS_VERSION: string = pkg.version\n\n/**\n * Well-known symbol for custom equality.\n *\n * Any object can implement `[tjsEquals](other)` to control how `==` / `Is()`\n * compares it. Useful for Proxies that should delegate equality to their target.\n *\n * Priority: tjsEquals symbol \u2192 .Equals method \u2192 structural comparison\n */\nexport const tjsEquals: unique symbol = Symbol.for('tjs.equals')\n\n/**\n * Parse semver version string into components\n */\nfunction parseVersion(version: string): {\n major: number\n minor: number\n patch: number\n} {\n const [major = 0, minor = 0, patch = 0] = version.split('.').map(Number)\n return { major, minor, patch }\n}\n\n/**\n * Compare two version strings\n * Returns: -1 if a < b, 0 if equal, 1 if a > b\n */\nexport function compareVersions(a: string, b: string): -1 | 0 | 1 {\n const va = parseVersion(a)\n const vb = parseVersion(b)\n\n if (va.major !== vb.major) return va.major < vb.major ? -1 : 1\n if (va.minor !== vb.minor) return va.minor < vb.minor ? -1 : 1\n if (va.patch !== vb.patch) return va.patch < vb.patch ? -1 : 1\n return 0\n}\n\n/**\n * Check if two versions are compatible (same major version)\n */\nexport function versionsCompatible(a: string, b: string): boolean {\n const va = parseVersion(a)\n const vb = parseVersion(b)\n return va.major === vb.major\n}\n\n/**\n * MonadicError - Internal error type for monadic error propagation\n *\n * This extends Error so:\n * 1. It's a real Error with proper stack traces\n * 2. User code can't accidentally process it as data (unlike { $error: true })\n * 3. It flows through function calls via instanceof checks\n *\n * NOT exported to user code - they just see Error instances.\n */\nexport class MonadicError extends Error {\n /** Path where the error occurred, e.g., \"src/file.ts:42:greet.name\" */\n readonly path: string\n /** Expected type */\n readonly expected?: string\n /** Actual type received */\n readonly actual?: string\n /** TJS call stack (only in debug mode) - shows source locations */\n readonly callStack?: string[]\n /** Why the check failed (from predicate reason strings) */\n readonly reason?: string\n\n constructor(\n message: string,\n path: string,\n expected?: string,\n actual?: string,\n callStack?: string[],\n reason?: string\n ) {\n super(message)\n this.name = 'MonadicError'\n this.path = path\n this.expected = expected\n this.actual = actual\n this.callStack = callStack\n this.reason = reason\n // Maintains proper stack trace in V8 environments\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, MonadicError)\n }\n }\n}\n\n/**\n * Create a type error for inline validation\n *\n * Called ONLY when a type check fails - no overhead on happy path.\n * Returns a MonadicError that propagates through the call chain.\n * In debug mode, captures the TJS call stack with source locations.\n *\n * @param path - Location of the error, e.g., \"src/file.ts:42:greet.name\"\n * @param expected - Expected type, e.g., \"string\"\n * @param value - The actual value that failed the check\n */\nexport function typeError(\n path: string,\n expected: string,\n value: unknown,\n reason?: string\n): MonadicError {\n const actual = value === null ? 'null' : typeof value\n // Capture call stack in debug mode (getStack returns [] if not in debug mode)\n const stack = config.callStacks || config.debug ? getStack() : undefined\n const msg = reason\n ? `Expected ${expected} for '${path}': ${reason}`\n : `Expected ${expected} for '${path}', got ${actual}`\n const err = new MonadicError(msg, path, expected, actual, stack, reason)\n\n // Track in error history ring buffer (zero cost on happy path)\n if (config.trackErrors !== false) {\n const size = config.maxErrors ?? ERROR_BUF_SIZE\n errorBuffer[errorHead] = err\n errorHead = (errorHead + 1) % size\n if (errorBufCount < size) errorBufCount++\n errorTotal++\n }\n\n // Log to console if configured (includes source location from path)\n if (config.logTypeErrors) {\n console.error(`[TJS TypeError] ${err.message}`)\n }\n\n // Throw instead of returning if configured (for debugging)\n if (config.throwTypeErrors) {\n throw err\n }\n\n return err\n}\n\n/**\n * Check if a value is a MonadicError (for internal use)\n */\nexport function isMonadicError(value: unknown): value is MonadicError {\n // Duck-type check instead of instanceof \u2014 works across module boundaries,\n // inline runtimes, and different copies of the MonadicError class\n return (\n value instanceof Error &&\n (value as any).name === 'MonadicError' &&\n 'path' in value\n )\n}\n\n/**\n * Error marker - identifies TJS error objects\n * @deprecated Use MonadicError instead. This interface is kept for backward compatibility.\n */\nexport interface TJSError {\n $error: true\n message: string\n /** Failure location - e.g., \"greet.name\" */\n path?: string\n /** Call stack in debug mode - e.g., [\"main\", \"processUser\", \"greet.name\"] */\n stack?: string[]\n expected?: string\n actual?: string\n /** Why the check failed (from predicate reason strings) */\n reason?: string\n cause?: Error | TJSError\n /** Source location for error reporting */\n loc?: { start: number; end: number }\n /** Multiple errors (when composing parameter errors) */\n errors?: TJSError[]\n}\n\n/**\n * Safety levels for runtime validation\n * - 'none': No validation unless explicitly forced with (?) or -?\n * - 'inputs': Validate inputs only (default) - outputs only with explicit -> or -?\n * - 'all': Validate both inputs and outputs unless explicitly skipped with (!) or -!\n */\nexport type SafetyLevel = 'none' | 'inputs' | 'all'\n\n/**\n * Runtime configuration\n */\nexport interface TJSConfig {\n /** Enable debug mode - captures call stacks in errors */\n debug?: boolean\n /** Safety level for validation (default: 'inputs') */\n safety?: SafetyLevel\n /** Require explicit return types (error if -> not specified) */\n requireReturnTypes?: boolean\n /** Track call stacks for error diagnostics (default: false).\n * Useful for server-side logging and agent debugging without devtools.\n * Uses a fixed ring buffer \u2014 no allocation pressure. */\n callStacks?: boolean\n /** Ring buffer size for call stack tracking (default: 64) */\n maxStackSize?: number\n /** Track recent type errors in a ring buffer (default: true).\n * Zero cost on happy path \u2014 only writes when an error occurs.\n * Lets you catch monadic errors that were silently ignored. */\n trackErrors?: boolean\n /** Ring buffer size for error tracking (default: 64) */\n maxErrors?: number\n /** Log type errors to console.error when they occur (default: false) */\n logTypeErrors?: boolean\n /** Throw type errors instead of returning them (default: false).\n * Useful for debugging \u2014 makes type errors impossible to ignore. */\n throwTypeErrors?: boolean\n}\n\n/** Default configuration values */\nconst DEFAULT_CONFIG: TJSConfig = {\n debug: false,\n safety: 'inputs',\n requireReturnTypes: false,\n callStacks: false,\n maxStackSize: 64,\n trackErrors: true,\n maxErrors: 64,\n}\n\n/** Current runtime configuration */\nlet config: TJSConfig = { ...DEFAULT_CONFIG }\n\n/** Ring buffer for call stack tracking \u2014 fixed size, zero allocation */\nconst STACK_SIZE = 64\nconst callStackBuffer: string[] = new Array(STACK_SIZE).fill('')\nlet callStackHead = 0\nlet callStackCount = 0\n\n/** Ring buffer for error history \u2014 zero cost on happy path */\nconst ERROR_BUF_SIZE = 64\nconst errorBuffer: any[] = new Array(ERROR_BUF_SIZE).fill(null)\nlet errorHead = 0\nlet errorBufCount = 0\nlet errorTotal = 0\n\n/** Unsafe mode depth - when > 0, skip validation in wrap() */\nlet unsafeDepth = 0\n\n/**\n * Enter unsafe mode - disables validation for all wrapped function calls\n * Can be nested (uses depth counter)\n */\nexport function enterUnsafe(): void {\n unsafeDepth++\n}\n\n/**\n * Exit unsafe mode - re-enables validation when depth returns to 0\n */\nexport function exitUnsafe(): void {\n if (unsafeDepth > 0) unsafeDepth--\n}\n\n/**\n * Check if currently in unsafe mode\n */\nexport function isUnsafeMode(): boolean {\n return unsafeDepth > 0\n}\n\n/**\n * Configure TJS runtime\n */\nexport function configure(options: TJSConfig): void {\n config = { ...config, ...options }\n}\n\n/**\n * Get current configuration\n */\nexport function getConfig(): TJSConfig {\n return { ...config }\n}\n\n/**\n * Push a function onto the call stack ring buffer.\n * Only tracks when callStacks or debug is enabled.\n * O(1), no allocation.\n */\nexport function pushStack(name: string): void {\n if ((config.callStacks || config.debug) && name) {\n const size = config.maxStackSize ?? STACK_SIZE\n callStackBuffer[callStackHead] = name\n callStackHead = (callStackHead + 1) % size\n if (callStackCount < size) callStackCount++\n }\n}\n\n/**\n * Pop a function from the call stack ring buffer.\n * O(1), no allocation.\n */\nexport function popStack(): void {\n if ((config.callStacks || config.debug) && callStackCount > 0) {\n const size = config.maxStackSize ?? STACK_SIZE\n callStackHead = (callStackHead - 1 + size) % size\n callStackCount--\n }\n}\n\n/**\n * Get current call stack snapshot (most recent entries, newest last)\n */\nexport function getStack(): string[] {\n if (callStackCount === 0) return []\n const size = config.maxStackSize ?? STACK_SIZE\n const result: string[] = []\n const start = (callStackHead - callStackCount + size) % size\n for (let i = 0; i < callStackCount; i++) {\n result.push(callStackBuffer[(start + i) % size])\n }\n return result\n}\n\n/**\n * Get recent type errors (newest last).\n * Only tracks when trackErrors is enabled (default: true).\n */\nexport function errors(): MonadicError[] {\n if (config.trackErrors === false || errorBufCount === 0) return []\n const size = config.maxErrors ?? ERROR_BUF_SIZE\n const result: MonadicError[] = []\n const start = (errorHead - errorBufCount + size) % size\n for (let i = 0; i < errorBufCount; i++) {\n result.push(errorBuffer[(start + i) % size])\n }\n return result\n}\n\n/**\n * Clear error history. Returns the cleared errors.\n */\nexport function clearErrors(): MonadicError[] {\n const cleared = errors()\n errorHead = 0\n errorBufCount = 0\n errorTotal = 0\n return cleared\n}\n\n/**\n * Total error count since last clear (may exceed buffer size).\n */\nexport function getErrorCount(): number {\n return errorTotal\n}\n\n/**\n * Reset runtime state to defaults\n *\n * Resets: config, callStack, errors, unsafeDepth\n * Use this in test teardown to prevent state leaking between tests.\n */\nexport function resetRuntime(): void {\n config = { ...DEFAULT_CONFIG }\n callStackHead = 0\n callStackCount = 0\n errorHead = 0\n errorBufCount = 0\n errorTotal = 0\n unsafeDepth = 0\n}\n\n/**\n * Structural equality - the == that works\n *\n * Rules:\n * 1. If left has [tjsEquals], call left[tjsEquals](right)\n * 2. If right has [tjsEquals], call right[tjsEquals](left)\n * 3. If left has .Equals, call left.Equals(right)\n * 4. If right has .Equals, call right.Equals(left)\n * 5. Arrays/objects: recursive structural comparison\n * 6. Primitives: strict equality (no coercion)\n *\n * Usage: `a Is b` transforms to `Is(a, b)`\n */\nexport function Is(a: unknown, b: unknown): boolean {\n // Check for [tjsEquals] symbol protocol (highest priority)\n if (\n a !== null &&\n typeof a === 'object' &&\n typeof (a as any)[tjsEquals] === 'function'\n ) {\n return (a as any)[tjsEquals](b)\n }\n if (\n b !== null &&\n typeof b === 'object' &&\n typeof (b as any)[tjsEquals] === 'function'\n ) {\n return (b as any)[tjsEquals](a)\n }\n\n // Check for .Equals method (backward compat)\n if (\n a !== null &&\n typeof a === 'object' &&\n typeof (a as any).Equals === 'function'\n ) {\n return (a as any).Equals(b)\n }\n if (\n b !== null &&\n typeof b === 'object' &&\n typeof (b as any).Equals === 'function'\n ) {\n return (b as any).Equals(a)\n }\n\n // Unwrap boxed primitives (new String, new Number, new Boolean)\n // so structural equality honors the intent: new String('foo') == 'foo'\n if (a instanceof String || a instanceof Number || a instanceof Boolean) {\n a = a.valueOf()\n }\n if (b instanceof String || b instanceof Number || b instanceof Boolean) {\n b = b.valueOf()\n }\n\n // Identical references or primitives\n if (a === b) return true\n\n // NaN === NaN (JS gets this wrong)\n if (\n typeof a === 'number' &&\n typeof b === 'number' &&\n isNaN(a as number) &&\n isNaN(b as number)\n ) {\n return true\n }\n\n // null and undefined are equal to each other (nullish equality)\n // This preserves the useful JS pattern: x == null checks for both\n if ((a === null || a === undefined) && (b === null || b === undefined)) {\n return true\n }\n\n // If only one is nullish, not equal\n if (a === null || a === undefined || b === null || b === undefined) {\n return false\n }\n\n // Different types - not equal (no coercion)\n if (typeof a !== typeof b) return false\n\n // Primitives that aren't === are not equal\n if (typeof a !== 'object') return false\n\n // Sets \u2014 order-independent element equality\n if (a instanceof Set && b instanceof Set) {\n if ((a as Set<unknown>).size !== (b as Set<unknown>).size) return false\n for (const v of a as Set<unknown>) {\n if (!(b as Set<unknown>).has(v)) return false\n }\n return true\n }\n\n // Maps \u2014 key-value structural equality\n if (a instanceof Map && b instanceof Map) {\n if ((a as Map<unknown, unknown>).size !== (b as Map<unknown, unknown>).size)\n return false\n for (const [k, v] of a as Map<unknown, unknown>) {\n if (!(b as Map<unknown, unknown>).has(k)) return false\n if (!Is(v, (b as Map<unknown, unknown>).get(k))) return false\n }\n return true\n }\n\n // Dates \u2014 compare timestamps\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime()\n }\n\n // RegExps \u2014 compare string representation\n if (a instanceof RegExp && b instanceof RegExp) {\n return a.toString() === b.toString()\n }\n\n // Arrays\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false\n return a.every((v, i) => Is(v, b[i]))\n }\n if (Array.isArray(a) !== Array.isArray(b)) return false\n\n // Objects - structural comparison\n const keysA = Object.keys(a as object)\n const keysB = Object.keys(b as object)\n if (keysA.length !== keysB.length) return false\n return keysA.every((k) => Is((a as any)[k], (b as any)[k]))\n}\n\n/**\n * Structural inequality - the != that works\n *\n * Usage: `a IsNot b` transforms to `IsNot(a, b)`\n */\nexport function IsNot(a: unknown, b: unknown): boolean {\n return !Is(a, b)\n}\n\n/**\n * Honest equality \u2014 what == should have been.\n *\n * Like === but fixes the two remaining footguns:\n * 1. Unwraps boxed primitives: new String('foo') Eq 'foo' \u2192 true\n * 2. Nullish equality: null Eq undefined \u2192 true\n *\n * Does NOT do deep structural comparison on objects/arrays (that's O(n)).\n * Use Is/IsNot for explicit structural comparison when you need it.\n *\n * Usage: `a == b` with TjsEquals transforms to `Eq(a, b)`\n */\n\n/**\n * Honest typeof \u2014 fixes `typeof null === 'object'`\n *\n * Returns `'null'` for null instead of `'object'`.\n * All other values return the same as standard typeof.\n *\n * Usage: `typeof x` with TjsEquals transforms to `TypeOf(x)`\n */\nexport function TypeOf(value: unknown): string {\n if (value === null) return 'null'\n return typeof value\n}\n\n/**\n * Honest boolean coercion. Like `Boolean(x)` but unwraps boxed primitives\n * first, fixing the JS footgun `Boolean(new Boolean(false)) === true`.\n *\n * Under TjsStandard, the source rewriter wraps every truthiness context\n * (if/while/for/do-while conditions, `!`, `&&`, `||`, ternary, and\n * top-level `Boolean(x)` calls) with this function so a boxed `false`\n * actually behaves as `false`.\n */\nexport function toBool(value: unknown): boolean {\n if (\n value instanceof Boolean ||\n value instanceof Number ||\n value instanceof String\n ) {\n return Boolean((value as any).valueOf())\n }\n return Boolean(value)\n}\n\nexport function Eq(a: unknown, b: unknown): boolean {\n // Unwrap boxed primitives\n if (a instanceof String || a instanceof Number || a instanceof Boolean) {\n a = a.valueOf()\n }\n if (b instanceof String || b instanceof Number || b instanceof Boolean) {\n b = b.valueOf()\n }\n\n // Identical references or primitives\n if (a === b) return true\n\n // NaN === NaN (JS gets this wrong)\n if (\n typeof a === 'number' &&\n typeof b === 'number' &&\n isNaN(a as number) &&\n isNaN(b as number)\n ) {\n return true\n }\n\n // null and undefined are equal to each other\n if ((a === null || a === undefined) && (b === null || b === undefined)) {\n return true\n }\n\n return false\n}\n\n/**\n * Honest inequality \u2014 what != should have been.\n *\n * Usage: `a != b` with TjsEquals transforms to `NotEq(a, b)`\n */\nexport function NotEq(a: unknown, b: unknown): boolean {\n return !Eq(a, b)\n}\n\n/**\n * Check if a value is a TJS error\n */\nexport function isError(value: unknown): value is TJSError {\n return (\n value !== null &&\n typeof value === 'object' &&\n (value as any).$error === true\n )\n}\n\n/**\n * Create a TJS error\n * In debug mode, captures the current call stack\n */\nexport function error(\n message: string,\n details?: Partial<Omit<TJSError, '$error' | 'message'>>\n): TJSError {\n const err: TJSError = {\n $error: true,\n message,\n ...details,\n }\n\n // Capture call stack when tracking is enabled\n if ((config.callStacks || config.debug) && callStackCount > 0) {\n const currentStack = getStack()\n const fullStack = details?.path\n ? [...currentStack, details.path]\n : currentStack\n err.stack = fullStack\n }\n\n return err\n}\n\n/**\n * Compose multiple errors into a single error\n * Used when multiple parameters have errors\n */\nexport function composeErrors(errors: TJSError[], funcName?: string): TJSError {\n if (errors.length === 0) {\n return error('Unknown error')\n }\n if (errors.length === 1) {\n return errors[0]\n }\n\n // Build a message listing all failed parameters\n const paramNames = errors\n .map((e) => {\n // Extract param name from path (e.g., \"func.paramName\" -> \"paramName\")\n if (e.path) {\n const parts = e.path.split('.')\n return parts[parts.length - 1]\n }\n return 'unknown'\n })\n .join(', ')\n\n const message = `Multiple parameter errors in ${\n funcName || 'function'\n }: ${paramNames}`\n\n return error(message, {\n path: funcName,\n errors,\n })\n}\n\n/**\n * Get the type of a value\n *\n * Enhanced typeof that handles:\n * - null (returns 'null' not 'object')\n * - undefined (returns 'undefined')\n * - arrays (returns 'array' not 'object')\n * - native/platform types (returns constructor name for objects)\n *\n * For objects, returns the constructor name which enables pragmatic\n * native type checking (e.g., 'HTMLElement', 'Buffer', 'Event')\n */\nexport function typeOf(value: unknown): string {\n if (value === null) return 'null'\n if (value === undefined) return 'undefined'\n if (Array.isArray(value)) return 'array'\n\n const t = typeof value\n if (t !== 'object') return t\n\n // For objects, return constructor name for pragmatic native type checking\n // This enables checking for HTMLElement, Buffer, Event, etc.\n const constructorName = (value as object).constructor?.name\n if (constructorName && constructorName !== 'Object') {\n return constructorName\n }\n\n return 'object'\n}\n\n/**\n * Check if a value is an instance of a native/platform type by constructor name\n *\n * This enables pragmatic native type checking without shipping type definitions:\n * - isNativeType(el, 'HTMLElement') - DOM element check\n * - isNativeType(buf, 'Buffer') - Node.js Buffer check\n * - isNativeType(evt, 'Event') - DOM Event check\n * - isNativeType(map, 'Map') - Map instance check\n *\n * @param value - The value to check\n * @param typeName - The constructor name to match (e.g., 'HTMLElement', 'Buffer')\n * @returns true if value's constructor.name matches or is in prototype chain\n */\nexport function isNativeType(value: unknown, typeName: string): boolean {\n if (value === null || value === undefined) return false\n if (typeof value !== 'object' && typeof value !== 'function') return false\n\n // Check constructor name\n let proto = value\n while (proto !== null) {\n const constructorName = (proto as object).constructor?.name\n if (constructorName === typeName) return true\n proto = Object.getPrototypeOf(proto)\n }\n\n return false\n}\n\n/**\n * Check if a value matches an expected type\n *\n * @param value - The value to check\n * @param expected - Either a string type name ('string', 'number', etc.)\n * or a RuntimeType instance with .check() method\n * @param path - Optional path for error messages\n */\nexport function checkType(\n value: unknown,\n expected:\n | string\n | { check: (v: unknown) => boolean | string; description: string },\n path?: string\n): TJSError | null {\n // If value is already an error, propagate it\n if (isError(value)) return value\n\n // Handle RuntimeType instances (Type() results)\n if (\n typeof expected === 'object' &&\n expected !== null &&\n 'check' in expected\n ) {\n const result = expected.check(value)\n if (result === true) return null\n const reason = typeof result === 'string' ? result : undefined\n const msg = reason\n ? `Expected ${expected.description} for '${path}': ${reason}`\n : `Expected ${expected.description} but got ${typeOf(value)}`\n return error(msg, {\n path,\n expected: expected.description,\n actual: typeOf(value),\n reason,\n })\n }\n\n const actual = typeOf(value)\n\n // Handle special cases\n if (expected === 'any') return null\n if (expected === actual) return null\n\n // Number accepts both number types\n if (expected === 'number' && actual === 'number') return null\n if (expected === 'integer' && actual === 'number' && Number.isInteger(value))\n return null\n if (\n expected === 'non-negative-integer' &&\n actual === 'number' &&\n Number.isInteger(value) &&\n (value as number) >= 0\n )\n return null\n\n // Object matching (basic)\n if (expected === 'object' && actual === 'object') return null\n\n return error(`Expected ${expected} but got ${actual}`, {\n path,\n expected,\n actual,\n })\n}\n\n/** Type specifier - either a string name or a RuntimeType */\ntype TypeSpec =\n | string\n | { check: (v: unknown) => boolean | string; description: string }\n\n/**\n * Check that a passed-in function's declared shape matches the expected\n * shape. Returns the function unchanged on a match, or a MonadicError on\n * mismatch. Untyped functions (no `__tjs` metadata \u2014 anonymous arrows\n * like `x => false`) pass through unchanged on the assumption that the\n * caller knows what they're doing; they accept any args and return\n * whatever they return.\n *\n * This is a ONE-SHOT check at pass time, NOT a per-call wrapper. The TJS\n * design call: a wrong-shape callback is ONE error at the boundary, not\n * N errors when the receiving function invokes the callback N times.\n *\n * Compatibility rules (deliberately permissive \u2014 strict subtyping is a\n * separate, larger feature):\n * - For each expected param: the actual function may declare fewer\n * params (extras simply not used). If both declare a kind, they\n * must match exactly. Either side being `any` always matches.\n * - For the return type: same exact-match rule when both are known.\n */\nexport function checkFnShape(\n fn: unknown,\n expectedParamKinds: string[],\n expectedReturnKind: string,\n path: string\n): unknown {\n if (typeof fn !== 'function') return fn // outer \"is callable\" check already ran\n const meta = (fn as any).__tjs\n if (!meta || !meta.params) return fn // untyped \u2014 let it run\n\n const actualEntries = Object.entries(meta.params) as Array<\n [string, { type?: { kind?: string } }]\n >\n for (let i = 0; i < expectedParamKinds.length; i++) {\n const expectedKind = expectedParamKinds[i]\n if (expectedKind === 'any') continue\n const actual = actualEntries[i]\n if (!actual) continue // function takes fewer params, OK\n const actualKind = actual[1]?.type?.kind\n if (!actualKind || actualKind === 'any') continue\n if (actualKind !== expectedKind) {\n return new MonadicError(\n `Expected (...arg${i}: ${expectedKind}, ...) for '${path}', ` +\n `but callback declares arg${i} as ${actualKind}`,\n `${path}(arg${i})`,\n expectedKind,\n actualKind\n )\n }\n }\n\n if (expectedReturnKind !== 'any' && meta.returns) {\n // Metadata's `returns` is `{ type: TypeDescriptor, defaults?: ... }`,\n // but defensively also accept a bare TypeDescriptor.\n const actualReturnKind = meta.returns.type?.kind ?? meta.returns.kind\n if (\n actualReturnKind &&\n actualReturnKind !== 'any' &&\n actualReturnKind !== expectedReturnKind\n ) {\n return new MonadicError(\n `Expected callback returning ${expectedReturnKind} for '${path}', ` +\n `but callback returns ${actualReturnKind}`,\n `${path}(return)`,\n expectedReturnKind,\n actualReturnKind\n )\n }\n }\n\n return fn\n}\n\n/** Parameter metadata with optional location */\ninterface ParamMeta {\n type: TypeSpec\n required: boolean\n default?: unknown\n loc?: { start: number; end: number }\n}\n\n/**\n * Validate function arguments against __tjs metadata\n * Returns first error found, or null if all valid\n */\nexport function validateArgs(\n args: Record<string, unknown>,\n meta: {\n params: Record<string, ParamMeta>\n },\n funcName?: string\n): TJSError | null {\n for (const [name, param] of Object.entries(meta.params)) {\n const value = args[name]\n\n // Check if any arg is already an error - propagate first one\n if (isError(value)) return value\n\n // Check required\n if (param.required && value === undefined) {\n const expectedDesc =\n typeof param.type === 'string' ? param.type : param.type.description\n return error(`Missing required parameter '${name}'`, {\n path: funcName ? `${funcName}.${name}` : name,\n expected: expectedDesc,\n actual: 'undefined',\n loc: param.loc,\n })\n }\n\n // Skip type check for undefined optional params\n if (value === undefined) continue\n\n // Type check\n const typeError = checkType(\n value,\n param.type,\n funcName ? `${funcName}.${name}` : name\n )\n if (typeError) {\n // Add location info if available\n if (param.loc) {\n typeError.loc = param.loc\n }\n return typeError\n }\n }\n\n return null\n}\n\n/**\n * Function metadata with safety flags\n */\nexport interface FunctionMeta {\n params: Record<string, any>\n returns?: { type: any; safe?: boolean; defaults?: Record<string, unknown> }\n /** Function marked with (!) - never validate inputs */\n unsafe?: boolean\n /** Function marked with (?) - always validate inputs */\n safe?: boolean\n /** Return type marked with -! - never validate output */\n unsafeReturn?: boolean\n /** Return type marked with -? - always validate output */\n safeReturn?: boolean\n /** Explicit function name for stack tracking (used when fn.name is empty) */\n name?: string\n /** Polymorphic dispatcher \u2014 skip wrapping, dispatch handles validation */\n polymorphic?: boolean\n}\n\n/**\n * Determine if we should validate inputs for this call\n * Reserved for future use with runtime validation modes\n */\nfunction _shouldValidateInputs(meta: FunctionMeta): boolean {\n // Per-function flags take precedence\n if (meta.unsafe) return false\n if (meta.safe) return true\n\n // Block-level override\n if (unsafeDepth > 0) return false\n\n // Global safety level\n return config.safety !== 'none'\n}\n\n/**\n * Determine if we should validate outputs for this call\n * Reserved for future use with runtime validation modes\n */\nfunction _shouldValidateOutputs(meta: FunctionMeta): boolean {\n // No return type declared = no validation\n if (!meta.returns) return false\n\n // Per-function return flags take precedence\n if (meta.unsafeReturn) return false\n if (meta.safeReturn) return true\n\n // Block-level override\n if (unsafeDepth > 0) return false\n\n // Global safety level: 'all' validates outputs, others don't by default\n return config.safety === 'all'\n}\n\n/**\n * Wrap a function with monadic type checking\n *\n * @param fn - The original function\n * @param meta - The __tjs metadata\n * @returns Wrapped function that validates inputs and propagates errors\n */\nexport function wrap<T extends (...args: any[]) => any>(\n fn: T,\n meta: FunctionMeta\n): T {\n // Always attach metadata for introspection/autocomplete\n ;(fn as any).__tjs = meta\n // Lazy JSON Schema generation \u2014 only computed when called\n ;(fn as any).__tjs.schema = () => functionMetaToJSONSchema(meta)\n\n // Determine if we need a wrapper at all\n // Polymorphic dispatchers handle their own routing \u2014 no wrapping needed\n const needsWrapper =\n !meta.polymorphic && // Has forced safety that requires validation\n (meta.safe ||\n meta.safeReturn ||\n // Global safety requires validation (and not explicitly unsafe)\n (config.safety !== 'none' && !meta.unsafe) ||\n // Has return type that might need validation\n (meta.returns && config.safety === 'all' && !meta.unsafeReturn))\n\n if (!needsWrapper) {\n return fn\n }\n\n // Pre-compute flags at wrap time\n const hasReturns = !!meta.returns\n const metaUnsafe = !!meta.unsafe\n const metaSafe = !!meta.safe\n const metaUnsafeReturn = !!meta.unsafeReturn\n const metaSafeReturn = !!meta.safeReturn\n // Pre-compute return defaults (for `key = value` in return type signatures)\n // NOTE: applying defaults adds an Object.assign per call \u2014 may need benchmarking\n const returnDefaults = meta.returns?.defaults\n const paramEntries = Object.entries(meta.params)\n const paramCount = paramEntries.length\n // Use meta.name as fallback when fn.name is empty (anonymous functions)\n const funcName = fn.name || meta.name || 'anonymous'\n\n const wrapped = function (this: any, ...args: Parameters<T>): ReturnType<T> {\n // Fast path: inside unsafe block, skip all validation\n if (unsafeDepth > 0) {\n return fn.apply(this, args)\n }\n\n // Compute validation flags\n const validateInputs = metaSafe || (!metaUnsafe && config.safety !== 'none')\n const validateOutputs =\n hasReturns &&\n (metaSafeReturn || (!metaUnsafeReturn && config.safety === 'all'))\n\n // Fast path: no validation needed\n if (!validateInputs && !validateOutputs) {\n return fn.apply(this, args)\n }\n\n // Fast path: check for error as first arg\n if (args.length > 0 && isError(args[0])) {\n return args[0] as ReturnType<T>\n }\n\n // Input validation\n if (validateInputs) {\n // Detect if single object arg (named params) vs positional\n const isNamedCall =\n args.length === 1 &&\n typeof args[0] === 'object' &&\n args[0] !== null &&\n !Array.isArray(args[0])\n\n // Collect all errors to compose them\n const collectedErrors: TJSError[] = []\n\n // Fast positional validation (avoids object allocation)\n if (!isNamedCall) {\n for (let i = 0; i < paramCount; i++) {\n const [name, param] = paramEntries[i]\n const value = args[i]\n\n // Check for error propagation (passed-in errors)\n if (isError(value)) {\n collectedErrors.push(value)\n continue\n }\n\n // Check required\n if (param.required && value === undefined) {\n collectedErrors.push(\n error(`Missing required parameter '${name}'`, {\n path: `${funcName}.${name}`,\n expected:\n typeof param.type === 'string'\n ? param.type\n : param.type?.description || 'value',\n actual: 'undefined',\n loc: param.loc,\n })\n )\n continue\n }\n\n // Type check (skip undefined optional)\n if (value !== undefined) {\n const typeErr = checkType(value, param.type, `${funcName}.${name}`)\n if (typeErr) {\n if (param.loc) typeErr.loc = param.loc\n collectedErrors.push(typeErr)\n }\n }\n }\n } else {\n // Named args path (slower, but supports object destructuring)\n const namedArgs = args[0] as Record<string, unknown>\n for (let i = 0; i < paramCount; i++) {\n const [name, param] = paramEntries[i]\n const value = namedArgs[name]\n\n if (isError(value)) {\n collectedErrors.push(value)\n continue\n }\n\n if (param.required && value === undefined) {\n collectedErrors.push(\n error(`Missing required parameter '${name}'`, {\n path: `${funcName}.${name}`,\n expected:\n typeof param.type === 'string'\n ? param.type\n : param.type?.description || 'value',\n actual: 'undefined',\n loc: param.loc,\n })\n )\n continue\n }\n\n if (value !== undefined) {\n const typeErr = checkType(value, param.type, `${funcName}.${name}`)\n if (typeErr) {\n if (param.loc) typeErr.loc = param.loc\n collectedErrors.push(typeErr)\n }\n }\n }\n }\n\n // If we collected any errors, compose and return them\n if (collectedErrors.length > 0) {\n return composeErrors(collectedErrors, funcName) as ReturnType<T>\n }\n }\n\n // Track call stack only when enabled (ring buffer, no allocation)\n const trackStack = config.callStacks || config.debug\n if (trackStack) pushStack(funcName)\n\n try {\n // Execute function\n const result = fn.apply(this, args)\n\n // Output validation\n if (validateOutputs && meta.returns && !isError(result)) {\n // Apply return defaults before validation\n const validated =\n returnDefaults && typeof result === 'object' && result !== null\n ? Object.assign({}, returnDefaults, result)\n : result\n const returnError = checkType(\n validated,\n meta.returns.type,\n `${funcName}()`\n )\n if (returnError) {\n if (trackStack) popStack()\n return returnError as ReturnType<T>\n }\n }\n\n if (trackStack) popStack()\n return result\n } catch (e) {\n if (trackStack) popStack()\n // Convert thrown errors to TJS errors\n return error((e as Error).message || String(e), {\n path: funcName,\n cause: e as Error,\n }) as ReturnType<T>\n }\n }\n\n // Preserve function name and metadata\n Object.defineProperty(wrapped, 'name', { value: fn.name })\n ;(wrapped as any).__tjs = meta\n ;(wrapped as any).__tjs.schema = () => functionMetaToJSONSchema(meta)\n\n return wrapped as T\n}\n\n/**\n * Wrap a class to make it callable without `new`\n *\n * In TJS, classes can be instantiated without the `new` keyword:\n * const obj = MyClass(args) // equivalent to new MyClass(args)\n *\n * This eliminates a common source of errors where developers forget `new`.\n * Using explicit `new` still works but should be flagged by the linter.\n */\nexport function wrapClass<T extends new (...args: any[]) => any>(\n cls: T\n): T & ((...args: ConstructorParameters<T>) => InstanceType<T>) {\n // Use a Proxy to intercept both `new Wrapper()` and `Wrapper()` calls\n const wrapped = new Proxy(cls, {\n // Called when using `new Wrapper(...)`\n construct(target, args, newTarget) {\n return Reflect.construct(target, args, newTarget)\n },\n // Called when using `Wrapper(...)` without new\n apply(target, _thisArg, args) {\n return Reflect.construct(target, args)\n },\n })\n\n // Preserve class name\n Object.defineProperty(wrapped, 'name', { value: cls.name })\n\n // Copy static properties and methods\n for (const key of Object.getOwnPropertyNames(cls)) {\n if (key !== 'length' && key !== 'name' && key !== 'prototype') {\n Object.defineProperty(\n wrapped,\n key,\n Object.getOwnPropertyDescriptor(cls, key)!\n )\n }\n }\n\n return wrapped as T & ((...args: ConstructorParameters<T>) => InstanceType<T>)\n}\n\n// ============================================================================\n// SafeFunction and Eval - moved to ./eval.ts\n// ============================================================================\n//\n// Eval and SafeFunction are in a separate module to keep the runtime lite.\n// Import from 'tjs-lang/eval' when you need dynamic code execution.\n//\n// Runtime (this file): ~5KB gzipped - type checking, Is/IsNot, wrap, etc.\n// Eval module: ~27KB gzipped - adds transpiler + VM for dynamic code\n// ============================================================================\n\n/**\n * Create an isolated TJS runtime instance\n *\n * Each call returns a fresh runtime with its own:\n * - config (debug, safety, etc.)\n * - callStack\n * - unsafeDepth\n *\n * The new instance inherits the current global config at creation time,\n * but subsequent changes are isolated.\n *\n * Use this to prevent state leaking between transpiled modules.\n */\nexport function createRuntime() {\n // Per-instance state - inherit current global config\n let instanceConfig: TJSConfig = { ...config }\n const instStackSize = instanceConfig.maxStackSize ?? STACK_SIZE\n const instanceStackBuffer: string[] = new Array(instStackSize).fill('')\n let instanceStackHead = 0\n let instanceStackCount = 0\n const instErrorSize = instanceConfig.maxErrors ?? ERROR_BUF_SIZE\n const instanceErrorBuffer: any[] = new Array(instErrorSize).fill(null)\n let instanceErrorHead = 0\n let instanceErrorBufCount = 0\n let instanceErrorTotal = 0\n let instanceUnsafeDepth = 0\n\n // Per-instance stateful functions\n function instanceConfigure(options: TJSConfig): void {\n instanceConfig = { ...instanceConfig, ...options }\n }\n\n function instanceGetConfig(): TJSConfig {\n return { ...instanceConfig }\n }\n\n function instancePushStack(name: string): void {\n if ((instanceConfig.callStacks || instanceConfig.debug) && name) {\n instanceStackBuffer[instanceStackHead] = name\n instanceStackHead = (instanceStackHead + 1) % instStackSize\n if (instanceStackCount < instStackSize) instanceStackCount++\n }\n }\n\n function instancePopStack(): void {\n if (\n (instanceConfig.callStacks || instanceConfig.debug) &&\n instanceStackCount > 0\n ) {\n instanceStackHead =\n (instanceStackHead - 1 + instStackSize) % instStackSize\n instanceStackCount--\n }\n }\n\n function instanceGetStack(): string[] {\n if (instanceStackCount === 0) return []\n const result: string[] = []\n const start =\n (instanceStackHead - instanceStackCount + instStackSize) % instStackSize\n for (let i = 0; i < instanceStackCount; i++) {\n result.push(instanceStackBuffer[(start + i) % instStackSize])\n }\n return result\n }\n\n function instanceResetRuntime(): void {\n instanceConfig = { ...DEFAULT_CONFIG }\n instanceStackHead = 0\n instanceStackCount = 0\n instanceErrorHead = 0\n instanceErrorBufCount = 0\n instanceErrorTotal = 0\n instanceUnsafeDepth = 0\n }\n\n function instanceEnterUnsafe(): void {\n instanceUnsafeDepth++\n }\n\n function instanceExitUnsafe(): void {\n if (instanceUnsafeDepth > 0) instanceUnsafeDepth--\n }\n\n function instanceIsUnsafeMode(): boolean {\n return instanceUnsafeDepth > 0\n }\n\n // Extension registry: typeName -> methodName -> fn\n const extensionRegistry = new Map<\n string,\n Map<string, (...args: any[]) => any>\n >()\n\n function instanceRegisterExtension(\n typeName: string,\n methodName: string,\n fn: (...args: any[]) => any\n ): void {\n if (!extensionRegistry.has(typeName)) {\n extensionRegistry.set(typeName, new Map())\n }\n extensionRegistry.get(typeName)!.set(methodName, fn)\n }\n\n function instanceResolveExtension(\n value: unknown,\n methodName: string\n ): ((...args: any[]) => any) | undefined {\n // Determine type name from value\n const t = typeof value\n let typeName: string\n if (value === null || value === undefined) return undefined\n if (t === 'string') typeName = 'String'\n else if (t === 'number') typeName = 'Number'\n else if (t === 'boolean') typeName = 'Boolean'\n else if (Array.isArray(value)) typeName = 'Array'\n else if (t === 'object') {\n // Check constructor name for class instances (including DOM classes)\n typeName = (value as any).constructor?.name || 'Object'\n } else {\n return undefined\n }\n\n // Walk prototype chain: HTMLInputElement -> HTMLElement -> Element -> Object\n let current: string | undefined = typeName\n while (current) {\n const methods = extensionRegistry.get(current)\n if (methods?.has(methodName)) {\n return methods.get(methodName)\n }\n // Walk up: try parent class (for DOM/custom class hierarchies)\n if (t === 'object' && !Array.isArray(value)) {\n const proto = Object.getPrototypeOf(\n current === typeName ? value : Object.getPrototypeOf(value)\n )\n current = proto?.constructor?.name\n if (current === 'Object' || current === typeName) break\n } else {\n break\n }\n }\n\n // Fallback: check 'Object' extensions\n const objectMethods = extensionRegistry.get('Object')\n if (objectMethods?.has(methodName)) {\n return objectMethods.get(methodName)\n }\n\n return undefined\n }\n\n function instanceTypeError(\n path: string,\n expected: string,\n value: unknown\n ): MonadicError {\n const actual = value === null ? 'null' : typeof value\n const stack =\n instanceConfig.callStacks || instanceConfig.debug\n ? instanceGetStack()\n : undefined\n const err = new MonadicError(\n `Expected ${expected} for '${path}', got ${actual}`,\n path,\n expected,\n actual,\n stack\n )\n\n // Track in error history\n if (instanceConfig.trackErrors !== false) {\n instanceErrorBuffer[instanceErrorHead] = err\n instanceErrorHead = (instanceErrorHead + 1) % instErrorSize\n if (instanceErrorBufCount < instErrorSize) instanceErrorBufCount++\n instanceErrorTotal++\n }\n\n if (instanceConfig.logTypeErrors) {\n console.error(`[TJS TypeError] ${err.message}`)\n }\n if (instanceConfig.throwTypeErrors) {\n throw err\n }\n\n return err\n }\n\n function instanceErrors(): MonadicError[] {\n if (instanceConfig.trackErrors === false || instanceErrorBufCount === 0)\n return []\n const result: MonadicError[] = []\n const start =\n (instanceErrorHead - instanceErrorBufCount + instErrorSize) %\n instErrorSize\n for (let i = 0; i < instanceErrorBufCount; i++) {\n result.push(instanceErrorBuffer[(start + i) % instErrorSize])\n }\n return result\n }\n\n function instanceClearErrors(): MonadicError[] {\n const cleared = instanceErrors()\n instanceErrorHead = 0\n instanceErrorBufCount = 0\n instanceErrorTotal = 0\n return cleared\n }\n\n function instanceGetErrorCount(): number {\n return instanceErrorTotal\n }\n\n function instanceError(\n message: string,\n details?: Partial<Omit<TJSError, '$error' | 'message'>>\n ): TJSError {\n const err: TJSError = {\n $error: true,\n message,\n ...details,\n }\n if (\n (instanceConfig.callStacks || instanceConfig.debug) &&\n instanceStackCount > 0\n ) {\n const fullStack = details?.path\n ? [...instanceGetStack(), details.path]\n : instanceGetStack()\n err.stack = fullStack\n }\n return err\n }\n\n /**\n * Bang access (!.) \u2014 asserted non-null member access.\n * Returns MonadicError if obj is null, undefined, or already a MonadicError.\n * Otherwise returns obj[prop] (bare access \u2014 throws as usual on other errors).\n */\n function instanceBang(obj: unknown, prop: string): unknown {\n if (obj === null || obj === undefined) {\n return instanceTypeError(`bang.${prop}`, 'non-null', obj)\n }\n if (isMonadicError(obj)) return obj\n return (obj as any)[prop]\n }\n\n return {\n version: TJS_VERSION,\n // Monadic error handling\n MonadicError,\n typeError: instanceTypeError,\n isMonadicError,\n // Bang access (!.)\n bang: instanceBang,\n // Legacy error handling\n isError,\n error: instanceError,\n composeErrors,\n typeOf,\n isNativeType,\n checkType,\n validateArgs,\n wrap,\n checkFnShape,\n wrapClass,\n compareVersions,\n versionsCompatible,\n // Create child runtime instances\n createRuntime,\n // Debug mode (instance-specific)\n configure: instanceConfigure,\n getConfig: instanceGetConfig,\n pushStack: instancePushStack,\n popStack: instancePopStack,\n getStack: instanceGetStack,\n errors: instanceErrors,\n clearErrors: instanceClearErrors,\n getErrorCount: instanceGetErrorCount,\n resetRuntime: instanceResetRuntime,\n // Unsafe mode (instance-specific)\n enterUnsafe: instanceEnterUnsafe,\n exitUnsafe: instanceExitUnsafe,\n isUnsafeMode: instanceIsUnsafeMode,\n // Type system\n validate,\n infer: s.infer.bind(s),\n Type,\n isRuntimeType,\n Union,\n Generic,\n Enum,\n FunctionPredicate,\n Nullable,\n Optional,\n TArray,\n TString,\n TNumber,\n TBoolean,\n TInteger,\n TPositiveInt,\n TNonEmptyString,\n TEmail,\n TUrl,\n TUuid,\n TPair,\n TRecord,\n // Structural equality\n Is,\n IsNot,\n // Honest equality (== / != with TjsEquals)\n Eq,\n NotEq,\n // Honest typeof (typeof with TjsEquals)\n TypeOf,\n // Honest truthiness (unwraps boxed primitives)\n toBool,\n tjsEquals,\n // Extensions\n registerExtension: instanceRegisterExtension,\n resolveExtension: instanceResolveExtension,\n }\n}\n\n/** Type for runtime instances */\nexport type TJSRuntime = ReturnType<typeof createRuntime>\n\n/**\n * TJS Runtime object - attached to globalThis.__tjs\n *\n * NOTE: This is a shared global instance. For isolated execution,\n * use createRuntime() instead.\n */\nexport const runtime = {\n version: TJS_VERSION,\n // Monadic error handling (new)\n MonadicError,\n typeError,\n isMonadicError,\n // Legacy error handling (deprecated)\n isError,\n error,\n composeErrors,\n typeOf,\n isNativeType,\n checkType,\n validateArgs,\n wrap,\n checkFnShape,\n wrapClass,\n compareVersions,\n versionsCompatible,\n // Debug mode\n configure,\n getConfig,\n pushStack,\n popStack,\n getStack,\n errors,\n clearErrors,\n getErrorCount,\n resetRuntime,\n // Unsafe mode\n enterUnsafe,\n exitUnsafe,\n isUnsafeMode,\n // Factory for isolated instances\n createRuntime,\n // Type system (used by transpiled Type declarations)\n validate,\n infer: s.infer.bind(s),\n Type,\n isRuntimeType,\n Union,\n Generic,\n Enum,\n FunctionPredicate,\n Nullable,\n Optional,\n TArray,\n // Built-in types\n TString,\n TNumber,\n TBoolean,\n TInteger,\n TPositiveInt,\n TNonEmptyString,\n TEmail,\n TUrl,\n TUuid,\n Timestamp,\n LegalDate,\n TPair,\n TRecord,\n // Structural equality (used by Is/IsNot operators)\n Is,\n IsNot,\n // Honest equality (used by == and != with TjsEquals)\n Eq,\n NotEq,\n // Honest typeof (used by typeof with TjsEquals)\n TypeOf,\n // Honest truthiness (used in TjsStandard for boxed-primitive coercion)\n toBool,\n}\n\n/**\n * Install runtime globally (idempotent, version-checked)\n *\n * Version handling:\n * - Same version: reuse existing (no warning)\n * - Compatible (same major): reuse existing, log info\n * - Incompatible (different major): warn, use newer version\n */\nexport function installRuntime(): typeof runtime {\n const g = globalThis as any\n\n if (g.__tjs) {\n const existingVersion = g.__tjs.version\n\n // Guard against polluted __tjs without proper version\n if (typeof existingVersion !== 'string') {\n g.__tjs = runtime\n return runtime\n }\n\n const comparison = compareVersions(TJS_VERSION, existingVersion)\n\n if (comparison === 0) {\n // Exact same version - just reuse\n return g.__tjs\n }\n\n if (versionsCompatible(TJS_VERSION, existingVersion)) {\n // Same major version - compatible, use newer\n if (comparison > 0) {\n console.info(\n `TJS runtime: upgrading ${existingVersion} \u2192 ${TJS_VERSION}`\n )\n g.__tjs = runtime\n } else {\n console.info(\n `TJS runtime: keeping ${existingVersion} (newer than ${TJS_VERSION})`\n )\n }\n } else {\n // Different major version - breaking change potential\n console.warn(\n `TJS runtime version conflict: ${existingVersion} vs ${TJS_VERSION} (major version mismatch)`\n )\n // Use the newer one but warn about potential issues\n if (comparison > 0) {\n console.warn(`Upgrading to ${TJS_VERSION} - check for breaking changes`)\n g.__tjs = runtime\n }\n }\n\n return g.__tjs\n }\n\n g.__tjs = runtime\n return runtime\n}\n\n/**\n * Generate runtime wrapper code for emitted JS\n * Skips wrapping for unsafe functions (marked with !)\n */\nexport function emitRuntimeWrapper(funcName: string): string {\n return `\n// TJS runtime wrapper (skips unsafe functions)\nif (typeof ${funcName}.__tjs === 'object' && !${funcName}.__tjs.unsafe && typeof globalThis.__tjs?.wrap === 'function') {\n ${funcName} = globalThis.__tjs.wrap(${funcName}, ${funcName}.__tjs)\n}\n`.trim()\n}\n\n/**\n * Generate class wrapper code for emitted JS\n * Makes classes callable without `new` keyword\n * Emits standalone JS - no runtime dependency\n */\nexport function emitClassWrapper(className: string): string {\n return `\n// TJS: callable without new\n${className} = new Proxy(${className}, { apply(t, _, a) { return Reflect.construct(t, a) } });\n`.trim()\n}\n\n/**\n * Questions/Notes:\n *\n * Q1: Should wrap() be automatic or opt-in?\n * Current: Must be explicitly wrapped\n * Could: Auto-wrap all functions with __tjs metadata\n *\n * Q2: Performance overhead of validation?\n * Need benchmarks comparing wrapped vs unwrapped\n * Could have 'production' mode that skips validation\n *\n * Q3: Async function handling?\n * wrap() should detect async and handle Promise returns\n *\n * Q4: Deep object validation?\n * Currently only checks top-level type\n * Could recursively validate object shapes\n */\n", "/**\n * JSON Schema generation from TJS TypeDescriptors and example values\n *\n * Converts TJS type information into standard JSON Schema (draft 2020-12).\n */\n\nimport type { TypeDescriptor } from './types'\n\nexport interface JSONSchemaObject {\n type?: string | string[]\n properties?: Record<string, JSONSchemaObject>\n items?: JSONSchemaObject | JSONSchemaObject[]\n required?: string[]\n additionalProperties?: boolean\n anyOf?: JSONSchemaObject[]\n minimum?: number\n examples?: unknown[]\n description?: string\n [key: string]: unknown\n}\n\n/**\n * Convert a TypeDescriptor to JSON Schema\n */\nexport function typeDescriptorToJSONSchema(\n td: TypeDescriptor\n): JSONSchemaObject {\n if (td.nullable) {\n const base = typeDescriptorToJSONSchema({ ...td, nullable: false })\n return { anyOf: [base, { type: 'null' }] }\n }\n\n switch (td.kind) {\n case 'string':\n return { type: 'string' }\n case 'number':\n return { type: 'number' }\n case 'integer':\n return { type: 'integer' }\n case 'non-negative-integer':\n return { type: 'integer', minimum: 0 }\n case 'boolean':\n return { type: 'boolean' }\n case 'null':\n return { type: 'null' }\n case 'undefined':\n return {}\n case 'any':\n return {}\n case 'array':\n if (td.items) {\n return { type: 'array', items: typeDescriptorToJSONSchema(td.items) }\n }\n return { type: 'array' }\n case 'object':\n if (td.shape) {\n const properties: Record<string, JSONSchemaObject> = {}\n const required: string[] = []\n for (const [key, fieldTd] of Object.entries(td.shape)) {\n properties[key] = typeDescriptorToJSONSchema(fieldTd)\n required.push(key)\n }\n return {\n type: 'object',\n properties,\n required,\n additionalProperties: false,\n }\n }\n return { type: 'object' }\n case 'union':\n if (td.members) {\n return { anyOf: td.members.map(typeDescriptorToJSONSchema) }\n }\n return {}\n default:\n return {}\n }\n}\n\n/**\n * Infer a JSON Schema from an example value (without going through TypeDescriptor)\n */\nexport function exampleToJSONSchema(value: unknown): JSONSchemaObject {\n if (value === null) return { type: 'null' }\n if (value === undefined) return {}\n\n switch (typeof value) {\n case 'string':\n return { type: 'string' }\n case 'number':\n return Number.isInteger(value) ? { type: 'integer' } : { type: 'number' }\n case 'boolean':\n return { type: 'boolean' }\n case 'object': {\n if (Array.isArray(value)) {\n if (value.length === 0) return { type: 'array' }\n // Infer item type from first element\n return { type: 'array', items: exampleToJSONSchema(value[0]) }\n }\n // Object\n const properties: Record<string, JSONSchemaObject> = {}\n const required: string[] = []\n for (const [key, val] of Object.entries(\n value as Record<string, unknown>\n )) {\n properties[key] = exampleToJSONSchema(val)\n required.push(key)\n }\n return {\n type: 'object',\n properties,\n required,\n additionalProperties: false,\n }\n }\n default:\n return {}\n }\n}\n\n/**\n * Generate JSON Schema for function parameters (as an object schema)\n * and return type from __tjs metadata\n */\nexport function functionMetaToJSONSchema(meta: {\n params: Record<string, any>\n returns?: { type: any; example?: any }\n}): { input: JSONSchemaObject; output?: JSONSchemaObject } {\n const properties: Record<string, JSONSchemaObject> = {}\n const required: string[] = []\n\n for (const [name, paramInfo] of Object.entries(meta.params)) {\n if (paramInfo?.type?.kind) {\n // Has TypeDescriptor\n properties[name] = typeDescriptorToJSONSchema(paramInfo.type)\n } else if (paramInfo?.example !== undefined) {\n // Has example value\n properties[name] = exampleToJSONSchema(paramInfo.example)\n } else {\n properties[name] = {}\n }\n if (paramInfo?.required !== false) {\n required.push(name)\n }\n if (paramInfo?.example !== undefined) {\n properties[name].examples = [paramInfo.example]\n }\n }\n\n const input: JSONSchemaObject = {\n type: 'object',\n properties,\n required,\n }\n\n let output: JSONSchemaObject | undefined\n if (meta.returns) {\n if (meta.returns.type?.kind) {\n output = typeDescriptorToJSONSchema(meta.returns.type)\n } else if (meta.returns.example !== undefined) {\n output = exampleToJSONSchema(meta.returns.example)\n }\n }\n\n return { input, output }\n}\n", "/**\n * Type() - Runtime type definitions with descriptions and validation\n *\n * Forms:\n * Type(description, predicate) - full form with custom validation\n * Type(description, schema) - schema-based validation\n * Type(schema) - schema only, self-documenting\n *\n * Usage:\n * const ZipCode = Type('5-digit US zip code', (s) => /^\\d{5}$/.test(s))\n * const Email = Type('valid email', s.string.email)\n * const Age = Type(s.number.min(0).max(150))\n *\n * ZipCode.check('12345') // true\n * ZipCode.check('abc') // false\n * ZipCode.description // '5-digit US zip code'\n */\n\nimport { validate, filter as schemaFilter, s, type Base } from 'tosijs-schema'\nimport { exampleToJSONSchema, type JSONSchemaObject } from '../lang/json-schema'\n\n/** JSON Schema object type (simplified) */\ntype JSONSchema = {\n type?: string\n properties?: Record<string, JSONSchema>\n items?: JSONSchema\n required?: string[]\n [key: string]: unknown\n}\n\n/** Schema can be a tosijs-schema builder or a raw JSON Schema object */\ntype Schema = Base<any> | JSONSchema\n\n/** A runtime type with description and validation */\nexport interface RuntimeType<T = unknown> {\n /** Human-readable description of the type */\n readonly description: string\n /** Check if a value matches this type. Returns true on pass, false on fail, or a reason string on fail. */\n check(value: unknown): boolean | string\n /** The underlying schema (if schema-based) */\n readonly schema?: Schema\n /** The predicate function (if predicate-based). May return a reason string on failure. */\n readonly predicate?: (value: unknown) => boolean | string\n /** Example value (for documentation and signature testing) */\n readonly example?: T\n /** Multiple example values (from schema metadata, for autocomplete hints) */\n readonly examples?: T[]\n /** Default value (for instantiation) */\n readonly default?: T\n /** Generate JSON Schema for this type */\n toJSONSchema(): JSONSchemaObject\n /** Strip a value down to only the fields matching this type's schema */\n strip(value: unknown): unknown\n /** Brand for type identification */\n readonly __runtimeType: true\n}\n\n/** Check if a value is a RuntimeType */\nexport function isRuntimeType(value: unknown): value is RuntimeType {\n return (\n value !== null &&\n typeof value === 'object' &&\n '__runtimeType' in value &&\n (value as any).__runtimeType === true\n )\n}\n\n/**\n * Create a runtime type with description and validation\n *\n * @overload Type(description, predicate) - custom validation function\n * @overload Type(description, schema) - schema-based validation\n * @overload Type(schema) - schema only\n */\n/**\n * Check if a value is a tosijs-schema builder (has .schema property)\n */\nfunction isSchemaBuilder(value: unknown): value is Base<any> {\n return (\n value !== null &&\n typeof value === 'object' &&\n 'schema' in value &&\n typeof (value as any).schema === 'object'\n )\n}\n\n/**\n * Check if a value looks like a raw JSON Schema object\n */\nfunction isJSONSchema(value: unknown): value is JSONSchema {\n return (\n value !== null &&\n typeof value === 'object' &&\n 'type' in value &&\n typeof (value as any).type === 'string'\n )\n}\n\nexport function Type<T = unknown>(\n descriptionOrSchema: string | Schema,\n predicateOrSchemaOrExample?:\n | ((value: unknown) => boolean | string)\n | Schema\n | T\n | undefined,\n exampleArg?: T,\n defaultArg?: T\n): RuntimeType<T> {\n // Parse arguments\n let description: string\n let predicate: ((value: unknown) => boolean | string) | undefined\n let schema: Schema | undefined\n let example: T | undefined = exampleArg\n let defaultValue: T | undefined = defaultArg\n\n if (typeof descriptionOrSchema === 'string') {\n // Form: Type(description, predicate/schema/example, example?, default?)\n description = descriptionOrSchema\n\n if (typeof predicateOrSchemaOrExample === 'function') {\n // Type(description, predicate, example?, default?)\n predicate = predicateOrSchemaOrExample as (\n value: unknown\n ) => boolean | string\n // If we have example, infer schema from it for the type guard in predicate\n if (example !== undefined) {\n schema = s.infer(example)\n }\n } else if (\n predicateOrSchemaOrExample === undefined &&\n example !== undefined\n ) {\n // Type(description, undefined, example, default?) - example provides schema\n schema = s.infer(example)\n } else if (isSchemaBuilder(predicateOrSchemaOrExample)) {\n // Type(description, schemaBuilder)\n schema = predicateOrSchemaOrExample\n } else if (isJSONSchema(predicateOrSchemaOrExample)) {\n // Type(description, jsonSchema)\n schema = predicateOrSchemaOrExample\n } else if (predicateOrSchemaOrExample !== undefined) {\n // Type(description, example) - second arg is the example/default, infer schema\n // This is the simple form: Type('Name', 'Alice')\n example = predicateOrSchemaOrExample as T\n defaultValue = example // In simple form, example IS the default\n schema = s.infer(example)\n } else {\n throw new Error(\n 'Type(description) requires a predicate, schema, or example'\n )\n }\n } else {\n // Form: Type(schema) or Type(schemaBuilder)\n if (isSchemaBuilder(descriptionOrSchema)) {\n schema = descriptionOrSchema\n } else {\n schema = descriptionOrSchema as Schema\n }\n description = schemaToDescription(schema)\n }\n\n // Extract examples from schema metadata (if any)\n let examples: T[] | undefined\n if (schema) {\n const jsonSchema = (schema as any)?.schema ?? schema\n if (\n jsonSchema &&\n typeof jsonSchema === 'object' &&\n Array.isArray((jsonSchema as any).examples)\n ) {\n examples = (jsonSchema as any).examples as T[]\n }\n }\n\n // If no explicit example was provided, use first schema example for autocomplete\n if (example === undefined && examples && examples.length > 0) {\n example = examples[0]\n }\n\n // Build the check function\n // Returns true on pass, false on fail, or a reason string on fail\n const check = (value: unknown): boolean | string => {\n if (predicate) {\n return predicate(value)\n }\n if (schema) {\n return validate(value, schema)\n }\n return false\n }\n\n return {\n description,\n check,\n schema,\n predicate,\n example,\n examples,\n default: defaultValue,\n toJSONSchema(): JSONSchemaObject {\n // If we have an underlying JSON Schema or builder, extract it\n if (schema) {\n const raw = (schema as any)?.schema ?? schema\n if (raw && typeof raw === 'object' && 'type' in raw) {\n return raw as JSONSchemaObject\n }\n }\n // Fall back to inferring from example\n if (example !== undefined) {\n return exampleToJSONSchema(example)\n }\n // Predicate-only types: best-effort from description\n return { description }\n },\n strip(value: unknown): unknown {\n if (schema) {\n return schemaFilter(value, schema)\n }\n // No schema \u2014 can't strip, return as-is\n return value\n },\n __runtimeType: true as const,\n }\n}\n\n/**\n * Generate a description from a schema\n */\nfunction schemaToDescription(schema: Schema): string {\n // tosijs-schema wraps JSON schema in .schema property\n const jsonSchema = (schema as any)?.schema ?? schema\n\n // Handle schema objects with type property\n if (jsonSchema && typeof jsonSchema === 'object' && 'type' in jsonSchema) {\n const s = jsonSchema as any\n switch (s.type) {\n case 'string':\n if (s.format) return `string (${s.format})`\n if (s.pattern) return `string matching ${s.pattern}`\n if (s.minLength !== undefined && s.maxLength !== undefined)\n return `string (${s.minLength}-${s.maxLength} chars)`\n return 'string'\n case 'number':\n case 'integer':\n if (s.minimum !== undefined && s.maximum !== undefined)\n return `${s.type} (${s.minimum}-${s.maximum})`\n if (s.minimum !== undefined) return `${s.type} >= ${s.minimum}`\n if (s.maximum !== undefined) return `${s.type} <= ${s.maximum}`\n return s.type\n case 'boolean':\n return 'boolean'\n case 'array':\n return 'array'\n case 'object':\n return 'object'\n case 'null':\n return 'null'\n }\n }\n\n // Fallback\n return 'value'\n}\n\n// ============================================================================\n// Built-in Types\n// ============================================================================\n\n/** String type */\nexport const TString = Type<string>('string', (v: unknown) => {\n if (typeof v === 'string') return true\n return `expected string, got ${v === null ? 'null' : typeof v}`\n})\n\n/** Number type */\nexport const TNumber = Type<number>('number', (v: unknown) => {\n if (typeof v === 'number') return true\n return `expected number, got ${v === null ? 'null' : typeof v}`\n})\n\n/** Boolean type */\nexport const TBoolean = Type<boolean>('boolean', (v: unknown) => {\n if (typeof v === 'boolean') return true\n return `expected boolean, got ${v === null ? 'null' : typeof v}`\n})\n\n/** Integer type */\nexport const TInteger = Type<number>('integer', (v: unknown) => {\n if (typeof v !== 'number')\n return `expected integer, got ${v === null ? 'null' : typeof v}`\n if (!Number.isInteger(v)) return `${v} is not an integer`\n return true\n})\n\n/** Positive integer type */\nexport const TPositiveInt = Type<number>('positive integer', (v: unknown) => {\n if (typeof v !== 'number')\n return `expected positive integer, got ${v === null ? 'null' : typeof v}`\n if (!Number.isInteger(v)) return `${v} is not an integer`\n if (v <= 0) return `${v} is not positive`\n return true\n})\n\n/** Non-empty string type */\nexport const TNonEmptyString = Type<string>(\n 'non-empty string',\n (v: unknown) => {\n if (typeof v !== 'string')\n return `expected string, got ${v === null ? 'null' : typeof v}`\n if (v.length === 0) return 'string is empty'\n return true\n }\n)\n\n/** Email type (basic validation) */\nexport const TEmail = Type<string>('email address', (v: unknown) => {\n if (typeof v !== 'string')\n return `expected string, got ${v === null ? 'null' : typeof v}`\n if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(v))\n return `\"${v}\" is not a valid email`\n return true\n})\n\n/**\n * Check if a string is a valid URL (portable helper for predicates)\n * This will become an AJS builtin\n */\nexport const isValidUrl = (v: string): boolean => {\n try {\n new URL(v)\n return true\n } catch {\n return false\n }\n}\n\n/** URL type */\nexport const TUrl = Type<string>('URL', (v: unknown) => {\n if (typeof v !== 'string')\n return `expected string, got ${v === null ? 'null' : typeof v}`\n if (!isValidUrl(v)) return `\"${v}\" is not a valid URL`\n return true\n})\n\n/** UUID type */\nexport const TUuid = Type<string>('UUID', (v: unknown) => {\n if (typeof v !== 'string')\n return `expected string, got ${v === null ? 'null' : typeof v}`\n if (\n !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v)\n )\n return `\"${v}\" is not a valid UUID`\n return true\n})\n\n/**\n * Check if a string is a valid ISO 8601 timestamp (portable helper for predicates)\n * This will become an AJS builtin\n */\nexport const isValidTimestamp = (v: string): boolean => {\n const d = new Date(v)\n return !isNaN(d.getTime()) && v.includes('T')\n}\n\n/**\n * Check if a string is a valid YYYY-MM-DD date (portable helper for predicates)\n * This will become an AJS builtin\n */\nexport const isValidLegalDate = (v: string): boolean => {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(v)) return false\n const d = new Date(v + 'T00:00:00Z')\n return !isNaN(d.getTime())\n}\n\n/** ISO 8601 timestamp string (e.g., \"2024-01-15T10:30:00Z\") */\nexport const Timestamp = Type<string>(\n 'ISO 8601 timestamp',\n (v: unknown) => typeof v === 'string' && isValidTimestamp(v)\n)\n\n/** Legal date string in YYYY-MM-DD format */\nexport const LegalDate = Type<string>(\n 'date (YYYY-MM-DD)',\n (v: unknown) => typeof v === 'string' && isValidLegalDate(v)\n)\n\n// ============================================================================\n// Type Combinators\n// ============================================================================\n\n/** Create a nullable version of a type */\nexport function Nullable<T>(type: RuntimeType<T>): RuntimeType<T | null> {\n return Type<T | null>(\n `${type.description} or null`,\n (v: unknown) => v === null || type.check(v) === true\n )\n}\n\n/** Create an optional version of a type (nullable + undefined) */\nexport function Optional<T>(\n type: RuntimeType<T>\n): RuntimeType<T | null | undefined> {\n return Type<T | null | undefined>(\n `${type.description} (optional)`,\n (v: unknown) => v === null || v === undefined || type.check(v) === true\n )\n}\n\n/**\n * Create a union type\n *\n * Two forms:\n * Union(...types: RuntimeType[]) - combine existing types\n * Union(description, values) - create literal union from values\n *\n * @example\n * // From RuntimeTypes\n * const StringOrNumber = Union(TString, TNumber)\n *\n * // From literal values (used by TJS syntax)\n * const Direction = Union('cardinal direction', ['up', 'down', 'left', 'right'])\n */\nexport function Union<T extends unknown[]>(\n descriptionOrType: string | RuntimeType,\n valuesOrType?: T | RuntimeType,\n ...restTypes: RuntimeType[]\n): RuntimeType {\n // New form: Union(description, values[])\n if (typeof descriptionOrType === 'string' && Array.isArray(valuesOrType)) {\n const description = descriptionOrType\n const values = valuesOrType as unknown[]\n const valueSet = new Set(values)\n\n const result: RuntimeType & { values: unknown[] } = {\n description,\n check: (v: unknown): v is T[number] => valueSet.has(v),\n toJSONSchema: () => ({\n enum: values,\n }),\n strip: (value: unknown) => value,\n __runtimeType: true as const,\n values, // Expose values for introspection\n }\n return result\n }\n\n // Old form: Union(...types: RuntimeType[])\n const types: RuntimeType[] = []\n if (isRuntimeType(descriptionOrType)) {\n types.push(descriptionOrType)\n }\n if (isRuntimeType(valuesOrType)) {\n types.push(valuesOrType as RuntimeType)\n }\n types.push(...restTypes)\n\n const description = types.map((t) => t.description).join(' | ')\n return Type(description, (v: unknown) =>\n types.some((t) => t.check(v) === true)\n )\n}\n\n/** Create an array type */\nexport function TArray<T>(itemType: RuntimeType<T>): RuntimeType<T[]> {\n return Type<T[]>(\n `array of ${itemType.description}`,\n (v: unknown) =>\n Array.isArray(v) && v.every((item) => itemType.check(item) === true)\n )\n}\n\n// ============================================================================\n// Generic Types\n// ============================================================================\n\n/** Type parameter - can be a RuntimeType, schema, or example value */\nexport type TypeParam = RuntimeType | Base<any> | JSONSchema | unknown\n\n/** Generic type factory */\nexport interface GenericType<TParams extends string[] = string[]> {\n /** Instantiate the generic with concrete type arguments */\n (...typeArgs: TypeParam[]): RuntimeType\n /** The type parameter names */\n readonly params: TParams\n /** Description template */\n readonly description: string\n}\n\n/**\n * Convert a type param to a check function\n */\nfunction typeParamToCheck(param: TypeParam): (value: unknown) => boolean {\n if (isRuntimeType(param)) {\n return (v) => param.check(v) === true\n }\n // Check if it's a schema builder (has .schema property)\n if (param && typeof param === 'object' && 'schema' in param) {\n return (v) => validate(v, param as Base<any>)\n }\n // It's an example value - infer schema using s.infer\n const schema = s.infer(param)\n return (v) => validate(v, schema)\n}\n\n/**\n * Create a generic (parameterized) type factory\n *\n * @param params Array of type parameter names, with optional defaults: ['T', ['U', defaultSchema]]\n * @param predicate Function receiving (value, ...typeChecks) where typeChecks are validation functions\n * @param description Human-readable description template (type params will be substituted)\n *\n * @example\n * // Pair<T, U>\n * const Pair = Generic(\n * ['T', 'U'],\n * (x, checkT, checkU) =>\n * Array.isArray(x) && x.length === 2 && checkT(x[0]) && checkU(x[1]),\n * 'Pair<T, U>'\n * )\n *\n * // Usage: Pair(TString, TNumber) creates a type for [string, number]\n * // Or with examples: Pair('', 0)\n */\nexport function Generic<TParams extends string[]>(\n params: (string | [string, TypeParam])[],\n predicate: (\n value: unknown,\n ...typeChecks: Array<(v: unknown) => boolean>\n ) => boolean,\n description: string\n): GenericType<TParams> {\n // Extract param names and defaults\n const paramNames: string[] = []\n const defaults: (TypeParam | undefined)[] = []\n\n for (const p of params) {\n if (typeof p === 'string') {\n paramNames.push(p)\n defaults.push(undefined)\n } else {\n paramNames.push(p[0])\n defaults.push(p[1])\n }\n }\n\n // The factory function\n const factory = (...typeArgs: TypeParam[]): RuntimeType => {\n // Resolve type arguments, using defaults where not provided\n const checks = paramNames.map((_, i) => {\n const arg = i < typeArgs.length ? typeArgs[i] : defaults[i]\n if (arg === undefined) {\n // No arg and no default - accept anything\n return () => true\n }\n return typeParamToCheck(arg)\n })\n\n // Build description with substituted types\n let desc = description\n paramNames.forEach((name, i) => {\n const arg = i < typeArgs.length ? typeArgs[i] : defaults[i]\n let typeStr = 'any'\n if (isRuntimeType(arg)) {\n typeStr = arg.description\n } else if (arg !== undefined) {\n typeStr = typeof arg === 'string' ? 'string' : JSON.stringify(arg)\n }\n desc = desc.replace(new RegExp(`\\\\b${name}\\\\b`, 'g'), typeStr)\n })\n\n return Type(desc, (value: unknown) => predicate(value, ...checks))\n }\n\n ;(factory as any).params = paramNames as TParams\n ;(factory as any).description = description\n\n return factory as GenericType<TParams>\n}\n\n// ============================================================================\n// Built-in Generic Types\n// ============================================================================\n\n/** Pair<T, U> - 2-element tuple */\nexport const TPair = Generic(\n ['T', 'U'],\n (x, checkT, checkU) =>\n Array.isArray(x) && x.length === 2 && checkT(x[0]) && checkU(x[1]),\n 'Pair<T, U>'\n)\n\n/** Record<V> - object with string keys and values of type V */\nexport const TRecord = Generic(\n ['V'],\n (x, checkV) =>\n typeof x === 'object' &&\n x !== null &&\n !Array.isArray(x) &&\n Object.values(x).every(checkV),\n 'Record<string, V>'\n)\n\n// ============================================================================\n// Enum Types\n// ============================================================================\n\n/** Enum type with bidirectional lookup */\nexport interface EnumType<\n T extends Record<string, string | number> = Record<string, string | number>\n> extends RuntimeType<T[keyof T]> {\n /** The enum members as { Name: value } */\n readonly members: T\n /** Reverse lookup: value -> name */\n readonly names: Record<string | number, string>\n /** Get all valid values */\n readonly values: Array<T[keyof T]>\n /** Get all member names */\n readonly keys: Array<keyof T>\n}\n\n/**\n * Create an enum type with bidirectional lookup\n *\n * @param description Human-readable description\n * @param members Object mapping names to values { Pending: 0, Active: 1 }\n *\n * @example\n * const Status = Enum('task status', { Pending: 0, Active: 1, Done: 2 })\n * Status.check(0) // true\n * Status.check('done') // false\n * Status.members.Pending // 0\n * Status.names[0] // 'Pending'\n * Status.values // [0, 1, 2]\n * Status.keys // ['Pending', 'Active', 'Done']\n *\n * const Color = Enum('CSS color', { Red: 'red', Green: 'green', Blue: 'blue' })\n * Color.check('red') // true\n * Color.members.Red // 'red'\n */\nexport function Enum<T extends Record<string, string | number>>(\n description: string,\n members: T\n): EnumType<T> {\n const values = Object.values(members) as Array<T[keyof T]>\n const valueSet = new Set(values)\n const keys = Object.keys(members) as Array<keyof T>\n\n // Build reverse lookup\n const names: Record<string | number, string> = {}\n for (const [key, value] of Object.entries(members)) {\n names[value] = key\n }\n\n const enumType: EnumType<T> = {\n description,\n check: (v: unknown): v is T[keyof T] => valueSet.has(v as T[keyof T]),\n toJSONSchema: () => ({\n enum: values as unknown[],\n }),\n strip: (value: unknown) => value,\n __runtimeType: true as const,\n members,\n names,\n values,\n keys,\n }\n\n return enumType\n}\n\n// =============================================================================\n// FunctionPredicate - Runtime type for function signatures\n// =============================================================================\n\n/** Return contract levels in order of strictness */\nexport type ReturnContract = 'assertReturns' | 'returns' | 'checkedReturns'\n\n/** Specification for a FunctionPredicate */\nexport interface FunctionPredicateSpec {\n /** Parameter types as example values */\n params?: Record<string, any>\n /** Return type as example value */\n returns?: any\n /** Return contract level */\n returnContract?: ReturnContract\n}\n\n/** A runtime type that validates function signatures */\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport interface FunctionPredicateType extends RuntimeType<Function> {\n /** Parameter specification */\n readonly params: Record<string, any>\n /** Return type specification */\n readonly returns?: any\n /** Return contract level */\n readonly returnContract: ReturnContract\n}\n\n/** A generic FunctionPredicate factory \u2014 call with type args to get a FunctionPredicateType */\nexport interface GenericFunctionPredicateType {\n (...typeArgs: TypeParam[]): FunctionPredicateType\n /** Type parameter names */\n readonly typeParamNames: string[]\n /** Description */\n readonly description: string\n /** Marker for runtime type detection */\n readonly __runtimeType: true\n}\n\n/** Infer a TypeDescriptor kind from an example value */\nfunction kindOfExample(example: unknown): string | null {\n if (example === null) return 'null'\n if (example === undefined) return 'undefined'\n switch (typeof example) {\n case 'string':\n return 'string'\n case 'boolean':\n return 'boolean'\n case 'number':\n return Number.isInteger(example) ? 'integer' : 'number'\n case 'object':\n return Array.isArray(example) ? 'array' : 'object'\n default:\n return null\n }\n}\n\n/**\n * Create a runtime type for function signatures.\n *\n * Forms:\n * FunctionPredicate(name, spec) - from a specification object\n * FunctionPredicate(name, fn) - from an existing typed function\n *\n * @example\n * const Callback = FunctionPredicate('Callback', {\n * params: { x: 0, y: 0 },\n * returns: 0,\n * })\n * Callback.check((a, b) => a + b) // true (typeof === 'function')\n * Callback.check(42) // false\n *\n * @example\n * function add(a: 0, b: 0) -> 0 { return a + b }\n * const Adder = FunctionPredicate('Adder', add)\n * // Extracts params/returns from add.__tjs\n *\n * @example\n * // Generic form \u2014 returns a factory\n * const Creator = FunctionPredicate('Creator', [['T', {}]], (T) => ({\n * params: { contents: [null] },\n * returns: T,\n * }))\n * const HtmlCreator = Creator({}) // FunctionPredicateType with returns: {}\n */\nexport function FunctionPredicate(\n name: string,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n specOrFn: FunctionPredicateSpec | Function | (string | [string, TypeParam])[],\n specBuilder?: (...typeArgs: any[]) => FunctionPredicateSpec\n): FunctionPredicateType | GenericFunctionPredicateType {\n // Generic form: FunctionPredicate(name, typeParams, specBuilder)\n if (Array.isArray(specOrFn) && specBuilder) {\n const typeParams = specOrFn as (string | [string, TypeParam])[]\n\n // Extract param names and defaults\n const paramNames: string[] = []\n const defaults: (TypeParam | undefined)[] = []\n for (const tp of typeParams) {\n if (Array.isArray(tp)) {\n paramNames.push(tp[0])\n defaults.push(tp[1])\n } else {\n paramNames.push(tp)\n defaults.push(undefined)\n }\n }\n\n const factory = ((...typeArgs: TypeParam[]) => {\n // Resolve type args with defaults\n const resolved: any[] = paramNames.map((_, idx) =>\n idx < typeArgs.length ? typeArgs[idx] : defaults[idx]\n )\n const spec = specBuilder(...resolved)\n return FunctionPredicate(name, spec) as FunctionPredicateType\n }) as GenericFunctionPredicateType\n\n Object.defineProperties(factory, {\n typeParamNames: { value: paramNames, enumerable: true },\n description: { value: name, enumerable: true },\n __runtimeType: { value: true, enumerable: true },\n })\n\n return factory\n }\n\n /* eslint-disable @typescript-eslint/no-unsafe-function-type */\n return _createFunctionPredicate(\n name,\n specOrFn as FunctionPredicateSpec | Function\n )\n /* eslint-enable @typescript-eslint/no-unsafe-function-type */\n}\n\n/** Internal: create a non-generic FunctionPredicateType */\nfunction _createFunctionPredicate(\n name: string,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n specOrFn: FunctionPredicateSpec | Function\n): FunctionPredicateType {\n let params: Record<string, any> = {}\n let returns: any = undefined\n let returnContract: ReturnContract = 'assertReturns'\n\n if (typeof specOrFn === 'function') {\n // Extract from function's __tjs metadata\n const meta = (specOrFn as any).__tjs\n if (meta) {\n // Build params from __tjs.params\n if (meta.params) {\n for (const [key, info] of Object.entries(meta.params)) {\n params[key] = (info as any)?.example ?? null\n }\n }\n // Extract return type\n if (meta.returns) {\n returns = (meta.returns as any)?.example ?? null\n }\n // Extract return contract from safety markers\n if (meta.safeReturn) returnContract = 'checkedReturns'\n else if (meta.unsafe) returnContract = 'assertReturns'\n else returnContract = 'returns'\n }\n } else {\n params = specOrFn.params ?? {}\n returns = specOrFn.returns\n returnContract = specOrFn.returnContract ?? 'assertReturns'\n }\n\n const fpType: FunctionPredicateType = {\n description: name,\n params,\n returns,\n returnContract,\n toJSONSchema: () => ({ description: name, type: 'function' as any }),\n strip: (value: unknown) => value,\n check: (value: unknown): boolean | string => {\n if (typeof value !== 'function')\n return `expected function, got ${\n value === null ? 'null' : typeof value\n }`\n\n // Structural validation: check arity and __tjs metadata\n const expectedArity = Object.keys(params).length\n if (expectedArity > 0) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n const fn = value as Function\n const meta = (fn as any).__tjs\n if (meta?.params) {\n // Has TJS metadata \u2014 check param count matches\n const metaParamCount = Object.keys(meta.params).length\n if (metaParamCount !== expectedArity)\n return `expected ${expectedArity} params, got ${metaParamCount}`\n\n // Check param type kinds match where both sides have type info\n const expectedKeys = Object.keys(params)\n const metaKeys = Object.keys(meta.params)\n for (let i = 0; i < expectedKeys.length; i++) {\n const metaInfo = meta.params[metaKeys[i]]\n const expectedExample = params[expectedKeys[i]]\n if (metaInfo?.type?.kind && expectedExample !== undefined) {\n const expectedKind = kindOfExample(expectedExample)\n if (\n expectedKind &&\n metaInfo.type.kind !== expectedKind &&\n metaInfo.type.kind !== 'any'\n )\n return `param '${expectedKeys[i]}' expected ${expectedKind}, got ${metaInfo.type.kind}`\n }\n }\n }\n }\n\n return true\n },\n __runtimeType: true as const,\n }\n\n return fpType\n}\n"],
|
|
4
|
+
"sourcesContent": ["{\n \"name\": \"tjs-lang\",\n \"version\": \"0.9.1\",\n \"description\": \"Type-safe JavaScript dialect with runtime validation, sandboxed VM execution, and AI agent orchestration. Transpiles TypeScript to validated JS with fuel-metered execution for untrusted code.\",\n \"keywords\": [\n \"typescript\",\n \"transpiler\",\n \"runtime-validation\",\n \"type-safety\",\n \"sandbox\",\n \"virtual-machine\",\n \"wasm-alternative\",\n \"ai-agents\",\n \"llm\",\n \"orchestration\",\n \"security\",\n \"fuel-metering\",\n \"capability-based\",\n \"json-ast\",\n \"untrusted-code\"\n ],\n \"license\": \"Apache-2.0\",\n \"main\": \"./dist/index.js\",\n \"types\": \"./dist/src/index.d.ts\",\n \"typesVersions\": {\n \"*\": {\n \"eval\": [\n \"./dist/src/lang/eval.d.ts\"\n ],\n \"lang\": [\n \"./dist/src/lang/transpiler.d.ts\"\n ],\n \"lang/from-ts\": [\n \"./dist/src/lang/emitters/from-ts.d.ts\"\n ],\n \"browser\": [\n \"./dist/src/lang/browser.d.ts\"\n ],\n \"browser/from-ts\": [\n \"./dist/src/lang/browser-from-ts.d.ts\"\n ],\n \"vm\": [\n \"./dist/src/vm/index.d.ts\"\n ],\n \"batteries\": [\n \"./dist/src/batteries/index.d.ts\"\n ],\n \"css\": [\n \"./dist/src/css/index.d.ts\"\n ],\n \"schema\": [\n \"./dist/src/schema/index.d.ts\"\n ],\n \"runtime\": [\n \"./dist/src/lang/runtime.d.ts\"\n ]\n }\n },\n \"exports\": {\n \".\": {\n \"bun\": \"./src/index.ts\",\n \"types\": \"./dist/src/index.d.ts\",\n \"default\": \"./dist/index.js\"\n },\n \"./eval\": {\n \"bun\": \"./src/lang/eval.ts\",\n \"types\": \"./dist/src/lang/eval.d.ts\",\n \"default\": \"./dist/tjs-eval.js\"\n },\n \"./lang\": {\n \"bun\": \"./src/lang/transpiler.ts\",\n \"types\": \"./dist/src/lang/transpiler.d.ts\",\n \"default\": \"./dist/tjs-lang.js\"\n },\n \"./lang/from-ts\": {\n \"bun\": \"./src/lang/emitters/from-ts.ts\",\n \"types\": \"./dist/src/lang/emitters/from-ts.d.ts\",\n \"default\": \"./dist/tjs-from-ts.js\"\n },\n \"./browser\": {\n \"types\": \"./dist/src/lang/browser.d.ts\",\n \"default\": \"./dist/tjs-browser.js\"\n },\n \"./browser/from-ts\": {\n \"types\": \"./dist/src/lang/browser-from-ts.d.ts\",\n \"default\": \"./dist/tjs-browser-from-ts.js\"\n },\n \"./vm\": {\n \"bun\": \"./src/vm/index.ts\",\n \"types\": \"./dist/src/vm/index.d.ts\",\n \"default\": \"./dist/tjs-vm.js\"\n },\n \"./batteries\": {\n \"bun\": \"./src/batteries/index.ts\",\n \"types\": \"./dist/src/batteries/index.d.ts\",\n \"default\": \"./dist/tjs-batteries.js\"\n },\n \"./linalg\": {\n \"bun\": \"./src/linalg/index.tjs\",\n \"default\": \"./dist/tjs-linalg.js\"\n },\n \"./css\": {\n \"bun\": \"./src/css/index.ts\",\n \"types\": \"./dist/src/css/index.d.ts\",\n \"default\": \"./dist/tjs-css.js\"\n },\n \"./schema\": {\n \"bun\": \"./src/schema/index.ts\",\n \"types\": \"./dist/src/schema/index.d.ts\",\n \"default\": \"./dist/tjs-schema.js\"\n },\n \"./runtime\": {\n \"bun\": \"./src/lang/runtime.ts\",\n \"types\": \"./dist/src/lang/runtime.d.ts\",\n \"default\": \"./dist/tjs-runtime.js\"\n },\n \"./bun-plugin\": {\n \"bun\": \"./src/bun-plugin/tjs-plugin.ts\"\n },\n \"./src\": \"./src/index.ts\",\n \"./editors/monaco\": \"./editors/monaco/ajs-monarch.js\",\n \"./editors/codemirror\": \"./editors/codemirror/ajs-language.js\",\n \"./editors/ace\": \"./editors/ace/ajs-mode.js\"\n },\n \"bin\": {\n \"tjs\": \"./src/cli/tjs.ts\",\n \"tjsx\": \"./src/cli/tjsx.ts\",\n \"tjs-playground\": \"./src/cli/playground.ts\",\n \"create-tjs-app\": \"./src/cli/create-app.ts\",\n \"ajs-install-vscode\": \"./bin/install-vscode.sh\",\n \"ajs-install-cursor\": \"./bin/install-cursor.sh\"\n },\n \"type\": \"module\",\n \"files\": [\n \"dist\",\n \"src\",\n \"docs\",\n \"editors\",\n \"bin\",\n \"demo\",\n \"tjs-lang.svg\",\n \"CONTEXT.md\",\n \"CLAUDE.md\",\n \"llms.txt\"\n ],\n \"sideEffects\": [\n \"./src/schema/index.ts\",\n \"./dist/tjs-schema.js\"\n ],\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/tonioloewald/tjs-lang.git\"\n },\n \"devDependencies\": {\n \"@codemirror/lang-css\": \"^6.3.1\",\n \"@codemirror/lang-html\": \"^6.4.11\",\n \"@codemirror/lang-javascript\": \"^6.2.4\",\n \"@codemirror/lang-markdown\": \"^6.5.0\",\n \"@codemirror/state\": \"^6.5.3\",\n \"@codemirror/theme-one-dark\": \"^6.1.3\",\n \"@codemirror/view\": \"^6.39.9\",\n \"@eslint/js\": \"^10.0.1\",\n \"@happy-dom/global-registrator\": \"^20.1.0\",\n \"@types/bun\": \"latest\",\n \"@types/jsdom\": \"^21.1.7\",\n \"acorn-walk\": \"^8.3.4\",\n \"chokidar\": \"^4.0.3\",\n \"codemirror\": \"^6.0.2\",\n \"esbuild\": \"^0.28.0\",\n \"eslint\": \"^10.4.1\",\n \"firebase\": \"^10.12.0\",\n \"firebase-admin\": \"^13.6.0\",\n \"firebase-functions\": \"^7.0.5\",\n \"globals\": \"^17.6.0\",\n \"marked\": \"^9.1.6\",\n \"prettier\": \"^2.8.8\",\n \"tosijs\": \"^1.5.6\",\n \"tosijs-ui\": \"^1.4.7\",\n \"typescript\": \"^5.6.2\",\n \"typescript-eslint\": \"^8.61.0\",\n \"valibot\": \"^0.36.0\",\n \"vitest\": \"^2.0.5\"\n },\n \"scripts\": {\n \"format\": \"bun eslint src --fix && bun prettier --write .\",\n \"lint\": \"eslint src\",\n \"build:grammars\": \"bun editors/build-grammars.ts\",\n \"build:editors\": \"bun scripts/build-editors.ts\",\n \"test:fast\": \"SKIP_LLM_TESTS=1 SKIP_BENCHMARKS=1 bun test\",\n \"test:llm\": \"bun test src/batteries/models.integration.test.ts\",\n \"bench\": \"bun bin/benchmarks.ts\",\n \"make\": \"rm -rf dist && bun format && bun run build:grammars && bun run build:editors && tsc -p tsconfig.build.json && bun scripts/build.ts\",\n \"build:bundles\": \"bun scripts/build.ts\",\n \"typecheck\": \"tsc --noEmit\",\n \"latest\": \"rm -rf node_modules && bun install\",\n \"docs\": \"node bin/docs.js\",\n \"dev\": \"bun run bin/dev.ts\",\n \"build:demo\": \"bun scripts/build-demo.ts\",\n \"build:cli\": \"bun build src/cli/tjs.ts --compile --outfile=dist/tjs && bun build src/cli/tjsx.ts --compile --outfile=dist/tjsx\",\n \"functions:build\": \"cd functions && npm run build\",\n \"functions:deploy\": \"cd functions && npm run deploy\",\n \"functions:serve\": \"cd functions && npm run serve\",\n \"deploy:hosting\": \"bun run build:demo && firebase deploy --only hosting\",\n \"deploy\": \"bun run build:demo && bun run functions:deploy && firebase deploy --only hosting\",\n \"start\": \"bun run build:demo && bun run dev\"\n },\n \"dependencies\": {\n \"acorn\": \"^8.15.0\",\n \"acorn-loose\": \"^8.5.2\",\n \"acorn-walk\": \"^8.3.4\",\n \"tosijs-schema\": \"^1.4.0\"\n }\n}\n", "/**\n * TJS Runtime\n *\n * Monadic type checking at runtime:\n * - Functions validate inputs against __tjs metadata\n * - If any input is an error, pass it through (no work)\n * - Type mismatches return error objects\n * - Errors propagate through call chains\n *\n * This runtime is attached to globalThis.__tjs and shared across modules.\n */\n\nimport { validate, s } from 'tosijs-schema'\nimport { functionMetaToJSONSchema } from './json-schema'\nimport {\n Type,\n isRuntimeType,\n Union,\n Generic,\n Enum,\n FunctionPredicate,\n Nullable,\n Optional,\n TArray,\n // Built-in types\n TString,\n TNumber,\n TBoolean,\n TInteger,\n TPositiveInt,\n TNonEmptyString,\n TEmail,\n TUrl,\n TUuid,\n Timestamp,\n LegalDate,\n // Built-in generics\n TPair,\n TRecord,\n // Portable predicate helpers (future AJS builtins)\n isValidUrl,\n isValidTimestamp,\n isValidLegalDate,\n} from '../types/Type'\n\n// Re-export Type utilities for consumers\nexport {\n Type,\n isRuntimeType,\n Union,\n Generic,\n Enum,\n FunctionPredicate,\n Nullable,\n Optional,\n TArray,\n TString,\n TNumber,\n TBoolean,\n TInteger,\n TPositiveInt,\n TNonEmptyString,\n TEmail,\n TUrl,\n TUuid,\n Timestamp,\n LegalDate,\n TPair,\n TRecord,\n isValidUrl,\n isValidTimestamp,\n isValidLegalDate,\n}\n\n// Version from package.json - injected at build time or imported\nconst pkg = require('../../package.json') as { version: string }\n\nexport const TJS_VERSION: string = pkg.version\n\n/**\n * Well-known symbol for custom equality.\n *\n * Any object can implement `[tjsEquals](other)` to control how `==` / `Is()`\n * compares it. Useful for Proxies that should delegate equality to their target.\n *\n * Priority: tjsEquals symbol \u2192 .Equals method \u2192 structural comparison\n */\nexport const tjsEquals: unique symbol = Symbol.for('tjs.equals')\n\n/**\n * Parse semver version string into components\n */\nfunction parseVersion(version: string): {\n major: number\n minor: number\n patch: number\n} {\n const [major = 0, minor = 0, patch = 0] = version.split('.').map(Number)\n return { major, minor, patch }\n}\n\n/**\n * Compare two version strings\n * Returns: -1 if a < b, 0 if equal, 1 if a > b\n */\nexport function compareVersions(a: string, b: string): -1 | 0 | 1 {\n const va = parseVersion(a)\n const vb = parseVersion(b)\n\n if (va.major !== vb.major) return va.major < vb.major ? -1 : 1\n if (va.minor !== vb.minor) return va.minor < vb.minor ? -1 : 1\n if (va.patch !== vb.patch) return va.patch < vb.patch ? -1 : 1\n return 0\n}\n\n/**\n * Check if two versions are compatible (same major version)\n */\nexport function versionsCompatible(a: string, b: string): boolean {\n const va = parseVersion(a)\n const vb = parseVersion(b)\n return va.major === vb.major\n}\n\n/**\n * MonadicError - Internal error type for monadic error propagation\n *\n * This extends Error so:\n * 1. It's a real Error with proper stack traces\n * 2. User code can't accidentally process it as data (unlike { $error: true })\n * 3. It flows through function calls via instanceof checks\n *\n * NOT exported to user code - they just see Error instances.\n */\nexport class MonadicError extends Error {\n /** Path where the error occurred, e.g., \"src/file.ts:42:greet.name\" */\n readonly path: string\n /** Expected type */\n readonly expected?: string\n /** Actual type received */\n readonly actual?: string\n /** TJS call stack (only in debug mode) - shows source locations */\n readonly callStack?: string[]\n /** Why the check failed (from predicate reason strings) */\n readonly reason?: string\n\n constructor(\n message: string,\n path: string,\n expected?: string,\n actual?: string,\n callStack?: string[],\n reason?: string\n ) {\n super(message)\n this.name = 'MonadicError'\n this.path = path\n this.expected = expected\n this.actual = actual\n this.callStack = callStack\n this.reason = reason\n // Maintains proper stack trace in V8 environments\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, MonadicError)\n }\n }\n}\n\n/**\n * Create a type error for inline validation\n *\n * Called ONLY when a type check fails - no overhead on happy path.\n * Returns a MonadicError that propagates through the call chain.\n * In debug mode, captures the TJS call stack with source locations.\n *\n * @param path - Location of the error, e.g., \"src/file.ts:42:greet.name\"\n * @param expected - Expected type, e.g., \"string\"\n * @param value - The actual value that failed the check\n */\nexport function typeError(\n path: string,\n expected: string,\n value: unknown,\n reason?: string\n): MonadicError {\n const actual = value === null ? 'null' : typeof value\n // Capture call stack in debug mode (getStack returns [] if not in debug mode)\n const stack = config.callStacks || config.debug ? getStack() : undefined\n const msg = reason\n ? `Expected ${expected} for '${path}': ${reason}`\n : `Expected ${expected} for '${path}', got ${actual}`\n const err = new MonadicError(msg, path, expected, actual, stack, reason)\n\n // Track in error history ring buffer (zero cost on happy path)\n if (config.trackErrors !== false) {\n const size = config.maxErrors ?? ERROR_BUF_SIZE\n errorBuffer[errorHead] = err\n errorHead = (errorHead + 1) % size\n if (errorBufCount < size) errorBufCount++\n errorTotal++\n }\n\n // Log to console if configured (includes source location from path)\n if (config.logTypeErrors) {\n console.error(`[TJS TypeError] ${err.message}`)\n }\n\n // Throw instead of returning if configured (for debugging)\n if (config.throwTypeErrors) {\n throw err\n }\n\n return err\n}\n\n/**\n * Check if a value is a MonadicError (for internal use)\n */\nexport function isMonadicError(value: unknown): value is MonadicError {\n // Duck-type check instead of instanceof \u2014 works across module boundaries,\n // inline runtimes, and different copies of the MonadicError class\n return (\n value instanceof Error &&\n (value as any).name === 'MonadicError' &&\n 'path' in value\n )\n}\n\n/**\n * Error marker - identifies TJS error objects\n * @deprecated Use MonadicError instead. This interface is kept for backward compatibility.\n */\nexport interface TJSError {\n $error: true\n message: string\n /** Failure location - e.g., \"greet.name\" */\n path?: string\n /** Call stack in debug mode - e.g., [\"main\", \"processUser\", \"greet.name\"] */\n stack?: string[]\n expected?: string\n actual?: string\n /** Why the check failed (from predicate reason strings) */\n reason?: string\n cause?: Error | TJSError\n /** Source location for error reporting */\n loc?: { start: number; end: number }\n /** Multiple errors (when composing parameter errors) */\n errors?: TJSError[]\n}\n\n/**\n * Safety levels for runtime validation\n * - 'none': No validation unless explicitly forced with (?) or -?\n * - 'inputs': Validate inputs only (default) - outputs only with explicit -> or -?\n * - 'all': Validate both inputs and outputs unless explicitly skipped with (!) or -!\n */\nexport type SafetyLevel = 'none' | 'inputs' | 'all'\n\n/**\n * Runtime configuration\n */\nexport interface TJSConfig {\n /** Enable debug mode - captures call stacks in errors */\n debug?: boolean\n /** Safety level for validation (default: 'inputs') */\n safety?: SafetyLevel\n /** Require explicit return types (error if -> not specified) */\n requireReturnTypes?: boolean\n /** Track call stacks for error diagnostics (default: false).\n * Useful for server-side logging and agent debugging without devtools.\n * Uses a fixed ring buffer \u2014 no allocation pressure. */\n callStacks?: boolean\n /** Ring buffer size for call stack tracking (default: 64) */\n maxStackSize?: number\n /** Track recent type errors in a ring buffer (default: true).\n * Zero cost on happy path \u2014 only writes when an error occurs.\n * Lets you catch monadic errors that were silently ignored. */\n trackErrors?: boolean\n /** Ring buffer size for error tracking (default: 64) */\n maxErrors?: number\n /** Log type errors to console.error when they occur (default: false) */\n logTypeErrors?: boolean\n /** Throw type errors instead of returning them (default: false).\n * Useful for debugging \u2014 makes type errors impossible to ignore. */\n throwTypeErrors?: boolean\n}\n\n/** Default configuration values */\nconst DEFAULT_CONFIG: TJSConfig = {\n debug: false,\n safety: 'inputs',\n requireReturnTypes: false,\n callStacks: false,\n maxStackSize: 64,\n trackErrors: true,\n maxErrors: 64,\n}\n\n/** Current runtime configuration */\nlet config: TJSConfig = { ...DEFAULT_CONFIG }\n\n/** Ring buffer for call stack tracking \u2014 fixed size, zero allocation */\nconst STACK_SIZE = 64\nconst callStackBuffer: string[] = new Array(STACK_SIZE).fill('')\nlet callStackHead = 0\nlet callStackCount = 0\n\n/** Ring buffer for error history \u2014 zero cost on happy path */\nconst ERROR_BUF_SIZE = 64\nconst errorBuffer: any[] = new Array(ERROR_BUF_SIZE).fill(null)\nlet errorHead = 0\nlet errorBufCount = 0\nlet errorTotal = 0\n\n/** Unsafe mode depth - when > 0, skip validation in wrap() */\nlet unsafeDepth = 0\n\n/**\n * Enter unsafe mode - disables validation for all wrapped function calls\n * Can be nested (uses depth counter)\n */\nexport function enterUnsafe(): void {\n unsafeDepth++\n}\n\n/**\n * Exit unsafe mode - re-enables validation when depth returns to 0\n */\nexport function exitUnsafe(): void {\n if (unsafeDepth > 0) unsafeDepth--\n}\n\n/**\n * Check if currently in unsafe mode\n */\nexport function isUnsafeMode(): boolean {\n return unsafeDepth > 0\n}\n\n/**\n * Configure TJS runtime\n */\nexport function configure(options: TJSConfig): void {\n config = { ...config, ...options }\n}\n\n/**\n * Get current configuration\n */\nexport function getConfig(): TJSConfig {\n return { ...config }\n}\n\n/**\n * Push a function onto the call stack ring buffer.\n * Only tracks when callStacks or debug is enabled.\n * O(1), no allocation.\n */\nexport function pushStack(name: string): void {\n if ((config.callStacks || config.debug) && name) {\n const size = config.maxStackSize ?? STACK_SIZE\n callStackBuffer[callStackHead] = name\n callStackHead = (callStackHead + 1) % size\n if (callStackCount < size) callStackCount++\n }\n}\n\n/**\n * Pop a function from the call stack ring buffer.\n * O(1), no allocation.\n */\nexport function popStack(): void {\n if ((config.callStacks || config.debug) && callStackCount > 0) {\n const size = config.maxStackSize ?? STACK_SIZE\n callStackHead = (callStackHead - 1 + size) % size\n callStackCount--\n }\n}\n\n/**\n * Get current call stack snapshot (most recent entries, newest last)\n */\nexport function getStack(): string[] {\n if (callStackCount === 0) return []\n const size = config.maxStackSize ?? STACK_SIZE\n const result: string[] = []\n const start = (callStackHead - callStackCount + size) % size\n for (let i = 0; i < callStackCount; i++) {\n result.push(callStackBuffer[(start + i) % size])\n }\n return result\n}\n\n/**\n * Get recent type errors (newest last).\n * Only tracks when trackErrors is enabled (default: true).\n */\nexport function errors(): MonadicError[] {\n if (config.trackErrors === false || errorBufCount === 0) return []\n const size = config.maxErrors ?? ERROR_BUF_SIZE\n const result: MonadicError[] = []\n const start = (errorHead - errorBufCount + size) % size\n for (let i = 0; i < errorBufCount; i++) {\n result.push(errorBuffer[(start + i) % size])\n }\n return result\n}\n\n/**\n * Clear error history. Returns the cleared errors.\n */\nexport function clearErrors(): MonadicError[] {\n const cleared = errors()\n errorHead = 0\n errorBufCount = 0\n errorTotal = 0\n return cleared\n}\n\n/**\n * Total error count since last clear (may exceed buffer size).\n */\nexport function getErrorCount(): number {\n return errorTotal\n}\n\n/**\n * Reset runtime state to defaults\n *\n * Resets: config, callStack, errors, unsafeDepth\n * Use this in test teardown to prevent state leaking between tests.\n */\nexport function resetRuntime(): void {\n config = { ...DEFAULT_CONFIG }\n callStackHead = 0\n callStackCount = 0\n errorHead = 0\n errorBufCount = 0\n errorTotal = 0\n unsafeDepth = 0\n}\n\n/**\n * Structural equality - the == that works\n *\n * Rules:\n * 1. If left has [tjsEquals], call left[tjsEquals](right)\n * 2. If right has [tjsEquals], call right[tjsEquals](left)\n * 3. If left has .Equals, call left.Equals(right)\n * 4. If right has .Equals, call right.Equals(left)\n * 5. Arrays/objects: recursive structural comparison\n * 6. Primitives: strict equality (no coercion)\n *\n * Usage: `a Is b` transforms to `Is(a, b)`\n */\nexport function Is(a: unknown, b: unknown): boolean {\n // Check for [tjsEquals] symbol protocol (highest priority)\n if (\n a !== null &&\n typeof a === 'object' &&\n typeof (a as any)[tjsEquals] === 'function'\n ) {\n return (a as any)[tjsEquals](b)\n }\n if (\n b !== null &&\n typeof b === 'object' &&\n typeof (b as any)[tjsEquals] === 'function'\n ) {\n return (b as any)[tjsEquals](a)\n }\n\n // Check for .Equals method (backward compat)\n if (\n a !== null &&\n typeof a === 'object' &&\n typeof (a as any).Equals === 'function'\n ) {\n return (a as any).Equals(b)\n }\n if (\n b !== null &&\n typeof b === 'object' &&\n typeof (b as any).Equals === 'function'\n ) {\n return (b as any).Equals(a)\n }\n\n // Unwrap boxed primitives (new String, new Number, new Boolean)\n // so structural equality honors the intent: new String('foo') == 'foo'\n if (a instanceof String || a instanceof Number || a instanceof Boolean) {\n a = a.valueOf()\n }\n if (b instanceof String || b instanceof Number || b instanceof Boolean) {\n b = b.valueOf()\n }\n\n // Identical references or primitives\n if (a === b) return true\n\n // NaN === NaN (JS gets this wrong)\n if (\n typeof a === 'number' &&\n typeof b === 'number' &&\n isNaN(a as number) &&\n isNaN(b as number)\n ) {\n return true\n }\n\n // null and undefined are equal to each other (nullish equality)\n // This preserves the useful JS pattern: x == null checks for both\n if ((a === null || a === undefined) && (b === null || b === undefined)) {\n return true\n }\n\n // If only one is nullish, not equal\n if (a === null || a === undefined || b === null || b === undefined) {\n return false\n }\n\n // Different types - not equal (no coercion)\n if (typeof a !== typeof b) return false\n\n // Primitives that aren't === are not equal\n if (typeof a !== 'object') return false\n\n // Sets \u2014 order-independent element equality\n if (a instanceof Set && b instanceof Set) {\n if ((a as Set<unknown>).size !== (b as Set<unknown>).size) return false\n for (const v of a as Set<unknown>) {\n if (!(b as Set<unknown>).has(v)) return false\n }\n return true\n }\n\n // Maps \u2014 key-value structural equality\n if (a instanceof Map && b instanceof Map) {\n if ((a as Map<unknown, unknown>).size !== (b as Map<unknown, unknown>).size)\n return false\n for (const [k, v] of a as Map<unknown, unknown>) {\n if (!(b as Map<unknown, unknown>).has(k)) return false\n if (!Is(v, (b as Map<unknown, unknown>).get(k))) return false\n }\n return true\n }\n\n // Dates \u2014 compare timestamps\n if (a instanceof Date && b instanceof Date) {\n return a.getTime() === b.getTime()\n }\n\n // RegExps \u2014 compare string representation\n if (a instanceof RegExp && b instanceof RegExp) {\n return a.toString() === b.toString()\n }\n\n // Arrays\n if (Array.isArray(a) && Array.isArray(b)) {\n if (a.length !== b.length) return false\n return a.every((v, i) => Is(v, b[i]))\n }\n if (Array.isArray(a) !== Array.isArray(b)) return false\n\n // Objects - structural comparison\n const keysA = Object.keys(a as object)\n const keysB = Object.keys(b as object)\n if (keysA.length !== keysB.length) return false\n return keysA.every((k) => Is((a as any)[k], (b as any)[k]))\n}\n\n/**\n * Structural inequality - the != that works\n *\n * Usage: `a IsNot b` transforms to `IsNot(a, b)`\n */\nexport function IsNot(a: unknown, b: unknown): boolean {\n return !Is(a, b)\n}\n\n/**\n * Honest equality \u2014 what == should have been.\n *\n * Like === but fixes the two remaining footguns:\n * 1. Unwraps boxed primitives: new String('foo') Eq 'foo' \u2192 true\n * 2. Nullish equality: null Eq undefined \u2192 true\n *\n * Does NOT do deep structural comparison on objects/arrays (that's O(n)).\n * Use Is/IsNot for explicit structural comparison when you need it.\n *\n * Usage: `a == b` with TjsEquals transforms to `Eq(a, b)`\n */\n\n/**\n * Honest typeof \u2014 fixes `typeof null === 'object'`\n *\n * Returns `'null'` for null instead of `'object'`.\n * All other values return the same as standard typeof.\n *\n * Usage: `typeof x` with TjsEquals transforms to `TypeOf(x)`\n */\nexport function TypeOf(value: unknown): string {\n if (value === null) return 'null'\n return typeof value\n}\n\n/**\n * Honest boolean coercion. Like `Boolean(x)` but unwraps boxed primitives\n * first, fixing the JS footgun `Boolean(new Boolean(false)) === true`.\n *\n * Under TjsStandard, the source rewriter wraps every truthiness context\n * (if/while/for/do-while conditions, `!`, `&&`, `||`, ternary, and\n * top-level `Boolean(x)` calls) with this function so a boxed `false`\n * actually behaves as `false`.\n */\nexport function toBool(value: unknown): boolean {\n if (\n value instanceof Boolean ||\n value instanceof Number ||\n value instanceof String\n ) {\n return Boolean((value as any).valueOf())\n }\n return Boolean(value)\n}\n\nexport function Eq(a: unknown, b: unknown): boolean {\n // Unwrap boxed primitives\n if (a instanceof String || a instanceof Number || a instanceof Boolean) {\n a = a.valueOf()\n }\n if (b instanceof String || b instanceof Number || b instanceof Boolean) {\n b = b.valueOf()\n }\n\n // Identical references or primitives\n if (a === b) return true\n\n // NaN === NaN (JS gets this wrong)\n if (\n typeof a === 'number' &&\n typeof b === 'number' &&\n isNaN(a as number) &&\n isNaN(b as number)\n ) {\n return true\n }\n\n // null and undefined are equal to each other\n if ((a === null || a === undefined) && (b === null || b === undefined)) {\n return true\n }\n\n return false\n}\n\n/**\n * Honest inequality \u2014 what != should have been.\n *\n * Usage: `a != b` with TjsEquals transforms to `NotEq(a, b)`\n */\nexport function NotEq(a: unknown, b: unknown): boolean {\n return !Eq(a, b)\n}\n\n/**\n * Check if a value is a TJS error\n */\nexport function isError(value: unknown): value is TJSError {\n return (\n value !== null &&\n typeof value === 'object' &&\n (value as any).$error === true\n )\n}\n\n/**\n * Create a TJS error\n * In debug mode, captures the current call stack\n */\nexport function error(\n message: string,\n details?: Partial<Omit<TJSError, '$error' | 'message'>>\n): TJSError {\n const err: TJSError = {\n $error: true,\n message,\n ...details,\n }\n\n // Capture call stack when tracking is enabled\n if ((config.callStacks || config.debug) && callStackCount > 0) {\n const currentStack = getStack()\n const fullStack = details?.path\n ? [...currentStack, details.path]\n : currentStack\n err.stack = fullStack\n }\n\n return err\n}\n\n/**\n * Compose multiple errors into a single error\n * Used when multiple parameters have errors\n */\nexport function composeErrors(errors: TJSError[], funcName?: string): TJSError {\n if (errors.length === 0) {\n return error('Unknown error')\n }\n if (errors.length === 1) {\n return errors[0]\n }\n\n // Build a message listing all failed parameters\n const paramNames = errors\n .map((e) => {\n // Extract param name from path (e.g., \"func.paramName\" -> \"paramName\")\n if (e.path) {\n const parts = e.path.split('.')\n return parts[parts.length - 1]\n }\n return 'unknown'\n })\n .join(', ')\n\n const message = `Multiple parameter errors in ${\n funcName || 'function'\n }: ${paramNames}`\n\n return error(message, {\n path: funcName,\n errors,\n })\n}\n\n/**\n * Get the type of a value\n *\n * Enhanced typeof that handles:\n * - null (returns 'null' not 'object')\n * - undefined (returns 'undefined')\n * - arrays (returns 'array' not 'object')\n * - native/platform types (returns constructor name for objects)\n *\n * For objects, returns the constructor name which enables pragmatic\n * native type checking (e.g., 'HTMLElement', 'Buffer', 'Event')\n */\nexport function typeOf(value: unknown): string {\n if (value === null) return 'null'\n if (value === undefined) return 'undefined'\n if (Array.isArray(value)) return 'array'\n\n const t = typeof value\n if (t !== 'object') return t\n\n // For objects, return constructor name for pragmatic native type checking\n // This enables checking for HTMLElement, Buffer, Event, etc.\n const constructorName = (value as object).constructor?.name\n if (constructorName && constructorName !== 'Object') {\n return constructorName\n }\n\n return 'object'\n}\n\n/**\n * Check if a value is an instance of a native/platform type by constructor name\n *\n * This enables pragmatic native type checking without shipping type definitions:\n * - isNativeType(el, 'HTMLElement') - DOM element check\n * - isNativeType(buf, 'Buffer') - Node.js Buffer check\n * - isNativeType(evt, 'Event') - DOM Event check\n * - isNativeType(map, 'Map') - Map instance check\n *\n * @param value - The value to check\n * @param typeName - The constructor name to match (e.g., 'HTMLElement', 'Buffer')\n * @returns true if value's constructor.name matches or is in prototype chain\n */\nexport function isNativeType(value: unknown, typeName: string): boolean {\n if (value === null || value === undefined) return false\n if (typeof value !== 'object' && typeof value !== 'function') return false\n\n // Check constructor name\n let proto = value\n while (proto !== null) {\n const constructorName = (proto as object).constructor?.name\n if (constructorName === typeName) return true\n proto = Object.getPrototypeOf(proto)\n }\n\n return false\n}\n\n/**\n * Check if a value matches an expected type\n *\n * @param value - The value to check\n * @param expected - Either a string type name ('string', 'number', etc.)\n * or a RuntimeType instance with .check() method\n * @param path - Optional path for error messages\n */\nexport function checkType(\n value: unknown,\n expected:\n | string\n | { check: (v: unknown) => boolean | string; description: string },\n path?: string\n): TJSError | null {\n // If value is already an error, propagate it\n if (isError(value)) return value\n\n // Handle RuntimeType instances (Type() results)\n if (\n typeof expected === 'object' &&\n expected !== null &&\n 'check' in expected\n ) {\n const result = expected.check(value)\n if (result === true) return null\n const reason = typeof result === 'string' ? result : undefined\n const msg = reason\n ? `Expected ${expected.description} for '${path}': ${reason}`\n : `Expected ${expected.description} but got ${typeOf(value)}`\n return error(msg, {\n path,\n expected: expected.description,\n actual: typeOf(value),\n reason,\n })\n }\n\n const actual = typeOf(value)\n\n // Handle special cases\n if (expected === 'any') return null\n if (expected === actual) return null\n\n // Number accepts both number types\n if (expected === 'number' && actual === 'number') return null\n if (expected === 'integer' && actual === 'number' && Number.isInteger(value))\n return null\n if (\n expected === 'non-negative-integer' &&\n actual === 'number' &&\n Number.isInteger(value) &&\n (value as number) >= 0\n )\n return null\n\n // Object matching (basic)\n if (expected === 'object' && actual === 'object') return null\n\n return error(`Expected ${expected} but got ${actual}`, {\n path,\n expected,\n actual,\n })\n}\n\n/** Type specifier - either a string name or a RuntimeType */\ntype TypeSpec =\n | string\n | { check: (v: unknown) => boolean | string; description: string }\n\n/**\n * Check that a passed-in function's declared shape matches the expected\n * shape. Returns the function unchanged on a match, or a MonadicError on\n * mismatch. Untyped functions (no `__tjs` metadata \u2014 anonymous arrows\n * like `x => false`) pass through unchanged on the assumption that the\n * caller knows what they're doing; they accept any args and return\n * whatever they return.\n *\n * This is a ONE-SHOT check at pass time, NOT a per-call wrapper. The TJS\n * design call: a wrong-shape callback is ONE error at the boundary, not\n * N errors when the receiving function invokes the callback N times.\n *\n * Compatibility rules (deliberately permissive \u2014 strict subtyping is a\n * separate, larger feature):\n * - For each expected param: the actual function may declare fewer\n * params (extras simply not used). If both declare a kind, they\n * must match exactly. Either side being `any` always matches.\n * - For the return type: same exact-match rule when both are known.\n */\nexport function checkFnShape(\n fn: unknown,\n expectedParamKinds: string[],\n expectedReturnKind: string,\n path: string\n): unknown {\n if (typeof fn !== 'function') return fn // outer \"is callable\" check already ran\n const meta = (fn as any).__tjs\n if (!meta || !meta.params) return fn // untyped \u2014 let it run\n\n const actualEntries = Object.entries(meta.params) as Array<\n [string, { type?: { kind?: string } }]\n >\n for (let i = 0; i < expectedParamKinds.length; i++) {\n const expectedKind = expectedParamKinds[i]\n if (expectedKind === 'any') continue\n const actual = actualEntries[i]\n if (!actual) continue // function takes fewer params, OK\n const actualKind = actual[1]?.type?.kind\n if (!actualKind || actualKind === 'any') continue\n if (actualKind !== expectedKind) {\n return new MonadicError(\n `Expected (...arg${i}: ${expectedKind}, ...) for '${path}', ` +\n `but callback declares arg${i} as ${actualKind}`,\n `${path}(arg${i})`,\n expectedKind,\n actualKind\n )\n }\n }\n\n if (expectedReturnKind !== 'any' && meta.returns) {\n // Metadata's `returns` is `{ type: TypeDescriptor, defaults?: ... }`,\n // but defensively also accept a bare TypeDescriptor.\n const actualReturnKind = meta.returns.type?.kind ?? meta.returns.kind\n if (\n actualReturnKind &&\n actualReturnKind !== 'any' &&\n actualReturnKind !== expectedReturnKind\n ) {\n return new MonadicError(\n `Expected callback returning ${expectedReturnKind} for '${path}', ` +\n `but callback returns ${actualReturnKind}`,\n `${path}(return)`,\n expectedReturnKind,\n actualReturnKind\n )\n }\n }\n\n return fn\n}\n\n/** Parameter metadata with optional location */\ninterface ParamMeta {\n type: TypeSpec\n required: boolean\n default?: unknown\n loc?: { start: number; end: number }\n}\n\n/**\n * Validate function arguments against __tjs metadata\n * Returns first error found, or null if all valid\n */\nexport function validateArgs(\n args: Record<string, unknown>,\n meta: {\n params: Record<string, ParamMeta>\n },\n funcName?: string\n): TJSError | null {\n for (const [name, param] of Object.entries(meta.params)) {\n const value = args[name]\n\n // Check if any arg is already an error - propagate first one\n if (isError(value)) return value\n\n // Check required\n if (param.required && value === undefined) {\n const expectedDesc =\n typeof param.type === 'string' ? param.type : param.type.description\n return error(`Missing required parameter '${name}'`, {\n path: funcName ? `${funcName}.${name}` : name,\n expected: expectedDesc,\n actual: 'undefined',\n loc: param.loc,\n })\n }\n\n // Skip type check for undefined optional params\n if (value === undefined) continue\n\n // Type check\n const typeError = checkType(\n value,\n param.type,\n funcName ? `${funcName}.${name}` : name\n )\n if (typeError) {\n // Add location info if available\n if (param.loc) {\n typeError.loc = param.loc\n }\n return typeError\n }\n }\n\n return null\n}\n\n/**\n * Function metadata with safety flags\n */\nexport interface FunctionMeta {\n params: Record<string, any>\n returns?: { type: any; safe?: boolean; defaults?: Record<string, unknown> }\n /** Function marked with (!) - never validate inputs */\n unsafe?: boolean\n /** Function marked with (?) - always validate inputs */\n safe?: boolean\n /** Return type marked with -! - never validate output */\n unsafeReturn?: boolean\n /** Return type marked with -? - always validate output */\n safeReturn?: boolean\n /** Explicit function name for stack tracking (used when fn.name is empty) */\n name?: string\n /** Polymorphic dispatcher \u2014 skip wrapping, dispatch handles validation */\n polymorphic?: boolean\n}\n\n/**\n * Determine if we should validate inputs for this call\n * Reserved for future use with runtime validation modes\n */\nfunction _shouldValidateInputs(meta: FunctionMeta): boolean {\n // Per-function flags take precedence\n if (meta.unsafe) return false\n if (meta.safe) return true\n\n // Block-level override\n if (unsafeDepth > 0) return false\n\n // Global safety level\n return config.safety !== 'none'\n}\n\n/**\n * Determine if we should validate outputs for this call\n * Reserved for future use with runtime validation modes\n */\nfunction _shouldValidateOutputs(meta: FunctionMeta): boolean {\n // No return type declared = no validation\n if (!meta.returns) return false\n\n // Per-function return flags take precedence\n if (meta.unsafeReturn) return false\n if (meta.safeReturn) return true\n\n // Block-level override\n if (unsafeDepth > 0) return false\n\n // Global safety level: 'all' validates outputs, others don't by default\n return config.safety === 'all'\n}\n\n/**\n * Wrap a function with monadic type checking\n *\n * @param fn - The original function\n * @param meta - The __tjs metadata\n * @returns Wrapped function that validates inputs and propagates errors\n */\nexport function wrap<T extends (...args: any[]) => any>(\n fn: T,\n meta: FunctionMeta\n): T {\n // Always attach metadata for introspection/autocomplete\n ;(fn as any).__tjs = meta\n // Lazy JSON Schema generation \u2014 only computed when called\n ;(fn as any).__tjs.schema = () => functionMetaToJSONSchema(meta)\n\n // Determine if we need a wrapper at all\n // Polymorphic dispatchers handle their own routing \u2014 no wrapping needed\n const needsWrapper =\n !meta.polymorphic && // Has forced safety that requires validation\n (meta.safe ||\n meta.safeReturn ||\n // Global safety requires validation (and not explicitly unsafe)\n (config.safety !== 'none' && !meta.unsafe) ||\n // Has return type that might need validation\n (meta.returns && config.safety === 'all' && !meta.unsafeReturn))\n\n if (!needsWrapper) {\n return fn\n }\n\n // Pre-compute flags at wrap time\n const hasReturns = !!meta.returns\n const metaUnsafe = !!meta.unsafe\n const metaSafe = !!meta.safe\n const metaUnsafeReturn = !!meta.unsafeReturn\n const metaSafeReturn = !!meta.safeReturn\n // Pre-compute return defaults (for `key = value` in return type signatures)\n // NOTE: applying defaults adds an Object.assign per call \u2014 may need benchmarking\n const returnDefaults = meta.returns?.defaults\n const paramEntries = Object.entries(meta.params)\n const paramCount = paramEntries.length\n // Use meta.name as fallback when fn.name is empty (anonymous functions)\n const funcName = fn.name || meta.name || 'anonymous'\n\n const wrapped = function (this: any, ...args: Parameters<T>): ReturnType<T> {\n // Fast path: inside unsafe block, skip all validation\n if (unsafeDepth > 0) {\n return fn.apply(this, args)\n }\n\n // Compute validation flags\n const validateInputs = metaSafe || (!metaUnsafe && config.safety !== 'none')\n const validateOutputs =\n hasReturns &&\n (metaSafeReturn || (!metaUnsafeReturn && config.safety === 'all'))\n\n // Fast path: no validation needed\n if (!validateInputs && !validateOutputs) {\n return fn.apply(this, args)\n }\n\n // Fast path: check for error as first arg\n if (args.length > 0 && isError(args[0])) {\n return args[0] as ReturnType<T>\n }\n\n // Input validation\n if (validateInputs) {\n // Detect if single object arg (named params) vs positional\n const isNamedCall =\n args.length === 1 &&\n typeof args[0] === 'object' &&\n args[0] !== null &&\n !Array.isArray(args[0])\n\n // Collect all errors to compose them\n const collectedErrors: TJSError[] = []\n\n // Fast positional validation (avoids object allocation)\n if (!isNamedCall) {\n for (let i = 0; i < paramCount; i++) {\n const [name, param] = paramEntries[i]\n const value = args[i]\n\n // Check for error propagation (passed-in errors)\n if (isError(value)) {\n collectedErrors.push(value)\n continue\n }\n\n // Check required\n if (param.required && value === undefined) {\n collectedErrors.push(\n error(`Missing required parameter '${name}'`, {\n path: `${funcName}.${name}`,\n expected:\n typeof param.type === 'string'\n ? param.type\n : param.type?.description || 'value',\n actual: 'undefined',\n loc: param.loc,\n })\n )\n continue\n }\n\n // Type check (skip undefined optional)\n if (value !== undefined) {\n const typeErr = checkType(value, param.type, `${funcName}.${name}`)\n if (typeErr) {\n if (param.loc) typeErr.loc = param.loc\n collectedErrors.push(typeErr)\n }\n }\n }\n } else {\n // Named args path (slower, but supports object destructuring)\n const namedArgs = args[0] as Record<string, unknown>\n for (let i = 0; i < paramCount; i++) {\n const [name, param] = paramEntries[i]\n const value = namedArgs[name]\n\n if (isError(value)) {\n collectedErrors.push(value)\n continue\n }\n\n if (param.required && value === undefined) {\n collectedErrors.push(\n error(`Missing required parameter '${name}'`, {\n path: `${funcName}.${name}`,\n expected:\n typeof param.type === 'string'\n ? param.type\n : param.type?.description || 'value',\n actual: 'undefined',\n loc: param.loc,\n })\n )\n continue\n }\n\n if (value !== undefined) {\n const typeErr = checkType(value, param.type, `${funcName}.${name}`)\n if (typeErr) {\n if (param.loc) typeErr.loc = param.loc\n collectedErrors.push(typeErr)\n }\n }\n }\n }\n\n // If we collected any errors, compose and return them\n if (collectedErrors.length > 0) {\n return composeErrors(collectedErrors, funcName) as ReturnType<T>\n }\n }\n\n // Track call stack only when enabled (ring buffer, no allocation)\n const trackStack = config.callStacks || config.debug\n if (trackStack) pushStack(funcName)\n\n try {\n // Execute function\n const result = fn.apply(this, args)\n\n // Output validation\n if (validateOutputs && meta.returns && !isError(result)) {\n // Apply return defaults before validation\n const validated =\n returnDefaults && typeof result === 'object' && result !== null\n ? Object.assign({}, returnDefaults, result)\n : result\n const returnError = checkType(\n validated,\n meta.returns.type,\n `${funcName}()`\n )\n if (returnError) {\n if (trackStack) popStack()\n return returnError as ReturnType<T>\n }\n }\n\n if (trackStack) popStack()\n return result\n } catch (e) {\n if (trackStack) popStack()\n // Convert thrown errors to TJS errors\n return error((e as Error).message || String(e), {\n path: funcName,\n cause: e as Error,\n }) as ReturnType<T>\n }\n }\n\n // Preserve function name and metadata\n Object.defineProperty(wrapped, 'name', { value: fn.name })\n ;(wrapped as any).__tjs = meta\n ;(wrapped as any).__tjs.schema = () => functionMetaToJSONSchema(meta)\n\n return wrapped as T\n}\n\n/**\n * Wrap a class to make it callable without `new`\n *\n * In TJS, classes can be instantiated without the `new` keyword:\n * const obj = MyClass(args) // equivalent to new MyClass(args)\n *\n * This eliminates a common source of errors where developers forget `new`.\n * Using explicit `new` still works but should be flagged by the linter.\n */\nexport function wrapClass<T extends new (...args: any[]) => any>(\n cls: T\n): T & ((...args: ConstructorParameters<T>) => InstanceType<T>) {\n // Use a Proxy to intercept both `new Wrapper()` and `Wrapper()` calls\n const wrapped = new Proxy(cls, {\n // Called when using `new Wrapper(...)`\n construct(target, args, newTarget) {\n return Reflect.construct(target, args, newTarget)\n },\n // Called when using `Wrapper(...)` without new\n apply(target, _thisArg, args) {\n return Reflect.construct(target, args)\n },\n })\n\n // Preserve class name\n Object.defineProperty(wrapped, 'name', { value: cls.name })\n\n // Copy static properties and methods\n for (const key of Object.getOwnPropertyNames(cls)) {\n if (key !== 'length' && key !== 'name' && key !== 'prototype') {\n Object.defineProperty(\n wrapped,\n key,\n Object.getOwnPropertyDescriptor(cls, key)!\n )\n }\n }\n\n return wrapped as T & ((...args: ConstructorParameters<T>) => InstanceType<T>)\n}\n\n// ============================================================================\n// SafeFunction and Eval - moved to ./eval.ts\n// ============================================================================\n//\n// Eval and SafeFunction are in a separate module to keep the runtime lite.\n// Import from 'tjs-lang/eval' when you need dynamic code execution.\n//\n// Runtime (this file): ~5KB gzipped - type checking, Is/IsNot, wrap, etc.\n// Eval module: ~27KB gzipped - adds transpiler + VM for dynamic code\n// ============================================================================\n\n/**\n * Create an isolated TJS runtime instance\n *\n * Each call returns a fresh runtime with its own:\n * - config (debug, safety, etc.)\n * - callStack\n * - unsafeDepth\n *\n * The new instance inherits the current global config at creation time,\n * but subsequent changes are isolated.\n *\n * Use this to prevent state leaking between transpiled modules.\n */\nexport function createRuntime() {\n // Per-instance state - inherit current global config\n let instanceConfig: TJSConfig = { ...config }\n const instStackSize = instanceConfig.maxStackSize ?? STACK_SIZE\n const instanceStackBuffer: string[] = new Array(instStackSize).fill('')\n let instanceStackHead = 0\n let instanceStackCount = 0\n const instErrorSize = instanceConfig.maxErrors ?? ERROR_BUF_SIZE\n const instanceErrorBuffer: any[] = new Array(instErrorSize).fill(null)\n let instanceErrorHead = 0\n let instanceErrorBufCount = 0\n let instanceErrorTotal = 0\n let instanceUnsafeDepth = 0\n\n // Per-instance stateful functions\n function instanceConfigure(options: TJSConfig): void {\n instanceConfig = { ...instanceConfig, ...options }\n }\n\n function instanceGetConfig(): TJSConfig {\n return { ...instanceConfig }\n }\n\n function instancePushStack(name: string): void {\n if ((instanceConfig.callStacks || instanceConfig.debug) && name) {\n instanceStackBuffer[instanceStackHead] = name\n instanceStackHead = (instanceStackHead + 1) % instStackSize\n if (instanceStackCount < instStackSize) instanceStackCount++\n }\n }\n\n function instancePopStack(): void {\n if (\n (instanceConfig.callStacks || instanceConfig.debug) &&\n instanceStackCount > 0\n ) {\n instanceStackHead =\n (instanceStackHead - 1 + instStackSize) % instStackSize\n instanceStackCount--\n }\n }\n\n function instanceGetStack(): string[] {\n if (instanceStackCount === 0) return []\n const result: string[] = []\n const start =\n (instanceStackHead - instanceStackCount + instStackSize) % instStackSize\n for (let i = 0; i < instanceStackCount; i++) {\n result.push(instanceStackBuffer[(start + i) % instStackSize])\n }\n return result\n }\n\n function instanceResetRuntime(): void {\n instanceConfig = { ...DEFAULT_CONFIG }\n instanceStackHead = 0\n instanceStackCount = 0\n instanceErrorHead = 0\n instanceErrorBufCount = 0\n instanceErrorTotal = 0\n instanceUnsafeDepth = 0\n }\n\n function instanceEnterUnsafe(): void {\n instanceUnsafeDepth++\n }\n\n function instanceExitUnsafe(): void {\n if (instanceUnsafeDepth > 0) instanceUnsafeDepth--\n }\n\n function instanceIsUnsafeMode(): boolean {\n return instanceUnsafeDepth > 0\n }\n\n // Extension registry: typeName -> methodName -> fn\n const extensionRegistry = new Map<\n string,\n Map<string, (...args: any[]) => any>\n >()\n\n function instanceRegisterExtension(\n typeName: string,\n methodName: string,\n fn: (...args: any[]) => any\n ): void {\n if (!extensionRegistry.has(typeName)) {\n extensionRegistry.set(typeName, new Map())\n }\n extensionRegistry.get(typeName)!.set(methodName, fn)\n }\n\n function instanceResolveExtension(\n value: unknown,\n methodName: string\n ): ((...args: any[]) => any) | undefined {\n // Determine type name from value\n const t = typeof value\n let typeName: string\n if (value === null || value === undefined) return undefined\n if (t === 'string') typeName = 'String'\n else if (t === 'number') typeName = 'Number'\n else if (t === 'boolean') typeName = 'Boolean'\n else if (Array.isArray(value)) typeName = 'Array'\n else if (t === 'object') {\n // Check constructor name for class instances (including DOM classes)\n typeName = (value as any).constructor?.name || 'Object'\n } else {\n return undefined\n }\n\n // Walk prototype chain: HTMLInputElement -> HTMLElement -> Element -> Object\n let current: string | undefined = typeName\n while (current) {\n const methods = extensionRegistry.get(current)\n if (methods?.has(methodName)) {\n return methods.get(methodName)\n }\n // Walk up: try parent class (for DOM/custom class hierarchies)\n if (t === 'object' && !Array.isArray(value)) {\n const proto = Object.getPrototypeOf(\n current === typeName ? value : Object.getPrototypeOf(value)\n )\n current = proto?.constructor?.name\n if (current === 'Object' || current === typeName) break\n } else {\n break\n }\n }\n\n // Fallback: check 'Object' extensions\n const objectMethods = extensionRegistry.get('Object')\n if (objectMethods?.has(methodName)) {\n return objectMethods.get(methodName)\n }\n\n return undefined\n }\n\n function instanceTypeError(\n path: string,\n expected: string,\n value: unknown\n ): MonadicError {\n const actual = value === null ? 'null' : typeof value\n const stack =\n instanceConfig.callStacks || instanceConfig.debug\n ? instanceGetStack()\n : undefined\n const err = new MonadicError(\n `Expected ${expected} for '${path}', got ${actual}`,\n path,\n expected,\n actual,\n stack\n )\n\n // Track in error history\n if (instanceConfig.trackErrors !== false) {\n instanceErrorBuffer[instanceErrorHead] = err\n instanceErrorHead = (instanceErrorHead + 1) % instErrorSize\n if (instanceErrorBufCount < instErrorSize) instanceErrorBufCount++\n instanceErrorTotal++\n }\n\n if (instanceConfig.logTypeErrors) {\n console.error(`[TJS TypeError] ${err.message}`)\n }\n if (instanceConfig.throwTypeErrors) {\n throw err\n }\n\n return err\n }\n\n function instanceErrors(): MonadicError[] {\n if (instanceConfig.trackErrors === false || instanceErrorBufCount === 0)\n return []\n const result: MonadicError[] = []\n const start =\n (instanceErrorHead - instanceErrorBufCount + instErrorSize) %\n instErrorSize\n for (let i = 0; i < instanceErrorBufCount; i++) {\n result.push(instanceErrorBuffer[(start + i) % instErrorSize])\n }\n return result\n }\n\n function instanceClearErrors(): MonadicError[] {\n const cleared = instanceErrors()\n instanceErrorHead = 0\n instanceErrorBufCount = 0\n instanceErrorTotal = 0\n return cleared\n }\n\n function instanceGetErrorCount(): number {\n return instanceErrorTotal\n }\n\n function instanceError(\n message: string,\n details?: Partial<Omit<TJSError, '$error' | 'message'>>\n ): TJSError {\n const err: TJSError = {\n $error: true,\n message,\n ...details,\n }\n if (\n (instanceConfig.callStacks || instanceConfig.debug) &&\n instanceStackCount > 0\n ) {\n const fullStack = details?.path\n ? [...instanceGetStack(), details.path]\n : instanceGetStack()\n err.stack = fullStack\n }\n return err\n }\n\n /**\n * Bang access (!.) \u2014 asserted non-null member access.\n * Returns MonadicError if obj is null, undefined, or already a MonadicError.\n * Otherwise returns obj[prop] (bare access \u2014 throws as usual on other errors).\n */\n function instanceBang(obj: unknown, prop: string): unknown {\n if (obj === null || obj === undefined) {\n return instanceTypeError(`bang.${prop}`, 'non-null', obj)\n }\n if (isMonadicError(obj)) return obj\n return (obj as any)[prop]\n }\n\n return {\n version: TJS_VERSION,\n // Monadic error handling\n MonadicError,\n typeError: instanceTypeError,\n isMonadicError,\n // Bang access (!.)\n bang: instanceBang,\n // Legacy error handling\n isError,\n error: instanceError,\n composeErrors,\n typeOf,\n isNativeType,\n checkType,\n validateArgs,\n wrap,\n checkFnShape,\n wrapClass,\n compareVersions,\n versionsCompatible,\n // Create child runtime instances\n createRuntime,\n // Debug mode (instance-specific)\n configure: instanceConfigure,\n getConfig: instanceGetConfig,\n pushStack: instancePushStack,\n popStack: instancePopStack,\n getStack: instanceGetStack,\n errors: instanceErrors,\n clearErrors: instanceClearErrors,\n getErrorCount: instanceGetErrorCount,\n resetRuntime: instanceResetRuntime,\n // Unsafe mode (instance-specific)\n enterUnsafe: instanceEnterUnsafe,\n exitUnsafe: instanceExitUnsafe,\n isUnsafeMode: instanceIsUnsafeMode,\n // Type system\n validate,\n infer: s.infer.bind(s),\n Type,\n isRuntimeType,\n Union,\n Generic,\n Enum,\n FunctionPredicate,\n Nullable,\n Optional,\n TArray,\n TString,\n TNumber,\n TBoolean,\n TInteger,\n TPositiveInt,\n TNonEmptyString,\n TEmail,\n TUrl,\n TUuid,\n TPair,\n TRecord,\n // Structural equality\n Is,\n IsNot,\n // Honest equality (== / != with TjsEquals)\n Eq,\n NotEq,\n // Honest typeof (typeof with TjsEquals)\n TypeOf,\n // Honest truthiness (unwraps boxed primitives)\n toBool,\n tjsEquals,\n // Extensions\n registerExtension: instanceRegisterExtension,\n resolveExtension: instanceResolveExtension,\n }\n}\n\n/** Type for runtime instances */\nexport type TJSRuntime = ReturnType<typeof createRuntime>\n\n/**\n * TJS Runtime object - attached to globalThis.__tjs\n *\n * NOTE: This is a shared global instance. For isolated execution,\n * use createRuntime() instead.\n */\nexport const runtime = {\n version: TJS_VERSION,\n // Monadic error handling (new)\n MonadicError,\n typeError,\n isMonadicError,\n // Legacy error handling (deprecated)\n isError,\n error,\n composeErrors,\n typeOf,\n isNativeType,\n checkType,\n validateArgs,\n wrap,\n checkFnShape,\n wrapClass,\n compareVersions,\n versionsCompatible,\n // Debug mode\n configure,\n getConfig,\n pushStack,\n popStack,\n getStack,\n errors,\n clearErrors,\n getErrorCount,\n resetRuntime,\n // Unsafe mode\n enterUnsafe,\n exitUnsafe,\n isUnsafeMode,\n // Factory for isolated instances\n createRuntime,\n // Type system (used by transpiled Type declarations)\n validate,\n infer: s.infer.bind(s),\n Type,\n isRuntimeType,\n Union,\n Generic,\n Enum,\n FunctionPredicate,\n Nullable,\n Optional,\n TArray,\n // Built-in types\n TString,\n TNumber,\n TBoolean,\n TInteger,\n TPositiveInt,\n TNonEmptyString,\n TEmail,\n TUrl,\n TUuid,\n Timestamp,\n LegalDate,\n TPair,\n TRecord,\n // Structural equality (used by Is/IsNot operators)\n Is,\n IsNot,\n // Honest equality (used by == and != with TjsEquals)\n Eq,\n NotEq,\n // Honest typeof (used by typeof with TjsEquals)\n TypeOf,\n // Honest truthiness (used in TjsStandard for boxed-primitive coercion)\n toBool,\n}\n\n/**\n * Install runtime globally (idempotent, version-checked)\n *\n * Version handling:\n * - Same version: reuse existing (no warning)\n * - Compatible (same major): reuse existing, log info\n * - Incompatible (different major): warn, use newer version\n */\nexport function installRuntime(): typeof runtime {\n const g = globalThis as any\n\n if (g.__tjs) {\n const existingVersion = g.__tjs.version\n\n // Guard against polluted __tjs without proper version\n if (typeof existingVersion !== 'string') {\n g.__tjs = runtime\n return runtime\n }\n\n const comparison = compareVersions(TJS_VERSION, existingVersion)\n\n if (comparison === 0) {\n // Exact same version - just reuse\n return g.__tjs\n }\n\n if (versionsCompatible(TJS_VERSION, existingVersion)) {\n // Same major version - compatible, use newer\n if (comparison > 0) {\n console.info(\n `TJS runtime: upgrading ${existingVersion} \u2192 ${TJS_VERSION}`\n )\n g.__tjs = runtime\n } else {\n console.info(\n `TJS runtime: keeping ${existingVersion} (newer than ${TJS_VERSION})`\n )\n }\n } else {\n // Different major version - breaking change potential\n console.warn(\n `TJS runtime version conflict: ${existingVersion} vs ${TJS_VERSION} (major version mismatch)`\n )\n // Use the newer one but warn about potential issues\n if (comparison > 0) {\n console.warn(`Upgrading to ${TJS_VERSION} - check for breaking changes`)\n g.__tjs = runtime\n }\n }\n\n return g.__tjs\n }\n\n g.__tjs = runtime\n return runtime\n}\n\n/**\n * Generate runtime wrapper code for emitted JS\n * Skips wrapping for unsafe functions (marked with !)\n */\nexport function emitRuntimeWrapper(funcName: string): string {\n return `\n// TJS runtime wrapper (skips unsafe functions)\nif (typeof ${funcName}.__tjs === 'object' && !${funcName}.__tjs.unsafe && typeof globalThis.__tjs?.wrap === 'function') {\n ${funcName} = globalThis.__tjs.wrap(${funcName}, ${funcName}.__tjs)\n}\n`.trim()\n}\n\n/**\n * Generate class wrapper code for emitted JS\n * Makes classes callable without `new` keyword\n * Emits standalone JS - no runtime dependency\n */\nexport function emitClassWrapper(className: string): string {\n return `\n// TJS: callable without new\n${className} = new Proxy(${className}, { apply(t, _, a) { return Reflect.construct(t, a) } });\n`.trim()\n}\n\n/**\n * Questions/Notes:\n *\n * Q1: Should wrap() be automatic or opt-in?\n * Current: Must be explicitly wrapped\n * Could: Auto-wrap all functions with __tjs metadata\n *\n * Q2: Performance overhead of validation?\n * Need benchmarks comparing wrapped vs unwrapped\n * Could have 'production' mode that skips validation\n *\n * Q3: Async function handling?\n * wrap() should detect async and handle Promise returns\n *\n * Q4: Deep object validation?\n * Currently only checks top-level type\n * Could recursively validate object shapes\n */\n", "/**\n * JSON Schema generation from TJS TypeDescriptors and example values\n *\n * Converts TJS type information into standard JSON Schema (draft 2020-12).\n */\n\nimport type { TypeDescriptor } from './types'\n\nexport interface JSONSchemaObject {\n type?: string | string[]\n properties?: Record<string, JSONSchemaObject>\n items?: JSONSchemaObject | JSONSchemaObject[]\n required?: string[]\n additionalProperties?: boolean\n anyOf?: JSONSchemaObject[]\n minimum?: number\n examples?: unknown[]\n description?: string\n [key: string]: unknown\n}\n\n/**\n * Convert a TypeDescriptor to JSON Schema\n */\nexport function typeDescriptorToJSONSchema(\n td: TypeDescriptor\n): JSONSchemaObject {\n if (td.nullable) {\n const base = typeDescriptorToJSONSchema({ ...td, nullable: false })\n return { anyOf: [base, { type: 'null' }] }\n }\n\n switch (td.kind) {\n case 'string':\n return { type: 'string' }\n case 'number':\n return { type: 'number' }\n case 'integer':\n return { type: 'integer' }\n case 'non-negative-integer':\n return { type: 'integer', minimum: 0 }\n case 'boolean':\n return { type: 'boolean' }\n case 'null':\n return { type: 'null' }\n case 'undefined':\n return {}\n case 'any':\n return {}\n case 'array':\n if (td.items) {\n return { type: 'array', items: typeDescriptorToJSONSchema(td.items) }\n }\n return { type: 'array' }\n case 'object':\n if (td.shape) {\n const properties: Record<string, JSONSchemaObject> = {}\n const required: string[] = []\n for (const [key, fieldTd] of Object.entries(td.shape)) {\n properties[key] = typeDescriptorToJSONSchema(fieldTd)\n required.push(key)\n }\n return {\n type: 'object',\n properties,\n required,\n additionalProperties: false,\n }\n }\n return { type: 'object' }\n case 'union':\n if (td.members) {\n return { anyOf: td.members.map(typeDescriptorToJSONSchema) }\n }\n return {}\n default:\n return {}\n }\n}\n\n/**\n * Infer a JSON Schema from an example value (without going through TypeDescriptor)\n */\nexport function exampleToJSONSchema(value: unknown): JSONSchemaObject {\n if (value === null) return { type: 'null' }\n if (value === undefined) return {}\n\n switch (typeof value) {\n case 'string':\n return { type: 'string' }\n case 'number':\n return Number.isInteger(value) ? { type: 'integer' } : { type: 'number' }\n case 'boolean':\n return { type: 'boolean' }\n case 'object': {\n if (Array.isArray(value)) {\n if (value.length === 0) return { type: 'array' }\n // Infer item type from first element\n return { type: 'array', items: exampleToJSONSchema(value[0]) }\n }\n // Object\n const properties: Record<string, JSONSchemaObject> = {}\n const required: string[] = []\n for (const [key, val] of Object.entries(\n value as Record<string, unknown>\n )) {\n properties[key] = exampleToJSONSchema(val)\n required.push(key)\n }\n return {\n type: 'object',\n properties,\n required,\n additionalProperties: false,\n }\n }\n default:\n return {}\n }\n}\n\n/**\n * Generate JSON Schema for function parameters (as an object schema)\n * and return type from __tjs metadata\n */\nexport function functionMetaToJSONSchema(meta: {\n params: Record<string, any>\n returns?: { type: any; example?: any }\n}): { input: JSONSchemaObject; output?: JSONSchemaObject } {\n const properties: Record<string, JSONSchemaObject> = {}\n const required: string[] = []\n\n for (const [name, paramInfo] of Object.entries(meta.params)) {\n if (paramInfo?.type?.kind) {\n // Has TypeDescriptor\n properties[name] = typeDescriptorToJSONSchema(paramInfo.type)\n } else if (paramInfo?.example !== undefined) {\n // Has example value\n properties[name] = exampleToJSONSchema(paramInfo.example)\n } else {\n properties[name] = {}\n }\n if (paramInfo?.required !== false) {\n required.push(name)\n }\n if (paramInfo?.example !== undefined) {\n properties[name].examples = [paramInfo.example]\n }\n }\n\n const input: JSONSchemaObject = {\n type: 'object',\n properties,\n required,\n }\n\n let output: JSONSchemaObject | undefined\n if (meta.returns) {\n if (meta.returns.type?.kind) {\n output = typeDescriptorToJSONSchema(meta.returns.type)\n } else if (meta.returns.example !== undefined) {\n output = exampleToJSONSchema(meta.returns.example)\n }\n }\n\n return { input, output }\n}\n", "/**\n * Type() - Runtime type definitions with descriptions and validation\n *\n * Forms:\n * Type(description, predicate) - full form with custom validation\n * Type(description, schema) - schema-based validation\n * Type(schema) - schema only, self-documenting\n *\n * Usage:\n * const ZipCode = Type('5-digit US zip code', (s) => /^\\d{5}$/.test(s))\n * const Email = Type('valid email', s.string.email)\n * const Age = Type(s.number.min(0).max(150))\n *\n * ZipCode.check('12345') // true\n * ZipCode.check('abc') // false\n * ZipCode.description // '5-digit US zip code'\n */\n\nimport { validate, filter as schemaFilter, s, type Base } from 'tosijs-schema'\nimport { exampleToJSONSchema, type JSONSchemaObject } from '../lang/json-schema'\n\n/** JSON Schema object type (simplified) */\ntype JSONSchema = {\n type?: string\n properties?: Record<string, JSONSchema>\n items?: JSONSchema\n required?: string[]\n [key: string]: unknown\n}\n\n/** Schema can be a tosijs-schema builder or a raw JSON Schema object */\ntype Schema = Base<any> | JSONSchema\n\n/** A runtime type with description and validation */\nexport interface RuntimeType<T = unknown> {\n /** Human-readable description of the type */\n readonly description: string\n /** Check if a value matches this type. Returns true on pass, false on fail, or a reason string on fail. */\n check(value: unknown): boolean | string\n /** The underlying schema (if schema-based) */\n readonly schema?: Schema\n /** The predicate function (if predicate-based). May return a reason string on failure. */\n readonly predicate?: (value: unknown) => boolean | string\n /** Example value (for documentation and signature testing) */\n readonly example?: T\n /** Multiple example values (from schema metadata, for autocomplete hints) */\n readonly examples?: T[]\n /** Default value (for instantiation) */\n readonly default?: T\n /** Generate JSON Schema for this type */\n toJSONSchema(): JSONSchemaObject\n /** Strip a value down to only the fields matching this type's schema */\n strip(value: unknown): unknown\n /** Brand for type identification */\n readonly __runtimeType: true\n}\n\n/** Check if a value is a RuntimeType */\nexport function isRuntimeType(value: unknown): value is RuntimeType {\n return (\n value !== null &&\n typeof value === 'object' &&\n '__runtimeType' in value &&\n (value as any).__runtimeType === true\n )\n}\n\n/**\n * Create a runtime type with description and validation\n *\n * @overload Type(description, predicate) - custom validation function\n * @overload Type(description, schema) - schema-based validation\n * @overload Type(schema) - schema only\n */\n/**\n * Check if a value is a tosijs-schema builder (has .schema property)\n */\nfunction isSchemaBuilder(value: unknown): value is Base<any> {\n return (\n value !== null &&\n typeof value === 'object' &&\n 'schema' in value &&\n typeof (value as any).schema === 'object'\n )\n}\n\n/**\n * Check if a value looks like a raw JSON Schema object\n */\nfunction isJSONSchema(value: unknown): value is JSONSchema {\n return (\n value !== null &&\n typeof value === 'object' &&\n 'type' in value &&\n typeof (value as any).type === 'string'\n )\n}\n\nexport function Type<T = unknown>(\n descriptionOrSchema: string | Schema,\n predicateOrSchemaOrExample?:\n | ((value: unknown) => boolean | string)\n | Schema\n | T\n | undefined,\n exampleArg?: T,\n defaultArg?: T\n): RuntimeType<T> {\n // Parse arguments\n let description: string\n let predicate: ((value: unknown) => boolean | string) | undefined\n let schema: Schema | undefined\n let example: T | undefined = exampleArg\n let defaultValue: T | undefined = defaultArg\n\n if (typeof descriptionOrSchema === 'string') {\n // Form: Type(description, predicate/schema/example, example?, default?)\n description = descriptionOrSchema\n\n if (typeof predicateOrSchemaOrExample === 'function') {\n // Type(description, predicate, example?, default?)\n predicate = predicateOrSchemaOrExample as (\n value: unknown\n ) => boolean | string\n // If we have example, infer schema from it for the type guard in predicate\n if (example !== undefined) {\n schema = s.infer(example)\n }\n } else if (\n predicateOrSchemaOrExample === undefined &&\n example !== undefined\n ) {\n // Type(description, undefined, example, default?) - example provides schema\n schema = s.infer(example)\n } else if (isSchemaBuilder(predicateOrSchemaOrExample)) {\n // Type(description, schemaBuilder)\n schema = predicateOrSchemaOrExample\n } else if (isJSONSchema(predicateOrSchemaOrExample)) {\n // Type(description, jsonSchema)\n schema = predicateOrSchemaOrExample\n } else if (predicateOrSchemaOrExample !== undefined) {\n // Type(description, example) - second arg is the example/default, infer schema\n // This is the simple form: Type('Name', 'Alice')\n example = predicateOrSchemaOrExample as T\n defaultValue = example // In simple form, example IS the default\n schema = s.infer(example)\n } else {\n throw new Error(\n 'Type(description) requires a predicate, schema, or example'\n )\n }\n } else {\n // Form: Type(schema) or Type(schemaBuilder)\n if (isSchemaBuilder(descriptionOrSchema)) {\n schema = descriptionOrSchema\n } else {\n schema = descriptionOrSchema as Schema\n }\n description = schemaToDescription(schema)\n }\n\n // Extract examples from schema metadata (if any)\n let examples: T[] | undefined\n if (schema) {\n const jsonSchema = (schema as any)?.schema ?? schema\n if (\n jsonSchema &&\n typeof jsonSchema === 'object' &&\n Array.isArray((jsonSchema as any).examples)\n ) {\n examples = (jsonSchema as any).examples as T[]\n }\n }\n\n // If no explicit example was provided, use first schema example for autocomplete\n if (example === undefined && examples && examples.length > 0) {\n example = examples[0]\n }\n\n // Build the check function\n // Returns true on pass, false on fail, or a reason string on fail\n const check = (value: unknown): boolean | string => {\n if (predicate) {\n return predicate(value)\n }\n if (schema) {\n return validate(value, schema)\n }\n return false\n }\n\n return {\n description,\n check,\n schema,\n predicate,\n example,\n examples,\n default: defaultValue,\n toJSONSchema(): JSONSchemaObject {\n // If we have an underlying JSON Schema or builder, extract it\n if (schema) {\n const raw = (schema as any)?.schema ?? schema\n if (raw && typeof raw === 'object' && 'type' in raw) {\n return raw as JSONSchemaObject\n }\n }\n // Fall back to inferring from example\n if (example !== undefined) {\n return exampleToJSONSchema(example)\n }\n // Predicate-only types: best-effort from description\n return { description }\n },\n strip(value: unknown): unknown {\n if (schema) {\n return schemaFilter(value, schema)\n }\n // No schema \u2014 can't strip, return as-is\n return value\n },\n __runtimeType: true as const,\n }\n}\n\n/**\n * Generate a description from a schema\n */\nfunction schemaToDescription(schema: Schema): string {\n // tosijs-schema wraps JSON schema in .schema property\n const jsonSchema = (schema as any)?.schema ?? schema\n\n // Handle schema objects with type property\n if (jsonSchema && typeof jsonSchema === 'object' && 'type' in jsonSchema) {\n const s = jsonSchema as any\n switch (s.type) {\n case 'string':\n if (s.format) return `string (${s.format})`\n if (s.pattern) return `string matching ${s.pattern}`\n if (s.minLength !== undefined && s.maxLength !== undefined)\n return `string (${s.minLength}-${s.maxLength} chars)`\n return 'string'\n case 'number':\n case 'integer':\n if (s.minimum !== undefined && s.maximum !== undefined)\n return `${s.type} (${s.minimum}-${s.maximum})`\n if (s.minimum !== undefined) return `${s.type} >= ${s.minimum}`\n if (s.maximum !== undefined) return `${s.type} <= ${s.maximum}`\n return s.type\n case 'boolean':\n return 'boolean'\n case 'array':\n return 'array'\n case 'object':\n return 'object'\n case 'null':\n return 'null'\n }\n }\n\n // Fallback\n return 'value'\n}\n\n// ============================================================================\n// Built-in Types\n// ============================================================================\n\n/** String type */\nexport const TString = Type<string>('string', (v: unknown) => {\n if (typeof v === 'string') return true\n return `expected string, got ${v === null ? 'null' : typeof v}`\n})\n\n/** Number type */\nexport const TNumber = Type<number>('number', (v: unknown) => {\n if (typeof v === 'number') return true\n return `expected number, got ${v === null ? 'null' : typeof v}`\n})\n\n/** Boolean type */\nexport const TBoolean = Type<boolean>('boolean', (v: unknown) => {\n if (typeof v === 'boolean') return true\n return `expected boolean, got ${v === null ? 'null' : typeof v}`\n})\n\n/** Integer type */\nexport const TInteger = Type<number>('integer', (v: unknown) => {\n if (typeof v !== 'number')\n return `expected integer, got ${v === null ? 'null' : typeof v}`\n if (!Number.isInteger(v)) return `${v} is not an integer`\n return true\n})\n\n/** Positive integer type */\nexport const TPositiveInt = Type<number>('positive integer', (v: unknown) => {\n if (typeof v !== 'number')\n return `expected positive integer, got ${v === null ? 'null' : typeof v}`\n if (!Number.isInteger(v)) return `${v} is not an integer`\n if (v <= 0) return `${v} is not positive`\n return true\n})\n\n/** Non-empty string type */\nexport const TNonEmptyString = Type<string>(\n 'non-empty string',\n (v: unknown) => {\n if (typeof v !== 'string')\n return `expected string, got ${v === null ? 'null' : typeof v}`\n if (v.length === 0) return 'string is empty'\n return true\n }\n)\n\n/** Email type (basic validation) */\nexport const TEmail = Type<string>('email address', (v: unknown) => {\n if (typeof v !== 'string')\n return `expected string, got ${v === null ? 'null' : typeof v}`\n if (!/^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(v))\n return `\"${v}\" is not a valid email`\n return true\n})\n\n/**\n * Check if a string is a valid URL (portable helper for predicates)\n * This will become an AJS builtin\n */\nexport const isValidUrl = (v: string): boolean => {\n try {\n new URL(v)\n return true\n } catch {\n return false\n }\n}\n\n/** URL type */\nexport const TUrl = Type<string>('URL', (v: unknown) => {\n if (typeof v !== 'string')\n return `expected string, got ${v === null ? 'null' : typeof v}`\n if (!isValidUrl(v)) return `\"${v}\" is not a valid URL`\n return true\n})\n\n/** UUID type */\nexport const TUuid = Type<string>('UUID', (v: unknown) => {\n if (typeof v !== 'string')\n return `expected string, got ${v === null ? 'null' : typeof v}`\n if (\n !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(v)\n )\n return `\"${v}\" is not a valid UUID`\n return true\n})\n\n/**\n * Check if a string is a valid ISO 8601 timestamp (portable helper for predicates)\n * This will become an AJS builtin\n */\nexport const isValidTimestamp = (v: string): boolean => {\n const d = new Date(v)\n return !isNaN(d.getTime()) && v.includes('T')\n}\n\n/**\n * Check if a string is a valid YYYY-MM-DD date (portable helper for predicates)\n * This will become an AJS builtin\n */\nexport const isValidLegalDate = (v: string): boolean => {\n if (!/^\\d{4}-\\d{2}-\\d{2}$/.test(v)) return false\n const d = new Date(v + 'T00:00:00Z')\n return !isNaN(d.getTime())\n}\n\n/** ISO 8601 timestamp string (e.g., \"2024-01-15T10:30:00Z\") */\nexport const Timestamp = Type<string>(\n 'ISO 8601 timestamp',\n (v: unknown) => typeof v === 'string' && isValidTimestamp(v)\n)\n\n/** Legal date string in YYYY-MM-DD format */\nexport const LegalDate = Type<string>(\n 'date (YYYY-MM-DD)',\n (v: unknown) => typeof v === 'string' && isValidLegalDate(v)\n)\n\n// ============================================================================\n// Type Combinators\n// ============================================================================\n\n/** Create a nullable version of a type */\nexport function Nullable<T>(type: RuntimeType<T>): RuntimeType<T | null> {\n return Type<T | null>(\n `${type.description} or null`,\n (v: unknown) => v === null || type.check(v) === true\n )\n}\n\n/** Create an optional version of a type (nullable + undefined) */\nexport function Optional<T>(\n type: RuntimeType<T>\n): RuntimeType<T | null | undefined> {\n return Type<T | null | undefined>(\n `${type.description} (optional)`,\n (v: unknown) => v === null || v === undefined || type.check(v) === true\n )\n}\n\n/**\n * Create a union type\n *\n * Two forms:\n * Union(...types: RuntimeType[]) - combine existing types\n * Union(description, values) - create literal union from values\n *\n * @example\n * // From RuntimeTypes\n * const StringOrNumber = Union(TString, TNumber)\n *\n * // From literal values (used by TJS syntax)\n * const Direction = Union('cardinal direction', ['up', 'down', 'left', 'right'])\n */\nexport function Union<T extends unknown[]>(\n descriptionOrType: string | RuntimeType,\n valuesOrType?: T | RuntimeType,\n ...restTypes: RuntimeType[]\n): RuntimeType {\n // New form: Union(description, values[])\n if (typeof descriptionOrType === 'string' && Array.isArray(valuesOrType)) {\n const description = descriptionOrType\n const values = valuesOrType as unknown[]\n const valueSet = new Set(values)\n\n const result: RuntimeType & { values: unknown[] } = {\n description,\n check: (v: unknown): v is T[number] => valueSet.has(v),\n toJSONSchema: () => ({\n enum: values,\n }),\n strip: (value: unknown) => value,\n __runtimeType: true as const,\n values, // Expose values for introspection\n }\n return result\n }\n\n // Old form: Union(...types: RuntimeType[])\n const types: RuntimeType[] = []\n if (isRuntimeType(descriptionOrType)) {\n types.push(descriptionOrType)\n }\n if (isRuntimeType(valuesOrType)) {\n types.push(valuesOrType as RuntimeType)\n }\n types.push(...restTypes)\n\n const description = types.map((t) => t.description).join(' | ')\n return Type(description, (v: unknown) =>\n types.some((t) => t.check(v) === true)\n )\n}\n\n/** Create an array type */\nexport function TArray<T>(itemType: RuntimeType<T>): RuntimeType<T[]> {\n return Type<T[]>(\n `array of ${itemType.description}`,\n (v: unknown) =>\n Array.isArray(v) && v.every((item) => itemType.check(item) === true)\n )\n}\n\n// ============================================================================\n// Generic Types\n// ============================================================================\n\n/** Type parameter - can be a RuntimeType, schema, or example value */\nexport type TypeParam = RuntimeType | Base<any> | JSONSchema | unknown\n\n/** Generic type factory */\nexport interface GenericType<TParams extends string[] = string[]> {\n /** Instantiate the generic with concrete type arguments */\n (...typeArgs: TypeParam[]): RuntimeType\n /** The type parameter names */\n readonly params: TParams\n /** Description template */\n readonly description: string\n}\n\n/**\n * Convert a type param to a check function\n */\nfunction typeParamToCheck(param: TypeParam): (value: unknown) => boolean {\n if (isRuntimeType(param)) {\n return (v) => param.check(v) === true\n }\n // Check if it's a schema builder (has .schema property)\n if (param && typeof param === 'object' && 'schema' in param) {\n return (v) => validate(v, param as Base<any>)\n }\n // It's an example value - infer schema using s.infer\n const schema = s.infer(param)\n return (v) => validate(v, schema)\n}\n\n/**\n * Create a generic (parameterized) type factory\n *\n * @param params Array of type parameter names, with optional defaults: ['T', ['U', defaultSchema]]\n * @param predicate Function receiving (value, ...typeChecks) where typeChecks are validation functions\n * @param description Human-readable description template (type params will be substituted)\n *\n * @example\n * // Pair<T, U>\n * const Pair = Generic(\n * ['T', 'U'],\n * (x, checkT, checkU) =>\n * Array.isArray(x) && x.length === 2 && checkT(x[0]) && checkU(x[1]),\n * 'Pair<T, U>'\n * )\n *\n * // Usage: Pair(TString, TNumber) creates a type for [string, number]\n * // Or with examples: Pair('', 0)\n */\nexport function Generic<TParams extends string[]>(\n params: (string | [string, TypeParam])[],\n predicate: (\n value: unknown,\n ...typeChecks: Array<(v: unknown) => boolean>\n ) => boolean,\n description: string\n): GenericType<TParams> {\n // Extract param names and defaults\n const paramNames: string[] = []\n const defaults: (TypeParam | undefined)[] = []\n\n for (const p of params) {\n if (typeof p === 'string') {\n paramNames.push(p)\n defaults.push(undefined)\n } else {\n paramNames.push(p[0])\n defaults.push(p[1])\n }\n }\n\n // The factory function\n const factory = (...typeArgs: TypeParam[]): RuntimeType => {\n // Resolve type arguments, using defaults where not provided\n const checks = paramNames.map((_, i) => {\n const arg = i < typeArgs.length ? typeArgs[i] : defaults[i]\n if (arg === undefined) {\n // No arg and no default - accept anything\n return () => true\n }\n return typeParamToCheck(arg)\n })\n\n // Build description with substituted types\n let desc = description\n paramNames.forEach((name, i) => {\n const arg = i < typeArgs.length ? typeArgs[i] : defaults[i]\n let typeStr = 'any'\n if (isRuntimeType(arg)) {\n typeStr = arg.description\n } else if (arg !== undefined) {\n typeStr = typeof arg === 'string' ? 'string' : JSON.stringify(arg)\n }\n desc = desc.replace(new RegExp(`\\\\b${name}\\\\b`, 'g'), typeStr)\n })\n\n return Type(desc, (value: unknown) => predicate(value, ...checks))\n }\n\n ;(factory as any).params = paramNames as TParams\n ;(factory as any).description = description\n\n return factory as GenericType<TParams>\n}\n\n// ============================================================================\n// Built-in Generic Types\n// ============================================================================\n\n/** Pair<T, U> - 2-element tuple */\nexport const TPair = Generic(\n ['T', 'U'],\n (x, checkT, checkU) =>\n Array.isArray(x) && x.length === 2 && checkT(x[0]) && checkU(x[1]),\n 'Pair<T, U>'\n)\n\n/** Record<V> - object with string keys and values of type V */\nexport const TRecord = Generic(\n ['V'],\n (x, checkV) =>\n typeof x === 'object' &&\n x !== null &&\n !Array.isArray(x) &&\n Object.values(x).every(checkV),\n 'Record<string, V>'\n)\n\n// ============================================================================\n// Enum Types\n// ============================================================================\n\n/** Enum type with bidirectional lookup */\nexport interface EnumType<\n T extends Record<string, string | number> = Record<string, string | number>\n> extends RuntimeType<T[keyof T]> {\n /** The enum members as { Name: value } */\n readonly members: T\n /** Reverse lookup: value -> name */\n readonly names: Record<string | number, string>\n /** Get all valid values */\n readonly values: Array<T[keyof T]>\n /** Get all member names */\n readonly keys: Array<keyof T>\n}\n\n/**\n * Create an enum type with bidirectional lookup\n *\n * @param description Human-readable description\n * @param members Object mapping names to values { Pending: 0, Active: 1 }\n *\n * @example\n * const Status = Enum('task status', { Pending: 0, Active: 1, Done: 2 })\n * Status.check(0) // true\n * Status.check('done') // false\n * Status.members.Pending // 0\n * Status.names[0] // 'Pending'\n * Status.values // [0, 1, 2]\n * Status.keys // ['Pending', 'Active', 'Done']\n *\n * const Color = Enum('CSS color', { Red: 'red', Green: 'green', Blue: 'blue' })\n * Color.check('red') // true\n * Color.members.Red // 'red'\n */\nexport function Enum<T extends Record<string, string | number>>(\n description: string,\n members: T\n): EnumType<T> {\n const values = Object.values(members) as Array<T[keyof T]>\n const valueSet = new Set(values)\n const keys = Object.keys(members) as Array<keyof T>\n\n // Build reverse lookup\n const names: Record<string | number, string> = {}\n for (const [key, value] of Object.entries(members)) {\n names[value] = key\n }\n\n const enumType: EnumType<T> = {\n description,\n check: (v: unknown): v is T[keyof T] => valueSet.has(v as T[keyof T]),\n toJSONSchema: () => ({\n enum: values as unknown[],\n }),\n strip: (value: unknown) => value,\n __runtimeType: true as const,\n members,\n names,\n values,\n keys,\n }\n\n return enumType\n}\n\n// =============================================================================\n// FunctionPredicate - Runtime type for function signatures\n// =============================================================================\n\n/** Return contract levels in order of strictness */\nexport type ReturnContract = 'assertReturns' | 'returns' | 'checkedReturns'\n\n/** Specification for a FunctionPredicate */\nexport interface FunctionPredicateSpec {\n /** Parameter types as example values */\n params?: Record<string, any>\n /** Return type as example value */\n returns?: any\n /** Return contract level */\n returnContract?: ReturnContract\n}\n\n/** A runtime type that validates function signatures */\n// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\nexport interface FunctionPredicateType extends RuntimeType<Function> {\n /** Parameter specification */\n readonly params: Record<string, any>\n /** Return type specification */\n readonly returns?: any\n /** Return contract level */\n readonly returnContract: ReturnContract\n}\n\n/** A generic FunctionPredicate factory \u2014 call with type args to get a FunctionPredicateType */\nexport interface GenericFunctionPredicateType {\n (...typeArgs: TypeParam[]): FunctionPredicateType\n /** Type parameter names */\n readonly typeParamNames: string[]\n /** Description */\n readonly description: string\n /** Marker for runtime type detection */\n readonly __runtimeType: true\n}\n\n/** Infer a TypeDescriptor kind from an example value */\nfunction kindOfExample(example: unknown): string | null {\n if (example === null) return 'null'\n if (example === undefined) return 'undefined'\n switch (typeof example) {\n case 'string':\n return 'string'\n case 'boolean':\n return 'boolean'\n case 'number':\n return Number.isInteger(example) ? 'integer' : 'number'\n case 'object':\n return Array.isArray(example) ? 'array' : 'object'\n default:\n return null\n }\n}\n\n/**\n * Create a runtime type for function signatures.\n *\n * Forms:\n * FunctionPredicate(name, spec) - from a specification object\n * FunctionPredicate(name, fn) - from an existing typed function\n *\n * @example\n * const Callback = FunctionPredicate('Callback', {\n * params: { x: 0, y: 0 },\n * returns: 0,\n * })\n * Callback.check((a, b) => a + b) // true (typeof === 'function')\n * Callback.check(42) // false\n *\n * @example\n * function add(a: 0, b: 0) -> 0 { return a + b }\n * const Adder = FunctionPredicate('Adder', add)\n * // Extracts params/returns from add.__tjs\n *\n * @example\n * // Generic form \u2014 returns a factory\n * const Creator = FunctionPredicate('Creator', [['T', {}]], (T) => ({\n * params: { contents: [null] },\n * returns: T,\n * }))\n * const HtmlCreator = Creator({}) // FunctionPredicateType with returns: {}\n */\nexport function FunctionPredicate(\n name: string,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n specOrFn: FunctionPredicateSpec | Function | (string | [string, TypeParam])[],\n specBuilder?: (...typeArgs: any[]) => FunctionPredicateSpec\n): FunctionPredicateType | GenericFunctionPredicateType {\n // Generic form: FunctionPredicate(name, typeParams, specBuilder)\n if (Array.isArray(specOrFn) && specBuilder) {\n const typeParams = specOrFn as (string | [string, TypeParam])[]\n\n // Extract param names and defaults\n const paramNames: string[] = []\n const defaults: (TypeParam | undefined)[] = []\n for (const tp of typeParams) {\n if (Array.isArray(tp)) {\n paramNames.push(tp[0])\n defaults.push(tp[1])\n } else {\n paramNames.push(tp)\n defaults.push(undefined)\n }\n }\n\n const factory = ((...typeArgs: TypeParam[]) => {\n // Resolve type args with defaults\n const resolved: any[] = paramNames.map((_, idx) =>\n idx < typeArgs.length ? typeArgs[idx] : defaults[idx]\n )\n const spec = specBuilder(...resolved)\n return FunctionPredicate(name, spec) as FunctionPredicateType\n }) as GenericFunctionPredicateType\n\n Object.defineProperties(factory, {\n typeParamNames: { value: paramNames, enumerable: true },\n description: { value: name, enumerable: true },\n __runtimeType: { value: true, enumerable: true },\n })\n\n return factory\n }\n\n /* eslint-disable @typescript-eslint/no-unsafe-function-type */\n return _createFunctionPredicate(\n name,\n specOrFn as FunctionPredicateSpec | Function\n )\n /* eslint-enable @typescript-eslint/no-unsafe-function-type */\n}\n\n/** Internal: create a non-generic FunctionPredicateType */\nfunction _createFunctionPredicate(\n name: string,\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n specOrFn: FunctionPredicateSpec | Function\n): FunctionPredicateType {\n let params: Record<string, any> = {}\n let returns: any = undefined\n let returnContract: ReturnContract = 'assertReturns'\n\n if (typeof specOrFn === 'function') {\n // Extract from function's __tjs metadata\n const meta = (specOrFn as any).__tjs\n if (meta) {\n // Build params from __tjs.params\n if (meta.params) {\n for (const [key, info] of Object.entries(meta.params)) {\n params[key] = (info as any)?.example ?? null\n }\n }\n // Extract return type\n if (meta.returns) {\n returns = (meta.returns as any)?.example ?? null\n }\n // Extract return contract from safety markers\n if (meta.safeReturn) returnContract = 'checkedReturns'\n else if (meta.unsafe) returnContract = 'assertReturns'\n else returnContract = 'returns'\n }\n } else {\n params = specOrFn.params ?? {}\n returns = specOrFn.returns\n returnContract = specOrFn.returnContract ?? 'assertReturns'\n }\n\n const fpType: FunctionPredicateType = {\n description: name,\n params,\n returns,\n returnContract,\n toJSONSchema: () => ({ description: name, type: 'function' as any }),\n strip: (value: unknown) => value,\n check: (value: unknown): boolean | string => {\n if (typeof value !== 'function')\n return `expected function, got ${\n value === null ? 'null' : typeof value\n }`\n\n // Structural validation: check arity and __tjs metadata\n const expectedArity = Object.keys(params).length\n if (expectedArity > 0) {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-function-type\n const fn = value as Function\n const meta = (fn as any).__tjs\n if (meta?.params) {\n // Has TJS metadata \u2014 check param count matches\n const metaParamCount = Object.keys(meta.params).length\n if (metaParamCount !== expectedArity)\n return `expected ${expectedArity} params, got ${metaParamCount}`\n\n // Check param type kinds match where both sides have type info\n const expectedKeys = Object.keys(params)\n const metaKeys = Object.keys(meta.params)\n for (let i = 0; i < expectedKeys.length; i++) {\n const metaInfo = meta.params[metaKeys[i]]\n const expectedExample = params[expectedKeys[i]]\n if (metaInfo?.type?.kind && expectedExample !== undefined) {\n const expectedKind = kindOfExample(expectedExample)\n if (\n expectedKind &&\n metaInfo.type.kind !== expectedKind &&\n metaInfo.type.kind !== 'any'\n )\n return `param '${expectedKeys[i]}' expected ${expectedKind}, got ${metaInfo.type.kind}`\n }\n }\n }\n }\n\n return true\n },\n __runtimeType: true as const,\n }\n\n return fpType\n}\n"],
|
|
5
5
|
"mappings": "+DAAA,IAAAA,GAAAC,GAAA,CAAAC,GAAAC,KAAA,CAAAA,GAAA,SACE,KAAQ,WACR,QAAW,QACX,YAAe,kMACf,SAAY,CACV,aACA,aACA,qBACA,cACA,UACA,kBACA,mBACA,YACA,MACA,gBACA,WACA,gBACA,mBACA,WACA,gBACF,EACA,QAAW,aACX,KAAQ,kBACR,MAAS,wBACT,cAAiB,CACf,IAAK,CACH,KAAQ,CACN,2BACF,EACA,KAAQ,CACN,iCACF,EACA,eAAgB,CACd,uCACF,EACA,QAAW,CACT,8BACF,EACA,kBAAmB,CACjB,sCACF,EACA,GAAM,CACJ,0BACF,EACA,UAAa,CACX,iCACF,EACA,IAAO,CACL,2BACF,EACA,OAAU,CACR,8BACF,EACA,QAAW,CACT,8BACF,CACF,CACF,EACA,QAAW,CACT,IAAK,CACH,IAAO,iBACP,MAAS,wBACT,QAAW,iBACb,EACA,SAAU,CACR,IAAO,qBACP,MAAS,4BACT,QAAW,oBACb,EACA,SAAU,CACR,IAAO,2BACP,MAAS,kCACT,QAAW,oBACb,EACA,iBAAkB,CAChB,IAAO,iCACP,MAAS,wCACT,QAAW,uBACb,EACA,YAAa,CACX,MAAS,+BACT,QAAW,uBACb,EACA,oBAAqB,CACnB,MAAS,uCACT,QAAW,+BACb,EACA,OAAQ,CACN,IAAO,oBACP,MAAS,2BACT,QAAW,kBACb,EACA,cAAe,CACb,IAAO,2BACP,MAAS,kCACT,QAAW,yBACb,EACA,WAAY,CACV,IAAO,yBACP,QAAW,sBACb,EACA,QAAS,CACP,IAAO,qBACP,MAAS,4BACT,QAAW,mBACb,EACA,WAAY,CACV,IAAO,wBACP,MAAS,+BACT,QAAW,sBACb,EACA,YAAa,CACX,IAAO,wBACP,MAAS,+BACT,QAAW,uBACb,EACA,eAAgB,CACd,IAAO,gCACT,EACA,QAAS,iBACT,mBAAoB,kCACpB,uBAAwB,uCACxB,gBAAiB,2BACnB,EACA,IAAO,CACL,IAAO,mBACP,KAAQ,oBACR,iBAAkB,0BAClB,iBAAkB,0BAClB,qBAAsB,0BACtB,qBAAsB,yBACxB,EACA,KA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",
|
|
6
6
|
"names": ["require_package", "__commonJSMin", "exports", "module", "validate", "s", "typeDescriptorToJSONSchema", "td", "properties", "required", "key", "fieldTd", "exampleToJSONSchema", "value", "val", "functionMetaToJSONSchema", "meta", "name", "paramInfo", "input", "output", "validate", "schemaFilter", "s", "isRuntimeType", "value", "isSchemaBuilder", "isJSONSchema", "Type", "descriptionOrSchema", "predicateOrSchemaOrExample", "exampleArg", "defaultArg", "description", "predicate", "schema", "example", "defaultValue", "s", "schemaToDescription", "examples", "jsonSchema", "validate", "raw", "exampleToJSONSchema", "schemaFilter", "TString", "v", "TNumber", "TBoolean", "TInteger", "TPositiveInt", "TNonEmptyString", "TEmail", "isValidUrl", "TUrl", "TUuid", "isValidTimestamp", "d", "isValidLegalDate", "Timestamp", "LegalDate", "Nullable", "type", "Optional", "Union", "descriptionOrType", "valuesOrType", "restTypes", "values", "valueSet", "types", "t", "TArray", "itemType", "item", "typeParamToCheck", "param", "Generic", "params", "paramNames", "defaults", "p", "factory", "typeArgs", "checks", "_", "i", "arg", "desc", "name", "typeStr", "TPair", "x", "checkT", "checkU", "TRecord", "checkV", "Enum", "members", "keys", "names", "key", "kindOfExample", "FunctionPredicate", "specOrFn", "specBuilder", "typeParams", "tp", "resolved", "idx", "spec", "_createFunctionPredicate", "returns", "returnContract", "meta", "info", "expectedArity", "metaParamCount", "expectedKeys", "metaKeys", "metaInfo", "expectedExample", "expectedKind", "pkg", "TJS_VERSION", "tjsEquals", "parseVersion", "version", "major", "minor", "patch", "compareVersions", "a", "b", "va", "vb", "versionsCompatible", "MonadicError", "_MonadicError", "message", "path", "expected", "actual", "callStack", "reason", "typeError", "value", "stack", "config", "getStack", "msg", "err", "size", "ERROR_BUF_SIZE", "errorBuffer", "errorHead", "errorBufCount", "errorTotal", "isMonadicError", "DEFAULT_CONFIG", "STACK_SIZE", "callStackBuffer", "callStackHead", "callStackCount", "unsafeDepth", "enterUnsafe", "exitUnsafe", "isUnsafeMode", "configure", "options", "getConfig", "pushStack", "name", "popStack", "result", "start", "i", "errors", "clearErrors", "cleared", "getErrorCount", "resetRuntime", "Is", "v", "k", "keysA", "keysB", "IsNot", "TypeOf", "toBool", "Eq", "NotEq", "isError", "error", "details", "currentStack", "fullStack", "composeErrors", "funcName", "paramNames", "e", "parts", "typeOf", "t", "constructorName", "isNativeType", "typeName", "proto", "checkType", "checkFnShape", "fn", "expectedParamKinds", "expectedReturnKind", "meta", "actualEntries", "expectedKind", "actualKind", "actualReturnKind", "validateArgs", "args", "param", "expectedDesc", "wrap", "fn", "meta", "functionMetaToJSONSchema", "config", "hasReturns", "metaUnsafe", "metaSafe", "metaUnsafeReturn", "metaSafeReturn", "returnDefaults", "paramEntries", "paramCount", "funcName", "wrapped", "args", "unsafeDepth", "validateInputs", "validateOutputs", "isError", "isNamedCall", "collectedErrors", "namedArgs", "i", "name", "param", "value", "error", "typeErr", "checkType", "composeErrors", "trackStack", "pushStack", "result", "validated", "returnError", "popStack", "e", "wrapClass", "cls", "target", "newTarget", "_thisArg", "key", "createRuntime", "instanceConfig", "instStackSize", "STACK_SIZE", "instanceStackBuffer", "instanceStackHead", "instanceStackCount", "instErrorSize", "ERROR_BUF_SIZE", "instanceErrorBuffer", "instanceErrorHead", "instanceErrorBufCount", "instanceErrorTotal", "instanceUnsafeDepth", "instanceConfigure", "options", "instanceGetConfig", "instancePushStack", "instancePopStack", "instanceGetStack", "start", "instanceResetRuntime", "DEFAULT_CONFIG", "instanceEnterUnsafe", "instanceExitUnsafe", "instanceIsUnsafeMode", "extensionRegistry", "instanceRegisterExtension", "typeName", "methodName", "instanceResolveExtension", "t", "current", "methods", "objectMethods", "instanceTypeError", "path", "expected", "actual", "stack", "err", "MonadicError", "instanceErrors", "instanceClearErrors", "cleared", "instanceGetErrorCount", "instanceError", "message", "details", "fullStack", "instanceBang", "obj", "prop", "isMonadicError", "TJS_VERSION", "typeOf", "isNativeType", "validateArgs", "checkFnShape", "compareVersions", "versionsCompatible", "validate", "s", "Type", "isRuntimeType", "Union", "Generic", "Enum", "FunctionPredicate", "Nullable", "Optional", "TArray", "TString", "TNumber", "TBoolean", "TInteger", "TPositiveInt", "TNonEmptyString", "TEmail", "TUrl", "TUuid", "TPair", "TRecord", "Is", "IsNot", "Eq", "NotEq", "TypeOf", "toBool", "tjsEquals", "runtime", "typeError", "configure", "getConfig", "getStack", "errors", "clearErrors", "getErrorCount", "resetRuntime", "enterUnsafe", "exitUnsafe", "isUnsafeMode", "Timestamp", "LegalDate", "installRuntime", "g", "existingVersion", "comparison", "emitRuntimeWrapper", "emitClassWrapper", "className"]
|
|
7
7
|
}
|