@stacksjs/tinker 0.75.541 → 0.75.542
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/dist/index.d.ts +1 -0
- package/dist/index.js +29 -26
- package/dist/protocol.d.ts +4 -2
- package/dist/serialize.d.ts +50 -0
- package/dist/session.d.ts +14 -0
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
package/dist/index.js
CHANGED
|
@@ -1,39 +1,42 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
import{appendFileSync as
|
|
3
|
-
`)){let i=
|
|
4
|
-
//# sourceURL=${n}.ts`}function
|
|
5
|
-
`}),
|
|
6
|
-
`}function
|
|
7
|
-
`);return e=i.pop()??"",i.map(r)},flush(){if(!e)return[];let n=e;return e="",[{stray:n}]}}}async function
|
|
8
|
-
`);while(
|
|
9
|
-
`)}}if(!
|
|
10
|
-
`).filter(Boolean)}function
|
|
11
|
-
`),i)try{q(n,384)}catch{}let
|
|
2
|
+
import{appendFileSync as de,chmodSync as q,existsSync as J,readFileSync as fe,writeFileSync as K,writeSync as pe}from"fs";import{homedir as ge}from"os";import{join as ke,resolve as ye}from"path";import F from"process";import{writeSync as ue}from"fs";import{isAbsolute as ne,resolve as D}from"path";import E from"process";var Y={maxDepth:8,maxItems:200,maxString:20000,maxNodes:50000},G=/^\s*at\s+(?:(.*?)\s+\()?(.+?):(\d+):(\d+)\)?\s*$/;function Q(e){if(!e)return[];let r=[];for(let n of e.split(`
|
|
3
|
+
`)){let i=G.exec(n);if(!i)continue;r.push({function:i[1]||void 0,file:i[2],line:Number(i[3]),column:Number(i[4])})}return r}function X(e){if(Function.prototype.toString.call(e).startsWith("class"))return"class";let n=e.constructor?.name;if(n==="AsyncFunction"||n==="AsyncGeneratorFunction")return"async";if(n==="GeneratorFunction")return"generator";return"function"}function j(e){let r=Object.getPrototypeOf(e);if(r===null)return"null prototype";let n=r.constructor?.name;return typeof n==="string"&&n&&n!=="Object"?n:void 0}var _=2000000;class A{kind;html;title;text;constructor(e,r,n,i){this.kind=e;this.html=r;this.title=n;this.text=i}}var Z=["hasOne","hasMany","belongsTo","belongsToMany","hasOneThrough","hasManyThrough","morphOne","morphMany","morphTo","morphToMany"];function R(e){let r=[];for(let n of Z){let i=e[n];if(!i)continue;if(Array.isArray(i)){for(let o of i)if(typeof o==="string")r.push({kind:n,model:o});else if(o&&typeof o==="object"&&typeof o.model==="string")r.push({kind:n,model:o.model,...typeof o.relationName==="string"?{name:o.relationName}:{}})}else if(typeof i==="object"){for(let[o,s]of Object.entries(i))if(typeof s==="string")r.push({kind:n,model:s,name:o})}else if(typeof i==="string")r.push({kind:n,model:i})}return r}function ee(e){let r=e._definition;return typeof r==="object"&&r!==null&&typeof r.name==="string"&&typeof e.toJSON==="function"&&typeof e.getAttributes==="function"}function O(e,r={}){let n={...Y,...r.limits},i=r.describers??[],o=new Map,s=0,b=1;function g(a,y){if(s++,a===void 0)return{t:"undefined"};if(a===null)return{t:"null"};switch(typeof a){case"boolean":return{t:"boolean",v:a};case"number":if(Number.isNaN(a))return{t:"number",v:"NaN"};if(a===Number.POSITIVE_INFINITY)return{t:"number",v:"Infinity"};if(a===Number.NEGATIVE_INFINITY)return{t:"number",v:"-Infinity"};if(Object.is(a,-0))return{t:"number",v:"-0"};return{t:"number",v:a};case"bigint":return{t:"bigint",v:a.toString()};case"string":return a.length>n.maxString?{t:"string",v:a.slice(0,n.maxString),truncated:a.length-n.maxString}:{t:"string",v:a};case"symbol":return{t:"symbol",v:a.description??""};case"function":return{t:"function",name:a.name||"(anonymous)",kind:X(a)}}let t=a,d=o.get(t);if(d!==void 0)return{t:"ref",id:d};if(t instanceof Date)return{t:"date",v:Number.isNaN(t.getTime())?null:t.toISOString()};if(t instanceof RegExp)return{t:"regexp",v:t.toString()};if(t instanceof URL)return{t:"url",v:t.href};if(t instanceof Promise)return{t:"promise"};if(ArrayBuffer.isView(t)||t instanceof ArrayBuffer){let c=t instanceof ArrayBuffer?new Uint8Array(t):new Uint8Array(t.buffer,t.byteOffset,t.byteLength);return{t:"bytes",ctor:t.constructor?.name??"ArrayBuffer",length:c.byteLength,hex:Buffer.from(c.subarray(0,64)).toString("hex")}}if(y>=n.maxDepth)return{t:"cut",reason:"depth",ctor:j(t)??(Array.isArray(t)?"Array":"Object")};if(s>=n.maxNodes)return{t:"cut",reason:"nodes",ctor:j(t)};let u=b++;o.set(t,u);let l=(c)=>g(c,y+1);if(t instanceof Error)return k(t,l);if(t instanceof A){let c=t.html.length-_;return{t:"html",kind:t.kind,...t.title?{title:t.title}:{},html:c>0?t.html.slice(0,_):t.html,...t.text?{text:t.text.slice(0,n.maxString)}:{},...c>0?{truncated:c}:{}}}if(ee(t))return N(t,u,l);for(let c of i){let p;try{p=c(t,l)}catch{p=void 0}if(p)return p}if(Array.isArray(t)){let c=[],p=Math.min(t.length,n.maxItems);for(let S=0;S<p&&s<n.maxNodes;S++)c.push(l(t[S]));let f=t.length-c.length,m=j(t);return{t:"array",id:u,...m&&m!=="Array"?{ctor:m}:{},length:t.length,items:c,...f>0?{more:f}:{}}}if(t instanceof Map){let c=[];for(let[f,m]of t){if(c.length>=n.maxItems||s>=n.maxNodes)break;c.push([l(f),l(m)])}let p=t.size-c.length;return{t:"map",id:u,size:t.size,entries:c,...p>0?{more:p}:{}}}if(t instanceof Set){let c=[];for(let f of t){if(c.length>=n.maxItems||s>=n.maxNodes)break;c.push(l(f))}let p=t.size-c.length;return{t:"set",id:u,size:t.size,items:c,...p>0?{more:p}:{}}}return V(t,u,l)}function N(a,y,t){let d=a._definition,u={};try{let h=a.toJSON();if(h&&typeof h==="object")u=h}catch{}let l={};try{l=a.getLoadedRelations?.()??{}}catch{l={}}let c=Object.keys(u).filter((h)=>!(h in l)),p=[];for(let h of c){if(p.length>=n.maxItems||s>=n.maxNodes)break;p.push([h,t(u[h])])}let f=Object.keys(a).filter((h)=>!(h in u)),m=[];for(let[h,H]of Object.entries(l)){if(m.length>=n.maxItems||s>=n.maxNodes)break;m.push([h,t(H)])}let S=R(d),w=typeof d.primaryKey==="string"?d.primaryKey:"id",T=c.length-p.length;return{t:"model",id:y,model:d.name,...typeof d.table==="string"?{table:d.table}:{},primaryKey:w,...u[w]!==void 0?{key:t(u[w])}:{},attributes:p,...f.length?{hidden:f}:{},...m.length?{loaded:m}:{},...S.length?{relations:S}:{},...T>0?{more:T}:{}}}function V(a,y,t){let d=j(a),u=a,l=Object.keys(a);if(l.length===0&&d&&typeof a.toJSON==="function")try{let f=a.toJSON();if(Array.isArray(f)){let m=t(f);return m.t==="array"?{...m,ctor:d}:m}if(f&&typeof f==="object")u=f,l=Object.keys(u)}catch{}let c=[];for(let f of l){if(c.length>=n.maxItems||s>=n.maxNodes)break;let m;try{m=u[f]}catch(S){m=S}c.push([f,t(m)])}let p=l.length-c.length;return{t:"object",id:y,...d?{ctor:d}:{},entries:c,...p>0?{more:p}:{}}}function k(a,y){let t={t:"error",name:a.name||"Error",message:String(a.message??"")};if(typeof a.stack==="string"){t.stack=a.stack;let u=Q(a.stack);if(u.length)t.frames=u}if(a.cause!==void 0)t.cause=y(a.cause);let d=[];for(let u of Object.keys(a)){if(u==="name"||u==="message"||u==="stack"||u==="cause")continue;if(d.length>=n.maxItems)break;d.push([u,y(a[u])])}if(d.length)t.entries=d;return t}return g(e,0)}function P(e,r={}){if(e instanceof Error)return O(e,r);return{t:"error",name:"Thrown",message:typeof e==="string"?e:Bun.inspect(e),cause:O(e,r)}}function te(){let e=[],r=new Set;for(let n of Object.getOwnPropertyNames(globalThis)){let i;try{i=globalThis[n]}catch{continue}if(!i||typeof i!=="object"&&typeof i!=="function")continue;let o=i.getDefinition;if(typeof o!=="function")continue;let s;try{s=o.call(i)}catch{continue}if(!s||typeof s.name!=="string"||r.has(s.name))continue;r.add(s.name),e.push({name:s.name,...typeof s.table==="string"?{table:s.table}:{},...typeof s.primaryKey==="string"?{primaryKey:s.primaryKey}:{},attributes:s.attributes&&typeof s.attributes==="object"?Object.keys(s.attributes):[],relations:R(s)})}return e.sort((n,i)=>n.name.localeCompare(i.name))}function re(){return{html(e,r){return new A("html",String(e),r)},async mail(e,r={}){let{templateByName:i}=await import("@stacksjs/email"),o=await i(e,{variables:r});if(!o?.html)throw Error(`No mail template named "${e}" rendered. Templates live in resources/emails.`);return new A("mail",o.html,e,o.text)}}}class I extends Error{constructor(){super("dd");this.name="TinkerHalt"}}var ie=/\bimport\((["'])(\.{1,2}\/[^"']*)\1\)/g;function B(e,r,n="tinker"){return`${new Bun.Transpiler({loader:"ts",replMode:!0}).transformSync(e).replace(ie,(s,b,g)=>`import(${b}${D(r,g)}${b})`)}
|
|
4
|
+
//# sourceURL=${n}.ts`}function oe(e){let r=e instanceof AggregateError?e.errors:[e],n=[];for(let i of r){if(!i||typeof i!=="object")continue;let{message:o,position:s}=i;n.push({message:typeof o==="string"?o:String(i),...s?.line!==void 0?{line:s.line}:{},...s?.column!==void 0?{column:s.column}:{},...s?.lineText?{lineText:s.lineText}:{}})}return n}async function se(e){let i=!0;try{let{overridesReady:o}=await import("@stacksjs/config");await o}catch(o){i=!1,e.push(`config not loaded: ${o instanceof Error?o.message:String(o)}`)}try{let{injectGlobalAutoImports:o}=await import("@stacksjs/server");await o()}catch(o){i=!1,e.push(`models and framework globals not injected: ${o instanceof Error?o.message:String(o)}`)}return i}var ae=["log","info","debug","dir","table"],ce=["warn","error","trace"];async function v(e={}){let r=e.cwd?ne(e.cwd)?e.cwd:D(E.cwd(),e.cwd):E.cwd();if(r!==E.cwd())E.chdir(r);let n={limits:e.limits,describers:e.describers},i=[],o=[],s="boot",b,g=(l)=>{b?.push(l);try{e.onFrame?.(l)}catch{}},N=console,V=(l)=>l.map((c)=>typeof c==="string"?c:Bun.inspect(c,{depth:6})).join(" ");for(let[l,c]of[[ae,"stdout"],[ce,"stderr"]])for(let p of l){let f=N[p];N[p]=(...m)=>g({type:c,id:s,text:`${V(m)}
|
|
5
|
+
`}),o.push(()=>{N[p]=f})}for(let[l,c]of[[E.stdout,"stdout"],[E.stderr,"stderr"]]){let p=l.write;l.write=(f,...m)=>(g({type:c,id:s,text:typeof f==="string"?f:Buffer.from(f).toString("utf8")}),m.find((w)=>typeof w==="function")?.(),!0),o.push(()=>{l.write=p})}let k=globalThis;if(k.dump=(...l)=>{for(let c of l)g({type:"dump",id:s,value:O(c,n)})},k.dd=(...l)=>{throw k.dump(...l),new I},k.preview=re(),e.globals)Object.assign(k,e.globals);let a=!1;if(typeof e.boot==="function")try{await e.boot(),a=!0}catch(l){i.push(`boot failed: ${l instanceof Error?l.message:String(l)}`)}else if(e.boot!==!1)a=await se(i);if(a&&e.boot!==!1&&typeof e.boot!=="function"){let l=(...f)=>{for(let m of f)g({type:"dump",id:s,value:O(m,n)})};k.dump=l,k.dd=(...f)=>{throw l(...f),new I};let c="@stacksjs/logging",p="@stacksjs/query-builder";try{let{registerTransport:f}=await import(c);o.push(f({name:"tinker",log(m){g({type:"log",id:s,level:m.level,message:m.message,timestamp:m.timestamp,...m.context?{context:O(m.context,n)}:{}})}}))}catch(f){i.push(`log capture unavailable: ${f instanceof Error?f.message:String(f)}`)}try{let{registerPersistentQueryHooks:f}=await import(p);o.push(f({onQueryEnd(m){g({type:"query",id:s,sql:m.sql,...m.params?.length?{params:O(m.params,n)}:{},...m.kind?{kind:m.kind}:{},durationMs:m.durationMs,...m.rowCount!==void 0?{rowCount:m.rowCount}:{}})},onQueryError(m){g({type:"query",id:s,sql:m.sql,...m.params?.length?{params:O(m.params,n)}:{},...m.kind?{kind:m.kind}:{},durationMs:m.durationMs,error:m.error instanceof Error?m.error.message:String(m.error)})}}))}catch(f){i.push(`query capture unavailable: ${f instanceof Error?f.message:String(f)}`)}}let y=eval,t=0,d=Promise.resolve();async function u(l,c){let p=[];b=p,s=c;let f=performance.now(),m=()=>Math.round((performance.now()-f)*100)/100,S;try{S=B(l,r,`tinker-${c}`)}catch(w){let T=m();return g({type:"error",id:c,phase:"parse",error:P(w,n),diagnostics:oe(w),durationMs:T}),g({type:"done",id:c,ok:!1}),b=void 0,{id:c,ok:!1,thrown:w,frames:p,durationMs:T}}try{let T=(await y(S))?.value,h=m();return g({type:"result",id:c,value:O(T,n),durationMs:h}),g({type:"done",id:c,ok:!0}),{id:c,ok:!0,value:T,frames:p,durationMs:h}}catch(w){let T=m();if(w instanceof I)return g({type:"result",id:c,value:{t:"undefined"},durationMs:T}),g({type:"done",id:c,ok:!0}),{id:c,ok:!0,frames:p,durationMs:T};return g({type:"error",id:c,phase:"run",error:P(w,n),durationMs:T}),g({type:"done",id:c,ok:!1}),{id:c,ok:!1,thrown:w,frames:p,durationMs:T}}finally{b=void 0}}return{info:{cwd:r,booted:a,bun:Bun.version,warnings:i},models:te,evaluate(l,c={}){let p=c.id??String(++t),f=d.then(()=>u(l,p));return d=f.catch(()=>{}),f},dispose(){while(o.length)o.pop()?.()}}}var z="\x1E",me=2;function le(e){return`${z}${JSON.stringify(e)}
|
|
6
|
+
`}function Ie(){let e="",r=(n)=>{if(n.startsWith(z))try{return{frame:JSON.parse(n.slice(z.length))}}catch{return{stray:n}}return{stray:n}};return{push(n){e+=n;let i=e.split(`
|
|
7
|
+
`);return e=i.pop()??"",i.map(r)},flush(){if(!e)return[];let n=e;return e="",[{stray:n}]}}}async function L(e={}){let r=e.write??((d)=>{ue(1,d)}),n=(d)=>r(le(d)),{input:i,write:o,once:s,...b}=e,g=await v({...b,onFrame:n});n({type:"ready",session:g.info,protocol:me});let N=!0,V=!1;if(s!==void 0)return{ok:(await g.evaluate(s)).ok,session:g};let k=new TextDecoder,a="",y=i??Bun.stdin.stream(),t=async(d)=>{if(!d.trim())return!0;let u;try{u=JSON.parse(d)}catch{return n({type:"protocol-error",message:"request is not valid JSON"}),!0}if(u.op==="exit")return!1;if(u.op==="ping")return n({type:"pong",...u.id?{id:u.id}:{}}),!0;if(u.op==="models")return n({type:"models",...u.id?{id:u.id}:{},models:g.models()}),!0;if(u.op==="eval"&&typeof u.code==="string"){if(!(await g.evaluate(u.code,{id:u.id})).ok)N=!1;return!0}return n({type:"protocol-error",message:`unknown request: ${String(u.op)}`}),!0};e:for await(let d of y){a+=typeof d==="string"?d:k.decode(d,{stream:!0});let u=a.indexOf(`
|
|
8
|
+
`);while(u!==-1){let l=a.slice(0,u);if(a=a.slice(u+1),!await t(l)){V=!0;break e}u=a.indexOf(`
|
|
9
|
+
`)}}if(!V&&a.trim())await t(a);return{ok:N,session:g}}function C(e){return e?.historyFile??ke(ge(),".stacks_tinker_history")}function U(e){let r=C(e);if(!J(r))return[];return fe(r,"utf-8").split(`
|
|
10
|
+
`).filter(Boolean)}function be(e,r){let n=C(r),i=!J(n);if(de(n,`${e}
|
|
11
|
+
`),i)try{q(n,384)}catch{}let o=r?.historySize??5000,s=U(r);if(s.length>o){let b=s.slice(s.length-o);K(n,b.join(`
|
|
12
12
|
`)+`
|
|
13
|
-
`);try{q(n,384)}catch{}}}function
|
|
14
|
-
`)}function
|
|
13
|
+
`);try{q(n,384)}catch{}}}function he(e){let r=C(e);K(r,"")}function we(e){let r=["",` \x1B[36mStacks Tinker\x1B[0m (Bun v${e.bun})`,e.booted?" Your app is booted: models, jobs, config and framework helpers are globals.":" Bare session: the app context is not booted."];for(let n of e.warnings)r.push(` \x1B[33m${n}\x1B[0m`);return r.push(""," \x1B[2mDeclarations persist between lines. dump(value) inspects, dd(value) inspects and stops."," .help for commands, .exit or Ctrl+D to leave.\x1B[0m","",""),r.join(`
|
|
14
|
+
`)}function x(e,r=1){pe(r,e)}function M(e,r=""){let n=`${r} `;switch(e.t){case"undefined":return"undefined";case"null":return"null";case"boolean":return String(e.v);case"number":return String(e.v);case"bigint":return`${e.v}n`;case"string":return JSON.stringify(e.v)+(e.truncated?` ... ${e.truncated} more characters`:"");case"symbol":return`Symbol(${e.v})`;case"function":return`[${e.kind==="class"?"class":"Function"}: ${e.name}]`;case"date":return e.v??"Invalid Date";case"regexp":return e.v;case"url":return e.v;case"promise":return"Promise {}";case"bytes":return`${e.ctor}(${e.length}) <${e.hex}${e.length>64?" ...":""}>`;case"ref":return`[Circular *${e.id}]`;case"cut":return`[${e.ctor??"Object"}]`;case"error":return e.stack??`${e.name}: ${e.message}`;case"array":{if(!e.items.length&&!e.more)return`${e.ctor?`${e.ctor} `:""}[]`;let i=e.items.map((o)=>`${n}${M(o,n)}`);if(e.more)i.push(`${n}... ${e.more} more`);return`${e.ctor?`${e.ctor} `:""}[
|
|
15
15
|
${i.join(`,
|
|
16
16
|
`)}
|
|
17
|
-
${r}]`}case"set":{let i=e.items.map((
|
|
17
|
+
${r}]`}case"set":{let i=e.items.map((o)=>`${n}${M(o,n)}`);if(e.more)i.push(`${n}... ${e.more} more`);return i.length?`Set(${e.size}) {
|
|
18
18
|
${i.join(`,
|
|
19
19
|
`)}
|
|
20
|
-
${r}}`:"Set(0) {}"}case"map":{let i=e.entries.map(([s
|
|
20
|
+
${r}}`:"Set(0) {}"}case"map":{let i=e.entries.map(([o,s])=>`${n}${M(o,n)} => ${M(s,n)}`);if(e.more)i.push(`${n}... ${e.more} more`);return i.length?`Map(${e.size}) {
|
|
21
21
|
${i.join(`,
|
|
22
22
|
`)}
|
|
23
|
-
${r}}`:"Map(0) {}"}case"
|
|
23
|
+
${r}}`:"Map(0) {}"}case"html":return`[${e.kind}${e.title?` ${e.title}`:""}: ${e.html.length} characters of markup]`;case"model":{let i=e.attributes.map(([o,s])=>`${n}${o}: ${M(s,n)}`);for(let o of e.hidden??[])i.push(`${n}${o}: [hidden]`);for(let[o,s]of e.loaded??[])i.push(`${n}${o}: ${M(s,n)}`);if(e.more)i.push(`${n}... ${e.more} more`);return`${e.model} {
|
|
24
24
|
${i.join(`,
|
|
25
25
|
`)}
|
|
26
|
-
${r}}`}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
`,2);
|
|
32
|
-
`)};if(e.
|
|
33
|
-
`,2);let
|
|
26
|
+
${r}}`}case"object":{if(!e.entries.length&&!e.more)return`${e.ctor?`${e.ctor} `:""}{}`;let i=e.entries.map(([o,s])=>`${n}${o}: ${M(s,n)}`);if(e.more)i.push(`${n}... ${e.more} more`);return`${e.ctor?`${e.ctor} `:""}{
|
|
27
|
+
${i.join(`,
|
|
28
|
+
`)}
|
|
29
|
+
${r}}`}}}function Te(e,r){switch(e.type){case"stdout":x(e.text);break;case"stderr":x(e.text,2);break;case"dump":x(`${M(e.value)}
|
|
30
|
+
`);break;case"query":if(r)x(`\x1B[2m ${e.durationMs??"?"}ms ${e.sql}\x1B[0m
|
|
31
|
+
`,2);break;case"log":if(r)x(`\x1B[2m [${e.level}] ${e.message}\x1B[0m
|
|
32
|
+
`,2);break}}async function xe(e,r){let n=[];for(let i of e??[]){let o=i.replace(/[@/\-.]/g,"_").replace(/^_+/,"");try{let s=i.startsWith(".")?ye(r,i):i;globalThis[o]=await import(s)}catch(s){n.push(`${i}: ${s instanceof Error?s.message:String(s)}`)}}return n}var Se=/Unexpected end of file|Unterminated|Expected "\}" but found end of file|Expected "\)" but found end of file|Expected "\]" but found end of file/;function $e(e,r){try{return B(e,r),!1}catch(n){return(n instanceof AggregateError?n.errors.map((o)=>String(o?.message??o)):[String(n?.message??n)]).some((o)=>Se.test(o))}}async function W(e={}){let r=e.cwd??F.cwd(),n=e.stacksPreload!==!1;if(e.serve){let t=e.eval??e.print,{ok:d}=await L({cwd:r,boot:n,...t!==void 0?{once:t}:{}});return{exitCode:d?0:1}}let i=e.verbose===!0,o=await v({cwd:r,boot:n,onFrame:(t)=>Te(t,i)});for(let t of await xe(e.preload,o.info.cwd))x(`\x1B[33mpreload failed: ${t}\x1B[0m
|
|
33
|
+
`,2);let s=(t,d)=>{if(!t.ok){let u=t.thrown;x(`${u instanceof Error?Bun.inspect(u,{colors:Boolean(F.stderr.isTTY)}):`Uncaught ${Bun.inspect(u)}`}
|
|
34
|
+
`,2);return}if(d&&t.value!==void 0)x(`${M(O(t.value))}
|
|
35
|
+
`)};if(e.eval!==void 0||e.print!==void 0){for(let d of o.info.warnings)x(`\x1B[33m${d}\x1B[0m
|
|
36
|
+
`,2);let t=await o.evaluate(e.print??e.eval??"");return s(t,e.print!==void 0),o.dispose(),{exitCode:t.ok?0:1}}if(e.banner!==!1)x(we(o.info));let{createInterface:b}=await import("readline"),{Writable:g}=await import("stream"),N=new g({write(t,d,u){x(typeof t==="string"?t:Buffer.from(t).toString("utf8")),u()}}),V=e.historySize??5000,k=b({input:F.stdin,output:N,terminal:Boolean(F.stdin.isTTY),history:U(e).slice(-V).reverse(),historySize:V,prompt:"> "}),a="",y=0;k.prompt();try{for await(let t of k){let d=t.trim();if(!a&&d.startsWith(".")){if(d===".exit")break;if(d===".help")x(` .exit leave
|
|
34
37
|
.clear forget the history file
|
|
35
38
|
.help this list
|
|
36
39
|
dump(v), dd(v) inspect a value; dd also stops the line
|
|
37
|
-
`);else if(
|
|
38
|
-
`);
|
|
39
|
-
${
|
|
40
|
+
`);else if(d===".clear")he(e);else x(` unknown command ${d}
|
|
41
|
+
`);k.prompt();continue}if(a=a?`${a}
|
|
42
|
+
${t}`:t,!a.trim()){a="",k.prompt();continue}if($e(a,o.info.cwd)){k.setPrompt("... "),k.prompt();continue}let u=a;a="";try{be(u.replace(/\n/g," "),e)}catch{}let l=await o.evaluate(u);s(l,!0),y=l.ok?0:y,k.setPrompt("> "),k.prompt()}}finally{k.close(),o.dispose()}return{exitCode:y}}async function De(e,r={}){return W({...r,eval:e})}async function Le(e,r={}){return W({...r,print:e})}export{z as FRAME_MARKER,me as PROTOCOL_VERSION,A as TinkerPreview,be as appendHistory,he as clearHistory,B as compileSnippet,Ie as createFrameReader,v as createTinkerSession,Y as defaultSerializeLimits,le as encodeFrame,C as getHistoryPath,$e as isIncompleteSnippet,ee as isModelInstance,te as listModels,Q as parseStack,U as readHistory,R as relationsOf,M as renderValue,O as serialize,P as serializeThrown,L as serveTinker,W as startTinker,De as tinkerEval,Le as tinkerPrint};
|
package/dist/protocol.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { TinkerFrame, TinkerSession, TinkerSessionInfo, TinkerSessionOptions } from './session';
|
|
1
|
+
import type { TinkerFrame, TinkerModelSummary, TinkerSession, TinkerSessionInfo, TinkerSessionOptions } from './session';
|
|
2
2
|
export declare function encodeFrame(frame: TinkerWireFrame): string;
|
|
3
3
|
/**
|
|
4
4
|
* Split a chunk of a session's output into frames and stray text.
|
|
@@ -31,7 +31,7 @@ export declare function serveTinker(options?: ServeOptions): Promise<{ ok: boole
|
|
|
31
31
|
*/
|
|
32
32
|
export declare const FRAME_MARKER: '\x1E';
|
|
33
33
|
/** Bumped when a frame changes shape in a way an older reader would misread. */
|
|
34
|
-
export declare const PROTOCOL_VERSION:
|
|
34
|
+
export declare const PROTOCOL_VERSION: 2;
|
|
35
35
|
export declare interface ServeOptions extends Omit<TinkerSessionOptions, 'onFrame'> {
|
|
36
36
|
input?: AsyncIterable<Uint8Array | string>
|
|
37
37
|
write?: (text: string) => void
|
|
@@ -39,8 +39,10 @@ export declare interface ServeOptions extends Omit<TinkerSessionOptions, 'onFram
|
|
|
39
39
|
}
|
|
40
40
|
export type TinkerRequest = | { op: 'eval', id?: string, code: string }
|
|
41
41
|
| { op: 'ping', id?: string }
|
|
42
|
+
| { op: 'models', id?: string }
|
|
42
43
|
| { op: 'exit' }
|
|
43
44
|
export type TinkerWireFrame = | TinkerFrame
|
|
44
45
|
| { type: 'ready', session: TinkerSessionInfo, protocol: number }
|
|
45
46
|
| { type: 'pong', id?: string }
|
|
47
|
+
| { type: 'models', id?: string, models: TinkerModelSummary[] }
|
|
46
48
|
| { type: 'protocol-error', message: string }
|
package/dist/serialize.d.ts
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
/** Parse a V8/JavaScriptCore `at fn (file:line:col)` stack into frames. */
|
|
2
2
|
export declare function parseStack(stack: string | undefined): TinkerStackFrame[];
|
|
3
|
+
/** The relations a model definition declares, flattened. */
|
|
4
|
+
export declare function relationsOf(definition: Record<string, unknown>): Array<{ kind: string, model: string, name?: string }>;
|
|
5
|
+
/**
|
|
6
|
+
* Whether a value is a Stacks ORM model instance. Told by shape, not by
|
|
7
|
+
* class, so this package needs no dependency on the ORM and a model from any
|
|
8
|
+
* copy of it is recognised.
|
|
9
|
+
*/
|
|
10
|
+
export declare function isModelInstance(value: object): value is ModelLike;
|
|
3
11
|
export declare function serialize(root: unknown, options?: SerializeOptions): TinkerValue;
|
|
4
12
|
/** Describe anything thrown, including non-Error throws, as an error value. */
|
|
5
13
|
export declare function serializeThrown(thrown: unknown, options?: SerializeOptions): TinkerErrorValue;
|
|
@@ -41,10 +49,38 @@ export declare interface TinkerErrorValue {
|
|
|
41
49
|
cause?: TinkerValue
|
|
42
50
|
entries?: Array<[string, TinkerValue]>
|
|
43
51
|
}
|
|
52
|
+
/** An ORM model instance: what it is, its visible attributes, and what it relates to. */
|
|
53
|
+
export declare interface TinkerModelValue {
|
|
54
|
+
t: 'model'
|
|
55
|
+
id: number
|
|
56
|
+
model: string
|
|
57
|
+
table?: string
|
|
58
|
+
primaryKey?: string
|
|
59
|
+
key?: TinkerValue
|
|
60
|
+
attributes: Array<[string, TinkerValue]>
|
|
61
|
+
hidden?: string[]
|
|
62
|
+
loaded?: Array<[string, TinkerValue]>
|
|
63
|
+
relations?: Array<{ kind: string, model: string, name?: string }>
|
|
64
|
+
more?: number
|
|
65
|
+
}
|
|
66
|
+
/** Rendered markup to show as a page instead of as text: a mail, a view, any HTML. */
|
|
67
|
+
export declare interface TinkerHtmlValue {
|
|
68
|
+
t: 'html'
|
|
69
|
+
kind: 'mail' | 'view' | 'html'
|
|
70
|
+
title?: string
|
|
71
|
+
html: string
|
|
72
|
+
text?: string
|
|
73
|
+
truncated?: number
|
|
74
|
+
}
|
|
44
75
|
export declare interface SerializeOptions {
|
|
45
76
|
limits?: Partial<SerializeLimits>
|
|
46
77
|
describers?: TinkerDescriber[]
|
|
47
78
|
}
|
|
79
|
+
declare interface ModelLike {
|
|
80
|
+
_definition: { name: string, table?: string, primaryKey?: string } & Record<string, unknown>
|
|
81
|
+
toJSON: () => unknown
|
|
82
|
+
getLoadedRelations?: () => Record<string, unknown>
|
|
83
|
+
}
|
|
48
84
|
export type TinkerValue = | { t: 'undefined' }
|
|
49
85
|
| { t: 'null' }
|
|
50
86
|
| { t: 'boolean', v: boolean }
|
|
@@ -62,6 +98,8 @@ export type TinkerValue = | { t: 'undefined' }
|
|
|
62
98
|
| { t: 'object', id: number, ctor?: string, entries: Array<[string, TinkerValue]>, more?: number }
|
|
63
99
|
| { t: 'map', id: number, size: number, entries: Array<[TinkerValue, TinkerValue]>, more?: number }
|
|
64
100
|
| { t: 'set', id: number, size: number, items: TinkerValue[], more?: number }
|
|
101
|
+
| TinkerModelValue
|
|
102
|
+
| TinkerHtmlValue
|
|
65
103
|
| { t: 'ref', id: number }
|
|
66
104
|
| { t: 'cut', reason: 'depth' | 'nodes', ctor?: string }
|
|
67
105
|
| TinkerErrorValue;
|
|
@@ -74,3 +112,15 @@ export type TinkerDescriber = (
|
|
|
74
112
|
value: object,
|
|
75
113
|
describe: (value: unknown) => TinkerValue,
|
|
76
114
|
) => TinkerValue | undefined;
|
|
115
|
+
/**
|
|
116
|
+
* A value that says "show me as rendered markup". Returned by the session's
|
|
117
|
+
* `preview` helpers; a snippet can also construct one.
|
|
118
|
+
*/
|
|
119
|
+
export declare class TinkerPreview {
|
|
120
|
+
readonly kind: TinkerHtmlValue['kind'];
|
|
121
|
+
readonly html: string;
|
|
122
|
+
readonly title?: string;
|
|
123
|
+
readonly text?: string;
|
|
124
|
+
constructor(kind: TinkerHtmlValue['kind'], html: string, title?: string, text?: string);
|
|
125
|
+
}
|
|
126
|
+
export {};
|
package/dist/session.d.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
1
|
import type { SerializeOptions, TinkerErrorValue, TinkerValue } from './serialize';
|
|
2
|
+
/**
|
|
3
|
+
* The models reachable as globals in this process. After a Stacks boot that
|
|
4
|
+
* is every model the app loaded; in a bare session it is none.
|
|
5
|
+
*/
|
|
6
|
+
export declare function listModels(): TinkerModelSummary[];
|
|
2
7
|
/**
|
|
3
8
|
* Compile a snippet into JavaScript that, evaluated at global scope, runs it
|
|
4
9
|
* and yields `{ value }` for its last expression.
|
|
@@ -35,8 +40,17 @@ export declare interface TinkerEvaluation {
|
|
|
35
40
|
frames: TinkerFrame[]
|
|
36
41
|
durationMs: number
|
|
37
42
|
}
|
|
43
|
+
/** One model the app knows, as a relation graph and a completion list need it. */
|
|
44
|
+
export declare interface TinkerModelSummary {
|
|
45
|
+
name: string
|
|
46
|
+
table?: string
|
|
47
|
+
primaryKey?: string
|
|
48
|
+
attributes: string[]
|
|
49
|
+
relations: Array<{ kind: string, model: string, name?: string }>
|
|
50
|
+
}
|
|
38
51
|
export declare interface TinkerSession {
|
|
39
52
|
info: TinkerSessionInfo
|
|
53
|
+
models: () => TinkerModelSummary[]
|
|
40
54
|
evaluate: (code: string, options?: { id?: string }) => Promise<TinkerEvaluation>
|
|
41
55
|
dispose: () => void
|
|
42
56
|
}
|
package/package.json
CHANGED