完善样式系统与调试链路底座
This commit is contained in:
250
miniprogram/engine/debug/mockSimulatorDebugLogger.ts
Normal file
250
miniprogram/engine/debug/mockSimulatorDebugLogger.ts
Normal file
@@ -0,0 +1,250 @@
|
||||
const DEFAULT_DEBUG_LOG_URL = 'wss://gs.gotomars.xyz/debug-log'
|
||||
const MAX_QUEUED_LOGS = 80
|
||||
|
||||
export type MockSimulatorDebugLogLevel = 'info' | 'warn' | 'error'
|
||||
|
||||
export interface MockSimulatorDebugLoggerState {
|
||||
enabled: boolean
|
||||
connected: boolean
|
||||
connecting: boolean
|
||||
url: string
|
||||
statusText: string
|
||||
}
|
||||
|
||||
export interface MockSimulatorDebugLogEntry {
|
||||
type: 'debug-log'
|
||||
timestamp: number
|
||||
scope: string
|
||||
level: MockSimulatorDebugLogLevel
|
||||
message: string
|
||||
payload?: Record<string, unknown>
|
||||
}
|
||||
|
||||
function normalizeMockSimulatorLogUrl(rawUrl: string): string {
|
||||
const trimmed = String(rawUrl || '').trim()
|
||||
if (!trimmed) {
|
||||
return DEFAULT_DEBUG_LOG_URL
|
||||
}
|
||||
|
||||
let normalized = trimmed
|
||||
if (!/^wss?:\/\//i.test(normalized)) {
|
||||
normalized = `ws://${normalized.replace(/^\/+/, '')}`
|
||||
}
|
||||
|
||||
if (!/\/debug-log(?:\?.*)?$/i.test(normalized)) {
|
||||
normalized = normalized.replace(/\/+$/, '')
|
||||
normalized = `${normalized}/debug-log`
|
||||
}
|
||||
|
||||
return normalized
|
||||
}
|
||||
|
||||
export class MockSimulatorDebugLogger {
|
||||
socketTask: WechatMiniprogram.SocketTask | null
|
||||
enabled: boolean
|
||||
connected: boolean
|
||||
connecting: boolean
|
||||
url: string
|
||||
queue: MockSimulatorDebugLogEntry[]
|
||||
onStateChange?: (state: MockSimulatorDebugLoggerState) => void
|
||||
|
||||
constructor(onStateChange?: (state: MockSimulatorDebugLoggerState) => void) {
|
||||
this.socketTask = null
|
||||
this.enabled = false
|
||||
this.connected = false
|
||||
this.connecting = false
|
||||
this.url = DEFAULT_DEBUG_LOG_URL
|
||||
this.queue = []
|
||||
this.onStateChange = onStateChange
|
||||
}
|
||||
|
||||
getState(): MockSimulatorDebugLoggerState {
|
||||
return {
|
||||
enabled: this.enabled,
|
||||
connected: this.connected,
|
||||
connecting: this.connecting,
|
||||
url: this.url,
|
||||
statusText: !this.enabled
|
||||
? `已关闭 (${this.url})`
|
||||
: this.connected
|
||||
? `已连接 (${this.url})`
|
||||
: this.connecting
|
||||
? `连接中 (${this.url})`
|
||||
: `未连接 (${this.url})`,
|
||||
}
|
||||
}
|
||||
|
||||
emitState(): void {
|
||||
if (this.onStateChange) {
|
||||
this.onStateChange(this.getState())
|
||||
}
|
||||
}
|
||||
|
||||
setEnabled(enabled: boolean): void {
|
||||
if (this.enabled === enabled) {
|
||||
return
|
||||
}
|
||||
|
||||
this.enabled = enabled
|
||||
if (!enabled) {
|
||||
this.disconnect()
|
||||
this.queue = []
|
||||
this.emitState()
|
||||
return
|
||||
}
|
||||
|
||||
this.emitState()
|
||||
this.connect()
|
||||
}
|
||||
|
||||
setUrl(url: string): void {
|
||||
const nextUrl = normalizeMockSimulatorLogUrl(url)
|
||||
if (this.url === nextUrl) {
|
||||
return
|
||||
}
|
||||
|
||||
this.url = nextUrl
|
||||
if (!this.enabled) {
|
||||
this.emitState()
|
||||
return
|
||||
}
|
||||
|
||||
this.disconnect()
|
||||
this.emitState()
|
||||
this.connect()
|
||||
}
|
||||
|
||||
log(
|
||||
scope: string,
|
||||
level: MockSimulatorDebugLogLevel,
|
||||
message: string,
|
||||
payload?: Record<string, unknown>,
|
||||
): void {
|
||||
if (!this.enabled) {
|
||||
return
|
||||
}
|
||||
|
||||
const entry: MockSimulatorDebugLogEntry = {
|
||||
type: 'debug-log',
|
||||
timestamp: Date.now(),
|
||||
scope,
|
||||
level,
|
||||
message,
|
||||
...(payload ? { payload } : {}),
|
||||
}
|
||||
|
||||
if (this.connected && this.socketTask) {
|
||||
this.send(entry)
|
||||
return
|
||||
}
|
||||
|
||||
this.queue.push(entry)
|
||||
if (this.queue.length > MAX_QUEUED_LOGS) {
|
||||
this.queue.splice(0, this.queue.length - MAX_QUEUED_LOGS)
|
||||
}
|
||||
this.connect()
|
||||
}
|
||||
|
||||
disconnect(): void {
|
||||
const socketTask = this.socketTask
|
||||
this.socketTask = null
|
||||
this.connected = false
|
||||
this.connecting = false
|
||||
if (socketTask) {
|
||||
try {
|
||||
socketTask.close({})
|
||||
} catch (_error) {
|
||||
// noop
|
||||
}
|
||||
}
|
||||
this.emitState()
|
||||
}
|
||||
|
||||
destroy(): void {
|
||||
this.disconnect()
|
||||
this.queue = []
|
||||
}
|
||||
|
||||
connect(): void {
|
||||
if (!this.enabled || this.connected || this.connecting) {
|
||||
return
|
||||
}
|
||||
|
||||
this.connecting = true
|
||||
this.emitState()
|
||||
try {
|
||||
const socketTask = wx.connectSocket({
|
||||
url: this.url,
|
||||
})
|
||||
this.socketTask = socketTask
|
||||
|
||||
socketTask.onOpen(() => {
|
||||
this.connected = true
|
||||
this.connecting = false
|
||||
this.emitState()
|
||||
this.send({
|
||||
type: 'debug-log',
|
||||
timestamp: Date.now(),
|
||||
scope: 'logger',
|
||||
level: 'info',
|
||||
message: 'logger channel connected',
|
||||
payload: {
|
||||
url: this.url,
|
||||
},
|
||||
})
|
||||
this.flush()
|
||||
})
|
||||
|
||||
socketTask.onClose(() => {
|
||||
this.connected = false
|
||||
this.connecting = false
|
||||
this.socketTask = null
|
||||
this.emitState()
|
||||
})
|
||||
|
||||
socketTask.onError(() => {
|
||||
this.connected = false
|
||||
this.connecting = false
|
||||
this.socketTask = null
|
||||
this.emitState()
|
||||
})
|
||||
|
||||
socketTask.onMessage(() => {
|
||||
// 模拟器会广播所有消息,debug logger 不消费回包。
|
||||
})
|
||||
} catch (_error) {
|
||||
this.connected = false
|
||||
this.connecting = false
|
||||
this.socketTask = null
|
||||
this.emitState()
|
||||
}
|
||||
}
|
||||
|
||||
flush(): void {
|
||||
if (!this.connected || !this.socketTask || !this.queue.length) {
|
||||
return
|
||||
}
|
||||
|
||||
const pending = this.queue.splice(0, this.queue.length)
|
||||
pending.forEach((entry) => {
|
||||
this.send(entry)
|
||||
})
|
||||
}
|
||||
|
||||
send(entry: MockSimulatorDebugLogEntry): void {
|
||||
if (!this.socketTask || !this.connected) {
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
this.socketTask.send({
|
||||
data: JSON.stringify(entry),
|
||||
})
|
||||
} catch (_error) {
|
||||
this.connected = false
|
||||
this.connecting = false
|
||||
this.socketTask = null
|
||||
this.emitState()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user