Skip to content

Commit eb57a35

Browse files
committed
fix: running page now opens the appropriate slug
1 parent ea7943f commit eb57a35

5 files changed

Lines changed: 90 additions & 92 deletions

File tree

src-tauri/src/commands.rs

Lines changed: 25 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -277,38 +277,34 @@ pub async fn run_script(
277277

278278
let app_clone = app.clone();
279279

280-
std::thread::spawn(move || {
281-
loop {
282-
// 1. Scope to limit how long we hold the lock
283-
let status = {
284-
let mut inner_guard = shared_process.lock().unwrap();
285-
if let Some(child) = inner_guard.as_mut() {
286-
child.try_wait()
287-
} else {
288-
return;
289-
}
290-
};
291-
292-
match status {
293-
Ok(Some(exit_status)) => {
294-
println!("Process {} exited with status: {}", id, exit_status);
280+
std::thread::spawn(move || loop {
281+
let status = {
282+
let mut inner_guard = shared_process.lock().unwrap();
283+
if let Some(child) = inner_guard.as_mut() {
284+
child.try_wait()
285+
} else {
286+
return;
287+
}
288+
};
295289

296-
if let Some(launcher_state) = app_clone.try_state::<Mutex<LauncherVariables>>()
297-
{
298-
let guard = launcher_state.lock().unwrap();
299-
guard.scripts.lock().unwrap().remove(&id);
300-
}
290+
match status {
291+
Ok(Some(exit_status)) => {
292+
println!("Process {} exited with status: {}", id, exit_status);
301293

302-
let _ = app_clone.emit("process-finished", id);
303-
break;
304-
}
305-
Ok(None) => {
306-
std::thread::sleep(std::time::Duration::from_millis(500));
307-
}
308-
Err(e) => {
309-
println!("Error checking process status: {}", e);
310-
break;
294+
if let Some(launcher_state) = app_clone.try_state::<Mutex<LauncherVariables>>() {
295+
let guard = launcher_state.lock().unwrap();
296+
guard.scripts.lock().unwrap().remove(&id);
311297
}
298+
299+
let _ = app_clone.emit("process-finished", id);
300+
break;
301+
}
302+
Ok(None) => {
303+
std::thread::sleep(std::time::Duration::from_millis(500));
304+
}
305+
Err(e) => {
306+
println!("Error checking process status: {}", e);
307+
break;
312308
}
313309
}
314310
});

src/lib/communication.svelte.ts

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,49 +2,59 @@ import { Channel } from "@tauri-apps/api/core"
22

33
interface ChannelEntry {
44
name: string
5-
channel: Channel<string>
6-
logs: string[]
5+
version: number
76
stopped: boolean
87
}
98

9+
const MAX_LOGS = 1000
10+
1011
class ChannelManager {
12+
private _logsBuffer: Record<number, string[]> = {}
13+
1114
processes = $state<number[]>([])
1215
channels = $state<Record<number, ChannelEntry>>({})
1316

1417
async createChannel(name: string): Promise<Channel<string>> {
1518
const channel = new Channel<string>()
1619
const id = channel.id
1720

21+
this._logsBuffer[id] = []
22+
this.channels[id] = { name, version: 0, stopped: false }
1823
this.processes.push(id)
19-
this.channels[id] = {
20-
name,
21-
channel,
22-
logs: [],
23-
stopped: false
24-
}
2524

26-
this.channels[id].channel.onmessage = (msg: string) => {
25+
channel.onmessage = (msg: string) => {
2726
const entry = this.channels[id]
28-
if (entry && !entry.stopped) {
29-
entry.logs.push(msg)
27+
if (!entry || entry.stopped) return
28+
29+
const buffer = this._logsBuffer[id]
30+
buffer.push(msg)
31+
32+
if (buffer.length > MAX_LOGS) {
33+
buffer.shift()
3034
}
35+
36+
entry.version++
3137
}
3238

33-
return this.channels[id].channel
39+
return channel
40+
}
41+
42+
getLogs(id: number): string[] {
43+
const entry = this.channels[id]
44+
if (!entry) return []
45+
entry.version
46+
return this._logsBuffer[id]
3447
}
3548

3649
stopChannel(id: number) {
37-
if (this.channels[id]) {
38-
this.channels[id].stopped = true
39-
}
50+
if (this.channels[id]) this.channels[id].stopped = true
4051
}
4152

4253
removeChannel(id: number) {
4354
if (!this.channels[id]) return
44-
55+
delete this._logsBuffer[id]
4556
delete this.channels[id]
4657
this.processes = this.processes.filter((item) => item !== id)
47-
console.log(`Channel "${id}" removed.`)
4858
}
4959
}
5060

src/routes/(app)/running/+layout.svelte

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,17 +19,12 @@
1919
)
2020
)
2121
22-
let selected = $state(0)
23-
const runningIdx = $derived(running.indexOf(process))
24-
$effect(() => {
25-
if (runningIdx == -1) {
26-
const stoppedIdx = stopped.indexOf(process)
27-
if (stoppedIdx != -1) {
28-
selected = stoppedIdx + running.length
29-
} else {
30-
selected = 0
31-
}
32-
}
22+
const selected = $derived.by(() => {
23+
const i = running.indexOf(process)
24+
if (i > -1) return i
25+
const idx = stopped.indexOf(process)
26+
if (idx == -1) return 0
27+
return idx + running.length
3328
})
3429
3530
const hasProcesses = $derived(running.length > 0 || stopped.length > 0)
@@ -53,15 +48,11 @@
5348
<ul class="h-full w-full overflow-y-scroll">
5449
{#each running as entry, idx}
5550
<li
56-
class="flex preset-outlined-success-200-800 hover:preset-tonal focus:preset-tonal"
51+
class="flex preset-outlined-success-200-800 text-sm hover:preset-tonal focus:preset-tonal"
5752
class:bg-surface-300-700={selected === idx}
5853
class:border-primary-300-700={selected === idx}
5954
>
60-
<a
61-
href={"/running/" + entry}
62-
class="my-2 flex h-full w-full justify-between px-2"
63-
onclick={() => (selected = idx)}
64-
>
55+
<a href={"/running/" + entry} class="my-2 flex h-full w-full justify-between px-2">
6556
{channelManager.channels[entry].name}
6657
</a>
6758
</li>
@@ -73,11 +64,7 @@
7364
class:bg-surface-300-700={selected === idx + running.length}
7465
class:border-primary-300-700={selected === idx + running.length}
7566
>
76-
<a
77-
href={"/running/" + entry}
78-
class="my-2 flex h-full w-full justify-between px-2"
79-
onclick={() => (selected = idx + running.length)}
80-
>
67+
<a href={"/running/" + entry} class="my-2 flex h-full w-full justify-between px-2">
8168
{channelManager.channels[entry].name}
8269
</a>
8370
</li>
@@ -107,7 +94,6 @@
10794
class="btn rounded-lg border border-surface-500 bg-surface-500/70 p-2"
10895
onclick={async () => {
10996
channelManager.removeChannel(stopped[selected - running.length])
110-
selected = -1
11197
await Promise.all([invalidate("layout:channel"), invalidate("layout:running")])
11298
await goto("/running")
11399
}}
@@ -119,7 +105,7 @@
119105
{/if}
120106

121107
<div
122-
class="block min-h-full w-full min-w-fit gap-2 px-4 text-left font-mono text-sm wrap-break-word whitespace-break-spaces"
108+
class="block min-h-full w-full min-w-fit gap-2 px-4 text-left wrap-break-word whitespace-break-spaces"
123109
class:bg-stone-950={hasProcesses}
124110
class:overflow-y-scroll={hasProcesses}
125111
>
Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,8 @@
1-
import { channelManager } from "$lib/communication.svelte"
2-
31
export const prerender = false
42
export const ssr = false
53

64
export const load = async ({ depends, params: { slug } }) => {
75
depends("layout:running")
86
const process = Number(slug)
9-
10-
return {
11-
process
12-
}
7+
return { process }
138
}
Lines changed: 27 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,38 @@
11
<script lang="ts">
22
import { channelManager } from "$lib/communication.svelte"
3+
34
let { data } = $props()
45
5-
function transformMessage(msg: string) {
6-
let style: string | null = null
7-
if (!msg.startsWith("\0\0")) return { message: msg, style }
8-
const flag = msg.slice(0, 8)
6+
const STYLES: Record<number, string> = {
7+
50: "text-yellow-500", //2 Warning
8+
52: "text-red-500", //4 Error
9+
56: "text-green-500" //8 Success
10+
}
911
10-
if (flag.endsWith("2")) {
11-
style = "warning"
12-
} else if (flag.endsWith("4")) {
13-
style = "error"
14-
} else if (flag.endsWith("8")) {
15-
style = "success"
12+
function transformLog(msg: string) {
13+
if (msg.length < 8 || msg.charCodeAt(0) !== 0 || msg.charCodeAt(1) !== 0) {
14+
return { text: msg, cls: "" }
1615
}
1716
18-
return { message: msg.slice(8), style }
17+
const code = msg.charCodeAt(7)
18+
return {
19+
text: msg.slice(8),
20+
cls: STYLES[code] || ""
21+
}
1922
}
23+
24+
let logs = $derived.by(() => {
25+
const raw = channelManager.getLogs(data.process)
26+
const out = new Array(raw.length)
27+
for (let i = 0; i < raw.length; i++) {
28+
out[i] = transformLog(raw[i])
29+
}
30+
return out
31+
})
2032
</script>
2133

22-
{#if channelManager.channels[data.process]}
23-
{#each channelManager.channels[data.process].logs as msg}
24-
{@const { message, style } = transformMessage(msg)}
25-
<p class={style ? `text-${style}-500` : ""}>{message}</p>
34+
<div class="font-mono text-sm leading-tight">
35+
{#each logs as log}
36+
<p class={log.cls}>{log.text}</p>
2637
{/each}
27-
{/if}
38+
</div>

0 commit comments

Comments
 (0)