@hyperfixi/core 2.0.0 → 2.2.0
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/api/hyperscript-api.d.ts +8 -1
- package/dist/ast-utils/index.d.ts +1 -1
- package/dist/ast-utils/index.js +11 -1
- package/dist/ast-utils/index.mjs +11 -1
- package/dist/ast-utils/interchange/index.d.ts +1 -1
- package/dist/ast-utils/interchange/lsp.d.ts +4 -1
- package/dist/behaviors/index.js +13 -5
- package/dist/behaviors/index.mjs +13 -5
- package/dist/bundle-generator/index.js +9 -0
- package/dist/bundle-generator/index.mjs +9 -0
- package/dist/chunks/{bridge-I6ceoWxV.js → bridge-D2DBo02Z.js} +2 -2
- package/dist/chunks/browser-modular-BA3JFmkq.js +2 -0
- package/dist/chunks/feature-eventsource-B5F2-H1r.js +2 -0
- package/dist/chunks/feature-sockets-ClOH7vk7.js +2 -0
- package/dist/chunks/feature-webworker-3bAp0ac9.js +2 -0
- package/dist/chunks/index-C6Fn0jGB.js +2 -0
- package/dist/commands/dom/toggle.d.ts +2 -0
- package/dist/commands/index.js +62 -6
- package/dist/commands/index.mjs +62 -6
- package/dist/debug/debug-controller.d.ts +62 -0
- package/dist/debug/index.d.ts +5 -0
- package/dist/expressions/index.js +16 -79
- package/dist/expressions/index.mjs +16 -79
- package/dist/hyperfixi-classic-i18n.js +1 -1
- package/dist/hyperfixi-hx.js +1 -1
- package/dist/hyperfixi-hybrid-complete.js +1 -1
- package/dist/hyperfixi-minimal.js +1 -1
- package/dist/hyperfixi-multilingual.js +1 -1
- package/dist/hyperfixi-standard.js +1 -1
- package/dist/hyperfixi.js +1 -1
- package/dist/hyperfixi.mjs +1 -1
- package/dist/i18n/error-catalog.d.ts +12 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +35334 -24306
- package/dist/index.min.js +1 -1
- package/dist/index.mjs +35333 -24307
- package/dist/lokascript-browser-classic-i18n.js +1 -1
- package/dist/lokascript-browser-minimal.js +1 -1
- package/dist/lokascript-browser-standard.js +1 -1
- package/dist/lokascript-browser.js +1 -1
- package/dist/lokascript-hybrid-complete.js +1 -1
- package/dist/lokascript-hybrid-hx.js +1 -1
- package/dist/lokascript-multilingual.js +1 -1
- package/dist/lse/index.d.ts +15 -0
- package/dist/lse/index.js +84 -0
- package/dist/lse/index.mjs +71 -0
- package/dist/metadata.d.ts +4 -4
- package/dist/metadata.js +4 -4
- package/dist/metadata.mjs +4 -4
- package/dist/parser/full-parser.js +608 -271
- package/dist/parser/full-parser.mjs +608 -271
- package/dist/parser/helpers/ast-helpers.d.ts +1 -0
- package/dist/parser/hybrid/index.js +35 -2
- package/dist/parser/hybrid/index.mjs +35 -2
- package/dist/parser/hybrid/parser-core.d.ts +1 -0
- package/dist/parser/hybrid/parser-core.js +35 -2
- package/dist/parser/hybrid/parser-core.mjs +35 -2
- package/dist/parser/hybrid/tokenizer.js +5 -0
- package/dist/parser/hybrid/tokenizer.mjs +5 -0
- package/dist/parser/hybrid-parser.js +35 -2
- package/dist/parser/hybrid-parser.mjs +35 -2
- package/dist/parser/parser-types.d.ts +22 -7
- package/dist/parser/parser.d.ts +7 -0
- package/dist/parser/pratt-parser.d.ts +42 -0
- package/dist/parser/token-consumer.d.ts +1 -2
- package/dist/parser/tokenizer.d.ts +0 -33
- package/dist/registry/index.js +16 -79
- package/dist/registry/index.mjs +16 -79
- package/dist/runtime/runtime-base.d.ts +4 -0
- package/dist/types/base-types.d.ts +11 -0
- package/dist/types/core.d.ts +1 -0
- package/package.json +15 -6
- package/dist/chunks/browser-modular-Dv6PAV3c.js +0 -2
- package/dist/chunks/feature-eventsource-DWb514fy.js +0 -2
- package/dist/chunks/feature-sockets-3PFuvCVY.js +0 -2
- package/dist/chunks/feature-webworker-DTm_eh-E.js +0 -2
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{v as e,z as t}from"./feature-sockets-ClOH7vk7.js";function n(e,t,n=1e3){e.push(t),e.length>n&&e.shift()}const r=e.object({source:t.object({url:e.string().min(1),withCredentials:e.boolean().default(!1),headers:t.record(e.string(),e.string()).default({}),retry:e.object({enabled:e.boolean().default(!0),maxAttempts:e.number().default(5),delay:e.number().default(3e3),backoff:t.enum(["linear","exponential"]).default("exponential"),maxDelay:e.number().default(3e4)}).default({}),timeout:e.object({enabled:e.boolean().default(!0),duration:e.number().default(6e4)}).default({})}),eventHandlers:e.array(e.object({event:e.string().min(1),commands:e.array(e.any()).min(1),filter:e.string().optional(),options:t.object({throttle:e.number().optional(),debounce:e.number().optional()}).optional()})).default([]),messageProcessing:e.object({format:t.enum(["text","json","raw"]).default("text"),validation:t.object({enabled:e.boolean().default(!0),schema:e.any().optional()}).default({}),buffer:e.object({enabled:e.boolean().default(!0),maxSize:e.number().min(0).default(100),flushInterval:e.number().default(1e3)}).default({})}).default({}),context:e.object({variables:t.record(e.string(),e.any()).default({}),me:e.any().optional(),it:e.any().optional(),target:e.any().optional()}).default({}),options:e.object({enableAutoConnect:e.boolean().default(!0),enableMessageBuffer:e.boolean().default(!0),enableErrorHandling:e.boolean().default(!0),maxConnections:e.number().default(1),connectionTimeout:e.number().default(3e4)}).default({}),environment:t.enum(["frontend","backend","universal"]).default("frontend"),debug:e.boolean().default(!1)}),s=e.object({contextId:e.string(),timestamp:e.number(),category:e.literal("Frontend"),capabilities:e.array(e.string()),state:t.enum(["ready","connecting","connected","disconnecting","disconnected","error"]),connection:t.object({connect:e.any(),disconnect:e.any(),reconnect:e.any(),getState:e.any(),getConnectionInfo:e.any(),isConnected:e.any()}),events:e.object({addHandler:e.any(),removeHandler:e.any(),getHandlers:e.any(),emit:e.any()}),messages:e.object({getHistory:e.any(),getBuffer:e.any(),flushBuffer:e.any(),clearHistory:e.any(),subscribe:e.any(),unsubscribe:e.any()}),errors:e.object({handle:e.any(),getErrorHistory:e.any(),clearErrors:e.any(),setErrorHandler:e.any()})});class o{constructor(){this.name="eventsourceFeature",this.category="Frontend",this.description="Type-safe Server-Sent Events management feature with connection handling, message processing, and comprehensive error recovery",this.inputSchema=r,this.outputType="Context",this.evaluationHistory=[],this.connections=new Map,this.messageHistory=[],this.eventHandlers=new Map,this.messageBuffers=new Map,this.errorHistory=[],this.throttleTimers=new Map,this.debounceTimers=new Map,this.filterCache=new Map,this.metadata={category:"Frontend",complexity:"complex",sideEffects:["sse-connection","event-listening","background-processing"],dependencies:["eventsource-api","stream-processing","connection-management"],returnTypes:["Context"],examples:[{input:'{ source: { url: "/api/events" }, eventHandlers: [{ event: "message", commands: [{ name: "processUpdate" }] }] }',description:"Create Server-Sent Events connection for real-time updates",expectedOutput:"TypedEventSourceContext with SSE connection and message handling"},{input:'{ source: { url: "/api/notifications", retry: { maxAttempts: 10 } }, messageProcessing: { format: "json" } }',description:"SSE connection with automatic retry and JSON message processing",expectedOutput:"Event source context with robust reconnection and data parsing"},{input:'{ source: { url: "/api/metrics" }, messageProcessing: { buffer: { enabled: true, maxSize: 500 } } }',description:"High-volume SSE with message buffering for performance",expectedOutput:"Buffered event source for handling high-frequency updates"}],relatedExpressions:[],relatedContexts:["socketsFeature","onFeature","executionContext"],frameworkDependencies:["eventsource-api","hyperscript-runtime"],environmentRequirements:{browser:!0,server:!1,nodejs:!1},performance:{averageTime:15,complexity:"O(n)"}},this.documentation={summary:"Creates and manages Server-Sent Events connections for real-time data streaming with type-safe message handling, automatic reconnection, and comprehensive error recovery",parameters:[{name:"sourceConfig",type:"EventSourceInput",description:"SSE configuration including server URL, event handlers, message processing options, and connection settings",optional:!1,examples:['{ source: { url: "/api/events" }, eventHandlers: [{ event: "message", commands: [{ name: "update" }] }] }','{ source: { url: "/api/stream", withCredentials: true }, messageProcessing: { format: "json" } }','{ source: { url: "/api/feed" }, messageProcessing: { buffer: { enabled: true, maxSize: 100 } } }']}],returns:{type:"EventSourceContext",description:"Server-Sent Events management context with connection lifecycle, message processing, buffer management, and error recovery capabilities",examples:["context.connection.connect() → establish SSE connection","context.messages.getHistory(50) → get last 50 messages","context.connection.reconnect() → reconnect after failure","context.messages.flushBuffer() → process buffered messages"]},examples:[{title:"Basic SSE connection",code:'const sseContext = await createEventSourceFeature({ source: { url: "/api/updates" } })',explanation:"Create Server-Sent Events connection for real-time updates",output:"SSE context ready for receiving server events"},{title:"JSON message processing",code:'await sseContext.events.addHandler("user-update", { name: "updateUserInterface", args: [] })',explanation:"Add handler for specific event types with JSON parsing",output:"Event-driven SSE with structured data processing"},{title:"Buffered high-frequency events",code:"await sseContext.messages.flushBuffer() // Process accumulated messages",explanation:"Batch process high-frequency events for performance",output:"Efficient handling of rapid event streams"}],seeAlso:["socketsFeature","onFeature","streamProcessing","realTimeUpdates"],tags:["server-sent-events","real-time","streaming","events","connection-management","type-safe","enhanced-pattern"]}}async initialize(e){const t=Date.now();try{const n=this.validate(e);if(!n.isValid)return{success:!1,error:n.errors[0]};const r=await this.initializeConfig(e),s={contextId:"eventsource-"+Date.now(),timestamp:t,category:"Frontend",capabilities:["sse-connection","message-processing","event-handling","automatic-reconnection","error-recovery"],state:"ready",connection:{connect:this.createConnectionEstablisher(r),disconnect:this.createConnectionDisconnector(),reconnect:this.createConnectionReconnector(),getState:this.createStateGetter(),getConnectionInfo:this.createConnectionInfoGetter(),isConnected:this.createConnectionChecker()},events:{addHandler:this.createEventHandlerAdder(),removeHandler:this.createEventHandlerRemover(),getHandlers:this.createEventHandlerGetter(),emit:this.createEventEmitter()},messages:{getHistory:this.createMessageHistoryGetter(),getBuffer:this.createBufferGetter(),flushBuffer:this.createBufferFlusher(),clearHistory:this.createHistoryClearer(),subscribe:this.createMessageSubscriber(),unsubscribe:this.createMessageUnsubscriber()},errors:{handle:this.createErrorHandler(),getErrorHistory:this.createErrorHistoryGetter(),clearErrors:this.createErrorClearer(),setErrorHandler:this.createErrorHandlerSetter()}};return!1!==e.options?.enableAutoConnect&&await this.createConnection(e.source,e.context||{}),this.trackPerformance(t,!0,s),{success:!0,value:s,type:"object"}}catch(e){return this.trackPerformance(t,!1),{success:!1,error:{type:"runtime-error",message:"EventSource feature initialization failed: "+(e instanceof Error?e.message:e+""),suggestions:["Verify EventSource URL is accessible","Check browser supports Server-Sent Events","Ensure server supports SSE with proper headers","Validate event configuration parameters"]}}}}validate(e){try{if(!e||"object"!=typeof e)return{isValid:!1,errors:[{type:"invalid-input",message:"Input must be an object",suggestions:[]}],suggestions:["Provide a valid EventSource configuration object"]};const t=e,n=[],r=[];if(void 0!==t.messageProcessing?.buffer?.maxSize&&0>t.messageProcessing.buffer.maxSize&&(n.push({type:"invalid-input",code:"invalid-buffer-size",message:"Buffer size must be non-negative (0 = unlimited)",path:"messageProcessing.buffer.maxSize",suggestions:[]}),r.push("Set buffer maxSize to 0 for unlimited or positive number for limit")),t.eventHandlers&&Array.isArray(t.eventHandlers))for(const e of t.eventHandlers)e.commands&&Array.isArray(e.commands)&&0===e.commands.length&&(n.push({type:"empty-config",code:"empty-commands-array",message:"Event handler commands array cannot be empty",path:"eventHandlers.commands",suggestions:[]}),r.push("Add at least one command to execute for event handler"));if(n.length>0)return{isValid:!1,errors:n,suggestions:r};const s=this.inputSchema.parse(e);if(s.source&&(this.isValidEventSourceURL(s.source.url)||(n.push({type:"invalid-input",code:"invalid-eventsource-url",message:`Invalid EventSource URL: "${s.source.url}"`,path:"source.url",suggestions:[]}),r.push("Use valid HTTP/HTTPS URL for EventSource connection")),s.source.retry&&(0>s.source.retry.maxAttempts&&(n.push({type:"invalid-input",code:"invalid-retry-attempts",message:"Retry max attempts must be non-negative",path:"source.retry.maxAttempts",suggestions:[]}),r.push("Set maxAttempts to 0 for no retry or positive number for retry limit")),0>s.source.retry.delay&&(n.push({type:"invalid-input",code:"invalid-retry-delay",message:"Retry delay must be non-negative",path:"source.retry.delay",suggestions:[]}),r.push("Set retry delay to positive number in milliseconds")),s.source.retry.delay>s.source.retry.maxDelay&&(n.push({type:"validation-error",message:"Max delay must be greater than or equal to delay",path:"source.retry.maxDelay",suggestions:[]}),r.push("Set maxDelay to be greater than or equal to delay"))),s.source.timeout&&1e3>s.source.timeout.duration&&(n.push({type:"invalid-input",code:"invalid-timeout-duration",message:"Timeout duration must be at least 1000ms",path:"source.timeout.duration",suggestions:[]}),r.push("Set timeout duration to at least 1000ms for proper operation"))),s.options&&(1>s.options.maxConnections&&(n.push({type:"invalid-input",code:"invalid-max-connections",message:"maxConnections must be at least 1",path:"options.maxConnections",suggestions:[]}),r.push("Set maxConnections to at least 1")),1e3>s.options.connectionTimeout&&(n.push({type:"invalid-input",code:"invalid-connection-timeout",message:"Connection timeout must be at least 1000ms",path:"options.connectionTimeout",suggestions:[]}),r.push("Set connection timeout to at least 1000ms for proper operation"))),s.eventHandlers&&s.eventHandlers.length>0)for(const e of s.eventHandlers)if(e.options?.throttle&&e.options?.debounce&&(n.push({type:"schema-validation",code:"conflicting-performance-options",message:"Cannot use both throttle and debounce simultaneously",path:"eventHandlers.options",suggestions:[]}),r.push("Choose either throttle OR debounce, not both")),e.filter)try{Function("event","return "+e.filter)}catch(t){n.push({type:"invalid-input",code:"invalid-filter-expression",message:"Invalid filter expression: "+e.filter,path:"eventHandlers.filter",suggestions:[]}),r.push("Use valid JavaScript expression for event filtering")}return"undefined"==typeof EventSource&&(n.push({type:"runtime-error",message:"Server-Sent Events are not supported in this environment",suggestions:[]}),r.push("EventSource requires a browser environment")),{isValid:0===n.length,errors:n,suggestions:r}}catch(e){return{isValid:!1,errors:[{type:"schema-validation",suggestions:[],message:e instanceof Error?e.message:"Invalid input format"}],suggestions:["Ensure input matches EventSourceInput schema","Check source configuration structure","Verify event handlers and message processing configurations"]}}}async initializeConfig(e){return{...e.options,environment:e.environment,debug:e.debug,initialized:Date.now()}}async createConnection(e,t){const r=`connection-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,s={id:r,url:e.url,eventSource:null,state:"connecting",createdAt:Date.now(),lastMessageTime:0,messageCount:0,errorCount:0,retryAttempts:0,maxRetryAttempts:e.retry?.maxAttempts||5};try{return s.eventSource=new EventSource(e.url,{withCredentials:e.withCredentials||!1}),s.eventSource.onopen=e=>{s.state="connected",s.connectedAt=Date.now(),s.retryAttempts=0,this.handleConnectionOpen(s,e)},s.eventSource.onmessage=e=>{s.messageCount++,s.lastMessageTime=Date.now(),this.handleMessage(s,e)},s.eventSource.onerror=e=>{s.errorCount++,s.state="error",this.handleConnectionError(s,e)},this.connections.set(r,s),s}catch(t){throw s.state="error",s.errorCount++,n(this.errorHistory,{error:t,timestamp:Date.now(),context:{connection:s,sourceConfig:e}}),t}}handleConnectionOpen(e,t){this.processEventHandlers(e.id,"open",t)}handleMessage(e,t){const r={id:`msg-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,connectionId:e.id,event:t.type,data:t.data,timestamp:Date.now(),format:this.detectMessageFormat(t.data),...t.lastEventId&&{lastEventId:t.lastEventId},...t.origin&&{origin:t.origin}};n(this.messageHistory,r);const s=this.messageBuffers.get(e.id);s&&(s.messages.push(r),s.maxSize>0&&s.messages.length>s.maxSize&&s.messages.shift()),this.processEventHandlers(e.id,"message",t)}handleConnectionError(e,t){n(this.errorHistory,{error:Error("EventSource connection error"),timestamp:Date.now(),context:{connection:e,event:t}}),this.processEventHandlers(e.id,"error",t),e.maxRetryAttempts>e.retryAttempts&&this.scheduleReconnection(e)}scheduleReconnection(e){e.retryAttempts++;setTimeout(()=>{this.attemptReconnection(e)},3e3*e.retryAttempts)}async attemptReconnection(e){try{e.eventSource&&e.eventSource.close(),e.state="connecting",e.eventSource=new EventSource(e.url),e.eventSource.onopen=t=>{e.state="connected",e.connectedAt=Date.now(),e.retryAttempts=0,this.handleConnectionOpen(e,t)},e.eventSource.onmessage=t=>{e.messageCount++,e.lastMessageTime=Date.now(),this.handleMessage(e,t)},e.eventSource.onerror=t=>{e.errorCount++,e.state="error",this.handleConnectionError(e,t)}}catch(t){n(this.errorHistory,{error:t,timestamp:Date.now(),context:{connection:e,reconnectAttempt:e.retryAttempts}})}}processEventHandlers(e,t,n){const r=Array.from(this.eventHandlers.values()).filter(n=>n.connectionId===e&&n.eventType===t&&n.isActive);for(const e of r)this.executeEventHandler(e,n)}async executeEventHandler(e,t){try{if(e.filter&&!this.testEventFilter(t,e.filter))return;if(e.options?.throttle&&this.isThrottled(e.id,e.options.throttle))return;if(e.options?.debounce)return void this.applyDebounce(e.id,e.options.debounce,()=>{this.executeCommands(e.commands,{event:t})});await this.executeCommands(e.commands,{event:t}),e.executionCount++,e.lastExecutionTime=Date.now()}catch(r){n(this.errorHistory,{error:r,timestamp:Date.now(),context:{handler:e,event:t}})}}async executeCommands(e,t){const n={success:!0,executed:e.length};for(const n of e)"object"==typeof n&&n.name&&await this.executeBasicCommand(n,t);return n}async executeBasicCommand(e,t){e.name}isValidEventSourceURL(e){try{const t=new URL(e,window?.location?.href);return"http:"===t.protocol||"https:"===t.protocol}catch{return!1}}detectMessageFormat(e){if("string"==typeof e)try{return JSON.parse(e),"json"}catch{return"text"}return"raw"}testEventFilter(e,t){try{let n=this.filterCache.get(t);return n||(n=Function("event","return "+t),this.filterCache.set(t,n)),!!n(e)}catch{return!0}}isThrottled(e,t){const n=this.throttleTimers.get(e)||0,r=Date.now();return t>r-n||(this.throttleTimers.set(e,r),!1)}applyDebounce(e,t,n){const r=this.debounceTimers.get(e);r&&clearTimeout(r);const s=setTimeout(n,t);this.debounceTimers.set(e,s)}createConnectionEstablisher(e){return async t=>{const n=t||e;return await this.createConnection(n,{})}}createConnectionDisconnector(){return async e=>{const t=this.connections.get(e);return!!t&&(t.state="disconnecting",t.eventSource&&(t.eventSource.close(),t.eventSource=null),t.state="disconnected",t.disconnectedAt=Date.now(),!0)}}createConnectionReconnector(){return async e=>{const t=this.connections.get(e);return!!t&&(await this.attemptReconnection(t),!0)}}createStateGetter(){return e=>{const t=this.connections.get(e);return t?t.state:"disconnected"}}createConnectionInfoGetter(){return e=>{const t=this.connections.get(e);return t?{id:t.id,url:t.url,state:t.state,createdAt:t.createdAt,connectedAt:t.connectedAt,messageCount:t.messageCount,errorCount:t.errorCount,retryAttempts:t.retryAttempts}:null}}createConnectionChecker(){return e=>{const t=this.connections.get(e);return!!t&&"connected"===t.state}}createEventHandlerAdder(){return async(e,t,n)=>{const r=`handler-${Date.now()}-${Math.random().toString(36).substring(2,11)}`;return this.eventHandlers.set(r,{id:r,connectionId:e,eventType:t,commands:[n],isActive:!0,executionCount:0,lastExecutionTime:0}),r}}createEventHandlerRemover(){return e=>this.eventHandlers.delete(e)}createEventHandlerGetter(){return e=>e?Array.from(this.eventHandlers.values()).filter(t=>t.connectionId===e):Array.from(this.eventHandlers.values())}createEventEmitter(){return async(e,t,n)=>!0}createMessageHistoryGetter(){return(e,t)=>{let n=this.messageHistory;return e&&(n=n.filter(t=>t.connectionId===e)),t&&(n=n.slice(-t)),n}}createBufferGetter(){return e=>{const t=this.messageBuffers.get(e);return t?t.messages.slice():[]}}createBufferFlusher(){return async e=>{const t=this.messageBuffers.get(e);if(!t||0===t.messages.length)return[];const n=t.messages.slice();return t.messages.length=0,t.lastFlushTime=Date.now(),n}}createHistoryClearer(){return e=>(this.messageHistory=e?this.messageHistory.filter(t=>t.connectionId!==e):[],!0)}createMessageSubscriber(){return async(e,t)=>{const n=`handler-${Date.now()}-${Math.random().toString(36).substring(2,11)}`;return this.eventHandlers.set(n,{id:n,connectionId:"",eventType:e,commands:[t],isActive:!0,executionCount:0,lastExecutionTime:0}),n}}createMessageUnsubscriber(){return e=>this.eventHandlers.delete(e)}createErrorHandler(){return async(e,t)=>(n(this.errorHistory,{error:e,timestamp:Date.now(),context:t}),!0)}createErrorHistoryGetter(){return e=>e?this.errorHistory.slice(-e):this.errorHistory.slice()}createErrorClearer(){return()=>(this.errorHistory=[],!0)}createErrorHandlerSetter(){return e=>!0}dispose(){for(const e of this.connections.values())e.eventSource&&(e.eventSource.close(),e.eventSource=null);this.connections.clear();for(const e of this.debounceTimers.values())clearTimeout(e);this.debounceTimers.clear();for(const e of this.throttleTimers.values())clearTimeout(e);this.throttleTimers.clear(),this.eventHandlers.clear(),this.messageBuffers.clear(),this.filterCache.clear(),this.messageHistory=[],this.errorHistory=[],this.evaluationHistory=[]}trackPerformance(e,t,r){const s=Date.now()-e;n(this.evaluationHistory,{input:{},output:r,success:t,duration:s,timestamp:e})}getPerformanceMetrics(){return{totalInitializations:this.evaluationHistory.length,successRate:this.evaluationHistory.filter(e=>e.success).length/Math.max(this.evaluationHistory.length,1),averageDuration:this.evaluationHistory.reduce((e,t)=>e+t.duration,0)/Math.max(this.evaluationHistory.length,1),lastEvaluationTime:this.evaluationHistory[this.evaluationHistory.length-1]?.timestamp||0,evaluationHistory:this.evaluationHistory.slice(-10),totalConnections:this.connections.size,totalMessages:this.messageHistory.length,totalErrors:this.errorHistory.length,totalEventHandlers:this.eventHandlers.size,bufferedMessages:Array.from(this.messageBuffers.values()).reduce((e,t)=>e+t.messages.length,0)}}}function a(){return new o}async function i(e,t){return(new o).initialize({source:{url:"",withCredentials:!1,headers:{},retry:{enabled:!0,maxAttempts:5,delay:3e3,backoff:"exponential",maxDelay:3e4},timeout:{enabled:!0,duration:6e4},...e},eventHandlers:[],messageProcessing:{format:"text",validation:{enabled:!0},buffer:{enabled:!0,maxSize:100,flushInterval:1e3}},context:{variables:{}},options:{enableAutoConnect:!0,enableMessageBuffer:!0,enableErrorHandling:!0,maxConnections:1,connectionTimeout:3e4},environment:"frontend",debug:!1,...t})}const c=new o;export{r as EventSourceInputSchema,s as EventSourceOutputSchema,o as TypedEventSourceFeatureImplementation,i as createEventSource,a as createEventSourceFeature,c as enhancedEventSourceImplementation};
|
|
2
|
+
//# sourceMappingURL=feature-eventsource-B5F2-H1r.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function e(e,t,n,s=[]){return{type:e,message:t,suggestions:s,...n&&{path:n}}}const t="undefined"!=typeof process&&"production"===process.env.NODE_ENV||"undefined"!=typeof process&&"true"===process.env.HYPERFIXI_SKIP_VALIDATION||"undefined"!=typeof globalThis&&"true"===globalThis.HYPERFIXI_SKIP_VALIDATION;let n;function s(){return n({validate:e=>({success:!0,data:e})})}function r(a,o){if(t)return s();const i=n({validate:t=>{if("object"!=typeof t||null===t||Array.isArray(t))return{success:!1,error:e("type-mismatch","Expected object, received "+typeof t)};const n=t,s={};if(o?.strict){const t=Object.keys(a),s=Object.keys(n).filter(e=>!t.includes(e));if(s.length>0)return{success:!1,error:e("runtime-error","Unexpected properties: "+s.join(", "))}}for(const[t,r]of Object.entries(a)){const a=n[t];if(!(t in n)&&!r._isOptional)return{success:!1,error:e("missing-argument",`Required field "${t}" is missing`,t)};const o=r.validate(a);if(!o.success){return{success:!1,error:e("validation-error",o.error.message||`Field "${t}" validation failed`,o.error.path?`${t}.${o.error.path}`:t)}}void 0!==o.data&&(s[t]=o.data)}return{success:!0,data:s}}});return i.strict=()=>r(a,{strict:!0}),i}function a(r,a="Custom validation failed"){return t?s():n({validate:t=>r(t)?{success:!0,data:t}:{success:!1,error:e("runtime-error",a)}})}n=function(t){return t.describe||(t.describe=function(e){return this.description=e,this}),t.safeParse||(t.safeParse=function(e){const t=this.validate(e);return t.success?{success:!0,data:t.data}:{success:!1,error:{errors:t.error?[t.error]:[]}}}),t.parse||(t.parse=function(e){const t=this.validate(e);if(t.success&&void 0!==t.data)return t.data;throw Error(t.error?.message||"Validation failed")}),t.optional||(t.optional=function(){const e=this.validate.bind(this),t={...this,_isOptional:!0,validate:t=>null==t?{success:!0,data:void 0}:e(t)};return n(t)}),t.min||(t.min=function(t){const s=this.validate.bind(this),r={...this,validate:n=>{const r=s(n);return r.success&&"string"==typeof r.data&&t>r.data.length?{success:!1,error:e("runtime-error",`String must be at least ${t} characters long`)}:r}};return n(r)}),t.max||(t.max=function(t){const s=this.validate.bind(this),r={...this,validate:n=>{const r=s(n);return r.success&&"string"==typeof r.data&&r.data.length>t?{success:!1,error:e("runtime-error",`String must be at most ${t} characters long`)}:r}};return n(r)}),t.default||(t.default=function(e){const t=this.validate.bind(this),s={...this,_defaultValue:e,_hasDefault:!0,validate:n=>void 0===n?{success:!0,data:e}:t(n)};return n(s)}),t.rest||(t.rest=function(e){return this}),t.refine||(t.refine=function(t,s){const r=this.validate.bind(this),a={...this,validate:n=>{const a=r(n);return a.success?t(a.data)?a:{success:!1,error:e("runtime-error",s||"Refinement validation failed")}:a}};return n(a)}),new Proxy(t,{get:(e,t,n)=>t in e||"string"!=typeof t||t.startsWith("_")||"constructor"===t||"validate"===t||"then"===t?Reflect.get(e,t,n):function(...e){return n}})};const o={string:r=>function(r={}){return t?s():n({validate:t=>r.optional&&null==t?{success:!0,data:void 0}:"string"!=typeof t?{success:!1,error:e("type-mismatch","Expected string, received "+typeof t)}:void 0!==r.minLength&&r.minLength>t.length?{success:!1,error:e("runtime-error",`String must be at least ${r.minLength} characters long`)}:void 0!==r.maxLength&&t.length>r.maxLength?{success:!1,error:e("runtime-error",`String must be at most ${r.maxLength} characters long`)}:r.pattern&&!r.pattern.test(t)?r.pattern.source.startsWith("^")&&r.pattern.source.endsWith("$")?{success:!1,error:e("runtime-error",`Expected "${r.pattern.source.slice(1,-1)}", received "${t}"`)}:{success:!1,error:e("missing-argument","String does not match required pattern")}:{success:!0,data:t},...r.description&&{description:r.description}})}(r||{}),number:r=>function(r={}){return t?s():n({validate:t=>{const n=Number(t);return isNaN(n)?{success:!1,error:e("type-mismatch","Expected number, received "+typeof t)}:void 0!==r.min&&r.min>n?{success:!1,error:e("runtime-error","Number must be at least "+r.min)}:void 0!==r.max&&n>r.max?{success:!1,error:e("runtime-error","Number must be at most "+r.max)}:{success:!0,data:n}}})}(r||{}),boolean:()=>t?s():n({validate:t=>"boolean"!=typeof t?{success:!1,error:e("type-mismatch","Expected boolean, received "+typeof t)}:{success:!0,data:t}}),object:e=>r(e),array:r=>function(r){return t?s():n({validate:t=>{if(!Array.isArray(t))return{success:!1,error:e("type-mismatch","Expected array, received "+typeof t)};const n=[];for(let s=0;t.length>s;s++){const a=r.validate(t[s]);if(!a.success)return{success:!1,error:e("runtime-error",a.error.message,a.error.path?`${s}.${a.error.path}`:""+s)};n.push(a.data)}return{success:!0,data:n}}})}(r),tuple:r=>function(r){return t?s():n({validate:t=>{if(!Array.isArray(t))return{success:!1,error:e("type-mismatch","Expected array, received "+typeof t)};if(t.length!==r.length)return{success:!1,error:e("runtime-error",`Expected tuple of length ${r.length}, received length ${t.length}`)};const n=[];for(let s=0;r.length>s;s++){const a=r[s].validate(t[s]);if(!a.success)return{success:!1,error:e("runtime-error",a.error.message,a.error.path?`${s}.${a.error.path}`:""+s)};n.push(a.data)}return{success:!0,data:n}}})}(r),union:r=>function(r){return t?s():n({validate:t=>{const n=[];for(const e of r){const s=e.validate(t);if(s.success)return s;n.push(s.error.message)}return{success:!1,error:e("type-mismatch","Value does not match any union type")}}})}(r),literal:r=>{return a=r,t?s():n({validate:t=>t===a?{success:!0,data:t}:{success:!1,error:e("runtime-error",`Expected ${JSON.stringify(a)}, received ${JSON.stringify(t)}`)}});var a},custom:(e,t)=>a(e,t),record:(r,a)=>function(r,a){return t?s():n({validate:t=>{if("object"!=typeof t||null===t||Array.isArray(t))return{success:!1,error:e("type-mismatch","Expected record object, received "+typeof t)};const n=t,s={};for(const[t,o]of Object.entries(n)){const n=r.validate(t);if(!n.success)return{success:!1,error:e("invalid-argument",`Invalid key "${t}": ${n.error.message}`,t)};const i=a.validate(o);if(!i.success)return{success:!1,error:e("runtime-error",i.error.message,i.error.path?`${t}.${i.error.path}`:t)};s[t]=i.data}return{success:!0,data:s}}})}(r,a),enum:r=>function(r){return t?s():n({validate:t=>"string"!=typeof t&&"number"!=typeof t&&"boolean"!=typeof t?{success:!1,error:e("type-mismatch","Expected string, received "+typeof t)}:r.includes(t)?{success:!0,data:t}:{success:!1,error:e("runtime-error",`Expected one of [${r.join(", ")}], received "${t}"`)}})}(r),function:()=>a(e=>"function"==typeof e,"Expected function"),unknown:()=>s(),any:()=>s(),null:()=>a(e=>null===e,"Expected null"),undefined:()=>a(e=>void 0===e,"Expected undefined"),instanceOf:e=>a(t=>t instanceof e,"Expected instance of "+e.name),instanceof:e=>a(t=>t instanceof e,"Expected instance of "+e.name)},i=o;function c(e,t,n=1e3){e.push(t),e.length>n&&e.shift()}const u=o.object({socket:i.object({url:o.string().url(),protocols:o.array(o.string()).default([]),reconnect:i.object({enabled:o.boolean().default(!0),maxAttempts:o.number().default(5),delay:o.number().default(1e3),backoff:i.enum(["linear","exponential"]).default("exponential"),maxDelay:o.number().default(3e4)}).default({}),heartbeat:o.object({enabled:o.boolean().default(!1),interval:o.number().default(3e4),message:o.string().default("ping"),timeout:o.number().default(5e3)}).default({}),compression:o.boolean().default(!1),binaryType:i.enum(["blob","arraybuffer"]).default("blob")}),eventHandlers:o.array(o.object({event:i.enum(["open","close","error","message"]),filter:o.string().optional(),commands:o.array(o.any()),options:i.object({once:o.boolean().default(!1),debounce:o.number().optional(),throttle:o.number().optional()}).default({})})).default([]),messageHandling:o.object({format:i.enum(["json","text","binary"]).default("json"),validation:i.object({enabled:o.boolean().default(!0),schema:o.any().optional()}).default({}),queue:o.object({enabled:o.boolean().default(!0),maxSize:o.number().default(100),persistence:o.boolean().default(!1)}).default({})}).default({}),context:o.object({variables:i.record(o.string(),o.any()).default({}),me:o.any().optional(),it:o.any().optional(),target:o.any().optional()}).default({}),options:o.object({enableAutoConnect:o.boolean().default(!0),enableMessageQueue:o.boolean().default(!0),enableErrorHandling:o.boolean().default(!0),maxConnections:o.number().default(5),connectionTimeout:o.number().default(1e4)}).default({}),environment:i.enum(["frontend","backend","universal"]).default("frontend"),debug:o.boolean().default(!1)}),l=o.object({contextId:o.string(),timestamp:o.number(),category:o.literal("Frontend"),capabilities:o.array(o.string()),state:i.enum(["ready","connecting","connected","disconnecting","disconnected","error"]),connection:i.object({connect:o.any(),disconnect:o.any(),reconnect:o.any(),isConnected:o.any(),getState:o.any(),getConnectionInfo:o.any()}),messaging:o.object({send:o.any(),sendJSON:o.any(),sendBinary:o.any(),subscribe:o.any(),unsubscribe:o.any(),getMessageHistory:o.any()}),events:o.object({addHandler:o.any(),removeHandler:o.any(),emit:o.any(),getHandlers:o.any()}),queue:o.object({add:o.any(),process:o.any(),clear:o.any(),getSize:o.any(),getPending:o.any()}),errors:o.object({handle:o.any(),getErrorHistory:o.any(),clearErrors:o.any(),setErrorHandler:o.any()})});class d{constructor(){this.name="socketsFeature",this.category="Frontend",this.description="Type-safe WebSocket management feature with reconnection, message queuing, and comprehensive error handling",this.inputSchema=u,this.outputType="Context",this.evaluationHistory=[],this.connections=new Map,this.eventHandlers=new Map,this.messageQueue=new Map,this.messageHistory=[],this.errorHistory=[],this.throttleTimers=new Map,this.debounceTimers=new Map,this.filterCache=new Map,this.metadata={category:"Frontend",complexity:"complex",sideEffects:["network-connection","websocket-management","message-transmission","reconnection-logic"],dependencies:["websocket-api","network-connection","message-serialization","event-system"],returnTypes:["Context"],examples:[{input:'{ socket: { url: "wss://api.example.com/ws" }, eventHandlers: [{ event: "message", commands: [{ name: "processMessage" }] }] }',description:"Connect to WebSocket server and handle incoming messages",expectedOutput:"TypedSocketsContext with connection management and message handling"},{input:'{ socket: { url: "wss://chat.example.com", reconnect: { enabled: true, maxAttempts: 10 } }, messageHandling: { format: "json" } }',description:"Chat WebSocket with auto-reconnection and JSON message handling",expectedOutput:"Resilient WebSocket connection with automatic recovery"},{input:'{ socket: { url: "wss://data.example.com", heartbeat: { enabled: true, interval: 30000 } }, messageHandling: { queue: { enabled: true } } }',description:"Data WebSocket with heartbeat monitoring and message queuing",expectedOutput:"Monitored connection with reliable message delivery"}],relatedContexts:["onFeature","behaviorFeature","eventSourceFeature"],relatedExpressions:[],frameworkDependencies:["websocket-api","network-stack"],environmentRequirements:{browser:!0,server:!0,nodejs:!0},performance:{averageTime:25.4,complexity:"O(n)"}},this.documentation={summary:"Creates type-safe WebSocket connections for hyperscript with automatic reconnection, message queuing, and comprehensive error handling",parameters:[{name:"socketsConfig",type:"SocketsInput",description:"WebSocket configuration including URL, protocols, reconnection settings, and event handlers",optional:!1,examples:['{ socket: { url: "wss://api.example.com/ws" }, eventHandlers: [{ event: "message", commands: [{ name: "handleMessage" }] }] }','{ socket: { url: "wss://chat.com", reconnect: { maxAttempts: 5 } }, messageHandling: { format: "json" } }','{ socket: { url: "wss://realtime.com", heartbeat: { enabled: true } }, options: { enableAutoConnect: true } }']}],returns:{type:"SocketsContext",description:"WebSocket management context with connection control, messaging, and event handling capabilities",examples:["context.connection.connect() → establish WebSocket connection",'context.messaging.sendJSON({data: "value"}) → send JSON message','context.events.addHandler("message", handler) → add message handler',"context.queue.add(message) → queue message for delivery"]},examples:[{title:"Basic WebSocket connection",code:'const socketsContext = await createSocketsFeature({ socket: { url: "wss://api.example.com/ws" }, eventHandlers: [{ event: "message", commands: [{ name: "processData" }] }] })',explanation:"Create WebSocket connection with message processing",output:"Connected WebSocket with automatic message handling"},{title:"Resilient chat connection",code:"await socketsContext.connection.connect({ reconnect: { enabled: true, maxAttempts: 10 }, heartbeat: { enabled: true } })",explanation:"Establish chat connection with reconnection and heartbeat monitoring",output:"Robust WebSocket suitable for real-time chat applications"},{title:"Send structured data",code:'await socketsContext.messaging.sendJSON({ type: "chat", message: "Hello", userId: 123 })',explanation:"Send JSON-formatted message through WebSocket",output:"Structured message transmitted with automatic serialization"}],seeAlso:["onFeature","eventSourceFeature","networkManagement","realTimeData"],tags:["websockets","realtime","networking","messaging","reconnection","type-safe","enhanced-pattern"]}}async initialize(e){const t=Date.now();try{const n=await this.initializeConfig(e),s=this.validate(e);if(!s.isValid)return{success:!1,error:s.errors[0]};const r={contextId:"sockets-"+Date.now(),timestamp:t,category:"Frontend",capabilities:["websocket-connection","message-handling","reconnection-management","queue-management","event-handling","error-recovery"],state:"ready",connection:{connect:this.createConnectionEstablisher(n),disconnect:this.createConnectionTerminator(),reconnect:this.createReconnector(),isConnected:this.createConnectionChecker(),getState:this.createStateGetter(),getConnectionInfo:this.createConnectionInfoGetter()},messaging:{send:this.createMessageSender(),sendJSON:this.createJSONSender(),sendBinary:this.createBinarySender(),subscribe:this.createMessageSubscriber(),unsubscribe:this.createMessageUnsubscriber(),getMessageHistory:this.createMessageHistoryGetter()},events:{addHandler:this.createEventHandlerAdder(),removeHandler:this.createEventHandlerRemover(),emit:this.createEventEmitter(),getHandlers:this.createHandlerGetter()},queue:{add:this.createQueueAdder(),process:this.createQueueProcessor(),clear:this.createQueueClearer(),getSize:this.createQueueSizeGetter(),getPending:this.createPendingGetter()},errors:{handle:this.createErrorHandler(),getErrorHistory:this.createErrorHistoryGetter(),clearErrors:this.createErrorClearer(),setErrorHandler:this.createErrorHandlerSetter()}};return e.options?.enableAutoConnect&&e.socket&&await this.createSocketConnection(e.socket,e.eventHandlers,e.context),this.trackPerformance(t,!0,r),{success:!0,value:r,type:"object"}}catch(e){return this.trackPerformance(t,!1),{success:!1,error:{type:"runtime-error",message:"Sockets feature initialization failed: "+(e instanceof Error?e.message:e+""),suggestions:["Verify WebSocket URL is valid and accessible","Check network connectivity and firewall settings","Ensure WebSocket server supports specified protocols","Validate event handler configurations are correct"]}}}}validate(e){try{if(!e||"object"!=typeof e)return{isValid:!1,errors:[{type:"invalid-input",message:"Input must be an object",suggestions:[]}],suggestions:["Provide a valid WebSocket configuration object"]};const t=this.inputSchema.parse(e),n=[],s=[],r=t;if(r.socket?.url)try{const e=new URL(r.socket.url);["ws:","wss:"].includes(e.protocol)||(n.push({type:"invalid-input",code:"invalid-websocket-protocol",message:"WebSocket URL must use ws:// or wss:// protocol",path:"socket.url",suggestions:[]}),s.push("Use ws:// for local development or wss:// for secure connections"))}catch(e){n.push({type:"invalid-input",code:"invalid-websocket-url",message:"Invalid WebSocket URL: "+r.socket.url,path:"socket.url",suggestions:[]}),s.push('Provide a valid WebSocket URL (e.g., "wss://api.example.com/ws")')}return r.socket?.reconnect&&(0>r.socket.reconnect.maxAttempts&&(n.push({type:"invalid-input",code:"invalid-reconnect-attempts",message:"Max reconnection attempts must be non-negative",path:"socket.reconnect.maxAttempts",suggestions:[]}),s.push("Set maxAttempts to 0 or positive number (0 = no reconnection)")),0>r.socket.reconnect.delay&&(n.push({type:"invalid-input",code:"invalid-reconnect-delay",message:"Reconnection delay must be non-negative",path:"socket.reconnect.delay",suggestions:[]}),s.push("Set delay to positive number in milliseconds")),r.socket.reconnect.delay>r.socket.reconnect.maxDelay&&(n.push({type:"validation-error",message:"Max delay must be greater than or equal to initial delay",path:"socket.reconnect.maxDelay",suggestions:[]}),s.push("Ensure maxDelay >= delay for proper backoff behavior"))),r.socket?.heartbeat?.enabled&&(r.socket.heartbeat.interval>0||(n.push({type:"invalid-input",code:"invalid-heartbeat-interval",message:"Heartbeat interval must be positive",path:"socket.heartbeat.interval",suggestions:[]}),s.push("Set heartbeat interval to positive number in milliseconds")),r.socket.heartbeat.timeout>0||(n.push({type:"invalid-input",code:"invalid-heartbeat-timeout",message:"Heartbeat timeout must be positive",path:"socket.heartbeat.timeout",suggestions:[]}),s.push("Set heartbeat timeout to positive number in milliseconds")),r.socket.heartbeat.interval>r.socket.heartbeat.timeout||(n.push({type:"validation-error",message:"Heartbeat timeout must be less than interval",path:"socket.heartbeat",suggestions:[]}),s.push("Ensure timeout < interval for proper heartbeat detection"))),r.eventHandlers&&r.eventHandlers.forEach((e,t)=>{if(e.filter)try{Function("message","event","return "+e.filter)}catch(r){n.push({type:"invalid-input",code:"invalid-filter-expression",message:"Invalid filter expression: "+e.filter,path:`eventHandlers[${t}].filter`,suggestions:[]}),s.push("Use valid JavaScript expression for message filtering")}e.options?.throttle&&e.options?.debounce&&(n.push({type:"schema-validation",code:"conflicting-performance-options",message:"Cannot use both throttle and debounce on the same event handler",path:`eventHandlers[${t}].options`,suggestions:[]}),s.push("Choose either throttle OR debounce, not both")),e.commands&&0!==e.commands.length||(n.push({type:"empty-config",code:"empty-commands-array",message:"Event handler must have at least one command",path:`eventHandlers[${t}].commands`,suggestions:[]}),s.push("Add at least one command to execute when event occurs"))}),r.messageHandling?.queue&&0>r.messageHandling.queue.maxSize&&(n.push({type:"invalid-input",code:"invalid-queue-size",message:"Queue max size must be non-negative (0 = unlimited)",path:"messageHandling.queue.maxSize",suggestions:[]}),s.push("Set queue maxSize to non-negative number (0 for unlimited)")),r.options?.maxConnections>0||(n.push({type:"invalid-input",code:"invalid-max-connections",message:"Max connections must be positive",path:"options.maxConnections",suggestions:[]}),s.push("Set maxConnections to positive number")),r.options?.connectionTimeout>0||(n.push({type:"invalid-input",code:"invalid-connection-timeout",message:"Connection timeout must be positive",path:"options.connectionTimeout",suggestions:[]}),s.push("Set connectionTimeout to positive number in milliseconds")),{isValid:0===n.length,errors:n,suggestions:s}}catch(e){return{isValid:!1,errors:[{type:"schema-validation",suggestions:[],message:e instanceof Error?e.message:"Invalid input format"}],suggestions:["Ensure input matches SocketsInput schema","Check WebSocket configuration structure","Verify event handler and message handling configurations are valid"]}}}async initializeConfig(e){return{...e.options,environment:e.environment,debug:e.debug,initialized:Date.now()}}async createSocketConnection(e,t,n){const s=`socket-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,r={id:s,url:e.url,protocols:e.protocols||[],websocket:null,state:"disconnected",reconnectAttempts:0,totalReconnects:0,messagesSent:0,messagesReceived:0};this.connections.set(s,r),this.messageQueue.set(s,[]);for(const e of t)await this.registerEventHandler(s,e);return r}async registerEventHandler(e,t){const n=`handler-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,s={id:n,event:t.event,filter:t.filter,commands:t.commands||[],options:t.options||{},isActive:!0,executionCount:0,lastExecutionTime:0};return this.eventHandlers.set(n,s),s}async connectWebSocket(e){const t=this.connections.get(e);if(!t)return!1;try{return t.state="connecting","undefined"!=typeof WebSocket?(t.websocket=new WebSocket(t.url,t.protocols),t.websocket.onopen=()=>this.handleWebSocketOpen(e),t.websocket.onclose=t=>this.handleWebSocketClose(e,t),t.websocket.onerror=t=>this.handleWebSocketError(e,t),t.websocket.onmessage=t=>this.handleWebSocketMessage(e,t)):(t.state="connected",t.connectedAt=Date.now(),await this.executeEventHandlers(e,"open",null)),!0}catch(n){return t.state="error",t.lastError=n,await this.executeEventHandlers(e,"error",n),!1}}async handleWebSocketOpen(e){const t=this.connections.get(e);t&&(t.state="connected",t.connectedAt=Date.now(),t.reconnectAttempts=0,await this.executeEventHandlers(e,"open",null),await this.processQueuedMessages(e))}async handleWebSocketClose(e,t){const n=this.connections.get(e);n&&(n.state="disconnected",n.disconnectedAt=Date.now(),await this.executeEventHandlers(e,"close",t))}async handleWebSocketError(e,t){const n=this.connections.get(e);n&&(n.state="error",n.lastError=Error("WebSocket error occurred"),await this.executeEventHandlers(e,"error",t))}async handleWebSocketMessage(e,t){const n=this.connections.get(e);if(!n)return;n.messagesReceived++;const s={id:`msg-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,connectionId:e,type:"incoming",data:t.data,format:this.detectMessageFormat(t.data),timestamp:Date.now(),size:this.calculateMessageSize(t.data),validated:!0};c(this.messageHistory,s),await this.executeEventHandlers(e,"message",t)}async executeEventHandlers(e,t,n){const s=Array.from(this.eventHandlers.values()).filter(e=>e.event===t&&e.isActive);for(const e of s)try{if(e.filter&&!this.testMessageFilter(n,e.filter))continue;if(e.options.throttle&&this.isThrottled(e.id,e.options.throttle))continue;if(e.options.debounce){this.applyDebounce(e.id,e.options.debounce,()=>{this.executeHandlerCommands(e,n)});continue}await this.executeHandlerCommands(e,n),e.executionCount++,e.lastExecutionTime=Date.now(),e.options.once&&(e.isActive=!1)}catch(t){c(this.errorHistory,{error:t,timestamp:Date.now(),context:{handler:e,eventData:n}})}}async executeHandlerCommands(e,t){const n={success:!0,executed:e.commands.length};for(const n of e.commands)"object"==typeof n&&n.name&&await this.executeBasicCommand(n,{eventData:t});return n}async executeBasicCommand(e,t){e.name}detectMessageFormat(e){if(e instanceof ArrayBuffer||e instanceof Blob)return"binary";if("string"==typeof e)try{return JSON.parse(e),"json"}catch{return"text"}return"text"}calculateMessageSize(e){return e instanceof ArrayBuffer?e.byteLength:e instanceof Blob?e.size:"string"==typeof e?new Blob([e]).size:0}testMessageFilter(e,t){try{let n=this.filterCache.get(t);return n||(n=Function("message","event","return "+t),this.filterCache.set(t,n)),!!n(e?.data,e)}catch{return!0}}isThrottled(e,t){const n=this.throttleTimers.get(e)||0,s=Date.now();return t>s-n||(this.throttleTimers.set(e,s),!1)}applyDebounce(e,t,n){const s=this.debounceTimers.get(e);s&&clearTimeout(s);const r=setTimeout(n,t);this.debounceTimers.set(e,r)}async processQueuedMessages(e){const t=this.messageQueue.get(e);if(!t||0===t.length)return;const n=this.connections.get(e);if(!n||"connected"!==n.state)return;const s=[];for(const n of t)try{await this.sendMessage(e,n.data,n.format)}catch(e){n.attempts++,n.lastAttempt=Date.now(),n.error=e,n.maxAttempts>n.attempts?s.push(n):c(this.errorHistory,{error:Error(`Message ${n.id} dropped after ${n.maxAttempts} failed attempts`),timestamp:Date.now(),context:{messageId:n.id,data:n.data,format:n.format}})}t.length=0,t.push(...s)}async sendMessage(e,t,n){const s=this.connections.get(e);if(!s||!s.websocket||"connected"!==s.state)return await this.queueMessage(e,t,n),!1;try{let r;switch(n){case"json":r=JSON.stringify(t);break;case"binary":r=t instanceof ArrayBuffer?t:new ArrayBuffer(0);break;default:r=t+""}if(s.websocket.readyState===WebSocket.OPEN){s.websocket.send(r),s.messagesSent++;const a={id:`msg-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,connectionId:e,type:"outgoing",data:t,format:n,timestamp:Date.now(),size:this.calculateMessageSize(r),validated:!0};return c(this.messageHistory,a),!0}return!1}catch(s){return await this.queueMessage(e,t,n),!1}}async queueMessage(e,t,n){const s=this.messageQueue.get(e);if(!s)return;const r={id:`queued-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,data:t,format:n,timestamp:Date.now(),attempts:0,maxAttempts:3};s.push(r);s.length>100&&s.shift()}createConnectionEstablisher(e){return async e=>{if("string"==typeof e)return await this.connectWebSocket(e);{const t=e||{url:"wss://localhost:8080",protocols:[],reconnect:{enabled:!0},heartbeat:{enabled:!1},compression:!1,binaryType:"blob"},n=await this.createSocketConnection(t,[],{});return await this.connectWebSocket(n.id)}}}createConnectionTerminator(){return async e=>{const t=this.connections.get(e);return!!t&&(t.state="disconnecting",t.websocket&&t.websocket.close(),t.state="disconnected",t.disconnectedAt=Date.now(),await this.executeEventHandlers(e,"close",null),!0)}}createReconnector(){return async e=>{const t=this.connections.get(e);return!!t&&(t.websocket&&t.websocket.close(),t.reconnectAttempts++,t.totalReconnects++,await this.connectWebSocket(e))}}createConnectionChecker(){return e=>{const t=this.connections.get(e);return"connected"===t?.state||!1}}createStateGetter(){return e=>{const t=this.connections.get(e);return t?.state||"disconnected"}}createConnectionInfoGetter(){return e=>{const t=this.connections.get(e);if(!t)return null;return{connectionId:t.id,...void 0!==t.connectedAt&&{connectedAt:t.connectedAt},totalReconnects:t.totalReconnects,messagesSent:t.messagesSent,messagesReceived:t.messagesReceived,bytesTransmitted:0,bytesReceived:0,averageLatency:0,errorCount:this.errorHistory.filter(t=>t.context?.connectionId===e).length,uptime:t.connectedAt?Date.now()-t.connectedAt:0}}}createMessageSender(){return async(e,t,n="text")=>await this.sendMessage(e,t,n)}createJSONSender(){return async(e,t)=>await this.sendMessage(e,t,"json")}createBinarySender(){return async(e,t)=>await this.sendMessage(e,t,"binary")}createMessageSubscriber(){return(e,t)=>this.registerEventHandler("*",{event:e,commands:[t]})}createMessageUnsubscriber(){return e=>this.eventHandlers.delete(e)}createMessageHistoryGetter(){return(e,t)=>{let n=this.messageHistory;return e&&(n=n.filter(t=>t.connectionId===e)),t&&(n=n.slice(-t)),n}}createEventHandlerAdder(){return async(e,t,n)=>await this.registerEventHandler(e,{event:t,commands:[n],options:{}})}createEventHandlerRemover(){return e=>this.eventHandlers.delete(e)}createEventEmitter(){return async(e,t,n)=>(await this.executeEventHandlers(e,t,n),!0)}createHandlerGetter(){return e=>e?Array.from(this.eventHandlers.values()).filter(t=>t.id.includes(e)):Array.from(this.eventHandlers.values())}createQueueAdder(){return async(e,t,n="json")=>(await this.queueMessage(e,t,n),!0)}createQueueProcessor(){return async e=>(await this.processQueuedMessages(e),!0)}createQueueClearer(){return e=>{const t=this.messageQueue.get(e);return!!t&&(t.length=0,!0)}}createQueueSizeGetter(){return e=>{const t=this.messageQueue.get(e);return t?t.length:0}}createPendingGetter(){return e=>{const t=this.messageQueue.get(e);return t?t.slice():[]}}createErrorHandler(){return async(e,t)=>(c(this.errorHistory,{error:e,timestamp:Date.now(),context:{connectionId:t}}),!0)}createErrorHistoryGetter(){return e=>e?this.errorHistory.slice(-e):this.errorHistory.slice()}createErrorClearer(){return()=>(this.errorHistory=[],!0)}createErrorHandlerSetter(){return e=>!0}dispose(){for(const e of this.connections.values())e.websocket&&e.websocket.close();this.connections.clear();for(const e of this.debounceTimers.values())clearTimeout(e);this.debounceTimers.clear();for(const e of this.throttleTimers.values())clearTimeout(e);this.throttleTimers.clear(),this.eventHandlers.clear(),this.messageQueue.clear(),this.filterCache.clear(),this.messageHistory=[],this.errorHistory=[],this.evaluationHistory=[]}trackPerformance(e,t,n){const s=Date.now()-e;c(this.evaluationHistory,{input:{},output:n,success:t,duration:s,timestamp:e})}getPerformanceMetrics(){return{totalInitializations:this.evaluationHistory.length,successRate:this.evaluationHistory.filter(e=>e.success).length/Math.max(this.evaluationHistory.length,1),averageDuration:this.evaluationHistory.reduce((e,t)=>e+t.duration,0)/Math.max(this.evaluationHistory.length,1),lastEvaluationTime:this.evaluationHistory[this.evaluationHistory.length-1]?.timestamp||0,evaluationHistory:this.evaluationHistory.slice(-10),totalConnections:this.connections.size,totalHandlers:this.eventHandlers.size,totalMessages:this.messageHistory.length,totalErrors:this.errorHistory.length,queuedMessages:Array.from(this.messageQueue.values()).reduce((e,t)=>e+t.length,0)}}}const m=new d;var h=Object.freeze({__proto__:null,SocketsInputSchema:u,SocketsOutputSchema:l,TypedSocketsFeatureImplementation:d,createSockets:async function(e,t){return(new d).initialize({socket:{url:"wss://localhost:8080",protocols:[],reconnect:{enabled:!0,maxAttempts:5,delay:1e3,backoff:"exponential",maxDelay:3e4},heartbeat:{enabled:!1,interval:3e4,message:"ping",timeout:5e3},compression:!1,binaryType:"blob",...e},eventHandlers:[],messageHandling:{format:"json",validation:{enabled:!0},queue:{enabled:!0,maxSize:100,persistence:!1}},context:{variables:{}},options:{enableAutoConnect:!0,enableMessageQueue:!0,enableErrorHandling:!0,maxConnections:5,connectionTimeout:1e4},environment:"frontend",debug:!1,...t})},createSocketsFeature:function(){return new d},enhancedSocketsImplementation:m});export{h as s,o as v,i as z};
|
|
2
|
+
//# sourceMappingURL=feature-sockets-ClOH7vk7.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{v as e,z as t}from"./feature-sockets-ClOH7vk7.js";function r(e,t,r=1e3){e.push(t),e.length>r&&e.shift()}const s=e.object({worker:t.object({script:e.string().min(1),type:t.enum(["module","classic"]).default("classic"),name:e.string().optional(),credentials:t.enum(["omit","same-origin","include"]).default("same-origin"),inline:e.boolean().default(!1)}),messaging:e.object({format:t.enum(["json","text","binary"]).default("json"),serialization:t.enum(["structured-clone","json"]).default("structured-clone"),transferables:e.array(e.string()).default([]),validation:t.object({enabled:e.boolean().default(!0),schema:e.any().optional()}).default({}),queue:e.object({enabled:e.boolean().default(!0),maxSize:e.number().min(0).default(100),persistence:e.boolean().default(!1)}).default({})}).default({}),eventHandlers:e.array(e.object({event:t.enum(["message","error","messageerror"]),commands:e.array(e.any()).min(1),filter:e.string().optional(),options:t.object({throttle:e.number().optional(),debounce:e.number().optional()}).optional()})).default([]),context:e.object({variables:t.record(e.string(),e.any()).default({}),me:e.any().optional(),it:e.any().optional(),target:e.any().optional()}).default({}),options:e.object({enableAutoStart:e.boolean().default(!0),enableMessageQueue:e.boolean().default(!0),enableErrorHandling:e.boolean().default(!0),maxWorkers:e.number().default(4),workerTimeout:e.number().default(3e4),terminationTimeout:e.number().default(5e3)}).default({}),environment:t.enum(["frontend","backend","universal"]).default("frontend"),debug:e.boolean().default(!1)}),a=e.object({contextId:e.string(),timestamp:e.number(),category:e.literal("Frontend"),capabilities:e.array(e.string()),state:t.enum(["ready","starting","running","terminating","terminated","error"]),workers:t.object({create:e.any(),terminate:e.any(),restart:e.any(),getWorker:e.any(),listWorkers:e.any(),getWorkerInfo:e.any()}),messaging:e.object({send:e.any(),sendJSON:e.any(),sendBinary:e.any(),broadcast:e.any(),getMessageHistory:e.any(),subscribe:e.any(),unsubscribe:e.any()}),events:e.object({addHandler:e.any(),removeHandler:e.any(),getHandlers:e.any(),emit:e.any()}),queue:e.object({add:e.any(),process:e.any(),getSize:e.any(),getPending:e.any(),clear:e.any()}),errors:e.object({handle:e.any(),getErrorHistory:e.any(),clearErrors:e.any(),setErrorHandler:e.any()})});class n{constructor(){this.name="webworkerFeature",this.category="Frontend",this.description="Type-safe Web Worker management feature with message handling, event processing, and comprehensive error management",this.inputSchema=s,this.outputType="Context",this.evaluationHistory=[],this.workers=new Map,this.messageHistory=[],this.eventHandlers=new Map,this.messageQueue=new Map,this.errorHistory=[],this.throttleTimers=new Map,this.debounceTimers=new Map,this.filterCache=new Map,this.metadata={category:"Frontend",complexity:"complex",sideEffects:["worker-creation","message-passing","background-execution"],dependencies:["web-worker-api","message-channel","transferable-objects"],returnTypes:["Context"],examples:[{input:'{ worker: { script: "./worker.js" }, messaging: { format: "json" } }',description:"Create a Web Worker for background JavaScript execution",expectedOutput:"TypedWebWorkerContext with worker management and message handling"},{input:'{ worker: { script: "self.onmessage = e => self.postMessage(e.data * 2)", inline: true } }',description:"Create inline worker for simple calculations",expectedOutput:"Worker context with inline script execution"},{input:'{ worker: { script: "./data-processor.js", type: "module" }, messaging: { transferables: ["ArrayBuffer"] } }',description:"Module worker with transferable object support for large data processing",expectedOutput:"High-performance worker context with zero-copy data transfer"}],relatedExpressions:[],relatedContexts:["socketsFeature","onFeature","executionContext"],frameworkDependencies:["web-worker-api","hyperscript-runtime"],environmentRequirements:{browser:!0,server:!1,nodejs:!1},performance:{averageTime:25,complexity:"O(n)"}},this.documentation={summary:"Creates and manages Web Workers for background JavaScript execution with type-safe message handling, event processing, and comprehensive error recovery",parameters:[{name:"workerConfig",type:"WebWorkerInput",description:"Web Worker configuration including script source, messaging format, event handlers, and performance options",optional:!1,examples:['{ worker: { script: "./worker.js" }, messaging: { format: "json" } }','{ worker: { script: "worker-code", inline: true }, options: { maxWorkers: 2 } }','{ worker: { script: "./module-worker.js", type: "module" }, messaging: { transferables: ["ArrayBuffer"] } }']}],returns:{type:"WebWorkerContext",description:"Web Worker management context with worker lifecycle, message handling, queue management, and error recovery capabilities",examples:["context.workers.create(config) → worker instance ID","context.messaging.sendJSON(workerId, data) → send JSON message to worker","context.queue.add(workerId, message) → queue message for worker","context.workers.terminate(workerId) → gracefully terminate worker"]},examples:[{title:"Basic worker creation",code:'const workerContext = await createWebWorkerFeature({ worker: { script: "./calc-worker.js" } })',explanation:"Create a Web Worker for background calculations",output:"Worker context with calculation worker ready"},{title:"Message passing with transferables",code:'await workerContext.messaging.sendBinary(workerId, arrayBuffer, ["ArrayBuffer"])',explanation:"Send large binary data to worker using transferable objects for zero-copy transfer",output:"High-performance message transfer without copying data"},{title:"Worker event handling",code:'await workerContext.events.addHandler(workerId, "message", { name: "processResult", args: [] })',explanation:"Add event handler for worker messages with command execution",output:"Event-driven worker communication with hyperscript integration"}],seeAlso:["socketsFeature","onFeature","messagingSystem","backgroundExecution"],tags:["webworkers","background-execution","message-passing","transferables","type-safe","enhanced-pattern"]}}async initialize(e){const t=Date.now();try{const r=this.validate(e);if(!r.isValid)return{success:!1,error:r.errors[0]};const s=await this.initializeConfig(e),a={contextId:"webworker-"+Date.now(),timestamp:t,category:"Frontend",capabilities:["worker-management","message-handling","background-execution","transferable-objects","error-recovery"],state:"ready",workers:{create:this.createWorkerCreator(s),terminate:this.createWorkerTerminator(),restart:this.createWorkerRestarter(),getWorker:this.createWorkerGetter(),listWorkers:this.createWorkerLister(),getWorkerInfo:this.createWorkerInfoGetter()},messaging:{send:this.createMessageSender(),sendJSON:this.createJSONSender(),sendBinary:this.createBinarySender(),broadcast:this.createBroadcaster(),getMessageHistory:this.createMessageHistoryGetter(),subscribe:this.createMessageSubscriber(),unsubscribe:this.createMessageUnsubscriber()},events:{addHandler:this.createEventHandlerAdder(),removeHandler:this.createEventHandlerRemover(),getHandlers:this.createEventHandlerGetter(),emit:this.createEventEmitter()},queue:{add:this.createQueueAdder(),process:this.createQueueProcessor(),getSize:this.createQueueSizeGetter(),getPending:this.createPendingGetter(),clear:this.createQueueClearer()},errors:{handle:this.createErrorHandler(),getErrorHistory:this.createErrorHistoryGetter(),clearErrors:this.createErrorClearer(),setErrorHandler:this.createErrorHandlerSetter()}};return e.worker.script&&!1!==e.options?.enableAutoStart&&await this.createWorker(e.worker,e.context||{}),this.trackPerformance(t,!0,a),{success:!0,value:a,type:"object"}}catch(e){return this.trackPerformance(t,!1),{success:!1,error:{type:"runtime-error",message:"WebWorker feature initialization failed: "+(e instanceof Error?e.message:e+""),suggestions:["Verify worker script URL is accessible","Check browser supports Web Workers","Ensure script has valid JavaScript syntax","Validate worker configuration parameters"]}}}}validate(e){try{if(!e||"object"!=typeof e)return{isValid:!1,errors:[{type:"invalid-input",message:"Input must be an object",suggestions:[]}],suggestions:["Provide a valid Web Worker configuration object"]};const t=e,r=[],s=[];if(void 0!==t.messaging?.queue?.maxSize&&0>t.messaging.queue.maxSize&&(r.push({type:"invalid-input",code:"invalid-queue-size",message:"Queue size must be non-negative (0 = unlimited)",path:"messaging.queue.maxSize",suggestions:[]}),s.push("Set queue maxSize to 0 for unlimited or positive number for limit")),t.eventHandlers&&Array.isArray(t.eventHandlers))for(const e of t.eventHandlers)e.commands&&Array.isArray(e.commands)&&0===e.commands.length&&(r.push({type:"empty-config",code:"empty-commands-array",message:"Event handler commands array cannot be empty",path:"eventHandlers.commands",suggestions:[]}),s.push("Add at least one command to execute for event handler"));if(r.length>0)return{isValid:!1,errors:r,suggestions:s};const a=this.inputSchema.parse(e);if(a.worker&&(a.worker.inline||this.isValidWorkerScript(a.worker.script)||(r.push({type:"invalid-input",code:"invalid-worker-script",message:`Invalid worker script: "${a.worker.script}"`,path:"worker.script",suggestions:[]}),s.push("Provide valid JavaScript file URL or inline script code")),a.worker.inline))try{"module"===a.worker.type&&a.worker.script.includes("import")||Function(a.worker.script)}catch(e){r.push({type:"syntax-error",code:"invalid-inline-script",message:"Invalid inline script syntax: "+a.worker.script,path:"worker.script",suggestions:[]}),s.push("Ensure inline script has valid JavaScript syntax")}if(a.options&&(1>a.options.maxWorkers&&(r.push({type:"invalid-input",code:"invalid-max-workers",message:"maxWorkers must be at least 1",path:"options.maxWorkers",suggestions:[]}),s.push("Set maxWorkers to at least 1")),1e3>a.options.workerTimeout&&(r.push({type:"invalid-input",code:"invalid-worker-timeout",message:"Worker timeout must be at least 1000ms",path:"options.workerTimeout",suggestions:[]}),s.push("Set worker timeout to at least 1000ms for proper operation")),1e3>a.options.terminationTimeout&&(r.push({type:"invalid-input",code:"invalid-termination-timeout",message:"Termination timeout must be at least 1000ms",path:"options.terminationTimeout",suggestions:[]}),s.push("Set termination timeout to at least 1000ms for graceful shutdown"))),a.eventHandlers&&a.eventHandlers.length>0)for(const e of a.eventHandlers)if(e.options?.throttle&&e.options?.debounce&&(r.push({type:"schema-validation",code:"conflicting-performance-options",message:"Cannot use both throttle and debounce simultaneously",path:"eventHandlers.options",suggestions:[]}),s.push("Choose either throttle OR debounce, not both")),e.filter)try{Function("message","return "+e.filter)}catch(t){r.push({type:"invalid-input",code:"invalid-filter-expression",message:"Invalid filter expression: "+e.filter,path:"eventHandlers.filter",suggestions:[]}),s.push("Use valid JavaScript expression for message filtering")}return"undefined"==typeof Worker&&(r.push({type:"runtime-error",message:"Web Workers are not supported in this environment",suggestions:[]}),s.push("Web Workers require a browser environment")),{isValid:0===r.length,errors:r,suggestions:s}}catch(e){return{isValid:!1,errors:[{type:"schema-validation",suggestions:[],message:e instanceof Error?e.message:"Invalid input format"}],suggestions:["Ensure input matches WebWorkerInput schema","Check worker configuration structure","Verify messaging and event handler configurations"]}}}async initializeConfig(e){return{...e.options,environment:e.environment,debug:e.debug,initialized:Date.now()}}async createWorker(e,t){const r=`worker-${Date.now()}-${Math.random().toString(36).substring(2,11)}`;let s;if(e.inline){const t=new Blob([e.script],{type:"application/javascript"}),a=URL.createObjectURL(t);s=new Worker(a,{type:e.type||"classic",name:e.name||r}),setTimeout(()=>URL.revokeObjectURL(a),0)}else s=new Worker(e.script,{type:e.type||"classic",name:e.name||r});const a={id:r,name:e.name,worker:s,script:e.script,type:e.type||"classic",state:"starting",createdAt:Date.now(),lastMessageTime:0,messageCount:0,errorCount:0,isTerminating:!1};return s.onmessage=e=>{a.messageCount++,a.lastMessageTime=Date.now(),this.handleWorkerMessage(a,e)},s.onerror=e=>{a.errorCount++,a.state="error",this.handleWorkerError(a,e)},s.onmessageerror=e=>{a.errorCount++,this.handleWorkerMessageError(a,e)},this.workers.set(r,a),a.state="running",a}handleWorkerMessage(e,t){const s={id:`msg-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,workerId:e.id,type:"incoming",data:t.data,timestamp:Date.now(),format:this.detectMessageFormat(t.data)};r(this.messageHistory,s),this.processEventHandlers(e.id,"message",t)}handleWorkerError(e,t){r(this.errorHistory,{error:Error("Worker error: "+t.message),timestamp:Date.now(),context:{worker:e,event:t}}),this.processEventHandlers(e.id,"error",t)}handleWorkerMessageError(e,t){r(this.errorHistory,{error:Error("Worker message error: Failed to deserialize message"),timestamp:Date.now(),context:{worker:e,event:t}}),this.processEventHandlers(e.id,"messageerror",t)}processEventHandlers(e,t,r){const s=Array.from(this.eventHandlers.values()).filter(r=>r.workerId===e&&r.eventType===t&&r.isActive);for(const e of s)this.executeEventHandler(e,r)}async executeEventHandler(e,t){try{if(e.filter&&!this.testMessageFilter(t,e.filter))return;if(e.options?.throttle&&this.isThrottled(e.id,e.options.throttle))return;if(e.options?.debounce)return void this.applyDebounce(e.id,e.options.debounce,()=>{this.executeCommands(e.commands,{event:t})});await this.executeCommands(e.commands,{event:t}),e.executionCount++,e.lastExecutionTime=Date.now()}catch(s){r(this.errorHistory,{error:s,timestamp:Date.now(),context:{handler:e,event:t}})}}async executeCommands(e,t){const r={success:!0,executed:e.length};for(const r of e)"object"==typeof r&&r.name&&await this.executeBasicCommand(r,t);return r}async executeBasicCommand(e,t){e.name}isValidWorkerScript(e){return!(!e.startsWith("http://")&&!e.startsWith("https://"))||!!(e.startsWith("./")||e.startsWith("../")||e.startsWith("/"))}detectMessageFormat(e){return e instanceof ArrayBuffer||e instanceof Uint8Array?"binary":"string"==typeof e?"text":"json"}testMessageFilter(e,t){try{let r=this.filterCache.get(t);return r||(r=Function("message","return "+t),this.filterCache.set(t,r)),!!r(e)}catch{return!0}}isThrottled(e,t){const r=this.throttleTimers.get(e)||0,s=Date.now();return t>s-r||(this.throttleTimers.set(e,s),!1)}applyDebounce(e,t,r){const s=this.debounceTimers.get(e);s&&clearTimeout(s);const a=setTimeout(r,t);this.debounceTimers.set(e,a)}createWorkerCreator(e){return async t=>{if(this.workers.size>=(e.maxWorkers||4))throw Error("Maximum number of workers reached");return await this.createWorker(t,{})}}createWorkerTerminator(){return async(e,t)=>{const r=this.workers.get(e);if(!r)return!1;r.isTerminating=!0,r.state="terminating";return setTimeout(()=>{"terminating"===r.state&&(r.worker.terminate(),r.state="terminated",this.workers.delete(e))},t||5e3),!0}}createWorkerRestarter(){return async e=>{const t=this.workers.get(e);if(!t)return!1;t.worker.terminate(),this.workers.delete(e);return(await this.createWorker({script:t.script,type:t.type,name:t.name,inline:!1},{})).id}}createWorkerGetter(){return e=>this.workers.get(e)||null}createWorkerLister(){return()=>Array.from(this.workers.keys())}createWorkerInfoGetter(){return e=>{const t=this.workers.get(e);return t?{id:t.id,name:t.name,state:t.state,createdAt:t.createdAt,messageCount:t.messageCount,errorCount:t.errorCount,lastMessageTime:t.lastMessageTime}:null}}createMessageSender(){return async(e,t,s)=>{const a=this.workers.get(e);if(!a||"running"!==a.state)return!1;try{a.worker.postMessage(t,s||[]);const n={id:`msg-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,workerId:e,type:"outgoing",data:t,...s&&{transferables:s},timestamp:Date.now(),format:this.detectMessageFormat(t)};return r(this.messageHistory,n),!0}catch(s){return r(this.errorHistory,{error:s,timestamp:Date.now(),context:{workerId:e,data:t}}),!1}}}createJSONSender(){return async(e,t)=>await this.createMessageSender()(e,t)}createBinarySender(){return async(e,t)=>{const r=t instanceof ArrayBuffer?[t]:[];return await this.createMessageSender()(e,t,r)}}createBroadcaster(){return async(e,t)=>{const r=[];for(const s of this.workers.keys()){const a=await this.createMessageSender()(s,e,t);r.push(a)}return r.every(e=>e)}}createMessageHistoryGetter(){return(e,t)=>{let r=this.messageHistory;return e&&(r=r.filter(t=>t.workerId===e)),t&&(r=r.slice(-t)),r}}createMessageSubscriber(){return async(e,t)=>{const r=`handler-${Date.now()}-${Math.random().toString(36).substring(2,11)}`;return this.eventHandlers.set(r,{id:r,workerId:"",eventType:e,commands:[t],isActive:!0,executionCount:0,lastExecutionTime:0}),r}}createMessageUnsubscriber(){return e=>this.eventHandlers.delete(e)}createEventHandlerAdder(){return async(e,t,r)=>{const s=`handler-${Date.now()}-${Math.random().toString(36).substring(2,11)}`;return this.eventHandlers.set(s,{id:s,workerId:e,eventType:t,commands:[r],isActive:!0,executionCount:0,lastExecutionTime:0}),s}}createEventHandlerRemover(){return e=>this.eventHandlers.delete(e)}createEventHandlerGetter(){return e=>e?Array.from(this.eventHandlers.values()).filter(t=>t.workerId===e):Array.from(this.eventHandlers.values())}createEventEmitter(){return async(e,t,r)=>!0}createQueueAdder(){return async(e,t)=>{this.messageQueue.has(e)||this.messageQueue.set(e,[]);return this.messageQueue.get(e).push({id:`queued-${Date.now()}-${Math.random().toString(36).substring(2,11)}`,workerId:e,type:"outgoing",data:t,timestamp:Date.now(),format:this.detectMessageFormat(t)}),!0}}createQueueProcessor(){return async e=>{const t=this.messageQueue.get(e);if(!t||0===t.length)return!0;const s=this.workers.get(e);if(!s||"running"!==s.state)return!1;try{for(const e of t)s.worker.postMessage(e.data),r(this.messageHistory,e);return t.length=0,!0}catch(s){return r(this.errorHistory,{error:s,timestamp:Date.now(),context:{workerId:e,queueSize:t.length}}),!1}}}createQueueSizeGetter(){return e=>{const t=this.messageQueue.get(e);return t?t.length:0}}createPendingGetter(){return e=>{const t=this.messageQueue.get(e);return t?t.slice():[]}}createQueueClearer(){return e=>{const t=this.messageQueue.get(e);return!!t&&(t.length=0,!0)}}createErrorHandler(){return async(e,t)=>(r(this.errorHistory,{error:e,timestamp:Date.now(),context:t}),!0)}createErrorHistoryGetter(){return e=>e?this.errorHistory.slice(-e):this.errorHistory.slice()}createErrorClearer(){return()=>(this.errorHistory=[],!0)}createErrorHandlerSetter(){return e=>!0}dispose(){for(const e of this.workers.values())e.worker.terminate();this.workers.clear();for(const e of this.debounceTimers.values())clearTimeout(e);this.debounceTimers.clear();for(const e of this.throttleTimers.values())clearTimeout(e);this.throttleTimers.clear(),this.eventHandlers.clear(),this.messageQueue.clear(),this.filterCache.clear(),this.messageHistory=[],this.errorHistory=[],this.evaluationHistory=[]}trackPerformance(e,t,s){const a=Date.now()-e;r(this.evaluationHistory,{input:{},output:s,success:t,duration:a,timestamp:e})}getPerformanceMetrics(){return{totalInitializations:this.evaluationHistory.length,successRate:this.evaluationHistory.filter(e=>e.success).length/Math.max(this.evaluationHistory.length,1),averageDuration:this.evaluationHistory.reduce((e,t)=>e+t.duration,0)/Math.max(this.evaluationHistory.length,1),lastEvaluationTime:this.evaluationHistory[this.evaluationHistory.length-1]?.timestamp||0,evaluationHistory:this.evaluationHistory.slice(-10),totalWorkers:this.workers.size,totalMessages:this.messageHistory.length,totalErrors:this.errorHistory.length,totalEventHandlers:this.eventHandlers.size,queuedMessages:Array.from(this.messageQueue.values()).reduce((e,t)=>e+t.length,0)}}}function o(){return new n}async function i(e,t){return(new n).initialize({worker:{script:"",type:"classic",credentials:"same-origin",inline:!1,...e},messaging:{format:"json",serialization:"structured-clone",transferables:[],validation:{enabled:!0},queue:{enabled:!0,maxSize:100,persistence:!1}},eventHandlers:[],context:{variables:{}},options:{enableAutoStart:!0,enableMessageQueue:!0,enableErrorHandling:!0,maxWorkers:4,workerTimeout:3e4,terminationTimeout:5e3},environment:"frontend",debug:!1,...t})}const c=new n;export{n as TypedWebWorkerFeatureImplementation,s as WebWorkerInputSchema,a as WebWorkerOutputSchema,i as createWebWorker,o as createWebWorkerFeature,c as enhancedWebWorkerImplementation};
|
|
2
|
+
//# sourceMappingURL=feature-webworker-3bAp0ac9.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
let n=null;async function t(){if(!n)try{n=await import("./browser-modular-BA3JFmkq.js").then(function(n){return n.n})}catch{throw Error("@lokascript/framework is required for LSE support. Install it: npm install @lokascript/framework")}return n}function r(){if(n)return!0;try{return require.resolve("@lokascript/framework"),!0}catch{return!1}}async function a(n,r){return(await t()).parseExplicit(n,r)}async function o(n){return(await t()).isExplicitSyntax(n)}async function i(n){return(await t()).renderExplicit(n)}async function e(n){return(await t()).fromInterchangeNode(n)}async function c(n){return(await t()).toProtocolJSON(n)}async function u(n){return(await t()).fromProtocolJSON(n)}async function s(n){return(await t()).validateProtocolJSON(n)}async function f(n){return(await t()).toEnvelopeJSON(n)}async function l(n){return(await t()).fromEnvelopeJSON(n)}async function w(n){return(await t()).isEnvelope(n)}async function p(n){return(await t()).semanticNodeToRuntimeAST(n)}export{l as fromEnvelopeJSON,e as fromInterchangeNode,u as fromProtocolJSON,w as isEnvelope,o as isExplicitSyntax,r as isLSEAvailable,a as parseExplicit,i as renderExplicit,p as semanticNodeToRuntimeAST,f as toEnvelopeJSON,c as toProtocolJSON,s as validateProtocolJSON};
|
|
2
|
+
//# sourceMappingURL=index-C6Fn0jGB.js.map
|
package/dist/commands/index.js
CHANGED
|
@@ -1683,8 +1683,9 @@ const SPECIAL_DOM_PROPERTIES = {
|
|
|
1683
1683
|
outerhtml: el => el.outerHTML,
|
|
1684
1684
|
value: el => (isFormElement(el) ? el.value : undefined),
|
|
1685
1685
|
checked: el => (isInputElement$1(el) ? el.checked : undefined),
|
|
1686
|
-
disabled: el => (
|
|
1686
|
+
disabled: el => ('disabled' in el ? el.disabled : undefined),
|
|
1687
1687
|
selected: el => (isOptionElement$1(el) ? el.selected : undefined),
|
|
1688
|
+
tabindex: el => (isHTMLElement$1(el) ? el.tabIndex : undefined),
|
|
1688
1689
|
hidden: el => (isHTMLElement$1(el) ? el.hidden : undefined),
|
|
1689
1690
|
style: el => getComputedStyle(el),
|
|
1690
1691
|
children: el => Array.from(el.children),
|
|
@@ -1693,7 +1694,19 @@ const SPECIAL_DOM_PROPERTIES = {
|
|
|
1693
1694
|
lastchild: el => el.lastElementChild,
|
|
1694
1695
|
nextsibling: el => el.nextElementSibling,
|
|
1695
1696
|
previoussibling: el => el.previousElementSibling,
|
|
1697
|
+
values: el => collectFormValues(el),
|
|
1696
1698
|
};
|
|
1699
|
+
function collectFormValues(el) {
|
|
1700
|
+
if (el instanceof HTMLFormElement)
|
|
1701
|
+
return new FormData(el);
|
|
1702
|
+
const fd = new FormData();
|
|
1703
|
+
el.querySelectorAll('input, select, textarea').forEach((input) => {
|
|
1704
|
+
const name = input.getAttribute('name');
|
|
1705
|
+
if (name && 'value' in input)
|
|
1706
|
+
fd.append(name, input.value);
|
|
1707
|
+
});
|
|
1708
|
+
return fd;
|
|
1709
|
+
}
|
|
1697
1710
|
function getElementProperty$1(element, property) {
|
|
1698
1711
|
if (property.startsWith('computed-')) {
|
|
1699
1712
|
const cssProperty = property.slice('computed-'.length);
|
|
@@ -2114,6 +2127,41 @@ let ToggleCommand = (() => {
|
|
|
2114
2127
|
if (propertyTarget) {
|
|
2115
2128
|
return { type: 'property', target: propertyTarget };
|
|
2116
2129
|
}
|
|
2130
|
+
if (firstArg.type === 'selector' &&
|
|
2131
|
+
typeof firstArg.value === 'string' &&
|
|
2132
|
+
firstArg.value.startsWith('*')) {
|
|
2133
|
+
let expression = firstArg.value;
|
|
2134
|
+
let argsConsumed = 1;
|
|
2135
|
+
if (expression === '*' && raw.args.length > 1 && raw.args[1].type === 'identifier') {
|
|
2136
|
+
expression = '*' + raw.args[1].name;
|
|
2137
|
+
argsConsumed = 2;
|
|
2138
|
+
}
|
|
2139
|
+
if (expression === '*' && raw.modifiers?.on) {
|
|
2140
|
+
const modOnName = raw.modifiers.on?.name;
|
|
2141
|
+
if (modOnName && ['display', 'visibility', 'opacity'].includes(modOnName)) {
|
|
2142
|
+
expression = '*' + modOnName;
|
|
2143
|
+
const { duration, untilEvent } = await parseTemporalModifiers(raw.modifiers, evaluator, context);
|
|
2144
|
+
const property = parseToggleableCSSProperty(expression);
|
|
2145
|
+
if (property) {
|
|
2146
|
+
const me = context.me;
|
|
2147
|
+
return {
|
|
2148
|
+
type: 'css-property',
|
|
2149
|
+
property,
|
|
2150
|
+
targets: me ? [me] : [],
|
|
2151
|
+
duration,
|
|
2152
|
+
untilEvent,
|
|
2153
|
+
};
|
|
2154
|
+
}
|
|
2155
|
+
}
|
|
2156
|
+
}
|
|
2157
|
+
const property = parseToggleableCSSProperty(expression);
|
|
2158
|
+
if (property) {
|
|
2159
|
+
const { duration, untilEvent } = await parseTemporalModifiers(raw.modifiers, evaluator, context);
|
|
2160
|
+
const resolveOpts = { filterPrepositions: true, fallbackModifierKey: 'on' };
|
|
2161
|
+
const targets = await resolveTargetsFromArgs(raw.args.slice(argsConsumed), evaluator, context, 'toggle', resolveOpts, raw.modifiers);
|
|
2162
|
+
return { type: 'css-property', property, targets, duration, untilEvent };
|
|
2163
|
+
}
|
|
2164
|
+
}
|
|
2117
2165
|
const { duration, untilEvent } = await parseTemporalModifiers(raw.modifiers, evaluator, context);
|
|
2118
2166
|
const { value: firstValue } = await evaluateFirstArg(firstArg, evaluator, context);
|
|
2119
2167
|
if (isPropertyTargetString(firstValue)) {
|
|
@@ -2928,6 +2976,7 @@ var Operation = {
|
|
|
2928
2976
|
};
|
|
2929
2977
|
var candidateNodes = new Set;
|
|
2930
2978
|
var candidateElements = new Set;
|
|
2979
|
+
var candidateElementsWithIds = new Set;
|
|
2931
2980
|
var unmatchedNodes = new Set;
|
|
2932
2981
|
var unmatchedElements = new Set;
|
|
2933
2982
|
var whitespaceNodes = new Set;
|
|
@@ -3147,6 +3196,7 @@ class Morph {
|
|
|
3147
3196
|
const toChildNodes = [...to.childNodes];
|
|
3148
3197
|
candidateNodes.clear();
|
|
3149
3198
|
candidateElements.clear();
|
|
3199
|
+
candidateElementsWithIds.clear();
|
|
3150
3200
|
unmatchedNodes.clear();
|
|
3151
3201
|
unmatchedElements.clear();
|
|
3152
3202
|
whitespaceNodes.clear();
|
|
@@ -3162,7 +3212,11 @@ class Morph {
|
|
|
3162
3212
|
candidateNodeTypeMap[i] = nodeType;
|
|
3163
3213
|
if (nodeType === ELEMENT_NODE_TYPE) {
|
|
3164
3214
|
candidateLocalNameMap[i] = candidate.localName;
|
|
3165
|
-
|
|
3215
|
+
if (candidate.id !== "") {
|
|
3216
|
+
candidateElementsWithIds.add(i);
|
|
3217
|
+
} else {
|
|
3218
|
+
candidateElements.add(i);
|
|
3219
|
+
}
|
|
3166
3220
|
} else if (nodeType === TEXT_NODE_TYPE && candidate.textContent?.trim() === "") {
|
|
3167
3221
|
whitespaceNodes.add(i);
|
|
3168
3222
|
} else {
|
|
@@ -3205,13 +3259,13 @@ class Morph {
|
|
|
3205
3259
|
if (id === "" && !idArray)
|
|
3206
3260
|
continue;
|
|
3207
3261
|
candidateLoop:
|
|
3208
|
-
for (const candidateIndex of
|
|
3262
|
+
for (const candidateIndex of candidateElementsWithIds) {
|
|
3209
3263
|
const candidate = fromChildNodes[candidateIndex];
|
|
3210
3264
|
if (localNameMap[unmatchedIndex] === candidateLocalNameMap[candidateIndex]) {
|
|
3211
3265
|
if (id !== "" && id === candidate.id) {
|
|
3212
3266
|
matches[unmatchedIndex] = candidateIndex;
|
|
3213
3267
|
op[unmatchedIndex] = Operation.SameElement;
|
|
3214
|
-
|
|
3268
|
+
candidateElementsWithIds.delete(candidateIndex);
|
|
3215
3269
|
unmatchedElements.delete(unmatchedIndex);
|
|
3216
3270
|
break candidateLoop;
|
|
3217
3271
|
}
|
|
@@ -3223,7 +3277,7 @@ class Morph {
|
|
|
3223
3277
|
if (candidateIdSet.has(arrayId)) {
|
|
3224
3278
|
matches[unmatchedIndex] = candidateIndex;
|
|
3225
3279
|
op[unmatchedIndex] = Operation.SameElement;
|
|
3226
|
-
|
|
3280
|
+
candidateElementsWithIds.delete(candidateIndex);
|
|
3227
3281
|
unmatchedElements.delete(unmatchedIndex);
|
|
3228
3282
|
break candidateLoop;
|
|
3229
3283
|
}
|
|
@@ -3298,6 +3352,8 @@ class Morph {
|
|
|
3298
3352
|
this.#removeNode(fromChildNodes[i]);
|
|
3299
3353
|
for (const i of candidateElements)
|
|
3300
3354
|
this.#removeNode(fromChildNodes[i]);
|
|
3355
|
+
for (const i of candidateElementsWithIds)
|
|
3356
|
+
this.#removeNode(fromChildNodes[i]);
|
|
3301
3357
|
const lisIndices = longestIncreasingSubsequence(matches);
|
|
3302
3358
|
const shouldNotMove = new Array(fromChildNodes.length);
|
|
3303
3359
|
for (let i = 0;i < lisIndices.length; i++) {
|
|
@@ -3442,7 +3498,7 @@ function longestIncreasingSubsequence(sequence) {
|
|
|
3442
3498
|
return result;
|
|
3443
3499
|
}
|
|
3444
3500
|
|
|
3445
|
-
//# debugId=
|
|
3501
|
+
//# debugId=3F4BCB911DEC843864756E2164756E21
|
|
3446
3502
|
|
|
3447
3503
|
const morphlexMorph = morph;
|
|
3448
3504
|
const morphlexMorphInner = morphInner;
|
package/dist/commands/index.mjs
CHANGED
|
@@ -1681,8 +1681,9 @@ const SPECIAL_DOM_PROPERTIES = {
|
|
|
1681
1681
|
outerhtml: el => el.outerHTML,
|
|
1682
1682
|
value: el => (isFormElement(el) ? el.value : undefined),
|
|
1683
1683
|
checked: el => (isInputElement$1(el) ? el.checked : undefined),
|
|
1684
|
-
disabled: el => (
|
|
1684
|
+
disabled: el => ('disabled' in el ? el.disabled : undefined),
|
|
1685
1685
|
selected: el => (isOptionElement$1(el) ? el.selected : undefined),
|
|
1686
|
+
tabindex: el => (isHTMLElement$1(el) ? el.tabIndex : undefined),
|
|
1686
1687
|
hidden: el => (isHTMLElement$1(el) ? el.hidden : undefined),
|
|
1687
1688
|
style: el => getComputedStyle(el),
|
|
1688
1689
|
children: el => Array.from(el.children),
|
|
@@ -1691,7 +1692,19 @@ const SPECIAL_DOM_PROPERTIES = {
|
|
|
1691
1692
|
lastchild: el => el.lastElementChild,
|
|
1692
1693
|
nextsibling: el => el.nextElementSibling,
|
|
1693
1694
|
previoussibling: el => el.previousElementSibling,
|
|
1695
|
+
values: el => collectFormValues(el),
|
|
1694
1696
|
};
|
|
1697
|
+
function collectFormValues(el) {
|
|
1698
|
+
if (el instanceof HTMLFormElement)
|
|
1699
|
+
return new FormData(el);
|
|
1700
|
+
const fd = new FormData();
|
|
1701
|
+
el.querySelectorAll('input, select, textarea').forEach((input) => {
|
|
1702
|
+
const name = input.getAttribute('name');
|
|
1703
|
+
if (name && 'value' in input)
|
|
1704
|
+
fd.append(name, input.value);
|
|
1705
|
+
});
|
|
1706
|
+
return fd;
|
|
1707
|
+
}
|
|
1695
1708
|
function getElementProperty$1(element, property) {
|
|
1696
1709
|
if (property.startsWith('computed-')) {
|
|
1697
1710
|
const cssProperty = property.slice('computed-'.length);
|
|
@@ -2112,6 +2125,41 @@ let ToggleCommand = (() => {
|
|
|
2112
2125
|
if (propertyTarget) {
|
|
2113
2126
|
return { type: 'property', target: propertyTarget };
|
|
2114
2127
|
}
|
|
2128
|
+
if (firstArg.type === 'selector' &&
|
|
2129
|
+
typeof firstArg.value === 'string' &&
|
|
2130
|
+
firstArg.value.startsWith('*')) {
|
|
2131
|
+
let expression = firstArg.value;
|
|
2132
|
+
let argsConsumed = 1;
|
|
2133
|
+
if (expression === '*' && raw.args.length > 1 && raw.args[1].type === 'identifier') {
|
|
2134
|
+
expression = '*' + raw.args[1].name;
|
|
2135
|
+
argsConsumed = 2;
|
|
2136
|
+
}
|
|
2137
|
+
if (expression === '*' && raw.modifiers?.on) {
|
|
2138
|
+
const modOnName = raw.modifiers.on?.name;
|
|
2139
|
+
if (modOnName && ['display', 'visibility', 'opacity'].includes(modOnName)) {
|
|
2140
|
+
expression = '*' + modOnName;
|
|
2141
|
+
const { duration, untilEvent } = await parseTemporalModifiers(raw.modifiers, evaluator, context);
|
|
2142
|
+
const property = parseToggleableCSSProperty(expression);
|
|
2143
|
+
if (property) {
|
|
2144
|
+
const me = context.me;
|
|
2145
|
+
return {
|
|
2146
|
+
type: 'css-property',
|
|
2147
|
+
property,
|
|
2148
|
+
targets: me ? [me] : [],
|
|
2149
|
+
duration,
|
|
2150
|
+
untilEvent,
|
|
2151
|
+
};
|
|
2152
|
+
}
|
|
2153
|
+
}
|
|
2154
|
+
}
|
|
2155
|
+
const property = parseToggleableCSSProperty(expression);
|
|
2156
|
+
if (property) {
|
|
2157
|
+
const { duration, untilEvent } = await parseTemporalModifiers(raw.modifiers, evaluator, context);
|
|
2158
|
+
const resolveOpts = { filterPrepositions: true, fallbackModifierKey: 'on' };
|
|
2159
|
+
const targets = await resolveTargetsFromArgs(raw.args.slice(argsConsumed), evaluator, context, 'toggle', resolveOpts, raw.modifiers);
|
|
2160
|
+
return { type: 'css-property', property, targets, duration, untilEvent };
|
|
2161
|
+
}
|
|
2162
|
+
}
|
|
2115
2163
|
const { duration, untilEvent } = await parseTemporalModifiers(raw.modifiers, evaluator, context);
|
|
2116
2164
|
const { value: firstValue } = await evaluateFirstArg(firstArg, evaluator, context);
|
|
2117
2165
|
if (isPropertyTargetString(firstValue)) {
|
|
@@ -2926,6 +2974,7 @@ var Operation = {
|
|
|
2926
2974
|
};
|
|
2927
2975
|
var candidateNodes = new Set;
|
|
2928
2976
|
var candidateElements = new Set;
|
|
2977
|
+
var candidateElementsWithIds = new Set;
|
|
2929
2978
|
var unmatchedNodes = new Set;
|
|
2930
2979
|
var unmatchedElements = new Set;
|
|
2931
2980
|
var whitespaceNodes = new Set;
|
|
@@ -3145,6 +3194,7 @@ class Morph {
|
|
|
3145
3194
|
const toChildNodes = [...to.childNodes];
|
|
3146
3195
|
candidateNodes.clear();
|
|
3147
3196
|
candidateElements.clear();
|
|
3197
|
+
candidateElementsWithIds.clear();
|
|
3148
3198
|
unmatchedNodes.clear();
|
|
3149
3199
|
unmatchedElements.clear();
|
|
3150
3200
|
whitespaceNodes.clear();
|
|
@@ -3160,7 +3210,11 @@ class Morph {
|
|
|
3160
3210
|
candidateNodeTypeMap[i] = nodeType;
|
|
3161
3211
|
if (nodeType === ELEMENT_NODE_TYPE) {
|
|
3162
3212
|
candidateLocalNameMap[i] = candidate.localName;
|
|
3163
|
-
|
|
3213
|
+
if (candidate.id !== "") {
|
|
3214
|
+
candidateElementsWithIds.add(i);
|
|
3215
|
+
} else {
|
|
3216
|
+
candidateElements.add(i);
|
|
3217
|
+
}
|
|
3164
3218
|
} else if (nodeType === TEXT_NODE_TYPE && candidate.textContent?.trim() === "") {
|
|
3165
3219
|
whitespaceNodes.add(i);
|
|
3166
3220
|
} else {
|
|
@@ -3203,13 +3257,13 @@ class Morph {
|
|
|
3203
3257
|
if (id === "" && !idArray)
|
|
3204
3258
|
continue;
|
|
3205
3259
|
candidateLoop:
|
|
3206
|
-
for (const candidateIndex of
|
|
3260
|
+
for (const candidateIndex of candidateElementsWithIds) {
|
|
3207
3261
|
const candidate = fromChildNodes[candidateIndex];
|
|
3208
3262
|
if (localNameMap[unmatchedIndex] === candidateLocalNameMap[candidateIndex]) {
|
|
3209
3263
|
if (id !== "" && id === candidate.id) {
|
|
3210
3264
|
matches[unmatchedIndex] = candidateIndex;
|
|
3211
3265
|
op[unmatchedIndex] = Operation.SameElement;
|
|
3212
|
-
|
|
3266
|
+
candidateElementsWithIds.delete(candidateIndex);
|
|
3213
3267
|
unmatchedElements.delete(unmatchedIndex);
|
|
3214
3268
|
break candidateLoop;
|
|
3215
3269
|
}
|
|
@@ -3221,7 +3275,7 @@ class Morph {
|
|
|
3221
3275
|
if (candidateIdSet.has(arrayId)) {
|
|
3222
3276
|
matches[unmatchedIndex] = candidateIndex;
|
|
3223
3277
|
op[unmatchedIndex] = Operation.SameElement;
|
|
3224
|
-
|
|
3278
|
+
candidateElementsWithIds.delete(candidateIndex);
|
|
3225
3279
|
unmatchedElements.delete(unmatchedIndex);
|
|
3226
3280
|
break candidateLoop;
|
|
3227
3281
|
}
|
|
@@ -3296,6 +3350,8 @@ class Morph {
|
|
|
3296
3350
|
this.#removeNode(fromChildNodes[i]);
|
|
3297
3351
|
for (const i of candidateElements)
|
|
3298
3352
|
this.#removeNode(fromChildNodes[i]);
|
|
3353
|
+
for (const i of candidateElementsWithIds)
|
|
3354
|
+
this.#removeNode(fromChildNodes[i]);
|
|
3299
3355
|
const lisIndices = longestIncreasingSubsequence(matches);
|
|
3300
3356
|
const shouldNotMove = new Array(fromChildNodes.length);
|
|
3301
3357
|
for (let i = 0;i < lisIndices.length; i++) {
|
|
@@ -3440,7 +3496,7 @@ function longestIncreasingSubsequence(sequence) {
|
|
|
3440
3496
|
return result;
|
|
3441
3497
|
}
|
|
3442
3498
|
|
|
3443
|
-
//# debugId=
|
|
3499
|
+
//# debugId=3F4BCB911DEC843864756E2164756E21
|
|
3444
3500
|
|
|
3445
3501
|
const morphlexMorph = morph;
|
|
3446
3502
|
const morphlexMorphInner = morphInner;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { RuntimeHooks } from '../types/hooks';
|
|
2
|
+
export type StepMode = 'continue' | 'over' | 'into' | 'out' | 'pause';
|
|
3
|
+
export interface BreakpointCondition {
|
|
4
|
+
id: string;
|
|
5
|
+
type: 'command' | 'element' | 'expression';
|
|
6
|
+
value: string;
|
|
7
|
+
enabled: boolean;
|
|
8
|
+
hitCount: number;
|
|
9
|
+
}
|
|
10
|
+
export interface DebugSnapshot {
|
|
11
|
+
commandName: string;
|
|
12
|
+
element: Element | null;
|
|
13
|
+
variables: Record<string, unknown>;
|
|
14
|
+
timestamp: number;
|
|
15
|
+
depth: number;
|
|
16
|
+
index: number;
|
|
17
|
+
}
|
|
18
|
+
export interface DebugState {
|
|
19
|
+
enabled: boolean;
|
|
20
|
+
paused: boolean;
|
|
21
|
+
stepMode: StepMode;
|
|
22
|
+
callDepth: number;
|
|
23
|
+
pauseDepth: number;
|
|
24
|
+
currentSnapshot: DebugSnapshot | null;
|
|
25
|
+
}
|
|
26
|
+
export type DebugEventType = 'paused' | 'resumed' | 'snapshot' | 'enabled' | 'disabled';
|
|
27
|
+
export type DebugEventListener = (data: DebugSnapshot | undefined) => void;
|
|
28
|
+
export declare class DebugController {
|
|
29
|
+
private state;
|
|
30
|
+
private history;
|
|
31
|
+
private breakpoints;
|
|
32
|
+
private snapshotIndex;
|
|
33
|
+
private _resumeResolver;
|
|
34
|
+
private listeners;
|
|
35
|
+
readonly hooks: RuntimeHooks;
|
|
36
|
+
constructor();
|
|
37
|
+
on(event: DebugEventType, listener: DebugEventListener): () => void;
|
|
38
|
+
private emit;
|
|
39
|
+
enable(): void;
|
|
40
|
+
disable(): void;
|
|
41
|
+
get enabled(): boolean;
|
|
42
|
+
continue(): void;
|
|
43
|
+
pause(): void;
|
|
44
|
+
stepOver(): void;
|
|
45
|
+
stepInto(): void;
|
|
46
|
+
stepOut(): void;
|
|
47
|
+
private resume;
|
|
48
|
+
setBreakpoint(condition: Omit<BreakpointCondition, 'id' | 'hitCount'>): string;
|
|
49
|
+
removeBreakpoint(id: string): boolean;
|
|
50
|
+
getBreakpoints(): BreakpointCondition[];
|
|
51
|
+
clearBreakpoints(): void;
|
|
52
|
+
getState(): Readonly<DebugState>;
|
|
53
|
+
getHistory(): DebugSnapshot[];
|
|
54
|
+
clearHistory(): void;
|
|
55
|
+
private beforeExecute;
|
|
56
|
+
private afterExecute;
|
|
57
|
+
private shouldPause;
|
|
58
|
+
private hitBreakpoint;
|
|
59
|
+
private evaluateCondition;
|
|
60
|
+
private captureSnapshot;
|
|
61
|
+
}
|
|
62
|
+
//# sourceMappingURL=debug-controller.d.ts.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export { DebugController } from './debug-controller';
|
|
2
|
+
export type { StepMode, BreakpointCondition, DebugSnapshot, DebugState, DebugEventType, DebugEventListener, } from './debug-controller';
|
|
3
|
+
import { DebugController } from './debug-controller';
|
|
4
|
+
export declare function createDebugController(): DebugController;
|
|
5
|
+
//# sourceMappingURL=index.d.ts.map
|