@linxin666/dsh-client-ui-task-board 0.2.2 → 0.2.4
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/lib/client.js +8 -4
- package/lib/client.js.map +1 -1
- package/package.json +10 -10
- package/src/client/settings-form.ts +8 -6
- package/src/core/controller.ts +9 -1
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@linxin666/dsh-client-ui-task-board",
|
|
3
3
|
"description": "Host-authoritative task board for the DSH Web GUI with real session execution, Host cron scheduling, and optional cross-platform idle-sleep protection; mounted without DSH source changes.",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.4",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"types": "lib/types/index.d.ts",
|
|
@@ -42,15 +42,15 @@
|
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
44
|
"@deepseek-ai/cordis": "^4.0.1",
|
|
45
|
-
"@deepseek-ai/dsh-client-connection": "^0.1.0-rc.
|
|
46
|
-
"@deepseek-ai/dsh-client-locale": "^0.1.0-rc.
|
|
47
|
-
"@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.
|
|
48
|
-
"@deepseek-ai/dsh-client-ui-settings": "^0.1.0-rc.
|
|
49
|
-
"@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.
|
|
50
|
-
"@deepseek-ai/dsh-host-apiproxy": "^0.1.0-rc.
|
|
51
|
-
"@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.
|
|
52
|
-
"@deepseek-ai/dsh-settings": "^0.1.0-rc.
|
|
53
|
-
"@deepseek-ai/dsh-system-prompt": "^0.1.0-rc.
|
|
45
|
+
"@deepseek-ai/dsh-client-connection": "^0.1.0-rc.8",
|
|
46
|
+
"@deepseek-ai/dsh-client-locale": "^0.1.0-rc.8",
|
|
47
|
+
"@deepseek-ai/dsh-client-runtime": "^0.1.0-rc.8",
|
|
48
|
+
"@deepseek-ai/dsh-client-ui-settings": "^0.1.0-rc.8",
|
|
49
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.1.0-rc.8",
|
|
50
|
+
"@deepseek-ai/dsh-host-apiproxy": "^0.1.0-rc.8",
|
|
51
|
+
"@deepseek-ai/dsh-host-webserver": "^0.1.0-rc.8",
|
|
52
|
+
"@deepseek-ai/dsh-settings": "^0.1.0-rc.8",
|
|
53
|
+
"@deepseek-ai/dsh-system-prompt": "^0.1.0-rc.8",
|
|
54
54
|
"@types/react": "~18.3.1",
|
|
55
55
|
"@types/react-dom": "^18.3.5",
|
|
56
56
|
"@types/node": "^22.20.0",
|
|
@@ -333,9 +333,11 @@ export class CardForm<T> {
|
|
|
333
333
|
const valid = plan.filter(item => item.run !== undefined)
|
|
334
334
|
if (plan.length === 0 || this.saving || valid.length !== plan.length) return
|
|
335
335
|
const plannedWrites = valid.map(item => item.op)
|
|
336
|
-
// Snapshot the
|
|
337
|
-
// flight
|
|
338
|
-
|
|
336
|
+
// Snapshot the staged entries this save writes, so an edit staged while it
|
|
337
|
+
// is in flight (which replaces the same key) survives: only delete the key
|
|
338
|
+
// when the entry is still the one this save started from.
|
|
339
|
+
const pending = new Map<string, StagedEdit | undefined>()
|
|
340
|
+
for (const item of plan) pending.set(item.field, this.staged.get(item.field))
|
|
339
341
|
this.saving = true
|
|
340
342
|
this.failed = false
|
|
341
343
|
this.failedReason = undefined
|
|
@@ -356,11 +358,11 @@ export class CardForm<T> {
|
|
|
356
358
|
if (await item.run!()) landed.add(item.field)
|
|
357
359
|
}
|
|
358
360
|
}
|
|
359
|
-
for (const field of
|
|
360
|
-
if (landed.has(field)) this.staged.delete(field)
|
|
361
|
+
for (const [field, before] of pending) {
|
|
362
|
+
if (landed.has(field) && this.staged.get(field) === before) this.staged.delete(field)
|
|
361
363
|
}
|
|
362
364
|
this.saving = false
|
|
363
|
-
this.failed = landed.size !==
|
|
365
|
+
this.failed = landed.size !== pending.size
|
|
364
366
|
this.publish()
|
|
365
367
|
}
|
|
366
368
|
|
package/src/core/controller.ts
CHANGED
|
@@ -509,7 +509,15 @@ export class BoardController {
|
|
|
509
509
|
/** Settle tasks left 'running' whose sessions already finished. */
|
|
510
510
|
private async reconcileRunningTasks(): Promise<void> {
|
|
511
511
|
if (this.deps.exec === undefined) return
|
|
512
|
-
if (this.reconcileInFlight)
|
|
512
|
+
if (this.reconcileInFlight) {
|
|
513
|
+
// A session change arrived while a pass was in flight. The in-flight
|
|
514
|
+
// pass already captured the task list it iterates and will not revisit
|
|
515
|
+
// this task, so dropping the notification would leave it stuck
|
|
516
|
+
// 'running'. Re-arm the debounce so the change is reconciled once the
|
|
517
|
+
// current pass settles.
|
|
518
|
+
this.scheduleReconcile()
|
|
519
|
+
return
|
|
520
|
+
}
|
|
513
521
|
this.reconcileInFlight = true
|
|
514
522
|
try {
|
|
515
523
|
type Settled = Extract<ExecutionEvent, { kind: 'settled' }>
|