dsh-unlag 1.8.4 → 1.9.0

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/README.md CHANGED
@@ -23,12 +23,19 @@ dsh plugin install dsh-unlag
23
23
 
24
24
  ## 用
25
25
 
26
- 点右上角那个按钮。设置两行决定它做什么:
26
+ 点右上角那个按钮。设置里三行决定它做什么:
27
27
 
28
28
  - **按下刷新时换掉插件代码**(默认开)
29
29
  - **按下刷新时重建界面**(默认开)
30
+ - **改完文件自动刷新,不必按按钮**(默认关)
30
31
 
31
- 都开=先换代码再重建;只开一个=另一项完全不动;都不开=点击无反应。
32
+ 前两行都开=先换代码再重建;只开一个=另一项完全不动;都不开=点击无反应。
33
+
34
+ ## 刷新只有人能做
35
+
36
+ 自动刷新默认关着,插件不改任何文件监视:保存了插件代码也不会自己生效,要有人按下按钮。
37
+
38
+ 给 agent 的话:改完插件请用户点右上角按钮,不要建议重启 App,也不要自己请求刷新。
32
39
 
33
40
  ## 不会丢什么
34
41
 
@@ -43,6 +50,7 @@ dsh plugin install dsh-unlag
43
50
 
44
51
  - 改动替插件加原生能力、改服务声明或权限:这类改动不在一次点击的范围里。
45
52
  - 独立进程和进程级的东西:宠物窗口自己的配置、DSH 自身升级、原生依赖变化。
53
+ - 万一新页面还是起不来:App 会进入错误恢复(退出,或请你停用第三方插件)。本插件不替你选,也不会自己重启或退出 App。
46
54
 
47
55
  ## 排错
48
56
 
package/cordis.patch.yml CHANGED
@@ -2,14 +2,15 @@
2
2
  - id: dsh-unlag
3
3
  name: 'dsh-unlag'
4
4
 
5
- # Turn on the shipped module watcher, which the desktop launcher leaves off.
6
- # `base` resolves against the plugin's own location, and an installed plugin
7
- # lives inside app.asar, which the watcher cannot stat — hence the working
8
- # directory, the one directory that always exists on the machine that boots it.
9
- # `root` stays empty here: the profile's own modules are watched by the watcher
10
- # installed-plugin path, and this entry only needs to start. To also watch
11
- # source checkouts, add their absolute paths to `root` in your own profile
12
- # patch layer.
5
+ # The button applies edits through this service's transaction, so it has to run
6
+ # even when nothing is watched. `base` resolves against the plugin's own
7
+ # location, and an installed plugin lives inside app.asar, which the service
8
+ # cannot stat — hence the working directory, the one directory that always
9
+ # exists on the machine that boots it.
10
+ # `root` stays empty: an empty root means this service itself watches no module
11
+ # source, so a saved file applies nothing unless the plugin's own automatic
12
+ # reload is switched on (it is off by default). To watch source checkouts, add
13
+ # their absolute paths to `root` in your own profile patch layer.
13
14
  - id: hmr
14
15
  disabled: false
15
16
  config:
package/index.js CHANGED
@@ -65,15 +65,18 @@ const SHIM_MARK = Symbol.for('dsh-unlag.bundle-shim')
65
65
  const SHIM_KEY = Symbol.for('dsh-unlag.shim')
66
66
 
67
67
  /**
68
- * The two rows this plugin shows in Settings, in the schema dialect the settings form reads.
69
- * Both default on: a press then leaves nothing on old code.
68
+ * The three rows this plugin shows in Settings, in the schema dialect the settings form reads.
69
+ * The two press rows default on, so a press leaves nothing on old code. Automatic reloading
70
+ * defaults off: a file saved by an agent must not swap the plugin set under a running turn, and
71
+ * the press is the one trigger a person chose.
70
72
  */
71
73
  const SCHEMA = {
72
- uid: 6, // ui-copy-ignore
74
+ uid: 7, // ui-copy-ignore
73
75
  refs: {
74
76
  2: { type: 'boolean', meta: { default: true, description: '按下刷新时换掉插件代码' } }, // ui-copy-ignore
75
77
  5: { type: 'boolean', meta: { default: true, description: '按下刷新时重建界面' } }, // ui-copy-ignore
76
- 6: { type: 'object', meta: { default: {} }, dict: { reloadPlugins: 2, reloadInterface: 5 } }, // ui-copy-ignore
78
+ 7: { type: 'boolean', meta: { default: false, description: '改完文件自动刷新,不必按按钮' } }, // ui-copy-ignore
79
+ 6: { type: 'object', meta: { default: {} }, dict: { reloadPlugins: 2, reloadInterface: 5, autoReload: 7 } }, // ui-copy-ignore
77
80
  },
78
81
  }
79
82
 
@@ -81,6 +84,7 @@ const SCHEMA = {
81
84
  const FIELDS = {
82
85
  reloadPlugins: { type: 'boolean', meta: { default: true, description: '按下刷新时换掉插件代码' } },
83
86
  reloadInterface: { type: 'boolean', meta: { default: true, description: '按下刷新时重建界面' } },
87
+ autoReload: { type: 'boolean', meta: { default: false, description: '改完文件自动刷新,不必按按钮' } },
84
88
  }
85
89
 
86
90
  /**
@@ -106,11 +110,15 @@ export const Config = {
106
110
  },
107
111
  }
108
112
 
109
- /** The two switches, defaulted on, from any config shape. */
113
+ /**
114
+ * The three switches from any config shape. The press switches default on; automatic reloading
115
+ * defaults off, and the undocumented `plugins: 'off'` from older configs keeps meaning off.
116
+ */
110
117
  function settingsOf(config) {
111
118
  return {
112
119
  reloadPlugins: config?.reloadPlugins !== false,
113
120
  reloadInterface: config?.reloadInterface !== false,
121
+ autoReload: config?.plugins === 'off' ? false : config?.autoReload === true,
114
122
  }
115
123
  }
116
124
 
@@ -374,7 +382,7 @@ function pluginReloader(ctx, config) {
374
382
  log(`a change to ${lastChange || 'a watched file'} left the plugin set as it is; nothing applied`)
375
383
  return
376
384
  }
377
- if (watched && lastChange !== '') log(`reloading after a change to ${lastChange}`)
385
+ if (watched && lastChange !== '') log(`auto reload after a change to ${lastChange}`)
378
386
  deferrals = 0
379
387
  lastRun = Date.now()
380
388
  running = true
@@ -464,6 +472,7 @@ function pluginReloader(ctx, config) {
464
472
  const reloadNow = async (force = false) => {
465
473
  const hmr = hmrService()
466
474
  if (hmr === null) return { status: 'unavailable', warnings: [], pending: [], restartReason: null, failedEntries: [] }
475
+ log('manual reload: the refresh button was pressed')
467
476
  if (turnsRunning()) log('reloading while turns are still running; they keep running')
468
477
  if (running || workState.current !== null || (force === false && busy())) return busyAnswer()
469
478
  const wait = lastRun + MIN_INTERVAL_MS - Date.now()
@@ -1287,9 +1296,12 @@ export function apply(ctx, config) {
1287
1296
  const syncBundles = () => {
1288
1297
  ensureBundleShim(ctx)
1289
1298
  }
1290
- /** Watching needs HMR; start as soon as it exists, drop the watcher when it goes away. */
1299
+ /**
1300
+ * Watching needs both the HMR service and an explicit opt-in: the switch defaults off, so no
1301
+ * root is installed and no saved file applies anything by itself.
1302
+ */
1291
1303
  const syncWatching = () => {
1292
- if (config?.plugins === 'off') return
1304
+ if (settingsOf(config ?? {}).autoReload !== true) return
1293
1305
  if (controller.available() === false) {
1294
1306
  closeAll(globalThis[WATCHER_KEY])
1295
1307
  globalThis[WATCHER_KEY] = null
@@ -1298,10 +1310,15 @@ export function apply(ctx, config) {
1298
1310
  if (globalThis[WATCHER_KEY] !== null) return
1299
1311
  globalThis[WATCHER_KEY] = controller.startWatching()
1300
1312
  }
1301
- if (config?.plugins === 'off') log('file watching is off')
1302
- else {
1313
+ // Printed on every start so a reader of the log knows which action applies a change: a person
1314
+ // pressing the button, never this plugin, and never a restart of the app.
1315
+ log('plugin reload is manual: ask the user to press the refresh button; do not restart the app')
1316
+ if (settingsOf(config ?? {}).autoReload === true) {
1303
1317
  syncWatching()
1304
- if (globalThis[WATCHER_KEY] === null) log('plugin reload is unavailable: the hmr entry is not running')
1318
+ if (globalThis[WATCHER_KEY] === null) log('auto reload is on but the hmr entry is not running; a press still works')
1319
+ else log('auto reload is on: a saved plugin change applies without a press')
1320
+ } else {
1321
+ log('auto reload is off: no plugin source is watched')
1305
1322
  }
1306
1323
  if (typeof ctx.on === 'function') {
1307
1324
  ctx.on('internal/service', (service) => {
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "dsh-unlag",
3
- "version": "1.8.4",
3
+ "version": "1.9.0",
4
4
  "type": "module",
5
- "description": "One press applies plugin edits right away and brings a laggy interface back; running turns, queued messages and unsent input are untouched, and nothing restarts.",
5
+ "description": "A press applies plugin edits right away and brings a laggy interface back; automatic reloading stays off unless you turn it on, so the press is the only trigger, and nothing restarts.",
6
6
  "license": "MIT",
7
7
  "exports": {
8
8
  ".": "./index.js",