ranuts 0.4.0-alpha.5 → 0.4.1-alpha.2

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.
Files changed (44) hide show
  1. package/CLAUDE.md +180 -32
  2. package/README.md +2 -0
  3. package/README.zh-CN.md +2 -0
  4. package/dist/{color-DPV7TsVU.js → color-BTvZUuf-.js} +1 -1
  5. package/dist/i18n-DW21b_DJ.js +1 -0
  6. package/dist/index.js +1 -1
  7. package/dist/src/conversation/engine.d.ts +109 -0
  8. package/dist/src/conversation/index.d.ts +12 -0
  9. package/dist/src/conversation/index.js +1 -0
  10. package/dist/src/conversation/types.d.ts +99 -0
  11. package/dist/src/node/index.js +1 -1
  12. package/dist/src/stream/accumulator.d.ts +51 -0
  13. package/dist/src/stream/budget.d.ts +89 -0
  14. package/dist/src/stream/index.d.ts +25 -0
  15. package/dist/src/stream/index.js +1 -0
  16. package/dist/src/stream/sse.d.ts +51 -0
  17. package/dist/src/stream/types.d.ts +106 -0
  18. package/dist/src/utils/binary.d.ts +33 -0
  19. package/dist/src/utils/canvas.d.ts +1 -0
  20. package/dist/src/utils/device.d.ts +8 -0
  21. package/dist/src/utils/diff.d.ts +51 -0
  22. package/dist/src/utils/i18n/index.js +1 -1
  23. package/dist/src/utils/index.d.ts +12 -7
  24. package/dist/src/utils/index.js +1 -1
  25. package/dist/src/utils/number.d.ts +20 -0
  26. package/dist/src/utils/placement.d.ts +42 -5
  27. package/dist/src/utils/scroll.d.ts +93 -0
  28. package/dist/src/utils/secure.d.ts +58 -0
  29. package/dist/src/utils/str.d.ts +75 -0
  30. package/dist/test/budget.test.d.ts +1 -0
  31. package/dist/test/conversation.test.d.ts +1 -0
  32. package/dist/test/diff.test.d.ts +1 -0
  33. package/dist/test/formatBytes.test.d.ts +1 -0
  34. package/dist/test/scroll.test.d.ts +1 -0
  35. package/dist/test/stream.test.d.ts +1 -0
  36. package/dist/test/utils/secure.test.d.ts +1 -0
  37. package/dist/test/utils/text-boundary.test.d.ts +1 -0
  38. package/dist/umd/index.umd.cjs +1 -1
  39. package/dist/umd/utils/utils.umd.cjs +1 -1
  40. package/dist/utils-B4FnyUzW.js +1 -0
  41. package/docs/API.md +94 -6
  42. package/package.json +11 -2
  43. package/dist/i18n-Bq-f7htr.js +0 -1
  44. package/dist/utils-BSvtPyGl.js +0 -1
@@ -0,0 +1 @@
1
+ var e=(e,t=2)=>String(e).padStart(t,"0"),t=e=>null==e?/* @__PURE__ */new Date:new Date(e),n=/YYYY|YY|MM|M|DD|D|HH|H|hh|h|mm|m|ss|s|SSS|A|a|\[([^[\]]*)]/g,r=(r,s="YYYY-MM-DD HH:mm:ss")=>{const a=t(r);if(Number.isNaN(a.getTime()))return"Invalid Date";const o=a.getHours(),i=o%12||12,c={YYYY:String(a.getFullYear()),YY:e(a.getFullYear()%100),MM:e(a.getMonth()+1),M:String(a.getMonth()+1),DD:e(a.getDate()),D:String(a.getDate()),HH:e(o),H:String(o),hh:e(i),h:String(i),mm:e(a.getMinutes()),m:String(a.getMinutes()),ss:e(a.getSeconds()),s:String(a.getSeconds()),SSS:e(a.getMilliseconds(),3),A:o<12?"AM":"PM",a:o<12?"am":"pm"};return s.replace(n,(e,t)=>void 0!==t?t:c[e])};function s(e){const t=e?new Date(e):/* @__PURE__ */new Date;return t.format=(e="YYYY-MM-DD HH:mm:ss")=>r(t,e),t}var a=t=>{if(!Number.isFinite(t))return"";const n=Math.max(0,Math.trunc(t)),r=Math.trunc(n/3600),s=Math.trunc(n%3600/60),a=e(n%60);return 0===r?`${e(s)}:${a}`:`${e(r)}:${e(s)}:${a}`},o=e=>a(e),i=/(?:(\d{2,}):)?(\d{2}):(\d{2})\.(\d{3})/,c=e=>{const t=e.trim().match(i);if(!t)return;const[,n,r,s,a]=t;return(n?3600*Number(n):0)+60*Number(r)+Number(s)+Number(a)/1e3},u=e=>{const[t,n]=e.split("--\x3e");if(!t||!n)return;const r=c(t),s=c(n.trim().split(/\s+/)[0]??"");return void 0!==r&&void 0!==s?{start:r,end:s}:void 0},l=[["year",315576e5],["month",26298e5],["week",6048e5],["day",864e5],["hour",36e5],["minute",6e4],["second",1e3]],d={year:"y",quarter:"q",month:"mo",week:"w",day:"d",hour:"h",minute:"m",second:"s"},f=/* @__PURE__ */new Map,h=(e,n={})=>{const{now:r,locale:s,style:a="long",numeric:o="auto"}=n,i=t(e).getTime(),c=t(r).getTime();if(Number.isNaN(i)||Number.isNaN(c))return"";const u=i-c,h=Math.abs(u);let g=l.findIndex(([,e])=>h>=e);-1===g&&(g=l.length-1);const m=u<0?-1:1;let[p,w]=l[g],y=m*Math.round(h/w);if(g>0&&Math.abs(y)*w>=l[g-1][1]&&([p,w]=l[g-1],y=m*Math.round(h/w)),"compact"===a)return`${Math.abs(y)}${d[p]??""}`;const _=((e,t,n)=>{if("undefined"==typeof Intl||"function"!=typeof Intl.RelativeTimeFormat)return;const r=`${String(e)}|${t}|${n}`;let s=f.get(r);return s||(s=new Intl.RelativeTimeFormat(e,{style:t,numeric:n}),f.set(r,s)),s})(s,a,o);if(!_){const e=d[p]??"";return y<0?`${Math.abs(y)}${e} ago`:`in ${y}${e}`}return _.format(y,p)},g=()=>{if("undefined"!=typeof document)return performance.now();if("undefined"!=typeof process){const[e,t]=process.hrtime();return 1e3*e+t/1e6}return Date.now()},m=e=>{const t=document.cookie.split("; ");for(let n=0;n<t.length;n++){const r=t[n].split("=");if(r[0]===e)return decodeURIComponent(r[1])}return""},p=(e,t)=>new Promise(function(n,r){const s=new XMLHttpRequest;s.open(t.method||"GET",e,!0),s.responseType=t.responseType||"arraybuffer",s.onload=function(){200===s.status?n({success:!0,data:s.response,message:""}):r({success:!1,data:s.status,message:`The request status is${s.status}`})},s.onerror=function(e){r({success:!1,data:e,message:""})},s.onprogress=e=>{t.onProgress&&t.onProgress(e)},s.withCredentials=t.withCredentials||!1,t.headers&&Object.keys(t.headers).forEach(function(e){t.headers?.[e]&&s.setRequestHeader(e,t.headers[e])}),s.send(t.body)}),w=e=>{const t=e.backingStorePixelRatio||e.webkitBackingStorePixelRatio||e.mozBackingStorePixelRatio||e.msBackingStorePixelRatio||e.oBackingStorePixelRatio||1;return(("undefined"==typeof window?1:window.devicePixelRatio)||1)/t},y=async e=>{if("string"==typeof e)return e;if(e instanceof Blob)return URL.createObjectURL(e);if(e instanceof ArrayBuffer)return URL.createObjectURL(new Blob([e]));if(e instanceof Response){const t=await e.blob();return URL.createObjectURL(t)}return e},_=(e=10)=>{const t=[];let n,r=0;return new Promise(s=>{const a=()=>{const o=g(),i=o-r;0!==r&&t.push(i),r=o,t.length>e&&(s(1/(t.reduce((e,t)=>e+t)/e)),cancelAnimationFrame(n)),n=requestAnimationFrame(a)};t.length<=e&&(n=requestAnimationFrame(a))})},b=e=>{const t={},n=(e=>{const t=e??("undefined"==typeof window?"":window.location.href),n=t.indexOf("?");if(-1===n)return"";const r=t.slice(n+1),s=r.indexOf("#");return-1===s?r:r.slice(0,s)})(e);if(!n)return t;for(const r of n.split("&")){if(!r)continue;const e=r.indexOf("="),n=-1===e?r:r.slice(0,e),s=-1===e?"":r.slice(e+1);if(n)try{t[decodeURIComponent(n.replace(/\+/g," "))]=decodeURIComponent(s.replace(/\+/g," "))}catch{t[n]=s}}return t},v=(e,t)=>{const n=b(t)[e];if(void 0===n)return!1;const r=n.toLowerCase();return""===r||"1"===r||"true"===r},M=()=>{if("undefined"==typeof window)return!1;try{return window.parent!==window}catch{return!0}};function S(e,t={}){let n=e;0===n.indexOf("//")&&(n=n.replace("//","https://"));const r=new URL(n);return t&&Object.keys(t).forEach(e=>{t[e]&&r.searchParams.set(e,t[e])}),r.href}function x(e){if("undefined"!=typeof window){const t=new RegExp(`(^| )${e}(?:=([^;]*))?(;|$)`).exec(document.cookie);if(t&&t[2])return t[2]}return""}var D=()=>"undefined"!=typeof window?{width:window.innerWidth,height:window.innerHeight}:{width:0,height:0},k=()=>{if("undefined"!=typeof window)return window.navigator.connection},$=/(?:[^\x21\x25\x26-\x3B\x3D\x3F-\x5B\x5D\x5F\x7E]|%(?:[^\da-f]|[\da-f][^\da-f]|$))+/gi,R=/(^|[^\uD800-\uDBFF])[\uDC00-\uDFFF]|[\uD800-\uDBFF]([^\uDC00-\uDFFF]|$)/g;function F(e){return String(e).replace(R,"$1�$2").replace($,encodeURI)}var Y=e=>new Promise((t,n)=>{const r=new Image,s=/* @__PURE__ */(new Date).getTime();r.src=e||`https://github.com/favicon.ico?d=${s}`,r.onload=()=>{t(/* @__PURE__ */(new Date).getTime()-s)},r.onerror=e=>{n(e)}}),N=(e,...t)=>n=>new Promise((r,s)=>{setTimeout(async()=>{try{r(await e(...t))}catch(n){s(n)}},n)}),O=async e=>{const{url:t,duration:n=3e3,count:r=5}=e;let s=0,a=0;const o=[];for(let i=0;i<r;i++){const e=await N(Y,t)(n);o.push(e)}return s=Math.max(...o)-Math.min(...o),a=o.reduce((e,t)=>e+t)/o.length,{ping:a,jitter:s}},L=()=>{if("undefined"!=typeof navigator)return navigator.vendor&&navigator.vendor.indexOf("Apple")>-1&&navigator.userAgent&&!navigator.userAgent.includes("CriOS")&&!navigator.userAgent.includes("FxiOS")},I=()=>{try{return"undefined"==typeof localStorage?null:localStorage}catch{return null}},P=(e,t)=>{try{I()?.setItem(e,t)}catch{}},C=e=>{try{return I()?.getItem(e)??""}catch{return""}},H=e=>{try{I()?.removeItem(e)}catch{}},A=(e="")=>{const t=t=>`${e}${t}`;return{keyOf:t,get:(e,n)=>{const r=C(t(e));if(!r)return n;try{return JSON.parse(r)}catch{return n}},set:(e,n)=>{let r;try{r=JSON.stringify(n)}catch{return!1}return P(t(e),r),C(t(e))===r},remove:e=>H(t(e))}},T=(e,t=2e4)=>{const n=e.slice(0,t);let r=0,s=0;for(const a of n){const e=a.codePointAt(0)??0;e>=19968&&e<=40959||e>=13312&&e<=19903?r++:(e>=65&&e<=90||e>=97&&e<=122)&&s++}return 0===r&&0===s?"other":r>=s?"zh":s>3*r?"en":"zh"},B=()=>{if("undefined"==typeof navigator)return"other";const e=(navigator.language||"").toLowerCase();return e.startsWith("zh")?"zh":e.startsWith("en")?"en":"other"},U=e=>{const{supported:t,query:n,cookie:r,storageKey:s,useNavigator:a=!0,url:o}=e,i=e.fallback??t[0]??"en";if(0===t.length)return i;const c=t.map(e=>e.toLowerCase()),u=e=>{if(!e)return;const n=e.trim().toLowerCase();if(!n)return;const r=c.indexOf(n);if(-1!==r)return t[r];const s=n.split("-")[0],a=c.findIndex(e=>e===s||e.split("-")[0]===s);return-1===a?void 0:t[a]},l=[];if(n&&l.push(b(o)[n]),r&&l.push(x(r)),s&&l.push(C(s)),a&&"undefined"!=typeof navigator){const{languages:e,language:t}=navigator;l.push(...e??[],t)}for(const d of l){const e=u(d);if(e)return e}return i},j=Object.freeze({}),q=class{_locale;_fallback;_messages;_persist;_storageKey;_handlers=/* @__PURE__ */new Set;constructor(e={}){this._messages={...e.messages},this._fallback=e.fallbackLocale??"en",this._persist=e.persist??!1,this._storageKey=e.storageKey??"ran-locale",this._locale=this._resolveInitialLocale(e)}_resolveInitialLocale(e){const t=Object.keys(this._messages),n=this._persist&&C(this._storageKey)||null;if(n&&(this._messages[n]||0===t.length))return n;if(e.locale)return e.locale;if(e.detectNavigator){const e=U({supported:t,useNavigator:!0,fallback:""});if(e)return e}return this._fallback}get locale(){return this._locale}getLocale(){return this._locale}setLocale(e){e!==this._locale&&(this._locale=e,this._persist&&P(this._storageKey,e),this._notify())}addMessages(e,t){this._messages[e]={...this._messages[e],...t}}getMessages(e=this._locale){return this._messages[e]??{}}get availableLocales(){return Object.keys(this._messages)}t(e,t){const n=this._messages[this._locale]?.[e]??this._messages[this._fallback]?.[e]??e;return this._interpolate(n,t)}_interpolate(e,t){const n=t??j;return e.replace(/\{\{|\}\}|\{(\w+)\}/g,(e,t)=>"{{"===e?"{":"}}"===e?"}":null!=n[t]?String(n[t]):e)}onChange(e){return this._handlers.add(e),()=>{this._handlers.delete(e)}}_notify(){for(const e of this._handlers)e(this._locale)}destroy(){this._handlers.clear()}},z=null;function E(e={}){const t=new q(e);return z=t,t}function K(){return z}export{h as A,M as C,p as D,v as E,s as F,c as M,g as N,r as O,o as P,Y as S,O as T,m as _,B as a,w as b,C as c,S as d,k as f,b as g,F as h,T as i,u as j,a as k,H as l,N as m,E as n,U as o,y as p,K as r,A as s,q as t,P as u,x as v,L as w,D as x,_ as y};
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- import{i as s}from"./enums-BAgbyGdH.js";import{$ as a,A as t,B as n,C as o,D as r,E as m,F as i,G as p,H as f,I as j,J as c,K as l,L as u,M as h,N as x,O as b,P as d,Q as e,R as g,S as k,T as v,U as w,V as y,W as C,X as D,Y as E,Z as S,_ as T,a as _,at as z,b as A,c as B,d as F,et as H,f as I,g as L,h as M,i as N,it as O,j as P,k as R,l as U,m as V,n as q,nt as G,o as J,ot as K,p as Q,q as W,r as X,rt as Y,s as Z,st as $,t as ss,tt as as,u as ts,v as ns,w as os,x as rs,y as ms,z as is}from"./color-DPV7TsVU.js";import{$ as ps,$t as fs,A as js,At as cs,B as ls,Bt as us,C as hs,Cn as xs,Ct as bs,D as ds,Dn as es,Dt as gs,E as ks,En as vs,Et as ws,F as ys,Ft as Cs,G as Ds,Gt as Es,H as Ss,Ht as Ts,I as _s,It as zs,J as As,Jt as Bs,K as Fs,Kt as Hs,L as Is,Lt as Ls,M as Ms,Mt as Ns,N as Os,Nt as Ps,O as Rs,On as Us,Ot as Vs,P as qs,Pt as Gs,Q as Js,Qt as Ks,R as Qs,Rt as Ws,S as Xs,Sn as Ys,St as Zs,T as $s,Tn as sa,Tt as aa,U as ta,Ut as na,V as oa,Vt as ra,W as ma,Wt as ia,X as pa,Xt as fa,Y as ja,Yt as ca,Z as la,Zt as ua,_ as ha,_n as xa,_t as ba,a as da,an as ea,at as ga,b as ka,bn as va,bt as wa,c as ya,cn as Ca,ct as Da,d as Ea,dn as Sa,dt as Ta,en as _a,et as za,f as Aa,fn as Ba,ft as Fa,g as Ha,gn as Ia,gt as La,h as Ma,hn as Na,ht as Oa,i as Pa,in as Ra,it as Ua,j as Va,jt as qa,k as Ga,kn as Ja,kt as Ka,l as Qa,ln as Wa,lt as Xa,m as Ya,mn as Za,mt as $a,n as st,nn as at,nt as tt,o as nt,on as ot,ot as rt,p as mt,pn as it,pt,q as ft,qt as jt,r as ct,rn as lt,rt as ut,s as ht,sn as xt,st as bt,t as dt,tn as et,tt as gt,u as kt,un as vt,ut as wt,v as yt,vn as Ct,vt as Dt,w as Et,wn as St,wt as Tt,x as _t,xn as zt,xt as At,y as Bt,yn as Ft,yt as Ht,z as It,zt as Lt}from"./utils-BSvtPyGl.js";import{A as Mt,B as Nt,C as Ot,D as Pt,E as Rt,F as Ut,H as Vt,I as qt,L as Gt,M as Jt,N as Kt,P as Qt,R as Wt,S as Xt,T as Yt,U as Zt,V as $t,_ as sn,a as an,b as tn,c as nn,d as on,f as rn,g as mn,h as pn,i as fn,j as jn,k as cn,l as ln,m as un,n as hn,o as xn,p as bn,r as dn,s as en,t as gn,u as kn,v as vn,w as wn,x as yn,y as Cn,z as Dn}from"./i18n-Bq-f7htr.js";import{n as En,t as Sn}from"./chain-CTywmh_H.js";export{ga as ADOPTED_SHEET_MARKER,rt as ADOPTED_STYLE_MARKER,na as AudioRecorder,at as BRIDGE_MARKER,lt as BridgeManager,Sn as Chain,Ra as Client,ss as Color,q as ColorScheme,ea as DEFAULT_CHANNEL,Vs as EventManager,X as FMT,N as HEX_COLOR_REGEX,_ as Hsl,J as Hsla,gn as I18nCore,cn as MOBILE_MEDIA_QUERY,Za as Mathjs,l as MessageCodec,f as MimeType,nt as Monitor,ot as Platform,xt as PostMessageBridge,ct as QuestQueue,Z as RGBA_REGEX,B as RGB_REGEX,U as Rgb,ts as Rgba,s as SyncHook,us as TOTP,Et as TimeoutError,ut as WebDB,_s as WorkerClient,Ma as ZIP_DEFLATE,Ha as ZIP_STORED,Ca as acceptPortBridge,qa as addClassToElement,Na as addNumSym,bt as adoptSheetText,Da as adoptStyles,on as appendUrl,W as arrayBufferToString,Ns as autosizeTextarea,Qs as base64ToBytes,F as blendMultiply,I as blendOverlay,Q as blendScreen,Wa as bridgeManager,V as brightnessContrast,za as buildOffsets,It as bytesToBase64,c as checkEncoding,At as circ,Ia as clamp,E as clearBr,D as clearStr,ia as cloneDeep,M as componentToHex,Lt as compose,la as computePlacement,rn as connection,Xa as convertImageToBase64,L as cosinePalette,ha as crc32,En as create,kt as createData,Ps as createDocumentFragment,Ka as createDoubleTapDetector,Ua as createHandoff,hn as createI18n,Js as createLocalePath,bn as createObjectURL,vt as createPortBridge,$s as createRaceGuard,ra as createSignal,Ba as createSpeechRecognizer,en as createStore,yt as createZip,Zs as cubic,Mt as currentDevice,wt as cutRound,Ls as debounce,ls as decodeTextBytes,ks as deferred,ds as delay,fn as detectLanguage,un as durationHandler,pn as encodeUrl,Gs as escapeHtml,bs as expo,Oa as fanShapedByArc,oa as fetchMaybeGzip,Es as filterObj,xa as fit,qt as formatDate,Gt as formatDuration,Hs as formatJson,Wt as formatRelative,mn as getAllQueryString,La as getAngle,ba as getArcPointerByDeg,sn as getCookie,vn as getCookieByName,w as getExtensions,Cn as getFrame,Ta as getImage,Dt as getLinearGradient,S as getMatchingSentences,Fa as getMatrix,C as getMime,Ya as getPerformance,tn as getPixelRatio,e as getRandomString,Ea as getReportUrl,Pa as getStatus,Ht as getTangentByPointer,yn as getWindow,Ss as gunzipMaybe,Ws as handleConsole,cs as handleError,ya as handleFetchHook,Qa as handleXhrHook,T as hexToAlpha,ns as hexToHsb,ms as hexToHsv,A as hexToRgb,rs as hsbToHsl,k as hsbToRgb,o as hslToHsb,os as hslToHsv,v as hslToRgb,m as hsvToHsl,r as hsvToRgb,b as hue2rgb,Xt as imageRequest,gt as indexForOffset,Bt as inflateRaw,Ct as inverseLerp,jn as isClient,jt as isEqual,ta as isGzip,ma as isHtmlDocument,pt as isImageSize,Ot as isInIframe,Jt as isMobile,wn as isSafari,it as isSpeechRecognitionSupported,a as isString,js as isUrlCached,Kt as isWeiXin,Ds as isZipContainer,Ft as lerp,R as linearToSrgb,va as linearstep,dt as loadScript,nn as localStorageGetItem,ln as localStorageRemoveItem,kn as localStorageSetItem,t as luma,Qt as matchMediaQuery,zt as mathjs,H as md5,fs as memoize,Bs as merge,ca as mergeExports,an as navigatorLanguage,Va as networkAllowsDownload,Yt as networkSpeed,Ks as noop,_a as once,$a as opacity,Sa as openPortBridge,ps as paginateText,Ys as parseChineseNumber,xs as parseEnglishNumber,St as parseRomanNumber,Dn as parseVttCueTiming,Nt as parseVttTimestamp,sa as perToNum,$t as performanceTime,Ms as prefetchUrl,Os as prefetchUrls,qs as prefetchWhenIdle,Tt as quad,aa as quart,Rt as queryFlag,fa as querystring,ws as quint,P as randomColor,as as randomString,vs as range,ft as readFileAsArrayBuffer,As as readFileAsDataURL,ja as readFileAsText,pa as readFileAsUint8Array,ka as readZipEntries,_t as readZipEntry,es as remap,Cs as removeClassToElement,ua as replaceOld,Aa as report,Pt as requestUrlToBuffer,xn as resolveLocale,Xs as rewriteZip,h as rgbToHex,x as rgbToHsb,d as rgbToHsl,i as rgbToHsv,j as rgbaString,u as rgbaToHex,g as rgbaToRgb,wa as roundRectByArc,is as saturation,Fs as saveFileToDisk,st as scriptOnLoad,tt as segmentByRanges,Is as serveWorker,zs as setFontSize2html,p as setMime,mt as setReportUrl,gs as sine,et as singleFlight,Us as smoothstep,n as srgbToLinear,da as status,G as strParse,Ts as subscribers,ht as throttle,Vt as timeFormat,Zt as timestampToTime,Y as toFullWidth,O as toHalfWidth,z as toString,Ja as transformNumber,K as transformText,$ as truncate,dn as useI18n,y as vibrance,Ut as watchMediaQuery,ys as whenIdle,Rs as withTimeout,Ga as withTimeoutFallback,hs as zipHasEntry};
1
+ import{$ as s,$t as a,A as t,An as n,At as o,B as r,Bn as m,Bt as i,C as p,Cn as f,Ct as j,D as c,Dn as l,Dt as u,E as d,En as h,Et as x,F as b,Fn as e,Ft as g,G as k,Gn as v,Gt as w,H as y,Hn as A,Ht as C,I as D,In as E,It as F,J as M,Jt as N,K as O,Kn as P,Kt as S,L as T,Ln as _,Lt as q,M as z,Mn as B,Mt as G,N as H,Nn as I,Nt as K,O as L,On as R,Ot as U,P as V,Pn as W,Pt as J,Q,Qt as X,R as Y,Rn as Z,Rt as $,S as ss,Sn as as,St as ts,T as ns,Tn as os,Tt as rs,U as ms,Un as is,Ut as ps,V as fs,Vn as js,Vt as cs,W as ls,Wn as us,Wt as ds,X as hs,Xt as xs,Y as bs,Yt as es,Z as gs,Zt as ks,_ as vs,_n as ws,_t as ys,a as As,an as Cs,at as Ds,b as Es,bn as Fs,bt as Ms,c as Ns,cn as Os,ct as Ps,d as Ss,dn as Ts,dt as _s,en as qs,et as zs,f as Bs,fn as Gs,ft as Hs,g as Is,gn as Ks,gt as Ls,h as Rs,hn as Us,ht as Vs,i as Ws,in as Js,it as Qs,j as Xs,jn as Ys,jt as Zs,k as $s,kn as sa,kt as aa,l as ta,ln as na,lt as oa,m as ra,mn as ma,mt as ia,n as pa,nn as fa,nt as ja,o as ca,on as la,ot as ua,p as da,pn as ha,pt as xa,q as ba,qn as ea,qt as ga,r as ka,rn as va,rt as wa,s as ya,sn as Aa,st as Ca,t as Da,tn as Ea,tt as Fa,u as Ma,un as Na,ut as Oa,v as Pa,vn as Sa,vt as Ta,w as _a,wn as qa,wt as za,x as Ba,xn as Ga,xt as Ha,y as Ia,yn as Ka,yt as La,z as Ra,zn as Ua,zt as Va}from"./utils-B4FnyUzW.js";import{i as Wa}from"./enums-BAgbyGdH.js";import{$ as Ja,A as Qa,B as Xa,C as Ya,D as Za,E as $a,F as st,G as at,H as tt,I as nt,J as ot,K as rt,L as mt,M as it,N as pt,O as ft,P as jt,Q as ct,R as lt,S as ut,T as dt,U as ht,V as xt,W as bt,X as et,Y as gt,Z as kt,_ as vt,a as wt,at as yt,b as At,c as Ct,ct as Dt,d as Et,dt as Ft,et as Mt,f as Nt,g as Ot,h as Pt,i as St,it as Tt,j as _t,k as qt,l as zt,lt as Bt,m as Gt,n as Ht,nt as It,o as Kt,ot as Lt,p as Rt,q as Ut,r as Vt,rt as Wt,s as Jt,st as Qt,t as Xt,tt as Yt,u as Zt,ut as $t,v as sn,w as an,x as tn,y as nn,z as on}from"./color-BTvZUuf-.js";import{A as rn,C as mn,D as pn,E as fn,F as jn,M as cn,N as ln,O as un,P as dn,S as hn,T as xn,_ as bn,a as en,b as gn,c as kn,d as vn,f as wn,g as yn,h as An,i as Cn,j as Dn,k as En,l as Fn,m as Mn,n as Nn,o as On,p as Pn,r as Sn,s as Tn,t as _n,u as qn,v as zn,w as Bn,x as Gn,y as Hn}from"./i18n-DW21b_DJ.js";import{n as In,t as Kn}from"./chain-CTywmh_H.js";export{xa as ADOPTED_SHEET_MARKER,ia as ADOPTED_STYLE_MARKER,Js as AudioRecorder,ws as BRIDGE_MARKER,Sa as BridgeManager,Kn as Chain,Ka as Client,Xt as Color,Ht as ColorScheme,Fs as DEFAULT_CHANNEL,F as EventManager,Vt as FMT,St as HEX_COLOR_REGEX,wt as Hsl,Kt as Hsla,_n as I18nCore,w as MOBILE_MEDIA_QUERY,sa as Mathjs,rt as MessageCodec,tt as MimeType,ca as Monitor,Ga as Platform,as as PostMessageBridge,ka as QuestQueue,Jt as RGBA_REGEX,Ct as RGB_REGEX,zt as Rgb,Zt as Rgba,Wa as SyncHook,Ea as TOTP,_a as TimeoutError,Y as UNAMBIGUOUS_ALPHABET,_s as WebDB,D as WorkerClient,Rs as ZIP_DEFLATE,Is as ZIP_STORED,f as acceptPortBridge,Va as addClassToElement,n as addNumSym,Vs as adoptSheetText,Ls as adoptStyles,Qs as alignCrossAxis,vn as appendUrl,Ut as arrayBufferToString,i as autosizeTextarea,y as base64ToBytes,ms as base64UrlToBytes,Et as blendMultiply,Nt as blendOverlay,Rt as blendScreen,qa as bridgeManager,Gt as brightnessContrast,Ps as buildOffsets,ls as bytesToBase64,k as bytesToBase64Url,ot as checkEncoding,aa as circ,Ys as clamp,gt as clearBr,et as clearStr,Cs as cloneDeep,Pt as componentToHex,qs as compose,Ds as computePlacement,O as concatBytes,wn as connection,ys as convertImageToBase64,Ot as cosinePalette,vs as crc32,In as create,ea as createBottomFollower,Ma as createData,cs as createDocumentFragment,q as createDoubleTapDetector,Hs as createHandoff,Nn as createI18n,ua as createLocalePath,Pn as createObjectURL,os as createPortBridge,ns as createRaceGuard,fa as createSignal,l as createSpeechRecognizer,Tn as createStore,Pa as createZip,kt as csvEscape,o as cubic,S as currentDevice,Ta as cutRound,X as debounce,ba as decodeTextBytes,d as deferred,c as delay,Cn as detectLanguage,P as diffLines,Mn as durationHandler,An as encodeUrl,C as escapeHtml,Zs as expo,j as fanShapedByArc,ct as fenceCode,M as fetchMaybeGzip,la as filterObj,B as fit,I as formatBytes,un as formatDate,En as formatDuration,Aa as formatJson,rn as formatRelative,yn as getAllQueryString,za as getAngle,rs as getArcPointerByDeg,bn as getCookie,zn as getCookieByName,ht as getExtensions,Hn as getFrame,La as getImage,x as getLinearGradient,Ja as getMatchingSentences,Ms as getMatrix,bt as getMime,ra as getPerformance,gn as getPixelRatio,Mt as getRandomString,Ss as getReportUrl,Ws as getStatus,u as getTangentByPointer,Gn as getWindow,bs as gunzipMaybe,a as handleConsole,$ as handleError,Ns as handleFetchHook,ta as handleXhrHook,vt as hexToAlpha,sn as hexToHsb,nn as hexToHsv,At as hexToRgb,tn as hsbToHsl,ut as hsbToRgb,Ya as hslToHsb,an as hslToHsv,dt as hslToRgb,$a as hsvToHsl,Za as hsvToRgb,ft as hue2rgb,hn as imageRequest,oa as indexForOffset,Ia as inflateRaw,W as inverseLerp,ga as isClient,Os as isEqual,hs as isGzip,gs as isHtmlDocument,Ha as isImageSize,mn as isInIframe,N as isMobile,Bn as isSafari,R as isSpeechRecognitionSupported,Yt as isString,t as isUrlCached,es as isWeiXin,Q as isZipContainer,e as lerp,qt as linearToSrgb,E as linearstep,Da as loadScript,kn as localStorageGetItem,Fn as localStorageRemoveItem,qn as localStorageSetItem,Qa as luma,xs as matchMediaQuery,_ as mathjs,It as md5,ma as memoize,na as merge,Na as mergeExports,en as navigatorLanguage,Xs as networkAllowsDownload,xn as networkSpeed,ha as noop,Us as once,ts as opacity,h as openPortBridge,Ca as paginateText,Z as parseChineseNumber,Ua as parseEnglishNumber,m as parseRomanNumber,Dn as parseVttCueTiming,cn as parseVttTimestamp,js as perToNum,ln as performanceTime,z as prefetchUrl,H as prefetchUrls,V as prefetchWhenIdle,G as quad,K as quart,fn as queryFlag,Ts as querystring,J as quint,_t as randomColor,Wt as randomString,A as range,zs as readFileAsArrayBuffer,Fa as readFileAsDataURL,ja as readFileAsText,wa as readFileAsUint8Array,Es as readZipEntries,Ba as readZipEntry,is as remap,ps as removeClassToElement,Gs as replaceOld,Bs as report,pn as requestUrlToBuffer,On as resolveLocale,ss as rewriteZip,it as rgbToHex,pt as rgbToHsb,jt as rgbToHsl,st as rgbToHsv,nt as rgbaString,mt as rgbaToHex,lt as rgbaToRgb,U as roundRectByArc,Ra as safeEqual,on as saturation,s as saveFileToDisk,pa as scriptOnLoad,r as secureRandomString,fs as secureToken,Oa as segmentByRanges,T as serveWorker,ds as setFontSize2html,at as setMime,da as setReportUrl,g as sine,Ks as singleFlight,Tt as slugify,us as smoothstep,Xa as srgbToLinear,As as status,yt as strParse,va as subscribers,ya as throttle,dn as timeFormat,jn as timestampToTime,Lt as toFullWidth,Qt as toHalfWidth,Dt as toString,v as transformNumber,Bt as transformText,$t as truncate,Ft as truncateWithMarker,Sn as useI18n,xt as vibrance,ks as watchMediaQuery,b as whenIdle,L as withTimeout,$s as withTimeoutFallback,p as zipHasEntry};
@@ -0,0 +1,109 @@
1
+ /**
2
+ * The engine that runs {@link ConversationNodeDefinition}s over an event log.
3
+ */
4
+ import type { ConversationNode, ConversationNodeDefinition } from './types.ts';
5
+ /** Defers work to the next paint, or to a microtask where there is no paint. */
6
+ export type FrameScheduler = (run: () => void) => () => void;
7
+ /** How to construct an engine. */
8
+ export interface ConversationEngineOptions<Event> {
9
+ /**
10
+ * The registered definitions. Every event is offered to all of them, so two definitions
11
+ * may both claim one event — that is how a single log event can drive, say, both a
12
+ * message node and a separate status node.
13
+ *
14
+ * Declared over `unknown` state so definitions with different state types register side
15
+ * by side; a concrete `ConversationNodeDefinition<Event, MyState>` assigns here without
16
+ * a cast, and its own methods stay fully typed at the definition site.
17
+ */
18
+ definitions: readonly ConversationNodeDefinition<Event, unknown>[];
19
+ /** Overrides frame scheduling; supply a manual one to make cadence deterministic in tests. */
20
+ scheduler?: FrameScheduler;
21
+ }
22
+ /** A running conversation projection. */
23
+ export interface ConversationEngine<Event> {
24
+ /**
25
+ * Offers one event to every definition and notifies subscribers per the resulting
26
+ * cadence.
27
+ *
28
+ * @param event The event to project.
29
+ */
30
+ push(event: Event): void;
31
+ /**
32
+ * Runs a burst of pushes as one publication.
33
+ *
34
+ * Without it, replaying a stored conversation is quadratic: every event publishes, every
35
+ * publication hands subscribers the whole node list, and a DOM subscriber walks all of it
36
+ * — so restoring n messages costs O(n²) row visits, each re-writing content that has not
37
+ * changed. Measured on a 600-message transcript that was 5.4 seconds of blocked main
38
+ * thread; the same replay batched is one pass.
39
+ *
40
+ * The cadence of the single publication is the highest any event in the burst asked for,
41
+ * which is the same escalation rule that applies within one event. A burst that accepted
42
+ * nothing publishes nothing.
43
+ *
44
+ * Nesting is flat: an inner batch joins the outer one rather than publishing early.
45
+ *
46
+ * @param run The pushes to run.
47
+ */
48
+ batch(run: () => void): void;
49
+ /** @returns The current nodes, ordered by the event that started each one. */
50
+ nodes(): readonly ConversationNode[];
51
+ /**
52
+ * Registers a subscriber.
53
+ *
54
+ * @param listener Called with the current nodes whenever a publication lands, and with
55
+ * the keys whose state changed since the previous publication. A subscriber that writes
56
+ * to the DOM should touch only those: on a long transcript the node list is mostly
57
+ * unchanged every frame, and rewriting all of it once per delta is the difference
58
+ * between a transcript that streams and one that stalls. `undefined` means every node
59
+ * changed, which is what a reset reports.
60
+ * @returns A function that removes the subscriber.
61
+ */
62
+ subscribe(listener: (nodes: readonly ConversationNode[], changed: ReadonlySet<string> | undefined) => void): () => void;
63
+ /**
64
+ * Drops one node and every node started after it.
65
+ *
66
+ * This is what editing, regenerating, and branching are made of: all three mean "the
67
+ * conversation diverges here", and what follows the divergence is no longer part of it.
68
+ * Without this the only way back is {@link ConversationEngine.reset} and a full replay,
69
+ * which throws away every node that did not change and makes the view flash.
70
+ *
71
+ * Ordering is by `seq` — when a node opened — not by position, so a node that has been
72
+ * updating since before the cut survives even though its latest update came after it.
73
+ * That is the same rule the node order itself follows.
74
+ *
75
+ * @param key The `kind:id` of the first node to drop.
76
+ * @returns How many nodes were dropped. Zero means the key names no live node, which is
77
+ * a caller's cue that its own idea of the conversation is stale — silently dropping
78
+ * nothing would leave the old tail on screen under freshly pushed events.
79
+ */
80
+ truncate(key: string): number;
81
+ /** Drops every node and pending publication, keeping the definitions. */
82
+ reset(): void;
83
+ /** Cancels any pending publication and drops subscribers. */
84
+ destroy(): void;
85
+ }
86
+ /**
87
+ * Creates an engine over a set of definitions.
88
+ *
89
+ * Semantics worth knowing before writing a definition:
90
+ *
91
+ * - **Every definition sees every event.** Claims are independent; the engine never stops
92
+ * at the first match.
93
+ * - **An `update` claim for an id with no open node is dropped.** That is the honest
94
+ * outcome when the start event was never seen — trimmed from a paged window, or emitted
95
+ * before the definition was registered — and inventing a node from a partial update
96
+ * would render something that never existed.
97
+ * - **Order is fixed at `start`.** A node that keeps updating stays where it opened, so a
98
+ * streaming message does not jump to the end of the list on every delta.
99
+ * - **Cadence escalates, never relaxes.** An `immediate` publication while a frame is
100
+ * pending fires now and cancels the frame; an `animation-frame` publication while one is
101
+ * already pending joins it.
102
+ * - **`truncate` cuts by `seq`, not by position.** A node that opened before the cut
103
+ * survives even if its most recent update came after it — the same rule node order
104
+ * follows, so what a reader sees above the cut is exactly what stays.
105
+ *
106
+ * @param options Definitions and optional scheduler.
107
+ * @returns The engine.
108
+ */
109
+ export declare function createConversationEngine<Event>(options: ConversationEngineOptions<Event>): ConversationEngine<Event>;
@@ -0,0 +1,12 @@
1
+ /**
2
+ * `ranuts/conversation` — project an append-only event log into renderable nodes.
3
+ *
4
+ * Pairs with `ranuts/stream`, which produces the events, and with `createBottomFollower`
5
+ * from `ranuts/utils`, which keeps the resulting view pinned to its floor. No DOM here:
6
+ * the projection is testable, and server-renderable, on its own.
7
+ *
8
+ * @module ranuts/conversation
9
+ */
10
+ export type { ConversationMatch, ConversationNode, ConversationNodeDefinition, ConversationPublication, ConversationReader, } from './types.ts';
11
+ export type { ConversationEngine, ConversationEngineOptions, FrameScheduler } from './engine.ts';
12
+ export { createConversationEngine } from './engine.ts';
@@ -0,0 +1 @@
1
+ var e=e=>{if("function"==typeof requestAnimationFrame){const n=requestAnimationFrame(e);return()=>cancelAnimationFrame(n)}let n=!1;return queueMicrotask(()=>{n||e()}),()=>{n=!0}};function n(n){const{definitions:t,scheduler:i=e}=n,o=/* @__PURE__ */new Set;for(const e of t){if(o.has(e.kind))throw new Error(`conversation: duplicate definition kind "${e.kind}"`);o.add(e.kind)}let r=[];const a=/* @__PURE__ */new Map,l=/* @__PURE__ */new Set;let s=/* @__PURE__ */new Set,d=0,u=null,c=0,f="none",m=null;const k=()=>(m??=r.map(e=>Object.freeze({...e})),m),h=()=>{const e=k(),n=null===s?void 0:new Set(s);s=/* @__PURE__ */new Set;for(const t of[...l])t(e,n)},p=e=>{if("none"!==e){if(!(c>0))return"immediate"===e?(u?.(),u=null,void h()):void(null===u&&(u=i(()=>{u=null,h()})));"immediate"===e?f="immediate":"none"===f&&(f="animation-frame")}},q={previous(e){for(let n=r.length-1;n>=0;n-=1)if(r[n].kind===e)return Object.freeze({...r[n]})}};return{push(e){let n="none";for(const i of t){const t=i.match(e);if(null===t)continue;const o=`${i.kind}:${t.id}`,l=a.get(o);if("start"===t.role){const n={key:o,kind:i.kind,id:t.id,seq:l?.seq??(d+=1),state:i.start(e,q)};void 0===l?r.push(n):r[r.indexOf(l)]=n,a.set(o,n)}else{if(void 0===l)continue;l.state=i.update(l.state,e)}m=null,s?.add(o);const u=i.publication?.(e)??"immediate";"immediate"===u?n="immediate":"animation-frame"===u&&"none"===n&&(n="animation-frame")}p(n)},truncate(e){const n=a.get(e);if(void 0===n)return 0;const t=r.filter(e=>e.seq<n.seq),i=r.length-t.length;for(const o of r)o.seq>=n.seq&&a.delete(o.key);return r=t,m=null,p("immediate"),i},batch(e){c+=1;try{e()}finally{if(c-=1,0===c){const e=f;f="none",p(e)}}},nodes:k,subscribe:e=>(l.add(e),()=>{l.delete(e)}),reset(){r=[],a.clear(),d=0,m=null,s=null,p("immediate")},destroy(){u?.(),u=null,l.clear()}}}export{n as createConversationEngine};
@@ -0,0 +1,99 @@
1
+ /**
2
+ * Vocabulary for turning an append-only event log into the nodes a conversation view
3
+ * renders.
4
+ *
5
+ * The alternative — a view that switches on event type and mutates a component tree — puts
6
+ * ordering, identity, and partial-update reconciliation in the view, where every new kind
7
+ * of content has to be threaded through by hand. Here each kind of content is an
8
+ * independently registered state machine: it says which events are its own, folds them
9
+ * into its own state, and never learns that the others exist. Adding a kind is adding a
10
+ * definition, not editing a renderer.
11
+ *
12
+ * @module ranuts/conversation
13
+ */
14
+ /** A definition's claim on one event. */
15
+ export interface ConversationMatch {
16
+ /**
17
+ * Identity of the node this event belongs to, unique within the definition's `kind`.
18
+ * The same id across events is what makes an update an update.
19
+ */
20
+ id: string;
21
+ /** `start` opens a node; `update` folds into the one already open under `id`. */
22
+ role: 'start' | 'update';
23
+ }
24
+ /**
25
+ * When subscribers should see the result of one accepted event.
26
+ *
27
+ * This is the throttle for streaming. A text delta arriving per token wants
28
+ * `animation-frame`, which coalesces every delta between two paints into one
29
+ * notification; a discrete fact — a tool result, an approval — wants `immediate`, because
30
+ * it is one event and waiting a frame only adds latency. `none` records the event without
31
+ * waking the view at all, for state a later publication will carry anyway.
32
+ */
33
+ export type ConversationPublication = 'none' | 'animation-frame' | 'immediate';
34
+ /** One live node, as a view sees it. */
35
+ export interface ConversationNode<State = unknown> {
36
+ /** `kind:id` — stable for the node's whole life, and unique across definitions. */
37
+ readonly key: string;
38
+ readonly kind: string;
39
+ readonly id: string;
40
+ /**
41
+ * Ordinal of the event that started this node. Nodes are ordered by it, so a node that
42
+ * updates for a long time — a streaming message — keeps its place instead of jumping to
43
+ * the end on every delta.
44
+ */
45
+ readonly seq: number;
46
+ readonly state: State;
47
+ }
48
+ /** Strictly-backward lookup offered to a definition while it starts a node. */
49
+ export interface ConversationReader {
50
+ /**
51
+ * Finds the most recently started node of `kind` that already exists.
52
+ *
53
+ * Backward only, and deliberately: a definition that could see nodes started after it
54
+ * would produce a different result depending on when it ran, and replaying the same log
55
+ * would not reproduce the same view.
56
+ *
57
+ * @param kind The definition kind to look for.
58
+ * @returns The nearest preceding node, or undefined when none is open.
59
+ */
60
+ previous<State>(kind: string): ConversationNode<State> | undefined;
61
+ }
62
+ /** One independently registered event-to-node state machine. */
63
+ export interface ConversationNodeDefinition<Event, State> {
64
+ /** Namespace for this definition's node ids. Must be unique in one engine. */
65
+ readonly kind: string;
66
+ /**
67
+ * Decides whether this event is this definition's business.
68
+ *
69
+ * Runs against the raw event with no access to engine state, so it stays a pure
70
+ * classification and cannot depend on what has been rendered so far.
71
+ *
72
+ * @param event The event being offered.
73
+ * @returns The claim, or null to ignore the event.
74
+ */
75
+ match(event: Event): ConversationMatch | null;
76
+ /**
77
+ * Builds the initial state for a newly opened node.
78
+ *
79
+ * @param event The event that started it.
80
+ * @param reader Backward lookup over nodes already open.
81
+ * @returns The node's initial state.
82
+ */
83
+ start(event: Event, reader: ConversationReader): State;
84
+ /**
85
+ * Folds one further event into an open node.
86
+ *
87
+ * @param state The node's current state.
88
+ * @param event The event being folded in.
89
+ * @returns The node's next state.
90
+ */
91
+ update(state: State, event: Event): State;
92
+ /**
93
+ * Chooses when subscribers see this event's result. Defaults to `immediate`.
94
+ *
95
+ * @param event The accepted event.
96
+ * @returns The requested cadence.
97
+ */
98
+ publication?(event: Event): ConversationPublication;
99
+ }
@@ -1 +1 @@
1
- import{G as e,W as t,nt as n,r}from"../../color-DPV7TsVU.js";import{Socket as o}from"node:net";import s from"node:http";import i from"node:os";import a,{createReadStream as c,createWriteStream as d,readdir as l,readdirSync as u,stat as f,statSync as h}from"node:fs";import p from"node:tty";import m,{hrtime as w}from"node:process";import g from"node:child_process";import y from"node:readline";import b from"node:https";import E,{join as v,resolve as x}from"node:path";import{promisify as T}from"node:util";import{Buffer as S}from"node:buffer";import O from"node:crypto";function P(){const e=i.networkInterfaces();for(const t in e){const n=e[t];if(n)for(let e=0;e<n.length;e++){const t=n[e];if("IPv4"===t.family&&"127.0.0.1"!==t.address&&!t.internal)return t.address}}}var q=class{middleware;ctx;constructor(){const e=new s.IncomingMessage(new o),t=new s.ServerResponse(e);this.ctx={ipv4:P,req:e,res:t},this.middleware=[]}use(e){if(!e)throw new Error("the use function has an incorrect argument");this.middleware.push(e)}listen(...e){const t=function(e){if(!Array.isArray(e))throw new TypeError("Middleware stack must be an array!");for(const t of e)if("function"!=typeof t)throw new TypeError("Middleware must be composed of functions!");return function(t,n){let r=-1;function o(s){if(s<=r)return Promise.reject(/* @__PURE__ */new Error("next() called multiple times"));r=s;let i=e[s];if(s===e.length&&n&&(i=n),!i)return Promise.resolve();try{return Promise.resolve(i(t,o.bind(null,s+1)))}catch(a){return Promise.reject(a)}}return o(0)}}(this.middleware);return s.createServer((e,n)=>{this.ctx.req=e,this.ctx.res=n,t(this.ctx).catch(C)}).listen(...e)}};function C(e){console.error(e.stack||e.toString())}var H=a,M=(e,t="utf-8")=>{const n=new AbortController,r=n.signal,o=new Promise((o,s)=>{H.readFile(e,{encoding:t,signal:r},(e,t)=>{e?(n.abort(),s({success:!1,_identification:!1,data:e})):o({success:!0,_identification:!0,data:t})})});return o.abort=n.abort,o},_=(e,t)=>new Promise((n,r)=>{H.appendFile(e,t,t=>{t?r({success:!1,_identification:!1,data:t}):M(e).then(e=>{n(e)})})}),F=m?.env&&!("NO_COLOR"in m.env||m.argv.includes("--no-color"))&&("FORCE_COLOR"in m.env||m.argv.includes("--color")||"win32"===m.platform||p.isatty(1)&&"dumb"!==m.env.TERM||"CI"in m.env),U=(e,t,n=e)=>r=>{const o=""+r,s=o.indexOf(t,e.length);return~s?e+j(o,t,n,s)+t:e+o+t},j=(e,t,n,r)=>{const o=e.substring(0,r)+n,s=e.substring(r+t.length),i=s.indexOf(t);return~i?o+j(s,t,n,i):o+s},k=Object.assign({},((e=F)=>{const t={};return Object.keys(r).forEach(n=>t[n]=e?U(r[n][0],r[n][1]):String),t})(),((e=F)=>({isColorSupported:e,reset:e?e=>`${r.reset[0]}${e}${r.reset[1]}`:String,bold:e?U(r.bold[0],r.bold[1],`${r.bold[1]}${r.bold[0]}`):String,dim:e?U(r.dim[0],r.dim[1],`${r.dim[1]}${r.dim[0]}`):String}))()),$=(e={})=>{const{uploadDir:t=".",encoding:r="",json:o=!0}=e;return(e,s)=>{const{req:i,res:c}=e,{url:d,method:l}=i,[u="",f=""]=d?.split("?")||[],h=f?new URLSearchParams(f):{};e.request||(e.request={}),e.request.method=l,e.request.path=u,e.request.url=d,e.request.query=h;const p=i.headers["content-type"];if("application/json"===p){r?i.setEncoding(r):i.setEncoding("utf-8");let t="";i.on("data",e=>{t+=e}),i.on("end",()=>{c.setHeader("content-type","application/json;charset=UTF-8");try{e.request.body=o?JSON.parse(t):t}catch{e.request.body=t}s()})}if(p?.includes("multipart/form-data;")){const[e,o]=i.headers["content-type"]?.split(";").map(e=>e.trim())||[],[d,l]=o.split("=");r?i.setEncoding(r):i.setEncoding("binary");let u="";i.on("data",e=>{u+=e}),i.on("end",()=>{const e={};u.split("\r\n").slice(0,4).forEach(t=>{Object.assign(e,n(t,";",/=|:/))});const r=e["Content-Type"],o=Buffer.from(e.filename,"latin1").toString("utf8"),i=u.indexOf(r)+r.length,d=u.substring(i).replace(/^\s+/,""),f=d.substring(0,d.indexOf(`--${l}--`));a.writeFile(`${t}/${o}`,f,{encoding:"binary"},e=>{if(e)throw e;c.setHeader("content-type","application/json;charset=UTF-8"),s()})})}}},I=(e,t)=>new Promise((n,r)=>{const o=g.spawn(e,t,{stdio:"inherit",shell:!1});o.on("error",e=>r(e)),o.on("exit",e=>0===e?n():r(/* @__PURE__ */new Error(`Command exited with code ${e}`)))}),A=({message:e,stream:t=process.stderr,defaultResponse:n="Y"})=>{const r=y.createInterface({input:process.stdin,output:t});return new Promise(t=>{r.question(`${e} `,e=>{r.close();const o=(e||n).toLowerCase();t("y"===o||"yes"===o)})})},B=()=>{};function D(e,t,n){return t(e.req,e.res,B),n()}function L(e,t,n){return new Promise((r,o)=>{t(e.req,e.res,e=>{e?o(e):r(n())})})}function R(e){const t=e.length<3?D:L;return function(n,r){return t(n,e,r)}}var N=e=>new Promise((t,n)=>{H.stat(e,(e,r)=>{e?n({success:!1,_identification:!1,data:e}):t({success:!0,_identification:!0,data:r})})}),K=({url:e})=>new Promise((t,n)=>{b.get(e,e=>{const n=[];e.on("data",e=>{n.push(e)}),e.on("end",()=>{const{data:e=[]}=JSON.parse(Buffer.concat(n).toString());e.forEach(e=>{}),t({success:!0,data:e,message:"request success"})})}).on("error",e=>{e.message,n({success:!1,data:e,message:e.message})})}),W=()=>{const e=i.networkInterfaces();for(const t in e){const n=e[t];for(let e=0;e<n.length;e++){const t=n[e];if("IPv4"===t.family&&"127.0.0.1"!==t.address&&!t.internal)return t.address}}};function z(e){const t=e.url;if(void 0===t)return;let n=e._parsedUrl;if(n&&n._raw===t)return n;n={},n.query=n.search=void 0,n.href=n.path=n.pathname=t;const r=t.indexOf("?",1);return-1!==r&&(n.search=t.substring(r),n.query=n.search.substring(1),n.pathname=t.substring(0,r)),n._raw=t,e._parsedUrl=n}var G=e=>{const{dirPath:t}=e;try{return H.readdirSync(t)}catch(n){throw n}},J=class{ctx;map;methods;paths;constructor(){this.map=/* @__PURE__ */new Map,this.methods=/* @__PURE__ */new Set,this.paths=/* @__PURE__ */new Set}get(e,t){this.addHandlerToMap("GET")(e,t)}post(e,t){this.addHandlerToMap("POST")(e,t)}put(e,t){this.addHandlerToMap("PUT")(e,t)}patch(e,t){this.addHandlerToMap("PATCH")(e,t)}del(e,t){this.addHandlerToMap("DELETE")(e,t)}head(e,t){this.addHandlerToMap("HEAD")(e,t)}options(e,t){this.addHandlerToMap("OPTIONS")(e,t)}addHandlerToMap(e){return this.methods.add(e),(t,n)=>{this.paths.add(t);let r=this.map.get(e);r||(r=/* @__PURE__ */new Map,this.map.set(e,r)),r.set(t,n)}}routes(){return(e,t)=>{this.ctx=e;const{path:n,method:r}=e.request,o=this.map.get(r),s=o?o.get(n):t;s&&s(e,t)}}allowedMethods(){return e=>{const{res:t}=e,{path:n,method:r}=e.request;!this.methods.has(r)&&this.paths.has(n)&&(t.statusCode=405,t.end("405, method is not allowed")),this.methods.has(r)&&!this.paths.has(n)&&(t.statusCode=404,t.end("404, the request address does not exist")),this.methods.has(r)||this.paths.has(n)||(t.statusCode=501,t.end("501, not support the functionality needed to satisfy the request"))}}},Y=(n={})=>{const{pathname:r,fileTypes:o={}}=n;return async(n,s)=>{try{const{req:i,res:c}=n;if(i.url){const n="text/html",s=r||process.cwd(),d=E.normalize(E.resolve(s)),l=E.extname(i.url).slice(1);Object.keys(o).forEach(t=>e(t,o[t]));const u=l?t(l):n;if(!Boolean(u))return c.writeHead(404,{"Content-Type":"text/html"}),void c.end("404: File not found");let f=i.url;if("/"===i.url)f="index.html";else if(!l)try{a.accessSync(E.join(d,i.url+".html"),a.constants.F_OK),f=i.url+".html"}catch{f=E.join(i.url,"index.html")}const h=E.join(d,f);if(!E.normalize(E.resolve(h)).startsWith(d))return c.writeHead(404,{"Content-Type":"text/html"}),void c.end("404: File not found");a.readFile(h,(e,t)=>{e?(c.writeHead(404,{"Content-Type":"text/html"}),c.end("404: File not found")):(c.writeHead(200,{"Content-Type":u}),c.end(t))})}await s()}catch{}}},Q=()=>{if("undefined"!=typeof window){const e=window.performance.now();return Symbol.for(`${e}`)}if("undefined"!=typeof process){const e=w.bigint();return Symbol.for(`${e}`)}return Symbol.for(`${Date.now()}`)},V=e=>{const{path:t}=e;if(t)return c(t);throw new Error("path is not defined")},X=e=>{const{path:t}=e;if(t)return d(t);throw new Error("path is not defined")},Z=e=>{const t=Symbol.keyFor(e);return"undefined"!=typeof window&&t?window.performance.now()-Number(t):"undefined"!=typeof process&&t?w.bigint()-BigInt(t):Date.now()-Number(t)},ee=T(f),te=T(l);async function ne(e,t,n=""){e=x(".",e);const r=await te(e);await Promise.all(r.map(async r=>{const o=v(e,r),s=await ee(o);return s.isDirectory()?ne(o,t,v(n,r)):t(v(n,r),o,s)}))}function re(e,t,n=""){e=x(".",e);const r=u(e);let o,s,i=0;for(;i<r.length;i++)o=v(e,r[i]),s=h(o),s.isDirectory()?re(o,t,v(n,r[i])):t(v(n,r[i]),o,s)}var oe=(e,t=20)=>new Promise(n=>{H.watchFile(e,{interval:t},(t,r)=>{t.mtime!==r.mtime?(H.unwatchFile(e),n({success:!0,_identification:!0,data:{},message:"file is changed"})):n({success:!1,_identification:!1,data:{},message:"file is not changed"})})});function se(e,t){const n=S.byteLength(e);let r=null;if(n>65535?(r=S.alloc(10+n),r[1]=127,r.writeUInt32BE(n,6),r.write(e,10)):n>125?(r=S.alloc(4+n),r[1]=126,r.writeUInt16BE(n,2),r.write(e,4)):(r=S.alloc(2+n),r[1]=n,r.write(e,2)),t){const e=t.opcode;e&&e<15&&e>=0&&(r[0]=128|e)}else r[0]=129;return r}function ie(e,t){if(!t)return e;const n=S.from(e);for(let r=0;r<n.length;++r)n[r]=n[r]^t[r%4];return n}function ae(){const e={};this.on=(t,n)=>{e[t]?e[t].push(n):e[t]=[n]},this.off=(t,n)=>{const r=e[t],o=r.indexOf(n);r&&-1!==o&&r.splice(o,1)},this.emit=(t,n)=>{e[t]&&e[t].forEach(e=>e(n))}}function ce(e){ae.call(this);const t=[];this.server=e,this.clients=t,this.broadcast=e=>{t.forEach(t=>{t.send(e)})},e.on("upgrade",(e,n)=>{n.write(["HTTP/1.1 101 Switching Protocols","Upgrade: websocket","Connection: Upgrade","Sec-WebSocket-Accept: "+O.createHash("sha1").update(e.headers["sec-websocket-key"]+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest("base64")].join("\n")+"\n\n");const r={send(e,t){n.write(se(e,t))},ping(){n.write(se("",{opcode:9}))},pong(){n.write(se("",{opcode:10}))},close(){if(-1===t.indexOf(r))return!1;t.splice(t.indexOf(r),1),n.write(se("",{opcode:8})),r.emit("close"),n.destroy()},socket:n};ae.call(r),this.emit("connect",r),t.push(r);let o=S.allocUnsafe(0),s=S.allocUnsafe(0);const i=[];let a=!0;function c(){const e=function(e){const t=S.from(e),n=127&t[1];let r=0,o=0;const s=t[1]>=128;return 127===n?(r=t.readUInt32BE(6),o=10):126===n?(r=t.readUInt16BE(2),o=4):(r=n,o=2),{fin:t[0]>=128,opcode:15&t[0],mask:s,maskKey:s?t.subarray(o,o+(s?4:0)):null,len7:n,len:r,lenMeta:o+(s?4:0)}}(o);i.push({l:e.lenMeta,f:()=>{a=!1,i.push({l:e.len,f:t=>{if(s=S.concat([s,ie(t,e.maskKey)]),a=!0,e.fin){if(8===e.opcode)return r.close();if(9===e.opcode)return r.pong();r.emit("message",s),s=S.allocUnsafe(0)}}})}})}n.on("data",e=>{for(o=S.concat([o,e]),a&&c();i[0]&&o.byteLength>=i[0].l;){const e=i[0].l;i[0].f(o.subarray(0,e)),o=o.subarray(e),i.splice(0,1)}}),n.on("end",()=>{r.close()}),n.on("error",e=>{r.emit("error",e),r.close()})})}var de=(e,t)=>new Promise((n,r)=>{H.writeFile(e,t,{mode:438,flag:"w+",encoding:"utf-8"},o=>{if(o)throw r({success:!1,_identification:!1,data:o}),o;n({success:!0,_identification:!1,data:{path:e,content:t}})})});export{J as Router,q as Server,ce as WSS,_ as appendFile,$ as body,k as colors,R as connect,K as get,W as getIPAdress,F as isColorSupported,z as paresUrl,A as prompt,N as queryFileInfo,G as readDir,M as readFile,V as readStream,I as runCommand,Q as startTask,Y as staticMiddleware,Z as taskEnd,ne as traverse,re as traverseSync,oe as watchFile,de as writeFile,X as writeStream};
1
+ import{G as e,W as t,at as n,r}from"../../color-BTvZUuf-.js";import{Socket as o}from"node:net";import s from"node:http";import i from"node:os";import a,{createReadStream as c,createWriteStream as d,readdir as l,readdirSync as u,stat as f,statSync as h}from"node:fs";import p from"node:tty";import m,{hrtime as w}from"node:process";import g from"node:child_process";import y from"node:readline";import b from"node:https";import E,{join as v,resolve as x}from"node:path";import{promisify as T}from"node:util";import{Buffer as S}from"node:buffer";import O from"node:crypto";function P(){const e=i.networkInterfaces();for(const t in e){const n=e[t];if(n)for(let e=0;e<n.length;e++){const t=n[e];if("IPv4"===t.family&&"127.0.0.1"!==t.address&&!t.internal)return t.address}}}var q=class{middleware;ctx;constructor(){const e=new s.IncomingMessage(new o),t=new s.ServerResponse(e);this.ctx={ipv4:P,req:e,res:t},this.middleware=[]}use(e){if(!e)throw new Error("the use function has an incorrect argument");this.middleware.push(e)}listen(...e){const t=function(e){if(!Array.isArray(e))throw new TypeError("Middleware stack must be an array!");for(const t of e)if("function"!=typeof t)throw new TypeError("Middleware must be composed of functions!");return function(t,n){let r=-1;function o(s){if(s<=r)return Promise.reject(/* @__PURE__ */new Error("next() called multiple times"));r=s;let i=e[s];if(s===e.length&&n&&(i=n),!i)return Promise.resolve();try{return Promise.resolve(i(t,o.bind(null,s+1)))}catch(a){return Promise.reject(a)}}return o(0)}}(this.middleware);return s.createServer((e,n)=>{this.ctx.req=e,this.ctx.res=n,t(this.ctx).catch(C)}).listen(...e)}};function C(e){console.error(e.stack||e.toString())}var H=a,M=(e,t="utf-8")=>{const n=new AbortController,r=n.signal,o=new Promise((o,s)=>{H.readFile(e,{encoding:t,signal:r},(e,t)=>{e?(n.abort(),s({success:!1,_identification:!1,data:e})):o({success:!0,_identification:!0,data:t})})});return o.abort=n.abort,o},_=(e,t)=>new Promise((n,r)=>{H.appendFile(e,t,t=>{t?r({success:!1,_identification:!1,data:t}):M(e).then(e=>{n(e)})})}),F=m?.env&&!("NO_COLOR"in m.env||m.argv.includes("--no-color"))&&("FORCE_COLOR"in m.env||m.argv.includes("--color")||"win32"===m.platform||p.isatty(1)&&"dumb"!==m.env.TERM||"CI"in m.env),U=(e,t,n=e)=>r=>{const o=""+r,s=o.indexOf(t,e.length);return~s?e+j(o,t,n,s)+t:e+o+t},j=(e,t,n,r)=>{const o=e.substring(0,r)+n,s=e.substring(r+t.length),i=s.indexOf(t);return~i?o+j(s,t,n,i):o+s},k=Object.assign({},((e=F)=>{const t={};return Object.keys(r).forEach(n=>t[n]=e?U(r[n][0],r[n][1]):String),t})(),((e=F)=>({isColorSupported:e,reset:e?e=>`${r.reset[0]}${e}${r.reset[1]}`:String,bold:e?U(r.bold[0],r.bold[1],`${r.bold[1]}${r.bold[0]}`):String,dim:e?U(r.dim[0],r.dim[1],`${r.dim[1]}${r.dim[0]}`):String}))()),$=(e={})=>{const{uploadDir:t=".",encoding:r="",json:o=!0}=e;return(e,s)=>{const{req:i,res:c}=e,{url:d,method:l}=i,[u="",f=""]=d?.split("?")||[],h=f?new URLSearchParams(f):{};e.request||(e.request={}),e.request.method=l,e.request.path=u,e.request.url=d,e.request.query=h;const p=i.headers["content-type"];if("application/json"===p){r?i.setEncoding(r):i.setEncoding("utf-8");let t="";i.on("data",e=>{t+=e}),i.on("end",()=>{c.setHeader("content-type","application/json;charset=UTF-8");try{e.request.body=o?JSON.parse(t):t}catch{e.request.body=t}s()})}if(p?.includes("multipart/form-data;")){const[e,o]=i.headers["content-type"]?.split(";").map(e=>e.trim())||[],[d,l]=o.split("=");r?i.setEncoding(r):i.setEncoding("binary");let u="";i.on("data",e=>{u+=e}),i.on("end",()=>{const e={};u.split("\r\n").slice(0,4).forEach(t=>{Object.assign(e,n(t,";",/=|:/))});const r=e["Content-Type"],o=Buffer.from(e.filename,"latin1").toString("utf8"),i=u.indexOf(r)+r.length,d=u.substring(i).replace(/^\s+/,""),f=d.substring(0,d.indexOf(`--${l}--`));a.writeFile(`${t}/${o}`,f,{encoding:"binary"},e=>{if(e)throw e;c.setHeader("content-type","application/json;charset=UTF-8"),s()})})}}},I=(e,t)=>new Promise((n,r)=>{const o=g.spawn(e,t,{stdio:"inherit",shell:!1});o.on("error",e=>r(e)),o.on("exit",e=>0===e?n():r(/* @__PURE__ */new Error(`Command exited with code ${e}`)))}),A=({message:e,stream:t=process.stderr,defaultResponse:n="Y"})=>{const r=y.createInterface({input:process.stdin,output:t});return new Promise(t=>{r.question(`${e} `,e=>{r.close();const o=(e||n).toLowerCase();t("y"===o||"yes"===o)})})},B=()=>{};function D(e,t,n){return t(e.req,e.res,B),n()}function L(e,t,n){return new Promise((r,o)=>{t(e.req,e.res,e=>{e?o(e):r(n())})})}function R(e){const t=e.length<3?D:L;return function(n,r){return t(n,e,r)}}var N=e=>new Promise((t,n)=>{H.stat(e,(e,r)=>{e?n({success:!1,_identification:!1,data:e}):t({success:!0,_identification:!0,data:r})})}),K=({url:e})=>new Promise((t,n)=>{b.get(e,e=>{const n=[];e.on("data",e=>{n.push(e)}),e.on("end",()=>{const{data:e=[]}=JSON.parse(Buffer.concat(n).toString());e.forEach(e=>{}),t({success:!0,data:e,message:"request success"})})}).on("error",e=>{e.message,n({success:!1,data:e,message:e.message})})}),W=()=>{const e=i.networkInterfaces();for(const t in e){const n=e[t];for(let e=0;e<n.length;e++){const t=n[e];if("IPv4"===t.family&&"127.0.0.1"!==t.address&&!t.internal)return t.address}}};function z(e){const t=e.url;if(void 0===t)return;let n=e._parsedUrl;if(n&&n._raw===t)return n;n={},n.query=n.search=void 0,n.href=n.path=n.pathname=t;const r=t.indexOf("?",1);return-1!==r&&(n.search=t.substring(r),n.query=n.search.substring(1),n.pathname=t.substring(0,r)),n._raw=t,e._parsedUrl=n}var G=e=>{const{dirPath:t}=e;try{return H.readdirSync(t)}catch(n){throw n}},J=class{ctx;map;methods;paths;constructor(){this.map=/* @__PURE__ */new Map,this.methods=/* @__PURE__ */new Set,this.paths=/* @__PURE__ */new Set}get(e,t){this.addHandlerToMap("GET")(e,t)}post(e,t){this.addHandlerToMap("POST")(e,t)}put(e,t){this.addHandlerToMap("PUT")(e,t)}patch(e,t){this.addHandlerToMap("PATCH")(e,t)}del(e,t){this.addHandlerToMap("DELETE")(e,t)}head(e,t){this.addHandlerToMap("HEAD")(e,t)}options(e,t){this.addHandlerToMap("OPTIONS")(e,t)}addHandlerToMap(e){return this.methods.add(e),(t,n)=>{this.paths.add(t);let r=this.map.get(e);r||(r=/* @__PURE__ */new Map,this.map.set(e,r)),r.set(t,n)}}routes(){return(e,t)=>{this.ctx=e;const{path:n,method:r}=e.request,o=this.map.get(r),s=o?o.get(n):t;s&&s(e,t)}}allowedMethods(){return e=>{const{res:t}=e,{path:n,method:r}=e.request;!this.methods.has(r)&&this.paths.has(n)&&(t.statusCode=405,t.end("405, method is not allowed")),this.methods.has(r)&&!this.paths.has(n)&&(t.statusCode=404,t.end("404, the request address does not exist")),this.methods.has(r)||this.paths.has(n)||(t.statusCode=501,t.end("501, not support the functionality needed to satisfy the request"))}}},Y=(n={})=>{const{pathname:r,fileTypes:o={}}=n;return async(n,s)=>{try{const{req:i,res:c}=n;if(i.url){const n="text/html",s=r||process.cwd(),d=E.normalize(E.resolve(s)),l=E.extname(i.url).slice(1);Object.keys(o).forEach(t=>e(t,o[t]));const u=l?t(l):n;if(!Boolean(u))return c.writeHead(404,{"Content-Type":"text/html"}),void c.end("404: File not found");let f=i.url;if("/"===i.url)f="index.html";else if(!l)try{a.accessSync(E.join(d,i.url+".html"),a.constants.F_OK),f=i.url+".html"}catch{f=E.join(i.url,"index.html")}const h=E.join(d,f);if(!E.normalize(E.resolve(h)).startsWith(d))return c.writeHead(404,{"Content-Type":"text/html"}),void c.end("404: File not found");a.readFile(h,(e,t)=>{e?(c.writeHead(404,{"Content-Type":"text/html"}),c.end("404: File not found")):(c.writeHead(200,{"Content-Type":u}),c.end(t))})}await s()}catch{}}},Q=()=>{if("undefined"!=typeof window){const e=window.performance.now();return Symbol.for(`${e}`)}if("undefined"!=typeof process){const e=w.bigint();return Symbol.for(`${e}`)}return Symbol.for(`${Date.now()}`)},V=e=>{const{path:t}=e;if(t)return c(t);throw new Error("path is not defined")},X=e=>{const{path:t}=e;if(t)return d(t);throw new Error("path is not defined")},Z=e=>{const t=Symbol.keyFor(e);return"undefined"!=typeof window&&t?window.performance.now()-Number(t):"undefined"!=typeof process&&t?w.bigint()-BigInt(t):Date.now()-Number(t)},ee=T(f),te=T(l);async function ne(e,t,n=""){e=x(".",e);const r=await te(e);await Promise.all(r.map(async r=>{const o=v(e,r),s=await ee(o);return s.isDirectory()?ne(o,t,v(n,r)):t(v(n,r),o,s)}))}function re(e,t,n=""){e=x(".",e);const r=u(e);let o,s,i=0;for(;i<r.length;i++)o=v(e,r[i]),s=h(o),s.isDirectory()?re(o,t,v(n,r[i])):t(v(n,r[i]),o,s)}var oe=(e,t=20)=>new Promise(n=>{H.watchFile(e,{interval:t},(t,r)=>{t.mtime!==r.mtime?(H.unwatchFile(e),n({success:!0,_identification:!0,data:{},message:"file is changed"})):n({success:!1,_identification:!1,data:{},message:"file is not changed"})})});function se(e,t){const n=S.byteLength(e);let r=null;if(n>65535?(r=S.alloc(10+n),r[1]=127,r.writeUInt32BE(n,6),r.write(e,10)):n>125?(r=S.alloc(4+n),r[1]=126,r.writeUInt16BE(n,2),r.write(e,4)):(r=S.alloc(2+n),r[1]=n,r.write(e,2)),t){const e=t.opcode;e&&e<15&&e>=0&&(r[0]=128|e)}else r[0]=129;return r}function ie(e,t){if(!t)return e;const n=S.from(e);for(let r=0;r<n.length;++r)n[r]=n[r]^t[r%4];return n}function ae(){const e={};this.on=(t,n)=>{e[t]?e[t].push(n):e[t]=[n]},this.off=(t,n)=>{const r=e[t],o=r.indexOf(n);r&&-1!==o&&r.splice(o,1)},this.emit=(t,n)=>{e[t]&&e[t].forEach(e=>e(n))}}function ce(e){ae.call(this);const t=[];this.server=e,this.clients=t,this.broadcast=e=>{t.forEach(t=>{t.send(e)})},e.on("upgrade",(e,n)=>{n.write(["HTTP/1.1 101 Switching Protocols","Upgrade: websocket","Connection: Upgrade","Sec-WebSocket-Accept: "+O.createHash("sha1").update(e.headers["sec-websocket-key"]+"258EAFA5-E914-47DA-95CA-C5AB0DC85B11").digest("base64")].join("\n")+"\n\n");const r={send(e,t){n.write(se(e,t))},ping(){n.write(se("",{opcode:9}))},pong(){n.write(se("",{opcode:10}))},close(){if(-1===t.indexOf(r))return!1;t.splice(t.indexOf(r),1),n.write(se("",{opcode:8})),r.emit("close"),n.destroy()},socket:n};ae.call(r),this.emit("connect",r),t.push(r);let o=S.allocUnsafe(0),s=S.allocUnsafe(0);const i=[];let a=!0;function c(){const e=function(e){const t=S.from(e),n=127&t[1];let r=0,o=0;const s=t[1]>=128;return 127===n?(r=t.readUInt32BE(6),o=10):126===n?(r=t.readUInt16BE(2),o=4):(r=n,o=2),{fin:t[0]>=128,opcode:15&t[0],mask:s,maskKey:s?t.subarray(o,o+(s?4:0)):null,len7:n,len:r,lenMeta:o+(s?4:0)}}(o);i.push({l:e.lenMeta,f:()=>{a=!1,i.push({l:e.len,f:t=>{if(s=S.concat([s,ie(t,e.maskKey)]),a=!0,e.fin){if(8===e.opcode)return r.close();if(9===e.opcode)return r.pong();r.emit("message",s),s=S.allocUnsafe(0)}}})}})}n.on("data",e=>{for(o=S.concat([o,e]),a&&c();i[0]&&o.byteLength>=i[0].l;){const e=i[0].l;i[0].f(o.subarray(0,e)),o=o.subarray(e),i.splice(0,1)}}),n.on("end",()=>{r.close()}),n.on("error",e=>{r.emit("error",e),r.close()})})}var de=(e,t)=>new Promise((n,r)=>{H.writeFile(e,t,{mode:438,flag:"w+",encoding:"utf-8"},o=>{if(o)throw r({success:!1,_identification:!1,data:o}),o;n({success:!0,_identification:!1,data:{path:e,content:t}})})});export{J as Router,q as Server,ce as WSS,_ as appendFile,$ as body,k as colors,R as connect,K as get,W as getIPAdress,F as isColorSupported,z as paresUrl,A as prompt,N as queryFileInfo,G as readDir,M as readFile,V as readStream,I as runCommand,Q as startTask,Y as staticMiddleware,Z as taskEnd,ne as traverse,re as traverseSync,oe as watchFile,de as writeFile,X as writeStream};
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Folds a {@link StreamChunk} sequence into the blocks it describes.
3
+ *
4
+ * A renderer wants "the current text", not "every delta since the start", and rebuilding
5
+ * that by concatenating in the view is where streaming UIs leak: the view ends up owning
6
+ * ordering, interleaving, and the block-end/delta reconciliation. This owns all three, so
7
+ * a view reads a snapshot and renders it.
8
+ */
9
+ import type { ContentBlock, FinishReason, StreamChunk, TokenUsage } from './types.ts';
10
+ /** Immutable view of everything received so far. */
11
+ export interface StreamSnapshot {
12
+ /** Completed and in-progress blocks, in `index` order. */
13
+ readonly blocks: readonly ContentBlock[];
14
+ /** Latest usage report, once one has arrived. */
15
+ readonly usage: TokenUsage | undefined;
16
+ /** Terminal reason, once `finish` has arrived. */
17
+ readonly finishReason: FinishReason | undefined;
18
+ /** True once `finish` has arrived. */
19
+ readonly done: boolean;
20
+ }
21
+ /** Stateful fold over one response's chunks. */
22
+ export interface StreamAccumulator {
23
+ /**
24
+ * Applies one chunk.
25
+ *
26
+ * A delta for an unseen `index` opens its block, because several providers omit
27
+ * `block-start` entirely. A `block-end` replaces whatever was accumulated at that index:
28
+ * the assembled block the provider sent is authoritative.
29
+ *
30
+ * @param chunk The chunk to fold in.
31
+ */
32
+ push(chunk: StreamChunk): void;
33
+ /** @returns An immutable view of the current state. */
34
+ snapshot(): StreamSnapshot;
35
+ /** @returns Every text block concatenated, in index order. */
36
+ text(): string;
37
+ /** @returns Every reasoning block concatenated, in index order. */
38
+ reasoning(): string;
39
+ /** @returns Completed tool calls, in index order. */
40
+ toolCalls(): readonly Extract<ContentBlock, {
41
+ type: 'tool-call';
42
+ }>[];
43
+ /** Discards all state so the instance can fold another response. */
44
+ reset(): void;
45
+ }
46
+ /**
47
+ * Creates a fold over one streamed response.
48
+ *
49
+ * @returns A fresh accumulator with no state.
50
+ */
51
+ export declare function createStreamAccumulator(): StreamAccumulator;
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Counting what a conversation costs, and deciding what to drop when it stops fitting.
3
+ *
4
+ * A chat client that never does this works for a week and then stops working: every turn
5
+ * carries the whole history, so the request grows monotonically until the provider refuses
6
+ * it. The refusal arrives as a wall — the conversation someone was having simply stops.
7
+ *
8
+ * Two pieces, deliberately separate:
9
+ *
10
+ * - **{@link estimateTokens}** answers "how big is this text" without a tokenizer. It is an
11
+ * estimate and named as one. A real tokenizer is a per-model dependency measured in
12
+ * megabytes, and this is used to decide *when to act*, not to bill anyone.
13
+ * - **{@link planCompaction}** answers "what has to go" given sizes and a ceiling. It knows
14
+ * nothing about messages, models, or summaries — it takes a list of sizes and returns how
15
+ * many leading entries no longer fit. What replaces them is the caller's business.
16
+ *
17
+ * @module ranuts/stream
18
+ */
19
+ import type { TokenUsage } from './types.ts';
20
+ /**
21
+ * Estimates how many tokens a string costs.
22
+ *
23
+ * Deliberately not a tokenizer. Every model's is different, shipping one is megabytes, and
24
+ * the number is used to decide when to compact rather than to charge anyone. It is
25
+ * calibrated to be roughly right per script rather than exactly right for one model.
26
+ *
27
+ * @param text The text to measure.
28
+ * @returns An estimated token count, never below one for a non-empty string.
29
+ */
30
+ export declare function estimateTokens(text: string): number;
31
+ /**
32
+ * Adds two usage reports.
33
+ *
34
+ * Every field is optional and providers differ in which they send, so an absent field on
35
+ * either side is zero rather than a reason to drop the field: a running total that lost
36
+ * `outputTokens` the moment one response omitted it would be worse than no total.
37
+ *
38
+ * @param total The running total.
39
+ * @param next The report to add.
40
+ * @returns A new total.
41
+ */
42
+ export declare function addUsage(total: TokenUsage | undefined, next: TokenUsage | undefined): TokenUsage;
43
+ /** What a compaction has to fit under, and what it may not touch. */
44
+ export interface CompactionLimits {
45
+ /** Token ceiling the next request must fit under, including everything the caller adds. */
46
+ limit: number;
47
+ /**
48
+ * How many trailing entries are never compacted.
49
+ *
50
+ * The recent turns are what the conversation is currently about; summarizing them is how
51
+ * a client starts answering the wrong question. Zero is legal and means the caller
52
+ * accepts that.
53
+ */
54
+ keepRecent: number;
55
+ /**
56
+ * Estimated size of whatever replaces the compacted entries.
57
+ *
58
+ * Required, not defaulted: a summary is not free, and a plan that assumed it was can
59
+ * return "this fits" for a request that does not.
60
+ */
61
+ summaryTokens: number;
62
+ }
63
+ /** What to do with a history that has grown. */
64
+ export interface CompactionPlan {
65
+ /** How many leading entries to replace with one summary; zero means nothing to do. */
66
+ compact: number;
67
+ /** Estimated tokens the request will cost once the plan is applied. */
68
+ projected: number;
69
+ /**
70
+ * Whether {@link CompactionPlan.projected} is under the limit.
71
+ *
72
+ * False means the kept entries alone exceed it — a single message longer than the whole
73
+ * context window, most often. The caller has to decide, and there is nothing this
74
+ * function can silently do that would not lose the user's own words.
75
+ */
76
+ fits: boolean;
77
+ }
78
+ /**
79
+ * Decides how much of a history no longer fits.
80
+ *
81
+ * Leading entries only. A conversation is a sequence, and dropping from the middle leaves
82
+ * the model reading an exchange with a hole in it; dropping from the front is what a summary
83
+ * can stand in for.
84
+ *
85
+ * @param sizes Estimated tokens per entry, in conversation order.
86
+ * @param limits The ceiling, the protected tail, and the summary's own cost.
87
+ * @returns How many leading entries to compact, and whether the result fits.
88
+ */
89
+ export declare function planCompaction(sizes: readonly number[], limits: CompactionLimits): CompactionPlan;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * `ranuts/stream` — streaming model responses, without a vendor.
3
+ *
4
+ * Three layers, each usable alone:
5
+ *
6
+ * 1. {@link parseEventStream} turns bytes into Server-Sent Events. Transport only.
7
+ * 2. {@link StreamChunk} is the provider-neutral vocabulary one response streams in.
8
+ * 3. {@link createStreamAccumulator} folds those chunks into renderable blocks.
9
+ * 4. {@link estimateTokens} and {@link planCompaction} decide when a history stops fitting.
10
+ *
11
+ * Mapping a vendor's event onto {@link StreamChunk} stays with the caller — that mapping
12
+ * is the only vendor-specific part, and baking one provider's wire format in here would
13
+ * make the other two layers unusable for anyone else. {@link mapEventStream} is the seam.
14
+ *
15
+ * Runtime: browser and node. No DOM — a stream can be folded in a test or on a server.
16
+ *
17
+ * @module ranuts/stream
18
+ */
19
+ export type { ContentBlock, ContentBlockType, FinishReason, ReasoningBlock, StreamChunk, TextBlock, TokenUsage, ToolCallBlock, } from './types.ts';
20
+ export type { ByteSource, ServerSentEvent } from './sse.ts';
21
+ export { mapEventStream, parseEventStream } from './sse.ts';
22
+ export type { StreamAccumulator, StreamSnapshot } from './accumulator.ts';
23
+ export { createStreamAccumulator } from './accumulator.ts';
24
+ export type { CompactionLimits, CompactionPlan } from './budget.ts';
25
+ export { addUsage, estimateTokens, planCompaction } from './budget.ts';
@@ -0,0 +1 @@
1
+ function e(e){const t=[];let n,o,i;for(const r of e.split("\n")){if(""===r||r.startsWith(":"))continue;const e=r.indexOf(":"),s=-1===e?r:r.slice(0,e);let c=-1===e?"":r.slice(e+1);c.startsWith(" ")&&(c=c.slice(1)),"data"===s?t.push(c):"event"===s?n=c:"id"!==s||c.includes("\0")?"retry"===s&&/^\d+$/.test(c)&&(i=Number(c)):o=c}if(0===t.length&&void 0===n&&void 0===o&&void 0===i)return null;const s={data:t.join("\n")};return void 0!==n&&(s.event=n),void 0!==o&&(s.id=o),void 0!==i&&(s.retry=i),s}async function*t(t){const n=new TextDecoder;let o="",i=!1;for await(const r of async function*(e){if("function"==typeof e[Symbol.asyncIterator])return void(yield*e);const t=e.getReader();try{for(;;){const{done:e,value:n}=await t.read();if(e)return;void 0!==n&&(yield n)}}finally{t.releaseLock()}}(t)){o+=n.decode(r,{stream:!0}),o=o.replace(/\r\n?/g,"\n"),i||(o.startsWith("\ufeff")&&(o=o.slice(1)),i=!0);let t=o.indexOf("\n\n");for(;-1!==t;){const n=o.slice(0,t);o=o.slice(t+2);const i=e(n);null!==i&&(yield i),t=o.indexOf("\n\n")}}o+=n.decode();const s=e(o.replace(/\r\n?/g,"\n"));null!==s&&(yield s)}async function*n(e,n){for await(const o of t(e))yield*n(o)}function o(){let e,t,n=/* @__PURE__ */new Map;const o=(e,t)=>{const o=n.get(e);if(void 0!==o&&o.type===t)return o;const i=function(e){return"text"===e?{type:"text",text:""}:"reasoning"===e?{type:"reasoning",text:""}:{type:"tool-call",id:"",name:"",arguments:""}}(t);return n.set(e,i),i},i=()=>[...n.entries()].sort(([e],[t])=>e-t).map(([,e])=>e);return{push(i){switch(i.type){case"block-start":return void o(i.index,i.blockType);case"text-delta":return void(o(i.index,"text").text+=i.text);case"reasoning-delta":return void(o(i.index,"reasoning").text+=i.text);case"tool-call-delta":{const e=o(i.index,"tool-call");return""!==i.id&&(e.id=i.id),void 0!==i.name&&""!==i.name&&(e.name=i.name),void(e.arguments+=i.argumentsDelta)}case"block-end":return void n.set(i.index,{...i.block});case"usage":return void(e=i.usage);case"finish":return void(t=i.reason)}},snapshot:()=>Object.freeze({blocks:Object.freeze(i().map(e=>Object.freeze({...e}))),usage:void 0===e?void 0:Object.freeze({...e}),finishReason:t,done:void 0!==t}),text:()=>i().reduce((e,t)=>"text"===t.type?e+t.text:e,""),reasoning:()=>i().reduce((e,t)=>"reasoning"===t.type?e+t.text:e,""),toolCalls:()=>i().filter(e=>"tool-call"===e.type),reset(){n=/* @__PURE__ */new Map,e=void 0,t=void 0}}}var i=/[ -〿぀-ヿ㐀-䶿一-鿿豈-﫿＀-￯가-힯]/u;function s(e){if(""===e)return 0;let t=0,n=0;for(const o of e)i.test(o)?t+=1:n+=1;return Math.max(1,t+Math.ceil(n/4))}function r(e,t){const n=(e,t)=>void 0===e&&void 0===t?void 0:(e??0)+(t??0);return{inputTokens:n(e?.inputTokens,t?.inputTokens),outputTokens:n(e?.outputTokens,t?.outputTokens),reasoningTokens:n(e?.reasoningTokens,t?.reasoningTokens),cachedInputTokens:n(e?.cachedInputTokens,t?.cachedInputTokens),totalTokens:n(e?.totalTokens,t?.totalTokens)}}function c(e,t){const{limit:n,keepRecent:o,summaryTokens:i}=t,s=e.reduce((e,t)=>e+t,0);if(s<=n)return{compact:0,projected:s,fits:!0};const r=Math.max(0,e.length-o);let c=0,a=0;for(;c<r&&i+s-a>n;)a+=e[c]??0,c+=1;if(0===c)return{compact:0,projected:s,fits:s<=n};const d=i+s-a;return{compact:c,projected:d,fits:d<=n}}export{r as addUsage,o as createStreamAccumulator,s as estimateTokens,n as mapEventStream,t as parseEventStream,c as planCompaction};
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Server-Sent Events parsing, to the WHATWG event-stream rules.
3
+ *
4
+ * This is the transport half of `ranuts/stream` and knows nothing about models: it turns
5
+ * bytes into {@link ServerSentEvent} records. Mapping an event's `data` onto
6
+ * {@link StreamChunk} is the caller's job, because that mapping is vendor-specific while
7
+ * the framing is not.
8
+ *
9
+ * The parts worth not re-deriving: a chunk boundary can fall anywhere, including inside a
10
+ * multi-byte character and between the two halves of a `\r\n`; `data:` repeats join with
11
+ * `\n`; exactly one space after the colon is stripped; a line starting with `:` is a
12
+ * comment (which is how servers keep a connection warm); and a trailing block with no
13
+ * terminating blank line is still an event.
14
+ */
15
+ import type { StreamChunk } from './types.ts';
16
+ /** One parsed `text/event-stream` event. */
17
+ export interface ServerSentEvent {
18
+ /** Joined `data:` payload; `\n` between repeats, no trailing newline. */
19
+ data: string;
20
+ /** `event:` field, when the server sent one. */
21
+ event?: string;
22
+ /** `id:` field, when the server sent one. */
23
+ id?: string;
24
+ /** `retry:` field in milliseconds, when the server sent a valid integer. */
25
+ retry?: number;
26
+ }
27
+ /** Anything `for await` can walk that yields byte chunks — a `fetch` body, or a fake. */
28
+ export type ByteSource = AsyncIterable<Uint8Array> | ReadableStream<Uint8Array>;
29
+ /**
30
+ * Parses a byte stream as `text/event-stream`.
31
+ *
32
+ * Decoding is streaming, so a multi-byte character split across two network chunks is
33
+ * reassembled rather than replaced. A final block with no terminating blank line is still
34
+ * yielded, which is what a server that closes the connection mid-event produces.
35
+ *
36
+ * @param source Byte source, typically `response.body`.
37
+ * @returns Each event in arrival order.
38
+ */
39
+ export declare function parseEventStream(source: ByteSource): AsyncGenerator<ServerSentEvent>;
40
+ /**
41
+ * Maps SSE events onto {@link StreamChunk} values using a caller-supplied vendor mapping.
42
+ *
43
+ * The mapping returns an array because one wire event commonly carries several normalized
44
+ * chunks — a delta plus a usage report, or two concurrent tool calls — and returning an
45
+ * empty array is how a keep-alive or a sentinel such as `[DONE]` is dropped.
46
+ *
47
+ * @param source Byte source, typically `response.body`.
48
+ * @param map Vendor mapping from one event to zero or more chunks.
49
+ * @returns Each normalized chunk in arrival order.
50
+ */
51
+ export declare function mapEventStream(source: ByteSource, map: (event: ServerSentEvent) => readonly StreamChunk[]): AsyncGenerator<StreamChunk>;