Archive v0.1.0 — 사진/영상 라이브러리 관리 프로그램
Tauri v2 + SolidJS + SQLite + ffmpeg 사이드카로 구현한 크로스플랫폼 사진·영상 관리 앱. 로컬/NAS(SFTP·WebDAV·FTP) 소스, 가상 그리드, 인앱 재생, 태그/이동/삭제/undo, 중복 탐지, 포터블 배포. - archive-db: SQLite 스키마·마이그레이션·단일 writer 스레드 + FTS5 trigram - archive-vfs: VFS 4백엔드(local/sftp/ftp/webdav) + 자격증명(키체인/볼트) - archive-indexer: 스캔·해시·썸네일·중복탐지·태그·파일작업·유지보수 - archive-media: localhost HTTP 미디어 서버(Range) + ffmpeg 스트림 잡 - 프론트: 3-pane UI, justified 가상 그리드, 라이트박스, 중복 검토 패널 Rust 테스트 49개 통과. CI: win x64/arm64 포터블 zip + macOS universal dmg. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
# WebView2 CDP (Chrome DevTools Protocol) E2E helper.
|
||||
# Usage: . .\scripts\cdp.ps1; Invoke-Cdp "document.title"
|
||||
# Prereq: app launched with WEBVIEW2_ADDITIONAL_BROWSER_ARGUMENTS=--remote-debugging-port=9223
|
||||
# NOTE: ASCII only in this file (PS 5.1 reads BOM-less files as ANSI).
|
||||
|
||||
function Invoke-Cdp {
|
||||
param(
|
||||
[Parameter(Mandatory)] [string]$Expression,
|
||||
[int]$Port = 9223,
|
||||
[int]$TimeoutSec = 20
|
||||
)
|
||||
$targets = Invoke-RestMethod "http://127.0.0.1:$Port/json"
|
||||
$page = $targets | Where-Object { $_.type -eq 'page' -and $_.url -notlike 'devtools*' } | Select-Object -First 1
|
||||
if (-not $page) { throw "no CDP page target" }
|
||||
|
||||
$ws = New-Object System.Net.WebSockets.ClientWebSocket
|
||||
$ct = [System.Threading.CancellationToken]::None
|
||||
$uri = [Uri]$page.webSocketDebuggerUrl
|
||||
$ws.ConnectAsync($uri, $ct).GetAwaiter().GetResult() | Out-Null
|
||||
|
||||
$msg = @{
|
||||
id = 1
|
||||
method = "Runtime.evaluate"
|
||||
params = @{
|
||||
expression = $Expression
|
||||
returnByValue = $true
|
||||
awaitPromise = $true
|
||||
}
|
||||
} | ConvertTo-Json -Depth 6 -Compress
|
||||
$bytes = [System.Text.Encoding]::UTF8.GetBytes($msg)
|
||||
$seg = New-Object System.ArraySegment[byte] -ArgumentList @(,$bytes)
|
||||
$ws.SendAsync($seg, [System.Net.WebSockets.WebSocketMessageType]::Text, $true, $ct).GetAwaiter().GetResult() | Out-Null
|
||||
|
||||
$buffer = New-Object byte[] 1048576
|
||||
$deadline = (Get-Date).AddSeconds($TimeoutSec)
|
||||
$response = $null
|
||||
while ((Get-Date) -lt $deadline) {
|
||||
$sb = New-Object System.Text.StringBuilder
|
||||
do {
|
||||
$rseg = New-Object System.ArraySegment[byte] -ArgumentList @(,$buffer)
|
||||
$result = $ws.ReceiveAsync($rseg, $ct).GetAwaiter().GetResult()
|
||||
$sb.Append([System.Text.Encoding]::UTF8.GetString($buffer, 0, $result.Count)) | Out-Null
|
||||
} while (-not $result.EndOfMessage)
|
||||
$obj = $sb.ToString() | ConvertFrom-Json
|
||||
if ($obj.id -eq 1) { $response = $obj; break }
|
||||
}
|
||||
$ws.Abort()
|
||||
if (-not $response) { throw "CDP response timeout" }
|
||||
if ($response.result.exceptionDetails) {
|
||||
throw "JS exception: $($response.result.exceptionDetails.text) $($response.result.exceptionDetails.exception.description)"
|
||||
}
|
||||
return $response.result.result.value
|
||||
}
|
||||
Reference in New Issue
Block a user