UNPKG

@neuroequality/neuroadapt-ai

Version:

AI-powered accessibility personalization for neurodivergent users

7 lines (5 loc) 5.59 kB
"use strict";const p=require("eventemitter3");class u extends p.EventEmitter{constructor(t={}){super(),this.processingQueue=[],this.activeProcessing=new Map,this.adaptationCache=new Map,this.config={chunkSize:t.chunkSize||500,processingDelay:t.processingDelay||100,enableRealTimeAnalysis:t.enableRealTimeAnalysis??!0,adaptationThreshold:t.adaptationThreshold||.7,maxConcurrentChunks:t.maxConcurrentChunks||3,retryAttempts:t.retryAttempts||2},this.processingStats=this.createEmptyStats(),this.startProcessingLoop()}async processContent(t,e,n){const s=Date.now(),i=this.generateContentId(t),r=this.adaptationCache.get(i);if(r)return r;try{const a=await this.adaptContent(t,e,n),o=this.detectAppliedAdaptations(t,a,e),c={id:i,originalContent:t,adaptedContent:a,adaptations:o,confidence:this.calculateConfidence(o,e),processingTime:Date.now()-s,metadata:{preferences:e,context:n,timestamp:Date.now()}};if(this.adaptationCache.set(i,c),this.adaptationCache.size>100){const h=this.adaptationCache.keys().next().value;this.adaptationCache.delete(h)}return this.emit("content-processed",c),c}catch(a){const o=a instanceof Error?a:new Error(String(a));throw this.emit("error",o),o}}async processStreamChunks(t,e,n){let s="",i=0;const r=Date.now();try{for await(const a of t)if(a.type==="token"){if(s+=a.content,this.shouldProcessBuffer(s)){const o=await this.processChunk(s,i++,e,n);this.emit("chunk-processed",o),s=""}}else if(a.type==="done"){if(s.trim()){const c=await this.processChunk(s,i++,e,n);this.emit("chunk-processed",c)}const o={...this.processingStats,totalProcessingTime:Date.now()-r};this.emit("processing-complete",o);break}else if(a.type==="error")throw new Error(`Stream error: ${a.content}`)}catch(a){const o=a instanceof Error?a:new Error(String(a));throw this.emit("error",o),o}}queueContent(t,e,n){const s=this.generateContentId(t),i={id:s,content:t,preferences:e,context:n,timestamp:Date.now(),retries:0};return this.processingQueue.push(i),s}getProcessingStats(){return{...this.processingStats}}clearCache(){this.adaptationCache.clear()}getCacheInfo(){return{size:this.adaptationCache.size,keys:Array.from(this.adaptationCache.keys())}}destroy(){this.processingQueue=[],this.activeProcessing.clear(),this.adaptationCache.clear(),this.removeAllListeners()}generateContentId(t){let e=0;for(let n=0;n<t.length;n++){const s=t.charCodeAt(n);e=(e<<5)-e+s,e=e&e}return`content_${Math.abs(e)}_${Date.now()}`}async adaptContent(t,e,n){let s=t;return e.highContrast&&(s=this.applyHighContrastAdaptation(s)),e.motionReduction&&(s=this.applyMotionReductionAdaptation(s)),typeof e.fontSize=="number"&&e.fontSize!==1&&(s=this.applyFontSizeAdaptation(s,e.fontSize)),typeof e.chunkSize=="number"&&e.chunkSize<4&&(s=await this.applyContentChunking(s,e.chunkSize)),e.simplifyLanguage&&(s=await this.applyLanguageSimplification(s)),s}applyHighContrastAdaptation(t){return t.replace(/<(p|div|span|h[1-6])([^>]*)>/gi,'<$1$2 data-high-contrast="true">')}applyMotionReductionAdaptation(t){return t.replace(/autoplay/gi,"data-autoplay-disabled").replace(/animation-/gi,"data-animation-disabled-").replace(/<video([^>]*)\s+autoplay/gi,"<video$1 data-motion-reduced")}applyFontSizeAdaptation(t,e){const n=Math.round(e*100);return t.replace(/<(p|div|span|h[1-6])([^>]*)>/gi,`<$1$2 style="font-size: ${n}%">`)}async applyContentChunking(t,e){const n=t.split(/[.!?]+/).filter(i=>i.trim()),s=[];for(let i=0;i<n.length;i+=e){const r=n.slice(i,i+e).join(". ");s.push(`<div class="content-chunk">${r}</div>`)}return s.join(` <div class="chunk-break"></div> `)}async applyLanguageSimplification(t){return t.replace(/utilize/gi,"use").replace(/demonstrate/gi,"show").replace(/accomplish/gi,"do").replace(/nevertheless/gi,"but").replace(/consequently/gi,"so")}detectAppliedAdaptations(t,e,n){const s=[];return e.includes("data-high-contrast")&&s.push("High contrast styling applied"),e.includes("data-motion-reduced")&&s.push("Motion reduction applied"),e.includes("font-size:")&&s.push("Font size adjustment applied"),e.includes("content-chunk")&&s.push("Content chunking applied"),t!==e&&s.length===0&&s.push("Language simplification applied"),s}calculateConfidence(t,e){const n=Object.keys(e).length,s=t.length;return Math.min(s/Math.max(n,1),1)}shouldProcessBuffer(t){return t.length>=this.config.chunkSize||/[.!?]\s/.test(t)||t.includes(` `)}async processChunk(t,e,n,s){const i=await this.adaptContent(t,n,s),r=this.detectAppliedAdaptations(t,i,n);return this.processingStats.processedChunks++,this.processingStats.totalAdaptations+=r.length,{id:`chunk_${e}`,chunkIndex:e,content:i,adaptations:r,confidence:this.calculateConfidence(r,n),timestamp:Date.now()}}startProcessingLoop(){setInterval(()=>{this.processQueue()},this.config.processingDelay)}async processQueue(){if(this.processingQueue.length===0||this.activeProcessing.size>=this.config.maxConcurrentChunks)return;const t=this.processingQueue.shift();if(!t)return;const e=this.processQueueItem(t);this.activeProcessing.set(t.id,e);try{await e}finally{this.activeProcessing.delete(t.id)}}async processQueueItem(t){try{const e=await this.processContent(t.content,t.preferences,t.context);this.processingStats.totalChunks++}catch(e){this.processingStats.failedChunks++,t.retries<this.config.retryAttempts?(t.retries++,this.processingQueue.push(t)):this.emit("error",e instanceof Error?e:new Error(String(e)))}}createEmptyStats(){return{totalChunks:0,processedChunks:0,failedChunks:0,totalAdaptations:0,averageConfidence:0,totalProcessingTime:0,suggestedImprovements:[]}}}exports.ContentAdapter=u; //# sourceMappingURL=content-adapter-ZmHfMI1P.cjs.map