'use strict'; const { PassThrough } = require('node:stream'); const { NxDebugAdapter } = require('./debugAdapter'); function frameMessage(message) { const json = JSON.stringify(message); return `Content-Length: ${Buffer.byteLength(json, 'utf8')}\r\n\r\n${json}`; } class NxInlineDebugAdapter { constructor() { this.input = new PassThrough(); this.output = new PassThrough(); this.outputBuffer = Buffer.alloc(0); this.listeners = new Set(); this.disposed = false; this.onDidSendMessage = (listener, thisArgs, disposables) => { const registration = { listener, thisArgs }; this.listeners.add(registration); const disposable = { dispose: () => this.listeners.delete(registration), }; if (Array.isArray(disposables)) disposables.push(disposable); return disposable; }; this.output.on('data', (chunk) => this.onOutput(chunk)); this.adapter = new NxDebugAdapter(this.input, this.output); } handleMessage(message) { if (!this.disposed) this.input.write(frameMessage(message)); } onOutput(chunk) { this.outputBuffer = Buffer.concat([this.outputBuffer, chunk]); while (true) { const headerEnd = this.outputBuffer.indexOf('\r\n\r\n'); if (headerEnd < 0) return; const header = this.outputBuffer.subarray(0, headerEnd).toString('ascii'); const match = /Content-Length:\s*(\d+)/i.exec(header); if (!match) throw new Error('missing DAP Content-Length header from NX adapter'); const contentLength = Number(match[1]); const messageEnd = headerEnd + 4 + contentLength; if (this.outputBuffer.length < messageEnd) return; const payload = this.outputBuffer.subarray(headerEnd + 4, messageEnd).toString('utf8'); this.outputBuffer = this.outputBuffer.subarray(messageEnd); const message = JSON.parse(payload); for (const { listener, thisArgs } of [...this.listeners]) { listener.call(thisArgs, message); } } } dispose() { if (this.disposed) return; this.disposed = true; this.adapter.dispose(); this.input.end(); this.output.destroy(); this.listeners.clear(); } } module.exports = { NxInlineDebugAdapter, frameMessage };