dsh-unlag 1.9.35 → 1.9.37

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
@@ -44,6 +44,7 @@ dsh plugin install dsh-unlag
44
44
  - 排队消息、输入草稿、附件:重建前先提交焦点里的内容;有人没存完就拦下,不硬刷。
45
45
  - 有未保存改动、开着弹窗、或下个页面要用的模块读不全:拦下并提示,提示里写明卡在哪一项,宁可不刷。
46
46
  - 原来就起不来的插件不挡这一下:换代码照做,日志里点名哪个插件本来就没在跑。
47
+ - 三个开关读不到时不硬刷:提示稍后再试,日志记下是哪一步没读到,绝不谎称代码已是最新。
47
48
  - 旧页面记着的启动清单分组变了(装过/卸过插件):按插件逐个补齐再交给新页面,不会因为清单 404 把 App 带走。
48
49
  - 从不自己重启或退出 App。
49
50
 
package/client.js CHANGED
@@ -15,8 +15,8 @@ window.__ModuleLoader__.load({
15
15
  * repeating one generic sentence.
16
16
  */
17
17
  const REASONS = zh
18
- ? { list: '读不到启动信息', slow: '启动信息读得太慢', row: '启动信息不完整', src: '启动脚本没有地址', graph: '已装插件清单读不到', plugin: '有插件已不在运行', script: '启动脚本读不到', empty: '启动脚本是空的', covers: '启动脚本缺插件', parse: '启动脚本内容不完整', verify: '插件后端没有应答' }
19
- : { list: 'startup info is unavailable', slow: 'the startup list answered too slowly', row: 'startup info is incomplete', src: 'a startup script has no address', graph: 'the plugin list cannot be read', plugin: 'a plugin is no longer running', script: 'a startup script cannot be read', empty: 'a startup script is empty', covers: 'a startup script misses a plugin', parse: 'a startup script is incomplete', verify: 'the plugin is not answering' };
18
+ ? { list: '读不到启动信息', slow: '启动信息读得太慢', row: '启动信息不完整', src: '启动脚本没有地址', graph: '已装插件清单读不到', plugin: '有插件已不在运行', script: '启动脚本读不到', empty: '启动脚本是空的', covers: '启动脚本缺插件', parse: '启动脚本内容不完整', size: '启动脚本太大', verify: '插件后端没有应答' }
19
+ : { list: 'startup info is unavailable', slow: 'the startup list answered too slowly', row: 'startup info is incomplete', src: 'a startup script has no address', graph: 'the plugin list cannot be read', plugin: 'a plugin is no longer running', script: 'a startup script cannot be read', empty: 'a startup script is empty', covers: 'a startup script misses a plugin', parse: 'a startup script is incomplete', size: 'a startup script is too large', verify: 'the plugin is not answering' };
20
20
 
21
21
  /** The last reason a readiness check refused for, or null after a check that passed. */
22
22
  let holdReason = null;
@@ -244,6 +244,7 @@ window.__ModuleLoader__.load({
244
244
  missing: 'script', // ui-copy-ignore
245
245
  network: 'script', // ui-copy-ignore
246
246
  parse: 'parse', // ui-copy-ignore
247
+ size: 'script', // ui-copy-ignore
247
248
  register: 'plugin', // ui-copy-ignore
248
249
  slow: 'slow', // ui-copy-ignore
249
250
  dependencies: 'covers',
@@ -650,8 +651,17 @@ window.__ModuleLoader__.load({
650
651
  };
651
652
  try {
652
653
  const settings = await readSettings();
653
- const replace = settings === null ? false : settings.plugins;
654
- const rebuild = settings === null ? true : settings.page;
654
+ /**
655
+ * Without the switches the press cannot know what it was asked for. Rebuilding anyway would
656
+ * reload the page and leave the code untouched while the notice claimed the code was
657
+ * current, so the press holds instead and says why.
658
+ */
659
+ if (settings === null) {
660
+ report('held', 'settings');
661
+ return stop('blocked');
662
+ }
663
+ const replace = settings.plugins;
664
+ const rebuild = settings.page;
655
665
  // Nothing is switched on: the press says so instead of looking broken.
656
666
  if (!replace && !rebuild) {
657
667
  report('off');
package/index.js CHANGED
@@ -91,6 +91,14 @@ const DEFAULT_ROOTS = [join(homedir(), '.dsh', 'plugins')]
91
91
  const MAX_DEFERRALS = 40
92
92
  const MAX_STARTUP_ROWS = 64
93
93
  const MAX_STARTUP_ROW_CHARS = 4096
94
+ /**
95
+ * The largest one startup script may be before a check refuses it. A real client bundle is far
96
+ * below this; a body past it is either a mistake or an attempt to make a check read (and compile)
97
+ * an unbounded amount of text inside the process that owns every running turn.
98
+ */
99
+ const MAX_SCRIPT_BYTES = 8 * 1024 * 1024
100
+ /** The same bound for one whole startup list, so a list of large bodies cannot add up either. */
101
+ const MAX_TOTAL_SCRIPT_BYTES = 32 * 1024 * 1024
94
102
 
95
103
  /**
96
104
  * The most plugin ids one bundle address may name. A real startup list is far below this; a made-up
@@ -1468,6 +1476,7 @@ export async function verifyStartupRows(graph, fetchBody, rows, budgetMs = MAX_V
1468
1476
  const listed = new Set()
1469
1477
  const bodies = []
1470
1478
  const began = Date.now()
1479
+ let totalBytes = 0
1471
1480
  for (const item of wanted) {
1472
1481
  if (Date.now() - began > budgetMs) {
1473
1482
  return { status: 'blocked', reason: 'slow', detail: 'the startup list took longer than this check waits' }
@@ -1485,6 +1494,10 @@ export async function verifyStartupRows(graph, fetchBody, rows, budgetMs = MAX_V
1485
1494
  }
1486
1495
  const bytes = Buffer.from(await response.arrayBuffer())
1487
1496
  if (bytes.length === 0) return { status: 'blocked', reason: 'empty', detail: `${item.url} answers an empty body` }
1497
+ totalBytes += bytes.length
1498
+ if (bytes.length > MAX_SCRIPT_BYTES || totalBytes > MAX_TOTAL_SCRIPT_BYTES) {
1499
+ return { status: 'blocked', reason: 'size', detail: `${item.url} answers ${String(bytes.length)} bytes; this check reads at most ${String(MAX_SCRIPT_BYTES)} per script and ${String(MAX_TOTAL_SCRIPT_BYTES)} in all` }
1500
+ }
1488
1501
  const text = bytes.toString('utf8')
1489
1502
  const complaint = parseAsScript(text, item.url)
1490
1503
  if (complaint !== null) return { status: 'blocked', reason: 'parse', detail: `${item.url}: ${complaint}` }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-unlag",
3
- "version": "1.9.35",
3
+ "version": "1.9.37",
4
4
  "type": "module",
5
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",