tjs-lang 0.8.7 → 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 +19 -5
- package/dist/experiments/ambient/probe.d.ts +52 -0
- package/dist/index.js +110 -162
- package/dist/index.js.map +4 -4
- package/dist/scripts/build-editors.d.ts +19 -0
- package/dist/src/css/dimensions.d.ts +23 -0
- package/dist/src/css/index.d.ts +85 -0
- package/dist/src/css/predicates.d.ts +38 -0
- package/dist/src/css/shorthands.d.ts +31 -0
- package/dist/src/css/style.d.ts +48 -0
- package/dist/src/lang/emitters/js-wasm.d.ts +2 -0
- package/dist/src/lang/emitters/js.d.ts +9 -1
- package/dist/src/lang/index.d.ts +2 -2
- package/dist/src/lang/parser-transforms.d.ts +9 -5
- package/dist/src/lang/parser-types.d.ts +7 -0
- package/dist/src/lang/parser.d.ts +2 -0
- package/dist/src/lang/predicate.d.ts +60 -0
- package/dist/src/lang/transpiler.d.ts +3 -2
- package/dist/src/lang/types.d.ts +16 -0
- package/dist/src/schema/index.d.ts +12 -0
- package/dist/tjs-browser-from-ts.js +20 -20
- package/dist/tjs-browser-from-ts.js.map +3 -3
- package/dist/tjs-browser.js +108 -94
- package/dist/tjs-browser.js.map +4 -4
- package/dist/tjs-css.js +193 -0
- package/dist/tjs-css.js.map +7 -0
- package/dist/tjs-eval.js +43 -42
- package/dist/tjs-eval.js.map +4 -4
- package/dist/tjs-from-ts.js +13 -13
- package/dist/tjs-from-ts.js.map +2 -2
- package/dist/tjs-lang.js +106 -92
- package/dist/tjs-lang.js.map +4 -4
- package/dist/tjs-runtime.js +10 -0
- package/dist/tjs-runtime.js.map +7 -0
- package/dist/tjs-schema.js +6 -0
- package/dist/tjs-schema.js.map +7 -0
- package/dist/tjs-vm.js +55 -54
- package/dist/tjs-vm.js.map +4 -4
- package/docs/ambient-contracts.md +261 -0
- package/docs/type-system-north-star.md +100 -0
- package/editors/ace/ajs-mode.js +214 -233
- package/editors/codemirror/ajs-language.js +1570 -233
- package/editors/editors-build.test.ts +29 -0
- package/editors/monaco/ajs-monarch.js +239 -195
- package/llms.txt +4 -0
- package/package.json +35 -4
- package/src/css/css.test.ts +122 -0
- package/src/css/dimensions.test.ts +112 -0
- package/src/css/dimensions.ts +146 -0
- package/src/css/index.ts +243 -0
- package/src/css/perf.bench.test.ts +109 -0
- package/src/css/predicates.ts +232 -0
- package/src/css/property-aware.test.ts +84 -0
- package/src/css/shorthands.test.ts +90 -0
- package/src/css/shorthands.ts +113 -0
- package/src/css/style.test.ts +125 -0
- package/src/css/style.ts +134 -0
- package/src/index-tsfree.test.ts +58 -0
- package/src/lang/emit-verified-predicate.test.ts +95 -0
- package/src/lang/emitters/dts.test.ts +31 -0
- package/src/lang/emitters/dts.ts +23 -4
- package/src/lang/emitters/js-wasm.ts +8 -4
- package/src/lang/emitters/js.ts +58 -1
- package/src/lang/from-ts.test.ts +1 -1
- package/src/lang/generic-verified-predicate.test.ts +39 -0
- package/src/lang/index.ts +14 -5
- package/src/lang/parser-transforms.ts +113 -15
- package/src/lang/parser-types.ts +7 -0
- package/src/lang/parser.ts +18 -3
- package/src/lang/predicate-evaluator.test.ts +49 -0
- package/src/lang/predicate-report.test.ts +78 -0
- package/src/lang/predicate.ts +268 -0
- package/src/lang/redos-lint.test.ts +81 -0
- package/src/lang/transpiler.ts +13 -0
- package/src/lang/type-verified-predicate.test.ts +83 -0
- package/src/lang/types.ts +17 -0
- package/src/lang/typescript-syntax.test.ts +2 -1
- 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/src/schema/index.ts +62 -0
- package/src/schema/schema.test.ts +66 -0
- package/src/use-cases/bootstrap.test.ts +14 -4
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
var rn=(e,n)=>()=>(n||e((n={exports:{}}).exports,n),n.exports);var ve=rn((On,ln)=>{ln.exports={name:"tjs-lang",version:"0.9.1",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.",keywords:["typescript","transpiler","runtime-validation","type-safety","sandbox","virtual-machine","wasm-alternative","ai-agents","llm","orchestration","security","fuel-metering","capability-based","json-ast","untrusted-code"],license:"Apache-2.0",main:"./dist/index.js",types:"./dist/src/index.d.ts",typesVersions:{"*":{eval:["./dist/src/lang/eval.d.ts"],lang:["./dist/src/lang/transpiler.d.ts"],"lang/from-ts":["./dist/src/lang/emitters/from-ts.d.ts"],browser:["./dist/src/lang/browser.d.ts"],"browser/from-ts":["./dist/src/lang/browser-from-ts.d.ts"],vm:["./dist/src/vm/index.d.ts"],batteries:["./dist/src/batteries/index.d.ts"],css:["./dist/src/css/index.d.ts"],schema:["./dist/src/schema/index.d.ts"],runtime:["./dist/src/lang/runtime.d.ts"]}},exports:{".":{bun:"./src/index.ts",types:"./dist/src/index.d.ts",default:"./dist/index.js"},"./eval":{bun:"./src/lang/eval.ts",types:"./dist/src/lang/eval.d.ts",default:"./dist/tjs-eval.js"},"./lang":{bun:"./src/lang/transpiler.ts",types:"./dist/src/lang/transpiler.d.ts",default:"./dist/tjs-lang.js"},"./lang/from-ts":{bun:"./src/lang/emitters/from-ts.ts",types:"./dist/src/lang/emitters/from-ts.d.ts",default:"./dist/tjs-from-ts.js"},"./browser":{types:"./dist/src/lang/browser.d.ts",default:"./dist/tjs-browser.js"},"./browser/from-ts":{types:"./dist/src/lang/browser-from-ts.d.ts",default:"./dist/tjs-browser-from-ts.js"},"./vm":{bun:"./src/vm/index.ts",types:"./dist/src/vm/index.d.ts",default:"./dist/tjs-vm.js"},"./batteries":{bun:"./src/batteries/index.ts",types:"./dist/src/batteries/index.d.ts",default:"./dist/tjs-batteries.js"},"./linalg":{bun:"./src/linalg/index.tjs",default:"./dist/tjs-linalg.js"},"./css":{bun:"./src/css/index.ts",types:"./dist/src/css/index.d.ts",default:"./dist/tjs-css.js"},"./schema":{bun:"./src/schema/index.ts",types:"./dist/src/schema/index.d.ts",default:"./dist/tjs-schema.js"},"./runtime":{bun:"./src/lang/runtime.ts",types:"./dist/src/lang/runtime.d.ts",default:"./dist/tjs-runtime.js"},"./bun-plugin":{bun:"./src/bun-plugin/tjs-plugin.ts"},"./src":"./src/index.ts","./editors/monaco":"./editors/monaco/ajs-monarch.js","./editors/codemirror":"./editors/codemirror/ajs-language.js","./editors/ace":"./editors/ace/ajs-mode.js"},bin:{tjs:"./src/cli/tjs.ts",tjsx:"./src/cli/tjsx.ts","tjs-playground":"./src/cli/playground.ts","create-tjs-app":"./src/cli/create-app.ts","ajs-install-vscode":"./bin/install-vscode.sh","ajs-install-cursor":"./bin/install-cursor.sh"},type:"module",files:["dist","src","docs","editors","bin","demo","tjs-lang.svg","CONTEXT.md","CLAUDE.md","llms.txt"],sideEffects:["./src/schema/index.ts","./dist/tjs-schema.js"],repository:{type:"git",url:"https://github.com/tonioloewald/tjs-lang.git"},devDependencies:{"@codemirror/lang-css":"^6.3.1","@codemirror/lang-html":"^6.4.11","@codemirror/lang-javascript":"^6.2.4","@codemirror/lang-markdown":"^6.5.0","@codemirror/state":"^6.5.3","@codemirror/theme-one-dark":"^6.1.3","@codemirror/view":"^6.39.9","@eslint/js":"^10.0.1","@happy-dom/global-registrator":"^20.1.0","@types/bun":"latest","@types/jsdom":"^21.1.7","acorn-walk":"^8.3.4",chokidar:"^4.0.3",codemirror:"^6.0.2",esbuild:"^0.28.0",eslint:"^10.4.1",firebase:"^10.12.0","firebase-admin":"^13.6.0","firebase-functions":"^7.0.5",globals:"^17.6.0",marked:"^9.1.6",prettier:"^2.8.8",tosijs:"^1.5.6","tosijs-ui":"^1.4.7",typescript:"^5.6.2","typescript-eslint":"^8.61.0",valibot:"^0.36.0",vitest:"^2.0.5"},scripts:{format:"bun eslint src --fix && bun prettier --write .",lint:"eslint src","build:grammars":"bun editors/build-grammars.ts","build:editors":"bun scripts/build-editors.ts","test:fast":"SKIP_LLM_TESTS=1 SKIP_BENCHMARKS=1 bun test","test:llm":"bun test src/batteries/models.integration.test.ts",bench:"bun bin/benchmarks.ts",make:"rm -rf dist && bun format && bun run build:grammars && bun run build:editors && tsc -p tsconfig.build.json && bun scripts/build.ts","build:bundles":"bun scripts/build.ts",typecheck:"tsc --noEmit",latest:"rm -rf node_modules && bun install",docs:"node bin/docs.js",dev:"bun run bin/dev.ts","build:demo":"bun scripts/build-demo.ts","build:cli":"bun build src/cli/tjs.ts --compile --outfile=dist/tjs && bun build src/cli/tjsx.ts --compile --outfile=dist/tjsx","functions:build":"cd functions && npm run build","functions:deploy":"cd functions && npm run deploy","functions:serve":"cd functions && npm run serve","deploy:hosting":"bun run build:demo && firebase deploy --only hosting",deploy:"bun run build:demo && bun run functions:deploy && firebase deploy --only hosting",start:"bun run build:demo && bun run dev"},dependencies:{acorn:"^8.15.0","acorn-loose":"^8.5.2","acorn-walk":"^8.3.4","tosijs-schema":"^1.4.0"}}});import{validate as Ie,s as ne}from"tosijs-schema";function F(e){if(e.nullable)return{anyOf:[F({...e,nullable:!1}),{type:"null"}]};switch(e.kind){case"string":return{type:"string"};case"number":return{type:"number"};case"integer":return{type:"integer"};case"non-negative-integer":return{type:"integer",minimum:0};case"boolean":return{type:"boolean"};case"null":return{type:"null"};case"undefined":return{};case"any":return{};case"array":return e.items?{type:"array",items:F(e.items)}:{type:"array"};case"object":if(e.shape){let n={},t=[];for(let[r,i]of Object.entries(e.shape))n[r]=F(i),t.push(r);return{type:"object",properties:n,required:t,additionalProperties:!1}}return{type:"object"};case"union":return e.members?{anyOf:e.members.map(F)}:{};default:return{}}}function D(e){if(e===null)return{type:"null"};if(e===void 0)return{};switch(typeof e){case"string":return{type:"string"};case"number":return Number.isInteger(e)?{type:"integer"}:{type:"number"};case"boolean":return{type:"boolean"};case"object":{if(Array.isArray(e))return e.length===0?{type:"array"}:{type:"array",items:D(e[0])};let n={},t=[];for(let[r,i]of Object.entries(e))n[r]=D(i),t.push(r);return{type:"object",properties:n,required:t,additionalProperties:!1}}default:return{}}}function ie(e){let n={},t=[];for(let[o,s]of Object.entries(e.params))s?.type?.kind?n[o]=F(s.type):s?.example!==void 0?n[o]=D(s.example):n[o]={},s?.required!==!1&&t.push(o),s?.example!==void 0&&(n[o].examples=[s.example]);let r={type:"object",properties:n,required:t},i;return e.returns&&(e.returns.type?.kind?i=F(e.returns.type):e.returns.example!==void 0&&(i=D(e.returns.example))),{input:r,output:i}}import{validate as oe,filter as sn,s as X}from"tosijs-schema";function v(e){return e!==null&&typeof e=="object"&&"__runtimeType"in e&&e.__runtimeType===!0}function Je(e){return e!==null&&typeof e=="object"&&"schema"in e&&typeof e.schema=="object"}function on(e){return e!==null&&typeof e=="object"&&"type"in e&&typeof e.type=="string"}function b(e,n,t,r){let i,o,s,a=t,l=r;if(typeof e=="string")if(i=e,typeof n=="function")o=n,a!==void 0&&(s=X.infer(a));else if(n===void 0&&a!==void 0)s=X.infer(a);else if(Je(n))s=n;else if(on(n))s=n;else if(n!==void 0)a=n,l=a,s=X.infer(a);else throw new Error("Type(description) requires a predicate, schema, or example");else Je(e),s=e,i=an(s);let f;if(s){let u=s?.schema??s;u&&typeof u=="object"&&Array.isArray(u.examples)&&(f=u.examples)}return a===void 0&&f&&f.length>0&&(a=f[0]),{description:i,check:u=>o?o(u):s?oe(u,s):!1,schema:s,predicate:o,example:a,examples:f,default:l,toJSONSchema(){if(s){let u=s?.schema??s;if(u&&typeof u=="object"&&"type"in u)return u}return a!==void 0?D(a):{description:i}},strip(u){return s?sn(u,s):u},__runtimeType:!0}}function an(e){let n=e?.schema??e;if(n&&typeof n=="object"&&"type"in n){let t=n;switch(t.type){case"string":return t.format?`string (${t.format})`:t.pattern?`string matching ${t.pattern}`:t.minLength!==void 0&&t.maxLength!==void 0?`string (${t.minLength}-${t.maxLength} chars)`:"string";case"number":case"integer":return t.minimum!==void 0&&t.maximum!==void 0?`${t.type} (${t.minimum}-${t.maximum})`:t.minimum!==void 0?`${t.type} >= ${t.minimum}`:t.maximum!==void 0?`${t.type} <= ${t.maximum}`:t.type;case"boolean":return"boolean";case"array":return"array";case"object":return"object";case"null":return"null"}}return"value"}var ae=b("string",e=>typeof e=="string"?!0:`expected string, got ${e===null?"null":typeof e}`),ue=b("number",e=>typeof e=="number"?!0:`expected number, got ${e===null?"null":typeof e}`),ce=b("boolean",e=>typeof e=="boolean"?!0:`expected boolean, got ${e===null?"null":typeof e}`),fe=b("integer",e=>typeof e!="number"?`expected integer, got ${e===null?"null":typeof e}`:Number.isInteger(e)?!0:`${e} is not an integer`),le=b("positive integer",e=>typeof e!="number"?`expected positive integer, got ${e===null?"null":typeof e}`:Number.isInteger(e)?e<=0?`${e} is not positive`:!0:`${e} is not an integer`),pe=b("non-empty string",e=>typeof e!="string"?`expected string, got ${e===null?"null":typeof e}`:e.length===0?"string is empty":!0),de=b("email address",e=>typeof e!="string"?`expected string, got ${e===null?"null":typeof e}`:/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(e)?!0:`"${e}" is not a valid email`),Pe=e=>{try{return new URL(e),!0}catch{return!1}},ye=b("URL",e=>typeof e!="string"?`expected string, got ${e===null?"null":typeof e}`:Pe(e)?!0:`"${e}" is not a valid URL`),me=b("UUID",e=>typeof e!="string"?`expected string, got ${e===null?"null":typeof e}`:/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i.test(e)?!0:`"${e}" is not a valid UUID`),Ae=e=>{let n=new Date(e);return!isNaN(n.getTime())&&e.includes("T")},Ce=e=>{if(!/^\d{4}-\d{2}-\d{2}$/.test(e))return!1;let n=new Date(e+"T00:00:00Z");return!isNaN(n.getTime())},Me=b("ISO 8601 timestamp",e=>typeof e=="string"&&Ae(e)),Ue=b("date (YYYY-MM-DD)",e=>typeof e=="string"&&Ce(e));function ge(e){return b(`${e.description} or null`,n=>n===null||e.check(n)===!0)}function be(e){return b(`${e.description} (optional)`,n=>n==null||e.check(n)===!0)}function Te(e,n,...t){if(typeof e=="string"&&Array.isArray(n)){let o=e,s=n,a=new Set(s);return{description:o,check:f=>a.has(f),toJSONSchema:()=>({enum:s}),strip:f=>f,__runtimeType:!0,values:s}}let r=[];v(e)&&r.push(e),v(n)&&r.push(n),r.push(...t);let i=r.map(o=>o.description).join(" | ");return b(i,o=>r.some(s=>s.check(o)===!0))}function ke(e){return b(`array of ${e.description}`,n=>Array.isArray(n)&&n.every(t=>e.check(t)===!0))}function un(e){if(v(e))return t=>e.check(t)===!0;if(e&&typeof e=="object"&&"schema"in e)return t=>oe(t,e);let n=X.infer(e);return t=>oe(t,n)}function H(e,n,t){let r=[],i=[];for(let s of e)typeof s=="string"?(r.push(s),i.push(void 0)):(r.push(s[0]),i.push(s[1]));let o=(...s)=>{let a=r.map((f,d)=>{let u=d<s.length?s[d]:i[d];return u===void 0?()=>!0:un(u)}),l=t;return r.forEach((f,d)=>{let u=d<s.length?s[d]:i[d],x="any";v(u)?x=u.description:u!==void 0&&(x=typeof u=="string"?"string":JSON.stringify(u)),l=l.replace(new RegExp(`\\b${f}\\b`,"g"),x)}),b(l,f=>n(f,...a))};return o.params=r,o.description=t,o}var he=H(["T","U"],(e,n,t)=>Array.isArray(e)&&e.length===2&&n(e[0])&&t(e[1]),"Pair<T, U>"),Se=H(["V"],(e,n)=>typeof e=="object"&&e!==null&&!Array.isArray(e)&&Object.values(e).every(n),"Record<string, V>");function je(e,n){let t=Object.values(n),r=new Set(t),i=Object.keys(n),o={};for(let[a,l]of Object.entries(n))o[l]=a;return{description:e,check:a=>r.has(a),toJSONSchema:()=>({enum:t}),strip:a=>a,__runtimeType:!0,members:n,names:o,values:t,keys:i}}function cn(e){if(e===null)return"null";if(e===void 0)return"undefined";switch(typeof e){case"string":return"string";case"boolean":return"boolean";case"number":return Number.isInteger(e)?"integer":"number";case"object":return Array.isArray(e)?"array":"object";default:return null}}function Q(e,n,t){if(Array.isArray(n)&&t){let r=n,i=[],o=[];for(let a of r)Array.isArray(a)?(i.push(a[0]),o.push(a[1])):(i.push(a),o.push(void 0));let s=((...a)=>{let l=i.map((d,u)=>u<a.length?a[u]:o[u]),f=t(...l);return Q(e,f)});return Object.defineProperties(s,{typeParamNames:{value:i,enumerable:!0},description:{value:e,enumerable:!0},__runtimeType:{value:!0,enumerable:!0}}),s}return fn(e,n)}function fn(e,n){let t={},r,i="assertReturns";if(typeof n=="function"){let s=n.__tjs;if(s){if(s.params)for(let[a,l]of Object.entries(s.params))t[a]=l?.example??null;s.returns&&(r=s.returns?.example??null),s.safeReturn?i="checkedReturns":s.unsafe?i="assertReturns":i="returns"}}else t=n.params??{},r=n.returns,i=n.returnContract??"assertReturns";return{description:e,params:t,returns:r,returnContract:i,toJSONSchema:()=>({description:e,type:"function"}),strip:s=>s,check:s=>{if(typeof s!="function")return`expected function, got ${s===null?"null":typeof s}`;let a=Object.keys(t).length;if(a>0){let f=s.__tjs;if(f?.params){let d=Object.keys(f.params).length;if(d!==a)return`expected ${a} params, got ${d}`;let u=Object.keys(t),x=Object.keys(f.params);for(let m=0;m<u.length;m++){let _=f.params[x[m]],R=t[u[m]];if(_?.type?.kind&&R!==void 0){let O=cn(R);if(O&&_.type.kind!==O&&_.type.kind!=="any")return`param '${u[m]}' expected ${O}, got ${_.type.kind}`}}}}return!0},__runtimeType:!0}}var pn=ve(),A=pn.version,W=Symbol.for("tjs.equals");function te(e){let[n=0,t=0,r=0]=e.split(".").map(Number);return{major:n,minor:t,patch:r}}function we(e,n){let t=te(e),r=te(n);return t.major!==r.major?t.major<r.major?-1:1:t.minor!==r.minor?t.minor<r.minor?-1:1:t.patch!==r.patch?t.patch<r.patch?-1:1:0}function Ee(e,n){let t=te(e),r=te(n);return t.major===r.major}var M=class e extends Error{path;expected;actual;callStack;reason;constructor(n,t,r,i,o,s){super(n),this.name="MonadicError",this.path=t,this.expected=r,this.actual=i,this.callStack=o,this.reason=s,Error.captureStackTrace&&Error.captureStackTrace(this,e)}};function dn(e,n,t,r){let i=t===null?"null":typeof t,o=p.callStacks||p.debug?Re():void 0,s=r?`Expected ${n} for '${e}': ${r}`:`Expected ${n} for '${e}', got ${i}`,a=new M(s,e,n,i,o,r);if(p.trackErrors!==!1){let l=p.maxErrors??re;Be[L]=a,L=(L+1)%l,q<l&&q++,se++}if(p.logTypeErrors&&console.error(`[TJS TypeError] ${a.message}`),p.throwTypeErrors)throw a;return a}function xe(e){return e instanceof Error&&e.name==="MonadicError"&&"path"in e}var $e={debug:!1,safety:"inputs",requireReturnTypes:!1,callStacks:!1,maxStackSize:64,trackErrors:!0,maxErrors:64},p={...$e},Z=64,qe=new Array(Z).fill(""),I=0,N=0,re=64,Be=new Array(re).fill(null),L=0,q=0,se=0,K=0;function yn(){K++}function mn(){K>0&&K--}function gn(){return K>0}function bn(e){p={...p,...e}}function Tn(){return{...p}}function Fe(e){if((p.callStacks||p.debug)&&e){let n=p.maxStackSize??Z;qe[I]=e,I=(I+1)%n,N<n&&N++}}function ee(){if((p.callStacks||p.debug)&&N>0){let e=p.maxStackSize??Z;I=(I-1+e)%e,N--}}function Re(){if(N===0)return[];let e=p.maxStackSize??Z,n=[],t=(I-N+e)%e;for(let r=0;r<N;r++)n.push(qe[(t+r)%e]);return n}function De(){if(p.trackErrors===!1||q===0)return[];let e=p.maxErrors??re,n=[],t=(L-q+e)%e;for(let r=0;r<q;r++)n.push(Be[(t+r)%e]);return n}function kn(){let e=De();return L=0,q=0,se=0,e}function hn(){return se}function Sn(){p={...$e},I=0,N=0,L=0,q=0,se=0,K=0}function V(e,n){if(e!==null&&typeof e=="object"&&typeof e[W]=="function")return e[W](n);if(n!==null&&typeof n=="object"&&typeof n[W]=="function")return n[W](e);if(e!==null&&typeof e=="object"&&typeof e.Equals=="function")return e.Equals(n);if(n!==null&&typeof n=="object"&&typeof n.Equals=="function")return n.Equals(e);if((e instanceof String||e instanceof Number||e instanceof Boolean)&&(e=e.valueOf()),(n instanceof String||n instanceof Number||n instanceof Boolean)&&(n=n.valueOf()),e===n||typeof e=="number"&&typeof n=="number"&&isNaN(e)&&isNaN(n)||e==null&&n==null)return!0;if(e==null||n===null||n===void 0||typeof e!=typeof n||typeof e!="object")return!1;if(e instanceof Set&&n instanceof Set){if(e.size!==n.size)return!1;for(let i of e)if(!n.has(i))return!1;return!0}if(e instanceof Map&&n instanceof Map){if(e.size!==n.size)return!1;for(let[i,o]of e)if(!n.has(i)||!V(o,n.get(i)))return!1;return!0}if(e instanceof Date&&n instanceof Date)return e.getTime()===n.getTime();if(e instanceof RegExp&&n instanceof RegExp)return e.toString()===n.toString();if(Array.isArray(e)&&Array.isArray(n))return e.length!==n.length?!1:e.every((i,o)=>V(i,n[o]));if(Array.isArray(e)!==Array.isArray(n))return!1;let t=Object.keys(e),r=Object.keys(n);return t.length!==r.length?!1:t.every(i=>V(e[i],n[i]))}function ze(e,n){return!V(e,n)}function Le(e){return e===null?"null":typeof e}function Ve(e){return e instanceof Boolean||e instanceof Number||e instanceof String?!!e.valueOf():!!e}function Oe(e,n){return(e instanceof String||e instanceof Number||e instanceof Boolean)&&(e=e.valueOf()),(n instanceof String||n instanceof Number||n instanceof Boolean)&&(n=n.valueOf()),!!(e===n||typeof e=="number"&&typeof n=="number"&&isNaN(e)&&isNaN(n)||e==null&&n==null)}function Ge(e,n){return!Oe(e,n)}function C(e){return e!==null&&typeof e=="object"&&e.$error===!0}function J(e,n){let t={$error:!0,message:e,...n};if((p.callStacks||p.debug)&&N>0){let r=Re(),i=n?.path?[...r,n.path]:r;t.stack=i}return t}function _e(e,n){if(e.length===0)return J("Unknown error");if(e.length===1)return e[0];let t=e.map(i=>{if(i.path){let o=i.path.split(".");return o[o.length-1]}return"unknown"}).join(", "),r=`Multiple parameter errors in ${n||"function"}: ${t}`;return J(r,{path:n,errors:e})}function Y(e){if(e===null)return"null";if(e===void 0)return"undefined";if(Array.isArray(e))return"array";let n=typeof e;if(n!=="object")return n;let t=e.constructor?.name;return t&&t!=="Object"?t:"object"}function Ke(e,n){if(e==null||typeof e!="object"&&typeof e!="function")return!1;let t=e;for(;t!==null;){if(t.constructor?.name===n)return!0;t=Object.getPrototypeOf(t)}return!1}function G(e,n,t){if(C(e))return e;if(typeof n=="object"&&n!==null&&"check"in n){let i=n.check(e);if(i===!0)return null;let o=typeof i=="string"?i:void 0,s=o?`Expected ${n.description} for '${t}': ${o}`:`Expected ${n.description} but got ${Y(e)}`;return J(s,{path:t,expected:n.description,actual:Y(e),reason:o})}let r=Y(e);return n==="any"||n===r||n==="number"&&r==="number"||n==="integer"&&r==="number"&&Number.isInteger(e)||n==="non-negative-integer"&&r==="number"&&Number.isInteger(e)&&e>=0||n==="object"&&r==="object"?null:J(`Expected ${n} but got ${r}`,{path:t,expected:n,actual:r})}function He(e,n,t,r){if(typeof e!="function")return e;let i=e.__tjs;if(!i||!i.params)return e;let o=Object.entries(i.params);for(let s=0;s<n.length;s++){let a=n[s];if(a==="any")continue;let l=o[s];if(!l)continue;let f=l[1]?.type?.kind;if(!(!f||f==="any")&&f!==a)return new M(`Expected (...arg${s}: ${a}, ...) for '${r}', but callback declares arg${s} as ${f}`,`${r}(arg${s})`,a,f)}if(t!=="any"&&i.returns){let s=i.returns.type?.kind??i.returns.kind;if(s&&s!=="any"&&s!==t)return new M(`Expected callback returning ${t} for '${r}', but callback returns ${s}`,`${r}(return)`,t,s)}return e}function We(e,n,t){for(let[r,i]of Object.entries(n.params)){let o=e[r];if(C(o))return o;if(i.required&&o===void 0){let a=typeof i.type=="string"?i.type:i.type.description;return J(`Missing required parameter '${r}'`,{path:t?`${t}.${r}`:r,expected:a,actual:"undefined",loc:i.loc})}if(o===void 0)continue;let s=G(o,i.type,t?`${t}.${r}`:r);if(s)return i.loc&&(s.loc=i.loc),s}return null}function Ye(e,n){if(e.__tjs=n,e.__tjs.schema=()=>ie(n),!(!n.polymorphic&&(n.safe||n.safeReturn||p.safety!=="none"&&!n.unsafe||n.returns&&p.safety==="all"&&!n.unsafeReturn)))return e;let r=!!n.returns,i=!!n.unsafe,o=!!n.safe,s=!!n.unsafeReturn,a=!!n.safeReturn,l=n.returns?.defaults,f=Object.entries(n.params),d=f.length,u=e.name||n.name||"anonymous",x=function(...m){if(K>0)return e.apply(this,m);let _=o||!i&&p.safety!=="none",R=r&&(a||!s&&p.safety==="all");if(!_&&!R)return e.apply(this,m);if(m.length>0&&C(m[0]))return m[0];if(_){let h=m.length===1&&typeof m[0]=="object"&&m[0]!==null&&!Array.isArray(m[0]),w=[];if(h){let $=m[0];for(let S=0;S<d;S++){let[k,T]=f[S],E=$[k];if(C(E)){w.push(E);continue}if(T.required&&E===void 0){w.push(J(`Missing required parameter '${k}'`,{path:`${u}.${k}`,expected:typeof T.type=="string"?T.type:T.type?.description||"value",actual:"undefined",loc:T.loc}));continue}if(E!==void 0){let B=G(E,T.type,`${u}.${k}`);B&&(T.loc&&(B.loc=T.loc),w.push(B))}}}else for(let $=0;$<d;$++){let[S,k]=f[$],T=m[$];if(C(T)){w.push(T);continue}if(k.required&&T===void 0){w.push(J(`Missing required parameter '${S}'`,{path:`${u}.${S}`,expected:typeof k.type=="string"?k.type:k.type?.description||"value",actual:"undefined",loc:k.loc}));continue}if(T!==void 0){let E=G(T,k.type,`${u}.${S}`);E&&(k.loc&&(E.loc=k.loc),w.push(E))}}if(w.length>0)return _e(w,u)}let O=p.callStacks||p.debug;O&&Fe(u);try{let h=e.apply(this,m);if(R&&n.returns&&!C(h)){let w=l&&typeof h=="object"&&h!==null?Object.assign({},l,h):h,$=G(w,n.returns.type,`${u}()`);if($)return O&&ee(),$}return O&&ee(),h}catch(h){return O&&ee(),J(h.message||String(h),{path:u,cause:h})}};return Object.defineProperty(x,"name",{value:e.name}),x.__tjs=n,x.__tjs.schema=()=>ie(n),x}function Ze(e){let n=new Proxy(e,{construct(t,r,i){return Reflect.construct(t,r,i)},apply(t,r,i){return Reflect.construct(t,i)}});Object.defineProperty(n,"name",{value:e.name});for(let t of Object.getOwnPropertyNames(e))t!=="length"&&t!=="name"&&t!=="prototype"&&Object.defineProperty(n,t,Object.getOwnPropertyDescriptor(e,t));return n}function Xe(){let e={...p},n=e.maxStackSize??Z,t=new Array(n).fill(""),r=0,i=0,o=e.maxErrors??re,s=new Array(o).fill(null),a=0,l=0,f=0,d=0;function u(c){e={...e,...c}}function x(){return{...e}}function m(c){(e.callStacks||e.debug)&&c&&(t[r]=c,r=(r+1)%n,i<n&&i++)}function _(){(e.callStacks||e.debug)&&i>0&&(r=(r-1+n)%n,i--)}function R(){if(i===0)return[];let c=[],g=(r-i+n)%n;for(let y=0;y<i;y++)c.push(t[(g+y)%n]);return c}function O(){e={...$e},r=0,i=0,a=0,l=0,f=0,d=0}function h(){d++}function w(){d>0&&d--}function $(){return d>0}let S=new Map;function k(c,g,y){S.has(c)||S.set(c,new Map),S.get(c).set(g,y)}function T(c,g){let y=typeof c,j;if(c==null)return;if(y==="string")j="String";else if(y==="number")j="Number";else if(y==="boolean")j="Boolean";else if(Array.isArray(c))j="Array";else if(y==="object")j=c.constructor?.name||"Object";else return;let P=j;for(;P;){let Ne=S.get(P);if(Ne?.has(g))return Ne.get(g);if(y==="object"&&!Array.isArray(c)){if(P=Object.getPrototypeOf(P===j?c:Object.getPrototypeOf(c))?.constructor?.name,P==="Object"||P===j)break}else break}let U=S.get("Object");if(U?.has(g))return U.get(g)}function E(c,g,y){let j=y===null?"null":typeof y,P=e.callStacks||e.debug?R():void 0,U=new M(`Expected ${g} for '${c}', got ${j}`,c,g,j,P);if(e.trackErrors!==!1&&(s[a]=U,a=(a+1)%o,l<o&&l++,f++),e.logTypeErrors&&console.error(`[TJS TypeError] ${U.message}`),e.throwTypeErrors)throw U;return U}function B(){if(e.trackErrors===!1||l===0)return[];let c=[],g=(a-l+o)%o;for(let y=0;y<l;y++)c.push(s[(g+y)%o]);return c}function Qe(){let c=B();return a=0,l=0,f=0,c}function en(){return f}function nn(c,g){let y={$error:!0,message:c,...g};if((e.callStacks||e.debug)&&i>0){let j=g?.path?[...R(),g.path]:R();y.stack=j}return y}function tn(c,g){return c==null?E(`bang.${g}`,"non-null",c):xe(c)?c:c[g]}return{version:A,MonadicError:M,typeError:E,isMonadicError:xe,bang:tn,isError:C,error:nn,composeErrors:_e,typeOf:Y,isNativeType:Ke,checkType:G,validateArgs:We,wrap:Ye,checkFnShape:He,wrapClass:Ze,compareVersions:we,versionsCompatible:Ee,createRuntime:Xe,configure:u,getConfig:x,pushStack:m,popStack:_,getStack:R,errors:B,clearErrors:Qe,getErrorCount:en,resetRuntime:O,enterUnsafe:h,exitUnsafe:w,isUnsafeMode:$,validate:Ie,infer:ne.infer.bind(ne),Type:b,isRuntimeType:v,Union:Te,Generic:H,Enum:je,FunctionPredicate:Q,Nullable:ge,Optional:be,TArray:ke,TString:ae,TNumber:ue,TBoolean:ce,TInteger:fe,TPositiveInt:le,TNonEmptyString:pe,TEmail:de,TUrl:ye,TUuid:me,TPair:he,TRecord:Se,Is:V,IsNot:ze,Eq:Oe,NotEq:Ge,TypeOf:Le,toBool:Ve,tjsEquals:W,registerExtension:k,resolveExtension:T}}var z={version:A,MonadicError:M,typeError:dn,isMonadicError:xe,isError:C,error:J,composeErrors:_e,typeOf:Y,isNativeType:Ke,checkType:G,validateArgs:We,wrap:Ye,checkFnShape:He,wrapClass:Ze,compareVersions:we,versionsCompatible:Ee,configure:bn,getConfig:Tn,pushStack:Fe,popStack:ee,getStack:Re,errors:De,clearErrors:kn,getErrorCount:hn,resetRuntime:Sn,enterUnsafe:yn,exitUnsafe:mn,isUnsafeMode:gn,createRuntime:Xe,validate:Ie,infer:ne.infer.bind(ne),Type:b,isRuntimeType:v,Union:Te,Generic:H,Enum:je,FunctionPredicate:Q,Nullable:ge,Optional:be,TArray:ke,TString:ae,TNumber:ue,TBoolean:ce,TInteger:fe,TPositiveInt:le,TNonEmptyString:pe,TEmail:de,TUrl:ye,TUuid:me,Timestamp:Me,LegalDate:Ue,TPair:he,TRecord:Se,Is:V,IsNot:ze,Eq:Oe,NotEq:Ge,TypeOf:Le,toBool:Ve};function Pn(){let e=globalThis;if(e.__tjs){let n=e.__tjs.version;if(typeof n!="string")return e.__tjs=z,z;let t=we(A,n);return t===0||(Ee(A,n)?t>0?(console.info(`TJS runtime: upgrading ${n} \u2192 ${A}`),e.__tjs=z):console.info(`TJS runtime: keeping ${n} (newer than ${A})`):(console.warn(`TJS runtime version conflict: ${n} vs ${A} (major version mismatch)`),t>0&&(console.warn(`Upgrading to ${A} - check for breaking changes`),e.__tjs=z))),e.__tjs}return e.__tjs=z,z}function An(e){return`
|
|
2
|
+
// TJS runtime wrapper (skips unsafe functions)
|
|
3
|
+
if (typeof ${e}.__tjs === 'object' && !${e}.__tjs.unsafe && typeof globalThis.__tjs?.wrap === 'function') {
|
|
4
|
+
${e} = globalThis.__tjs.wrap(${e}, ${e}.__tjs)
|
|
5
|
+
}
|
|
6
|
+
`.trim()}function Cn(e){return`
|
|
7
|
+
// TJS: callable without new
|
|
8
|
+
${e} = new Proxy(${e}, { apply(t, _, a) { return Reflect.construct(t, a) } });
|
|
9
|
+
`.trim()}export{je as Enum,Oe as Eq,Q as FunctionPredicate,H as Generic,V as Is,ze as IsNot,Ue as LegalDate,M as MonadicError,Ge as NotEq,ge as Nullable,be as Optional,ke as TArray,ce as TBoolean,de as TEmail,fe as TInteger,A as TJS_VERSION,pe as TNonEmptyString,ue as TNumber,he as TPair,le as TPositiveInt,Se as TRecord,ae as TString,ye as TUrl,me as TUuid,Me as Timestamp,b as Type,Le as TypeOf,Te as Union,He as checkFnShape,G as checkType,kn as clearErrors,we as compareVersions,_e as composeErrors,bn as configure,Xe as createRuntime,Cn as emitClassWrapper,An as emitRuntimeWrapper,yn as enterUnsafe,J as error,De as errors,mn as exitUnsafe,Tn as getConfig,hn as getErrorCount,Re as getStack,Pn as installRuntime,C as isError,xe as isMonadicError,Ke as isNativeType,v as isRuntimeType,gn as isUnsafeMode,Ce as isValidLegalDate,Ae as isValidTimestamp,Pe as isValidUrl,ee as popStack,Fe as pushStack,Sn as resetRuntime,z as runtime,W as tjsEquals,Ve as toBool,dn as typeError,Y as typeOf,We as validateArgs,Ee as versionsCompatible,Ye as wrap,Ze as wrapClass};
|
|
10
|
+
//# sourceMappingURL=tjs-runtime.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 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.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
|
+
"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
|
+
"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
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import{setPredicateEvaluator as R,getPredicateEvaluator as U}from"tosijs-schema";import*as h from"acorn";import*as y from"acorn-walk";var P=new Set(["parseInt","parseFloat","isNaN","isFinite","encodeURIComponent","decodeURIComponent","String","Number","Boolean","Array","Object","Eq","NotEq","Is","IsNot","TypeOf"]),k=new Set(["Math","JSON","Object","Array","String","Number"]),_=new Set(["Math.random","Date.now"]);function w(o,e){let t=o[e],a=0;if(t==="*"||t==="+")a=1;else if(t==="{"){let r=o.slice(e).match(/^\{\d+,\}/);r&&(a=r[0].length)}return a===0?0:(o[e+a]==="?"&&a++,a)}function O(o){let e=[],t=0,a=!1;for(;t<o.length;){let r=o[t];if(r==="\\"){t+=2;continue}if(a){r==="]"&&(a=!1),t++;continue}if(r==="["){a=!0,t++;continue}if(r==="("){e.push({hadUnbounded:!1}),t++;continue}if(r===")"){let i=e.pop()??{hadUnbounded:!1},d=w(o,t+1);if(d>0){if(i.hadUnbounded)return"an unbounded quantifier is nested inside another (e.g. `(a+)+`)";e.length&&(e[e.length-1].hadUnbounded=!0),t+=1+d;continue}i.hadUnbounded&&e.length&&(e[e.length-1].hadUnbounded=!0),t++;continue}let n=w(o,t);if(n>0){e.length&&(e[e.length-1].hadUnbounded=!0),t+=n;continue}t++}return null}var $=new Set(["startsWith","endsWith","includes","indexOf","lastIndexOf","slice","substring","substr","toLowerCase","toUpperCase","trim","trimStart","trimEnd","split","replace","replaceAll","match","matchAll","charAt","charCodeAt","codePointAt","padStart","padEnd","repeat","concat","at","normalize","search","localeCompare","every","some","map","filter","reduce","reduceRight","find","findIndex","findLast","findLastIndex","flat","flatMap","join","keys","entries","values","forEach","test","exec","toFixed","toPrecision","toString","valueOf","hasOwnProperty"]),v=["fetch","XMLHttpRequest","WebSocket","Date","console","setTimeout","setInterval","requestAnimationFrame","queueMicrotask","localStorage","sessionStorage","indexedDB","document","window","globalThis","self","process","require","eval","Function","import","crypto","performance","navigator"];function x(o,e={}){let t=e.effectful??new Set(v),a;try{a=h.parse(o,{ecmaVersion:"latest",locations:!0})}catch(i){return{safe:!1,predicates:[],diagnostics:[{predicate:"<source>",message:`parse error: ${i.message}`,line:i.loc?.line??0,column:i.loc?.column??0}]}}let r=new Set(e.knownPredicates??[]);for(let i of a.body)i.type==="FunctionDeclaration"&&i.id&&r.add(i.id.name);let n=[];for(let i of a.body){if(i.type!=="FunctionDeclaration"||!i.id)continue;let d=i.id.name,c=(l,s)=>n.push({predicate:d,message:l,line:s?.loc?.start?.line??0,column:s?.loc?.start?.column??0}),f=l=>c("loops are not allowed \u2014 iterate with recursion or array methods (every/some/map/filter/reduce) so work stays fuel-bounded",l);y.simple(i,{AwaitExpression(l){c("`await` not allowed \u2014 predicates must be synchronous",l)},NewExpression(l){c("`new` not allowed in a predicate (non-pure construction)",l)},WhileStatement:f,DoWhileStatement:f,ForStatement:f,ForInStatement:f,ForOfStatement:f,Literal(l){if(l.regex&&typeof l.regex.pattern=="string"){let s=O(l.regex.pattern);s&&c(`regex /${l.regex.pattern}/ risks catastrophic backtracking (ReDoS): ${s}. A single match is not fuel-bounded, so it can't be certified predicate-safe \u2014 simplify the pattern or validate without it.`,l)}},CallExpression(l){let s=l.callee;if(s.type==="Identifier"){let u=s.name;t.has(u)?c(`'${u}' is effectful \u2014 not allowed in a predicate`,s):r.has(u)||P.has(u)||c(`unknown reference '${u}' \u2014 not a predicate or pure builtin`,s);return}if(s.type==="MemberExpression"&&!s.computed){let u=s.property.name,p=s.object;p.type==="Identifier"&&t.has(p.name)?c(`'${p.name}.${u}' is effectful`,s):p.type==="Identifier"&&k.has(p.name)?_.has(`${p.name}.${u}`)&&c(`'${p.name}.${u}' is nondeterministic`,s):$.has(u)||c(`method '.${u}()' is not a known pure method`,s.property);return}c("unsupported call form in a predicate",s)}})}return{safe:n.length===0,predicates:[...r],diagnostics:n}}function F(o){return o.map(e=>` ${e.predicate} (${e.line}:${e.column}): ${e.message}`).join(`
|
|
2
|
+
`)}var m=class extends Error{constructor(e){super(`predicate exceeded its fuel budget (${e})`),this.name="PredicateFuelExhausted"}};function A(o){let e=h.parse(o,{ecmaVersion:"latest"}),t=[],a=n=>t.push([n.body.start+1,"__fuel();"]);y.simple(e,{FunctionDeclaration:a,FunctionExpression:a,ArrowFunctionExpression(n){n.body.type==="BlockStatement"?t.push([n.body.start+1,"__fuel();"]):(t.push([n.body.start,"(__fuel(), "]),t.push([n.body.end,")"]))}}),t.sort((n,i)=>i[0]-n[0]);let r=o;for(let[n,i]of t)r=r.slice(0,n)+i+r.slice(n);return r}function C(o,e,t={}){let a=x(o,t);if(!a.safe)throw new Error(`Not predicate-safe:
|
|
3
|
+
${F(a.diagnostics)}`);let r=t.fuel??1e6,n=A(o),i=v.filter(u=>u!=="import"&&u!=="eval"&&u!=="arguments"),d=new Function("__fuel",...i,`"use strict";
|
|
4
|
+
${n}
|
|
5
|
+
;return { ${e.join(", ")} };`),c=0,l=d(()=>{if(--c<0)throw new m(r)},...i.map(()=>{})),s={};for(let u of e){let p=l[u];s[u]=(...S)=>{c=r;try{return p(...S)}catch(g){throw g instanceof RangeError&&/stack/i.test(g.message)?new m(r):g}}}return s}function b(o={}){let{onUnsafe:e,...t}=o,a=new Map,r=new Set;return(n,i)=>{let d=a.get(n);if(d===void 0){try{let c=x(n,t).predicates,f=c[c.length-1];if(!f)throw new Error("$predicate declares no function");d=C(n,[f],t)[f]}catch(c){if(d=null,!r.has(n)){r.add(n);let f=c instanceof Error?c:new Error(String(c));e?e(n,f):console.warn(`[tjs-lang] $predicate not verifiable \u2014 failing closed: ${f.message}`)}}a.set(n,d)}if(d===null)return!1;try{return d(i)===!0}catch{return!1}}}export*from"tosijs-schema";var E=!1;function D(o){R(b(o)),E=!0}function M(){return E&&U()!==null}D();export{b as createPredicateEvaluator,D as installPredicateSupport,M as predicateSupportInstalled};
|
|
6
|
+
//# sourceMappingURL=tjs-schema.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/schema/index.ts", "../src/lang/predicate.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * `tjs-lang/schema` \u2014 tosijs-schema, pre-wired with predicate support.\n *\n * A drop-in for `tosijs-schema` that additionally evaluates the `$predicate`\n * keyword: importing this module registers tjs-lang's verified predicate engine\n * as the evaluator, so JSON-Schema validation is predicate-aware **out of the\n * box** \u2014 no manual `setPredicateEvaluator` call. Everything tosijs-schema\n * exports is re-exported here, so this is the only import a consumer needs:\n *\n * ```ts\n * import { s, validate } from 'tjs-lang/schema'\n * // a schema whose node carries `$predicate` now validates computationally\n * ```\n *\n * Why it lives here and not in tosijs-schema: tjs-lang depends on tosijs-schema,\n * so the reverse would be a circular dependency. This entry sits on the side of\n * the graph that may know about both \u2014 it's the \"batteries-included\" packaging\n * of the two.\n *\n * Registration is a global (tosijs-schema keeps one evaluator), so importing\n * this module makes `$predicate` work for tosijs-schema usage app-wide, even in\n * code that imports `tosijs-schema` directly. Call `setPredicateEvaluator(null)`\n * to opt back out, or `installPredicateSupport(opts)` to re-install with custom\n * options (fuel budget, atom-aware effects, etc.).\n */\nimport { setPredicateEvaluator, getPredicateEvaluator } from 'tosijs-schema'\nimport {\n createPredicateEvaluator,\n type PredicateEvaluatorOptions,\n} from '../lang/predicate'\n\n// The full tosijs-schema surface (s, validate, filter, diff, types,\n// setPredicateEvaluator, getPredicateEvaluator, PredicateEvaluator, \u2026).\nexport * from 'tosijs-schema'\n// The evaluator factory, for advanced/custom wiring.\nexport {\n createPredicateEvaluator,\n type PredicateEvaluatorOptions,\n} from '../lang/predicate'\n\nlet installed = false\n\n/**\n * Register tjs-lang's predicate engine as tosijs-schema's `$predicate` evaluator.\n * Called automatically when this module is imported; exposed so callers can\n * re-install with custom {@link PredicateEvaluatorOptions} (e.g. a smaller fuel\n * budget, or an atom-aware effectful set) after opting out.\n */\nexport function installPredicateSupport(\n opts?: PredicateEvaluatorOptions\n): void {\n setPredicateEvaluator(createPredicateEvaluator(opts))\n installed = true\n}\n\n/** True once predicate support has been installed (and not since cleared). */\nexport function predicateSupportInstalled(): boolean {\n return installed && getPredicateEvaluator() !== null\n}\n\n// Batteries included: wire the engine up on import.\ninstallPredicateSupport()\n", "/**\n * Predicate-safety verifier.\n *\n * A *predicate* is a pure, synchronous function of its inputs. A cluster of\n * predicates is **predicate-safe** iff every function in it uses only pure\n * constructs and calls only pure builtins, pure globals, or other\n * predicate-safe predicates \u2014 a closure property, so the cluster is safe iff\n * each function is. Verified predicates have \"earned\" the native fast path:\n * they compile to plain synchronous JS where ergonomic composition\n * (`isHex(v) || isVar(v)`, `tokens.every(isToken)`, recursion) just works.\n *\n * This is pure static analysis over the parsed source, so it has none of the VM\n * interpreter's restrictions (calls-in-expressions, named callbacks) \u2014 it\n * accepts the ergonomic source and certifies it. The serializable AJS AST stays\n * the portable form (the \"missing computational half\" of JSON Schema); native\n * JS is the execution form.\n *\n * Effect classification of atoms comes from the VM's `effects` tag \u2014 pass\n * `effectfulFromAtoms(registry)` for atom-aware checking; without it, atom calls\n * still fail closed as \"unknown reference\". See `experiments/predicates/` for\n * the CSS torture set and `src/vm/atom-effects.test.ts` for the drift guard.\n */\nimport * as acorn from 'acorn'\nimport * as walk from 'acorn-walk'\n\nexport interface PredicateDiagnostic {\n /** Name of the predicate the problem is in. */\n predicate: string\n message: string\n line: number\n column: number\n}\n\nexport interface PredicateVerifyResult {\n safe: boolean\n /** Names of the top-level functions found (the predicate cluster). */\n predicates: string[]\n diagnostics: PredicateDiagnostic[]\n}\n\nexport interface VerifyPredicateOptions {\n /**\n * Names that are effectful and must not be called \u2014 IO atoms + JS IO globals.\n * Compose from the atom registry with `effectfulFromAtoms`. The built-in JS IO\n * globals are always included.\n */\n effectful?: Set<string>\n /**\n * Externally-verified predicate names this source may compose with (a shared\n * registry), in addition to the functions declared in `source`.\n */\n knownPredicates?: Set<string>\n}\n\n// --- the safe substrate -----------------------------------------------------\n\n/** Pure deterministic globals callable by bare name. */\nconst PURE_GLOBALS = new Set([\n 'parseInt',\n 'parseFloat',\n 'isNaN',\n 'isFinite',\n 'encodeURIComponent',\n 'decodeURIComponent',\n 'String',\n 'Number',\n 'Boolean',\n 'Array',\n 'Object',\n // TJS-injected pure helpers. Native-TJS predicate bodies are rewritten before\n // they reach the verifier: `==`/`!=` \u2192 `Eq`/`NotEq`, the explicit `Is`/`IsNot`\n // operators \u2192 `Is`/`IsNot`, `typeof x` \u2192 `TypeOf(x)`. All are pure, total\n // functions (footgun-free equality / structural equality / safe typeof), so a\n // predicate that uses TJS equality still verifies as predicate-safe.\n 'Eq',\n 'NotEq',\n 'Is',\n 'IsNot',\n 'TypeOf',\n])\n\n/** Namespaces whose static methods are pure (with effectful exceptions below). */\nconst PURE_NAMESPACES = new Set([\n 'Math',\n 'JSON',\n 'Object',\n 'Array',\n 'String',\n 'Number',\n])\n\n/** Static members that are NOT pure even on a pure namespace. */\nconst EFFECTFUL_STATICS = new Set(['Math.random', 'Date.now'])\n\n/**\n * A match at `pattern[pos]` for an *unbounded* quantifier (`*`, `+`, `{n,}` and\n * their lazy `?` variants) \u2014 the repetitions that drive backtracking blowups.\n * `?`, `{n}` and `{n,m}` are bounded, so they don't count. Returns the consumed\n * length, or 0 if there's no unbounded quantifier here.\n */\nfunction unboundedQuantifierLen(pattern: string, pos: number): number {\n const c = pattern[pos]\n let len = 0\n if (c === '*' || c === '+') {\n len = 1\n } else if (c === '{') {\n // `{n,}` is unbounded; `{n}` / `{n,m}` are bounded.\n const m = pattern.slice(pos).match(/^\\{\\d+,\\}/)\n if (m) len = m[0].length\n }\n if (len === 0) return 0\n // A trailing `?` makes it lazy \u2014 still unbounded, still backtracks.\n if (pattern[pos + len] === '?') len++\n return len\n}\n\n/**\n * Conservative ReDoS detector: flags a regex whose **star height is \u2265 2** \u2014 an\n * unbounded quantifier nested inside a group that is itself unbounded-quantified\n * (the classic `(a+)+`, `(a*)*`, `([a-z]+)*`, `(.*)*` exponential-backtracking\n * shapes). A predicate verifier should fail closed: over-flagging a safe pattern\n * only costs it its \"verified\" badge (it still runs), whereas certifying a\n * dangerous one is a broken safety promise.\n *\n * Not caught (known limitation, documented): *polynomial* ReDoS from adjacent\n * overlapping quantifiers (`\\d+\\d+$`, `a.*a.*a`) and alternation-overlap\n * (`(a|a)*`). The exponential class above is the one the safety story commits to.\n *\n * @returns a reason string if risky, else null.\n */\nfunction reDoSRisk(pattern: string): string | null {\n // Per-group frame: did this group contain an unbounded quantifier?\n const stack: Array<{ hadUnbounded: boolean }> = []\n let i = 0\n let inClass = false\n while (i < pattern.length) {\n const c = pattern[i]\n if (c === '\\\\') {\n i += 2 // skip an escaped char (regex escapes are 2 chars here)\n continue\n }\n if (inClass) {\n if (c === ']') inClass = false\n i++\n continue\n }\n if (c === '[') {\n inClass = true\n i++\n continue\n }\n if (c === '(') {\n stack.push({ hadUnbounded: false })\n i++\n continue\n }\n if (c === ')') {\n const frame = stack.pop() ?? { hadUnbounded: false }\n const qlen = unboundedQuantifierLen(pattern, i + 1)\n if (qlen > 0) {\n // This group is itself unbounded-repeated. If it already contained an\n // unbounded quantifier, that's star height \u2265 2 \u2192 catastrophic.\n if (frame.hadUnbounded)\n return 'an unbounded quantifier is nested inside another (e.g. `(a+)+`)'\n // The parent group now contains an unbounded repetition (this group).\n if (stack.length) stack[stack.length - 1].hadUnbounded = true\n i += 1 + qlen\n continue\n }\n // No quantifier on this group, but if it contained an unbounded\n // repetition, that repetition lives in the parent's scope too \u2014 propagate\n // so `((a+))+` is caught the same as `(a+)+`.\n if (frame.hadUnbounded && stack.length)\n stack[stack.length - 1].hadUnbounded = true\n i++\n continue\n }\n // An unbounded quantifier on a plain atom at the current nesting level.\n const qlen = unboundedQuantifierLen(pattern, i)\n if (qlen > 0) {\n if (stack.length) stack[stack.length - 1].hadUnbounded = true\n i += qlen\n continue\n }\n i++\n }\n return null\n}\n\n/**\n * Instance methods known to be pure regardless of receiver type. A method call\n * whose method name isn't here (and whose receiver isn't a pure namespace) is\n * flagged \u2014 so `x.then()`, `obj.fetch()`, `arr.push()` (mutates) don't pass.\n */\nconst PURE_INSTANCE_METHODS = new Set([\n // string\n 'startsWith',\n 'endsWith',\n 'includes',\n 'indexOf',\n 'lastIndexOf',\n 'slice',\n 'substring',\n 'substr',\n 'toLowerCase',\n 'toUpperCase',\n 'trim',\n 'trimStart',\n 'trimEnd',\n 'split',\n 'replace',\n 'replaceAll',\n 'match',\n 'matchAll',\n 'charAt',\n 'charCodeAt',\n 'codePointAt',\n 'padStart',\n 'padEnd',\n 'repeat',\n 'concat',\n 'at',\n 'normalize',\n 'search',\n 'localeCompare',\n // array (non-mutating)\n 'every',\n 'some',\n 'map',\n 'filter',\n 'reduce',\n 'reduceRight',\n 'find',\n 'findIndex',\n 'findLast',\n 'findLastIndex',\n 'flat',\n 'flatMap',\n 'join',\n 'keys',\n 'entries',\n 'values',\n 'forEach',\n // regexp\n 'test',\n 'exec',\n // number / shared\n 'toFixed',\n 'toPrecision',\n 'toString',\n 'valueOf',\n 'hasOwnProperty',\n])\n\n/** JS globals that perform IO / are nondeterministic / have side effects. */\nconst EFFECTFUL_GLOBALS = [\n 'fetch',\n 'XMLHttpRequest',\n 'WebSocket',\n 'Date',\n 'console',\n 'setTimeout',\n 'setInterval',\n 'requestAnimationFrame',\n 'queueMicrotask',\n 'localStorage',\n 'sessionStorage',\n 'indexedDB',\n 'document',\n 'window',\n 'globalThis',\n 'self',\n 'process',\n 'require',\n 'eval',\n 'Function',\n 'import',\n 'crypto',\n 'performance',\n 'navigator',\n]\n\n/**\n * Build the effectful-name set from a VM atom registry: every atom tagged\n * `effects: 'io'`, plus the built-in JS IO globals. This is how the verifier\n * consumes the atom-effects classification (the keystone).\n */\nexport function effectfulFromAtoms(\n atoms: Record<string, { op?: string; effects?: 'pure' | 'io' }>\n): Set<string> {\n const set = new Set(EFFECTFUL_GLOBALS)\n for (const [name, atom] of Object.entries(atoms)) {\n if (atom?.effects === 'io') set.add(atom.op ?? name)\n }\n return set\n}\n\n// --- the verifier -----------------------------------------------------------\n\n/**\n * Verify every top-level function declaration in `source` is predicate-safe.\n * Returns all diagnostics; `safe` is true iff there are none (closure property).\n */\nexport function verifyPredicate(\n source: string,\n opts: VerifyPredicateOptions = {}\n): PredicateVerifyResult {\n const effectful = opts.effectful ?? new Set(EFFECTFUL_GLOBALS)\n let ast: any\n try {\n ast = acorn.parse(source, { ecmaVersion: 'latest', locations: true })\n } catch (e: any) {\n return {\n safe: false,\n predicates: [],\n diagnostics: [\n {\n predicate: '<source>',\n message: `parse error: ${e.message}`,\n line: e.loc?.line ?? 0,\n column: e.loc?.column ?? 0,\n },\n ],\n }\n }\n\n const predicateNames = new Set<string>(opts.knownPredicates ?? [])\n for (const node of ast.body) {\n if (node.type === 'FunctionDeclaration' && node.id)\n predicateNames.add(node.id.name)\n }\n\n const diagnostics: PredicateDiagnostic[] = []\n\n for (const fn of ast.body) {\n if (fn.type !== 'FunctionDeclaration' || !fn.id) continue\n const pname = fn.id.name\n const flag = (message: string, n: any) =>\n diagnostics.push({\n predicate: pname,\n message,\n line: n?.loc?.start?.line ?? 0,\n column: n?.loc?.start?.column ?? 0,\n })\n\n const loop = (n: any) =>\n flag(\n 'loops are not allowed \u2014 iterate with recursion or array methods (every/some/map/filter/reduce) so work stays fuel-bounded',\n n\n )\n walk.simple(fn, {\n AwaitExpression(n: any) {\n flag('`await` not allowed \u2014 predicates must be synchronous', n)\n },\n NewExpression(n: any) {\n flag('`new` not allowed in a predicate (non-pure construction)', n)\n },\n WhileStatement: loop,\n DoWhileStatement: loop,\n ForStatement: loop,\n ForInStatement: loop,\n ForOfStatement: loop,\n Literal(n: any) {\n // Regex literals are the one primitive fuel can't bound: a single\n // `.match`/`.test`/`.replace` is opaque to the function-entry fuel hook,\n // so a catastrophic-backtracking pattern could hang on hostile input.\n // Certifying it \"safe\" would be a false guarantee, so flag it. (Dynamic\n // `RegExp(...)` is already rejected \u2014 `RegExp` isn't a pure global and\n // `new` is banned \u2014 so only literals need analysis.)\n if (n.regex && typeof n.regex.pattern === 'string') {\n const risk = reDoSRisk(n.regex.pattern)\n if (risk)\n flag(\n `regex /${n.regex.pattern}/ risks catastrophic backtracking (ReDoS): ${risk}. A single match is not fuel-bounded, so it can't be certified predicate-safe \u2014 simplify the pattern or validate without it.`,\n n\n )\n }\n },\n CallExpression(n: any) {\n const callee = n.callee\n // Bare call: f(...)\n if (callee.type === 'Identifier') {\n const name = callee.name\n if (effectful.has(name))\n flag(`'${name}' is effectful \u2014 not allowed in a predicate`, callee)\n else if (predicateNames.has(name)) {\n /* composition with another predicate \u2014 OK */\n } else if (PURE_GLOBALS.has(name)) {\n /* pure global \u2014 OK */\n } else {\n flag(\n `unknown reference '${name}' \u2014 not a predicate or pure builtin`,\n callee\n )\n }\n return\n }\n // Method call: recv.method(...)\n if (callee.type === 'MemberExpression' && !callee.computed) {\n const method = callee.property.name\n const recv = callee.object\n if (recv.type === 'Identifier' && effectful.has(recv.name)) {\n flag(`'${recv.name}.${method}' is effectful`, callee)\n } else if (\n recv.type === 'Identifier' &&\n PURE_NAMESPACES.has(recv.name)\n ) {\n if (EFFECTFUL_STATICS.has(`${recv.name}.${method}`))\n flag(`'${recv.name}.${method}' is nondeterministic`, callee)\n // else pure namespace method \u2014 OK\n } else if (!PURE_INSTANCE_METHODS.has(method)) {\n flag(\n `method '.${method}()' is not a known pure method`,\n callee.property\n )\n }\n return\n }\n // Anything else (computed member, call-of-call, etc.) \u2014 be conservative.\n flag('unsupported call form in a predicate', callee)\n },\n })\n }\n\n return {\n safe: diagnostics.length === 0,\n predicates: [...predicateNames],\n diagnostics,\n }\n}\n\n/** Format diagnostics for a thrown error / log. */\nexport function formatPredicateDiagnostics(d: PredicateDiagnostic[]): string {\n return d\n .map((x) => ` ${x.predicate} (${x.line}:${x.column}): ${x.message}`)\n .join('\\n')\n}\n\n// --- suggestion mining (#4: autocomplete companion) -------------------------\n\nexport interface Suggestion {\n value: string\n /**\n * `'value'` \u2014 a concrete candidate (a keyword/literal the predicate accepts);\n * `'stub'` \u2014 a partial completion to keep typing (e.g. `var(--`, `calc(`),\n * mined from a `startsWith(...)` guard. TS's `string` fallback\n * offers neither; a finite TS union offers only `'value'`.\n */\n kind: 'value' | 'stub'\n}\n\nexport interface SuggestOptions extends CompilePredicateOptions {\n /** Only return candidates relevant to the text typed so far. */\n prefix?: string\n /** Cap the number of suggestions (default 50). */\n limit?: number\n /**\n * Run each mined *value* through the compiled entry predicate and keep only\n * those that actually pass \u2014 so completions are guaranteed valid, not merely\n * enumerated. Default true when the cluster is predicate-safe; stubs are never\n * validated (they're partial by construction).\n */\n validate?: boolean\n /** Entry predicate to validate against (default: last top-level function). */\n entry?: string\n}\n\nconst isStringLiteral = (n: any): n is { value: string } =>\n n && n.type === 'Literal' && typeof n.value === 'string'\n\n/**\n * Mine a predicate cluster's source for autocomplete candidates. Two sources:\n * - **values** \u2014 string literals compared with `==`/`===` and members of\n * array literals (the keyword sets a predicate checks membership against).\n * - **stubs** \u2014 the argument of a `.startsWith(...)` guard, surfaced as a\n * partial completion (`var(--`, `calc(`) the user keeps typing.\n *\n * Pure syntactic mining over the parsed source \u2014 no execution. By default the\n * mined *values* are then run through the compiled entry predicate, so the\n * returned set is exactly what the predicate accepts (a literal that only ever\n * appears in a `!=` / negative context is dropped). This is the autocomplete\n * win over a TS `string` fallback (which suggests nothing) and over a finite TS\n * union (which can't offer the open-ended `var(--`/`calc(` stubs).\n */\nexport function suggest(\n source: string,\n opts: SuggestOptions = {}\n): Suggestion[] {\n let ast: any\n try {\n ast = acorn.parse(source, { ecmaVersion: 'latest' })\n } catch {\n return []\n }\n\n const values = new Set<string>()\n const stubs = new Set<string>()\n walk.simple(ast, {\n BinaryExpression(n: any) {\n if (n.operator === '==' || n.operator === '===') {\n if (isStringLiteral(n.left)) values.add(n.left.value)\n if (isStringLiteral(n.right)) values.add(n.right.value)\n }\n },\n ArrayExpression(n: any) {\n for (const el of n.elements) if (isStringLiteral(el)) values.add(el.value)\n },\n CallExpression(n: any) {\n const callee = n.callee\n if (callee.type !== 'MemberExpression' || callee.computed) return\n const method = callee.property.name\n const arg = n.arguments[0]\n if (!isStringLiteral(arg)) return\n if (method === 'startsWith') stubs.add(arg.value)\n // `.includes('x')` / `.endsWith('x')` aren't standalone completions:\n // includes-arg is a substring, endsWith-arg is a tail \u2014 skip both.\n },\n })\n\n // Validate mined values against the predicate unless told not to / unsafe.\n let accept: ((v: string) => boolean) | null = null\n if (opts.validate !== false) {\n const verified = verifyPredicate(source, opts)\n if (verified.safe && verified.predicates.length) {\n const entry =\n opts.entry ?? verified.predicates[verified.predicates.length - 1]\n try {\n const mod = compilePredicate(source, [entry], opts)\n const fn = mod[entry]\n accept = (v) => {\n try {\n return fn(v) === true\n } catch {\n return false // fuel exhaustion / runtime miss \u2192 not a suggestion\n }\n }\n } catch {\n accept = null // not compilable \u2192 fall back to raw mining\n }\n }\n }\n\n const out: Suggestion[] = []\n for (const v of values)\n if (!accept || accept(v)) out.push({ value: v, kind: 'value' })\n for (const s of stubs) out.push({ value: s, kind: 'stub' })\n\n let filtered = out\n if (opts.prefix) {\n const p = opts.prefix\n filtered = out.filter(\n (s) =>\n s.value.startsWith(p) || (s.kind === 'stub' && p.startsWith(s.value))\n )\n }\n filtered.sort(\n (a, b) =>\n (a.kind === b.kind ? 0 : a.kind === 'value' ? -1 : 1) ||\n a.value.localeCompare(b.value)\n )\n return opts.limit ? filtered.slice(0, opts.limit) : filtered\n}\n\n/** Thrown when a predicate exceeds its fuel budget (likely a pathological input). */\nexport class PredicateFuelExhausted extends Error {\n constructor(budget: number) {\n super(`predicate exceeded its fuel budget (${budget})`)\n this.name = 'PredicateFuelExhausted'\n }\n}\n\nexport interface CompilePredicateOptions extends VerifyPredicateOptions {\n /** Max fuel per top-level predicate call (default 1,000,000). */\n fuel?: number\n}\n\n/**\n * Inject `__fuel()` at every function-body entry and comma-wrap expression-body\n * arrows, by splicing at source offsets (no codegen needed). Because loops are\n * rejected, function-entry fuel bounds all iteration: recursion costs fuel per\n * call, and array-method callbacks (`xs.every(p)`) cost fuel per element via the\n * callback's own entry.\n */\nfunction injectFuel(source: string): string {\n const ast = acorn.parse(source, { ecmaVersion: 'latest' }) as any\n // Each edit: [offset, text]. Applied descending so offsets stay valid.\n const edits: Array<[number, string]> = []\n const enterBlockBody = (n: any) => edits.push([n.body.start + 1, '__fuel();'])\n walk.simple(ast, {\n FunctionDeclaration: enterBlockBody,\n FunctionExpression: enterBlockBody,\n ArrowFunctionExpression(n: any) {\n if (n.body.type === 'BlockStatement') {\n edits.push([n.body.start + 1, '__fuel();'])\n } else {\n // expression-body arrow: `x => EXPR` \u2192 `x => (__fuel(), EXPR)`\n edits.push([n.body.start, '(__fuel(), '])\n edits.push([n.body.end, ')'])\n }\n },\n })\n edits.sort((a, b) => b[0] - a[0])\n let out = source\n for (const [off, text] of edits)\n out = out.slice(0, off) + text + out.slice(off)\n return out\n}\n\n/**\n * Verify, then compile the cluster to native synchronous JS functions \u2014\n * **fuel-bounded and global-shadowed**. Throws (with located diagnostics) at\n * definition time if not predicate-safe.\n *\n * Each compiled predicate runs with a fresh fuel budget; a runaway input throws\n * `PredicateFuelExhausted` rather than hanging. The effectful globals are\n * shadowed to `undefined` as defense-in-depth beneath the static verifier.\n *\n * NOTE: preserves JS semantics (no structural-`==` rewrite yet \u2014 a future\n * opt-in). Emission is offset-spliced source, not a full AJS-AST\u2192JS codegen.\n */\nexport function compilePredicate(\n source: string,\n exportNames: string[],\n opts: CompilePredicateOptions = {}\n): Record<string, (...args: any[]) => any> {\n const result = verifyPredicate(source, opts)\n if (!result.safe)\n throw new Error(\n `Not predicate-safe:\\n${formatPredicateDiagnostics(result.diagnostics)}`\n )\n\n const budget = opts.fuel ?? 1_000_000\n const instrumented = injectFuel(source)\n\n // Shadow the effectful globals to undefined (defense-in-depth under the\n // verifier), and inject the fuel hook. `new Function` params shadow globals.\n // Exclude reserved words that can't be parameter names (still verifier-rejected).\n const shadowed = EFFECTFUL_GLOBALS.filter(\n (g) => g !== 'import' && g !== 'eval' && g !== 'arguments'\n )\n const factory = new Function(\n '__fuel',\n ...shadowed,\n `\"use strict\";\\n${instrumented}\\n;return { ${exportNames.join(', ')} };`\n )\n\n let fuel = 0\n const fuelHook = () => {\n if (--fuel < 0) throw new PredicateFuelExhausted(budget)\n }\n const raw = factory(fuelHook, ...shadowed.map(() => undefined))\n\n // Each top-level call gets a fresh budget; inner composed calls share it.\n // A stack overflow (deep recursion past the JS frame limit before fuel runs\n // out) is the same \"runaway\" signal, so normalize it to PredicateFuelExhausted.\n const wrapped: Record<string, (...args: any[]) => any> = {}\n for (const name of exportNames) {\n const fn = raw[name]\n wrapped[name] = (...args: any[]) => {\n fuel = budget\n try {\n return fn(...args)\n } catch (e) {\n if (e instanceof RangeError && /stack/i.test(e.message))\n throw new PredicateFuelExhausted(budget)\n throw e\n }\n }\n }\n return wrapped\n}\n\nexport interface EmitPredicateResult {\n /** True iff the cluster passed predicate-safety verification. */\n safe: boolean\n /**\n * When `safe`, a self-contained JS **expression** that evaluates to the guard\n * function `(...args) => boolean`. Inline it directly into transpiler output \u2014\n * it carries its own fuel counter (no global `__fuel`, no runtime dependency\n * on the predicate engine or the `PredicateFuelExhausted` class). Undefined\n * when `!safe`.\n */\n code?: string\n /** Verifier diagnostics (the reasons, when `!safe`). */\n diagnostics: PredicateDiagnostic[]\n}\n\n/**\n * Verify a predicate cluster and, if safe, emit a **self-contained source\n * expression** for its guard \u2014 the transpile-time counterpart to\n * `compilePredicate` (which evals to live closures). This is what lets a\n * verified `Type`/`FunctionPredicate` predicate compile to a fuel-bounded native\n * guard in standalone output: no import of this module, no shared runtime.\n *\n * Fuel model mirrors `compilePredicate` (function-entry `__fuel()` bounds all\n * iteration since loops are rejected), but because a guard answers a boolean\n * question, a runaway input **returns `false`** (\"not a valid instance of this\n * type\") instead of throwing \u2014 DoS-safe validation that never crashes the caller.\n * A deep-recursion stack overflow is the same runaway signal, normalized the\n * same way.\n *\n * The runtime effectful-global shadow that `compilePredicate` applies is omitted\n * here on purpose: a `safe` cluster provably references no effectful global (the\n * static verifier guarantees it), so the shadow would only bloat emitted output.\n *\n * @param source the predicate cluster (one or more `function` declarations)\n * @param entryName which declared function is the guard entry point\n * @param opts verify options + `fuel` budget (default 1,000,000)\n */\nexport function emitVerifiedPredicate(\n source: string,\n entryName: string,\n opts: CompilePredicateOptions = {}\n): EmitPredicateResult {\n const result = verifyPredicate(source, opts)\n if (!result.safe) {\n return { safe: false, diagnostics: result.diagnostics }\n }\n if (!result.predicates.includes(entryName)) {\n return {\n safe: false,\n diagnostics: [\n {\n predicate: entryName,\n message: `entry predicate '${entryName}' not found in the verified cluster`,\n line: 0,\n column: 0,\n },\n ],\n }\n }\n\n const budget = opts.fuel ?? 1_000_000\n const instrumented = injectFuel(source)\n\n // A self-contained IIFE: fuel counter in a closure, guard entry re-armed per\n // top-level call, runaway (fuel or stack) \u2192 `false`.\n const code =\n `(() => {` +\n `let __f = 0;` +\n `const __fuel = () => { if (--__f < 0) throw new RangeError('tjs:predicate-fuel'); };` +\n `${instrumented}` +\n `return (...__a) => {` +\n `__f = ${budget};` +\n `try { return !!${entryName}(...__a); }` +\n `catch (e) {` +\n `if (e instanceof RangeError && /tjs:predicate-fuel|stack/i.test(e.message)) return false;` +\n `throw e;` +\n `}` +\n `};` +\n `})()`\n\n return { safe: true, code, diagnostics: [] }\n}\n\n// --- $predicate evaluator (#6: the tosijs-schema integration point) ---------\n\nexport interface PredicateEvaluatorOptions extends CompilePredicateOptions {\n /**\n * Called once per source that fails to verify/compile. Default: `console.warn`.\n * The evaluator fails **closed** on such a source (returns `false`), so an\n * unverifiable `$predicate` can never validate a value as `true`.\n */\n onUnsafe?: (source: string, error: Error) => void\n}\n\n/**\n * Build a pluggable `$predicate` evaluator: `(source, value) => boolean`.\n *\n * This is the bridge for a predicate-aware JSON-Schema validator that lives in\n * another package (e.g. `tosijs-schema`, which cannot depend on `tjs-lang` \u2014 the\n * dependency runs the other way). Such a validator stays zero-dep and exposes a\n * hook; a consumer that has this engine injects an evaluator built here.\n *\n * Each distinct source is verified + compiled **once** and cached, so repeated\n * validation is just a native call. Semantics match `compilePredicateSchema`:\n * the LAST top-level function is the entry; a source that isn't predicate-safe\n * (or throws / exhausts fuel at runtime) yields `false` \u2014 never a thrown error\n * mid-validation, never a silent pass.\n */\nexport function createPredicateEvaluator(\n opts: PredicateEvaluatorOptions = {}\n): (source: string, value: unknown) => boolean {\n const { onUnsafe, ...compileOpts } = opts\n const cache = new Map<string, ((value: unknown) => boolean) | null>()\n const warned = new Set<string>()\n\n return (source: string, value: unknown): boolean => {\n let fn = cache.get(source)\n if (fn === undefined) {\n try {\n const names = verifyPredicate(source, compileOpts).predicates\n const entry = names[names.length - 1]\n if (!entry) throw new Error('$predicate declares no function')\n const mod = compilePredicate(source, [entry], compileOpts)\n fn = mod[entry] as (value: unknown) => boolean\n } catch (e) {\n fn = null // fail closed\n if (!warned.has(source)) {\n warned.add(source)\n const err = e instanceof Error ? e : new Error(String(e))\n if (onUnsafe) onUnsafe(source, err)\n else\n console.warn(\n `[tjs-lang] $predicate not verifiable \u2014 failing closed: ${err.message}`\n )\n }\n }\n cache.set(source, fn)\n }\n if (fn === null) return false\n try {\n return fn(value) === true\n } catch {\n return false // fuel exhaustion / runtime miss \u2192 not valid\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["setPredicateEvaluator", "getPredicateEvaluator", "acorn", "walk", "PURE_GLOBALS", "PURE_NAMESPACES", "EFFECTFUL_STATICS", "unboundedQuantifierLen", "pattern", "pos", "c", "len", "m", "reDoSRisk", "stack", "i", "inClass", "frame", "qlen", "PURE_INSTANCE_METHODS", "EFFECTFUL_GLOBALS", "verifyPredicate", "source", "opts", "effectful", "EFFECTFUL_GLOBALS", "ast", "e", "predicateNames", "node", "diagnostics", "fn", "pname", "flag", "message", "n", "loop", "risk", "reDoSRisk", "callee", "name", "PURE_GLOBALS", "method", "recv", "PURE_NAMESPACES", "EFFECTFUL_STATICS", "PURE_INSTANCE_METHODS", "formatPredicateDiagnostics", "d", "x", "PredicateFuelExhausted", "budget", "injectFuel", "source", "ast", "edits", "enterBlockBody", "a", "b", "out", "off", "text", "compilePredicate", "exportNames", "opts", "result", "verifyPredicate", "formatPredicateDiagnostics", "instrumented", "shadowed", "EFFECTFUL_GLOBALS", "g", "factory", "fuel", "raw", "wrapped", "name", "fn", "args", "e", "createPredicateEvaluator", "opts", "onUnsafe", "compileOpts", "cache", "warned", "source", "value", "fn", "names", "verifyPredicate", "entry", "compilePredicate", "e", "err", "installed", "installPredicateSupport", "opts", "setPredicateEvaluator", "createPredicateEvaluator", "predicateSupportInstalled", "getPredicateEvaluator"]
|
|
7
|
+
}
|