@marktrue/dsh-mobile-remote 3.2.1-alpha.1 → 3.2.1-alpha.2-app

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.
Files changed (349) hide show
  1. package/DSH-Remote-v3.2.1.apk +4 -0
  2. package/README.md +6 -253
  3. package/manifest.json +21 -0
  4. package/package.json +10 -65
  5. package/CHANGELOG.md +0 -796
  6. package/CONTRIBUTING.md +0 -59
  7. package/FAQ.md +0 -111
  8. package/cordis.patch.yml +0 -14
  9. package/docs/00-/345/274/200/345/217/221/346/200/273/347/272/262.md +0 -122
  10. package/docs/01-PRD.md +0 -148
  11. package/docs/02-architecture.md +0 -249
  12. package/docs/03-api.md +0 -816
  13. package/docs/04-security.md +0 -96
  14. package/docs/05-test-cases.md +0 -326
  15. package/docs/06-install-run.md +0 -308
  16. package/docs/07-user-manual.md +0 -65
  17. package/docs/08-/346/211/251/345/261/225/345/274/200/345/217/221/346/214/207/345/215/227.md +0 -86
  18. package/docs/09-compatibility.md +0 -195
  19. package/docs/10-release.md +0 -927
  20. package/docs/screenshots/01-home.png +0 -0
  21. package/docs/screenshots/02-notifications.png +0 -0
  22. package/docs/screenshots/03-sessions.png +0 -0
  23. package/docs/screenshots/04-chat.png +0 -0
  24. package/docs/screenshots/05-settings.png +0 -0
  25. package/docs/screenshots/06-new-session.png +0 -0
  26. package/docs/screenshots/pgy-appstore.jpg +0 -0
  27. package/docs/screenshots/pgy-mobile-app.jpg +0 -0
  28. package/docs/screenshots/pgy-pc-client.jpg +0 -0
  29. package/lib/account-usage.js +0 -145
  30. package/lib/app-alignment.js +0 -112
  31. package/lib/app-carrier-store.js +0 -1972
  32. package/lib/app-carrier.js +0 -602
  33. package/lib/client.js +0 -706
  34. package/lib/desktop-form.js +0 -738
  35. package/lib/endpoint-registry.js +0 -162
  36. package/lib/git-read-bundled-provider.js +0 -255
  37. package/lib/git-read-service.js +0 -322
  38. package/lib/index.js +0 -9292
  39. package/lib/plugin-content-digest.js +0 -80
  40. package/lib/plugin-self-update.js +0 -758
  41. package/lib/plugin-update-controller.js +0 -95
  42. package/lib/plugin-update-transaction.js +0 -322
  43. package/lib/plugin-update.js +0 -309
  44. package/lib/runtime-dependency-snapshot.js +0 -345
  45. package/lib/session-title-cache.js +0 -123
  46. package/lib/session-title-refresh.js +0 -261
  47. package/lib/update-fetch.js +0 -24
  48. package/lib/update-lock-arbiter.js +0 -158
  49. package/lib/update-supervisor.js +0 -312
  50. package/node_modules/ansi-regex/index.d.ts +0 -37
  51. package/node_modules/ansi-regex/index.js +0 -10
  52. package/node_modules/ansi-regex/license +0 -9
  53. package/node_modules/ansi-regex/package.json +0 -55
  54. package/node_modules/ansi-regex/readme.md +0 -78
  55. package/node_modules/ansi-styles/index.d.ts +0 -345
  56. package/node_modules/ansi-styles/index.js +0 -163
  57. package/node_modules/ansi-styles/license +0 -9
  58. package/node_modules/ansi-styles/package.json +0 -56
  59. package/node_modules/ansi-styles/readme.md +0 -152
  60. package/node_modules/camelcase/index.d.ts +0 -63
  61. package/node_modules/camelcase/index.js +0 -76
  62. package/node_modules/camelcase/license +0 -9
  63. package/node_modules/camelcase/package.json +0 -43
  64. package/node_modules/camelcase/readme.md +0 -99
  65. package/node_modules/cliui/CHANGELOG.md +0 -76
  66. package/node_modules/cliui/LICENSE.txt +0 -14
  67. package/node_modules/cliui/README.md +0 -115
  68. package/node_modules/cliui/index.js +0 -354
  69. package/node_modules/cliui/package.json +0 -65
  70. package/node_modules/color-convert/CHANGELOG.md +0 -54
  71. package/node_modules/color-convert/LICENSE +0 -21
  72. package/node_modules/color-convert/README.md +0 -68
  73. package/node_modules/color-convert/conversions.js +0 -839
  74. package/node_modules/color-convert/index.js +0 -81
  75. package/node_modules/color-convert/package.json +0 -48
  76. package/node_modules/color-convert/route.js +0 -97
  77. package/node_modules/color-name/LICENSE +0 -8
  78. package/node_modules/color-name/README.md +0 -11
  79. package/node_modules/color-name/index.js +0 -152
  80. package/node_modules/color-name/package.json +0 -28
  81. package/node_modules/decamelize/index.js +0 -13
  82. package/node_modules/decamelize/license +0 -21
  83. package/node_modules/decamelize/package.json +0 -38
  84. package/node_modules/decamelize/readme.md +0 -48
  85. package/node_modules/dijkstrajs/.travis.yml +0 -4
  86. package/node_modules/dijkstrajs/CONTRIBUTING.md +0 -8
  87. package/node_modules/dijkstrajs/LICENSE.md +0 -19
  88. package/node_modules/dijkstrajs/README.md +0 -18
  89. package/node_modules/dijkstrajs/dijkstra.js +0 -165
  90. package/node_modules/dijkstrajs/package.json +0 -60
  91. package/node_modules/dijkstrajs/test/dijkstra.test.js +0 -96
  92. package/node_modules/emoji-regex/LICENSE-MIT.txt +0 -20
  93. package/node_modules/emoji-regex/README.md +0 -73
  94. package/node_modules/emoji-regex/es2015/index.js +0 -6
  95. package/node_modules/emoji-regex/es2015/text.js +0 -6
  96. package/node_modules/emoji-regex/index.d.ts +0 -23
  97. package/node_modules/emoji-regex/index.js +0 -6
  98. package/node_modules/emoji-regex/package.json +0 -50
  99. package/node_modules/emoji-regex/text.js +0 -6
  100. package/node_modules/find-up/index.d.ts +0 -137
  101. package/node_modules/find-up/index.js +0 -89
  102. package/node_modules/find-up/license +0 -9
  103. package/node_modules/find-up/package.json +0 -53
  104. package/node_modules/find-up/readme.md +0 -156
  105. package/node_modules/get-caller-file/LICENSE.md +0 -6
  106. package/node_modules/get-caller-file/README.md +0 -41
  107. package/node_modules/get-caller-file/index.d.ts +0 -2
  108. package/node_modules/get-caller-file/index.js +0 -22
  109. package/node_modules/get-caller-file/index.js.map +0 -1
  110. package/node_modules/get-caller-file/package.json +0 -42
  111. package/node_modules/is-fullwidth-code-point/index.d.ts +0 -17
  112. package/node_modules/is-fullwidth-code-point/index.js +0 -50
  113. package/node_modules/is-fullwidth-code-point/license +0 -9
  114. package/node_modules/is-fullwidth-code-point/package.json +0 -42
  115. package/node_modules/is-fullwidth-code-point/readme.md +0 -39
  116. package/node_modules/locate-path/index.d.ts +0 -83
  117. package/node_modules/locate-path/index.js +0 -65
  118. package/node_modules/locate-path/license +0 -9
  119. package/node_modules/locate-path/package.json +0 -45
  120. package/node_modules/locate-path/readme.md +0 -122
  121. package/node_modules/p-limit/index.d.ts +0 -38
  122. package/node_modules/p-limit/index.js +0 -57
  123. package/node_modules/p-limit/license +0 -9
  124. package/node_modules/p-limit/package.json +0 -52
  125. package/node_modules/p-limit/readme.md +0 -101
  126. package/node_modules/p-locate/index.d.ts +0 -64
  127. package/node_modules/p-locate/index.js +0 -52
  128. package/node_modules/p-locate/license +0 -9
  129. package/node_modules/p-locate/package.json +0 -53
  130. package/node_modules/p-locate/readme.md +0 -90
  131. package/node_modules/p-try/index.d.ts +0 -39
  132. package/node_modules/p-try/index.js +0 -9
  133. package/node_modules/p-try/license +0 -9
  134. package/node_modules/p-try/package.json +0 -42
  135. package/node_modules/p-try/readme.md +0 -58
  136. package/node_modules/path-exists/index.d.ts +0 -28
  137. package/node_modules/path-exists/index.js +0 -23
  138. package/node_modules/path-exists/license +0 -9
  139. package/node_modules/path-exists/package.json +0 -39
  140. package/node_modules/path-exists/readme.md +0 -52
  141. package/node_modules/pngjs/.eslintignore +0 -2
  142. package/node_modules/pngjs/.eslintrc.json +0 -19
  143. package/node_modules/pngjs/.prettierignore +0 -3
  144. package/node_modules/pngjs/LICENSE +0 -20
  145. package/node_modules/pngjs/README.md +0 -429
  146. package/node_modules/pngjs/browser.js +0 -16096
  147. package/node_modules/pngjs/coverage/lcov-report/base.css +0 -354
  148. package/node_modules/pngjs/coverage/lcov-report/bitmapper.js.html +0 -881
  149. package/node_modules/pngjs/coverage/lcov-report/bitpacker.js.html +0 -554
  150. package/node_modules/pngjs/coverage/lcov-report/block-navigation.js +0 -77
  151. package/node_modules/pngjs/coverage/lcov-report/chunkstream.js.html +0 -647
  152. package/node_modules/pngjs/coverage/lcov-report/constants.js.html +0 -176
  153. package/node_modules/pngjs/coverage/lcov-report/crc.js.html +0 -200
  154. package/node_modules/pngjs/coverage/lcov-report/favicon.png +0 -0
  155. package/node_modules/pngjs/coverage/lcov-report/filter-pack.js.html +0 -593
  156. package/node_modules/pngjs/coverage/lcov-report/filter-parse-async.js.html +0 -152
  157. package/node_modules/pngjs/coverage/lcov-report/filter-parse-sync.js.html +0 -143
  158. package/node_modules/pngjs/coverage/lcov-report/filter-parse.js.html +0 -611
  159. package/node_modules/pngjs/coverage/lcov-report/format-normaliser.js.html +0 -359
  160. package/node_modules/pngjs/coverage/lcov-report/index.html +0 -426
  161. package/node_modules/pngjs/coverage/lcov-report/interlace.js.html +0 -365
  162. package/node_modules/pngjs/coverage/lcov-report/packer-async.js.html +0 -230
  163. package/node_modules/pngjs/coverage/lcov-report/packer-sync.js.html +0 -248
  164. package/node_modules/pngjs/coverage/lcov-report/packer.js.html +0 -467
  165. package/node_modules/pngjs/coverage/lcov-report/paeth-predictor.js.html +0 -128
  166. package/node_modules/pngjs/coverage/lcov-report/parser-async.js.html +0 -575
  167. package/node_modules/pngjs/coverage/lcov-report/parser-sync.js.html +0 -404
  168. package/node_modules/pngjs/coverage/lcov-report/parser.js.html +0 -950
  169. package/node_modules/pngjs/coverage/lcov-report/png-sync.js.html +0 -116
  170. package/node_modules/pngjs/coverage/lcov-report/png.js.html +0 -662
  171. package/node_modules/pngjs/coverage/lcov-report/prettify.css +0 -101
  172. package/node_modules/pngjs/coverage/lcov-report/prettify.js +0 -1007
  173. package/node_modules/pngjs/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  174. package/node_modules/pngjs/coverage/lcov-report/sorter.js +0 -169
  175. package/node_modules/pngjs/coverage/lcov-report/sync-inflate.js.html +0 -584
  176. package/node_modules/pngjs/coverage/lcov-report/sync-reader.js.html +0 -215
  177. package/node_modules/pngjs/coverage/lcov.info +0 -2177
  178. package/node_modules/pngjs/lib/bitmapper.js +0 -267
  179. package/node_modules/pngjs/lib/bitpacker.js +0 -158
  180. package/node_modules/pngjs/lib/chunkstream.js +0 -189
  181. package/node_modules/pngjs/lib/constants.js +0 -32
  182. package/node_modules/pngjs/lib/crc.js +0 -40
  183. package/node_modules/pngjs/lib/filter-pack.js +0 -171
  184. package/node_modules/pngjs/lib/filter-parse-async.js +0 -24
  185. package/node_modules/pngjs/lib/filter-parse-sync.js +0 -21
  186. package/node_modules/pngjs/lib/filter-parse.js +0 -177
  187. package/node_modules/pngjs/lib/format-normaliser.js +0 -93
  188. package/node_modules/pngjs/lib/interlace.js +0 -95
  189. package/node_modules/pngjs/lib/packer-async.js +0 -50
  190. package/node_modules/pngjs/lib/packer-sync.js +0 -56
  191. package/node_modules/pngjs/lib/packer.js +0 -129
  192. package/node_modules/pngjs/lib/paeth-predictor.js +0 -16
  193. package/node_modules/pngjs/lib/parser-async.js +0 -165
  194. package/node_modules/pngjs/lib/parser-sync.js +0 -108
  195. package/node_modules/pngjs/lib/parser.js +0 -290
  196. package/node_modules/pngjs/lib/png-sync.js +0 -12
  197. package/node_modules/pngjs/lib/png.js +0 -194
  198. package/node_modules/pngjs/lib/sync-inflate.js +0 -168
  199. package/node_modules/pngjs/lib/sync-reader.js +0 -45
  200. package/node_modules/pngjs/package.json +0 -73
  201. package/node_modules/qrcode/README.md +0 -770
  202. package/node_modules/qrcode/bin/qrcode +0 -159
  203. package/node_modules/qrcode/helper/to-sjis-browser.js +0 -2
  204. package/node_modules/qrcode/helper/to-sjis.js +0 -105
  205. package/node_modules/qrcode/lib/browser.js +0 -76
  206. package/node_modules/qrcode/lib/can-promise.js +0 -7
  207. package/node_modules/qrcode/lib/core/alignment-pattern.js +0 -83
  208. package/node_modules/qrcode/lib/core/alphanumeric-data.js +0 -59
  209. package/node_modules/qrcode/lib/core/bit-buffer.js +0 -37
  210. package/node_modules/qrcode/lib/core/bit-matrix.js +0 -65
  211. package/node_modules/qrcode/lib/core/byte-data.js +0 -30
  212. package/node_modules/qrcode/lib/core/error-correction-code.js +0 -135
  213. package/node_modules/qrcode/lib/core/error-correction-level.js +0 -50
  214. package/node_modules/qrcode/lib/core/finder-pattern.js +0 -22
  215. package/node_modules/qrcode/lib/core/format-info.js +0 -29
  216. package/node_modules/qrcode/lib/core/galois-field.js +0 -69
  217. package/node_modules/qrcode/lib/core/kanji-data.js +0 -54
  218. package/node_modules/qrcode/lib/core/mask-pattern.js +0 -234
  219. package/node_modules/qrcode/lib/core/mode.js +0 -167
  220. package/node_modules/qrcode/lib/core/numeric-data.js +0 -43
  221. package/node_modules/qrcode/lib/core/polynomial.js +0 -62
  222. package/node_modules/qrcode/lib/core/qrcode.js +0 -495
  223. package/node_modules/qrcode/lib/core/reed-solomon-encoder.js +0 -56
  224. package/node_modules/qrcode/lib/core/regex.js +0 -31
  225. package/node_modules/qrcode/lib/core/segments.js +0 -330
  226. package/node_modules/qrcode/lib/core/utils.js +0 -63
  227. package/node_modules/qrcode/lib/core/version-check.js +0 -9
  228. package/node_modules/qrcode/lib/core/version.js +0 -163
  229. package/node_modules/qrcode/lib/index.js +0 -12
  230. package/node_modules/qrcode/lib/renderer/canvas.js +0 -63
  231. package/node_modules/qrcode/lib/renderer/png.js +0 -78
  232. package/node_modules/qrcode/lib/renderer/svg-tag.js +0 -81
  233. package/node_modules/qrcode/lib/renderer/svg.js +0 -19
  234. package/node_modules/qrcode/lib/renderer/terminal/terminal-small.js +0 -85
  235. package/node_modules/qrcode/lib/renderer/terminal/terminal.js +0 -49
  236. package/node_modules/qrcode/lib/renderer/terminal.js +0 -9
  237. package/node_modules/qrcode/lib/renderer/utf8.js +0 -71
  238. package/node_modules/qrcode/lib/renderer/utils.js +0 -99
  239. package/node_modules/qrcode/lib/server.js +0 -138
  240. package/node_modules/qrcode/license +0 -10
  241. package/node_modules/qrcode/package.json +0 -77
  242. package/node_modules/require-directory/.jshintrc +0 -67
  243. package/node_modules/require-directory/.npmignore +0 -1
  244. package/node_modules/require-directory/.travis.yml +0 -3
  245. package/node_modules/require-directory/LICENSE +0 -22
  246. package/node_modules/require-directory/README.markdown +0 -184
  247. package/node_modules/require-directory/index.js +0 -86
  248. package/node_modules/require-directory/package.json +0 -40
  249. package/node_modules/require-main-filename/CHANGELOG.md +0 -26
  250. package/node_modules/require-main-filename/LICENSE.txt +0 -14
  251. package/node_modules/require-main-filename/README.md +0 -26
  252. package/node_modules/require-main-filename/index.js +0 -18
  253. package/node_modules/require-main-filename/package.json +0 -35
  254. package/node_modules/set-blocking/CHANGELOG.md +0 -26
  255. package/node_modules/set-blocking/LICENSE.txt +0 -14
  256. package/node_modules/set-blocking/README.md +0 -31
  257. package/node_modules/set-blocking/index.js +0 -7
  258. package/node_modules/set-blocking/package.json +0 -42
  259. package/node_modules/string-width/index.d.ts +0 -29
  260. package/node_modules/string-width/index.js +0 -47
  261. package/node_modules/string-width/license +0 -9
  262. package/node_modules/string-width/package.json +0 -56
  263. package/node_modules/string-width/readme.md +0 -50
  264. package/node_modules/strip-ansi/index.d.ts +0 -17
  265. package/node_modules/strip-ansi/index.js +0 -4
  266. package/node_modules/strip-ansi/license +0 -9
  267. package/node_modules/strip-ansi/package.json +0 -54
  268. package/node_modules/strip-ansi/readme.md +0 -46
  269. package/node_modules/which-module/LICENSE +0 -13
  270. package/node_modules/which-module/README.md +0 -58
  271. package/node_modules/which-module/index.js +0 -9
  272. package/node_modules/which-module/package.json +0 -41
  273. package/node_modules/wrap-ansi/index.js +0 -186
  274. package/node_modules/wrap-ansi/license +0 -9
  275. package/node_modules/wrap-ansi/package.json +0 -61
  276. package/node_modules/wrap-ansi/readme.md +0 -97
  277. package/node_modules/y18n/CHANGELOG.md +0 -35
  278. package/node_modules/y18n/LICENSE +0 -13
  279. package/node_modules/y18n/README.md +0 -109
  280. package/node_modules/y18n/index.js +0 -188
  281. package/node_modules/y18n/package.json +0 -39
  282. package/node_modules/yargs/CHANGELOG.md +0 -420
  283. package/node_modules/yargs/LICENSE +0 -21
  284. package/node_modules/yargs/README.md +0 -140
  285. package/node_modules/yargs/build/lib/apply-extends.d.ts +0 -2
  286. package/node_modules/yargs/build/lib/apply-extends.js +0 -65
  287. package/node_modules/yargs/build/lib/argsert.d.ts +0 -2
  288. package/node_modules/yargs/build/lib/argsert.js +0 -65
  289. package/node_modules/yargs/build/lib/command.d.ts +0 -64
  290. package/node_modules/yargs/build/lib/command.js +0 -416
  291. package/node_modules/yargs/build/lib/common-types.d.ts +0 -36
  292. package/node_modules/yargs/build/lib/common-types.js +0 -25
  293. package/node_modules/yargs/build/lib/completion-templates.d.ts +0 -2
  294. package/node_modules/yargs/build/lib/completion-templates.js +0 -50
  295. package/node_modules/yargs/build/lib/completion.d.ts +0 -21
  296. package/node_modules/yargs/build/lib/completion.js +0 -135
  297. package/node_modules/yargs/build/lib/is-promise.d.ts +0 -1
  298. package/node_modules/yargs/build/lib/is-promise.js +0 -9
  299. package/node_modules/yargs/build/lib/levenshtein.d.ts +0 -1
  300. package/node_modules/yargs/build/lib/levenshtein.js +0 -58
  301. package/node_modules/yargs/build/lib/middleware.d.ts +0 -10
  302. package/node_modules/yargs/build/lib/middleware.js +0 -57
  303. package/node_modules/yargs/build/lib/obj-filter.d.ts +0 -1
  304. package/node_modules/yargs/build/lib/obj-filter.js +0 -14
  305. package/node_modules/yargs/build/lib/parse-command.d.ts +0 -11
  306. package/node_modules/yargs/build/lib/parse-command.js +0 -36
  307. package/node_modules/yargs/build/lib/process-argv.d.ts +0 -2
  308. package/node_modules/yargs/build/lib/process-argv.js +0 -31
  309. package/node_modules/yargs/build/lib/usage.d.ts +0 -49
  310. package/node_modules/yargs/build/lib/usage.js +0 -540
  311. package/node_modules/yargs/build/lib/validation.d.ts +0 -34
  312. package/node_modules/yargs/build/lib/validation.js +0 -330
  313. package/node_modules/yargs/build/lib/yargs.d.ts +0 -274
  314. package/node_modules/yargs/build/lib/yargs.js +0 -1190
  315. package/node_modules/yargs/build/lib/yerror.d.ts +0 -4
  316. package/node_modules/yargs/build/lib/yerror.js +0 -11
  317. package/node_modules/yargs/index.js +0 -40
  318. package/node_modules/yargs/locales/be.json +0 -46
  319. package/node_modules/yargs/locales/de.json +0 -46
  320. package/node_modules/yargs/locales/en.json +0 -51
  321. package/node_modules/yargs/locales/es.json +0 -46
  322. package/node_modules/yargs/locales/fi.json +0 -49
  323. package/node_modules/yargs/locales/fr.json +0 -53
  324. package/node_modules/yargs/locales/hi.json +0 -49
  325. package/node_modules/yargs/locales/hu.json +0 -46
  326. package/node_modules/yargs/locales/id.json +0 -50
  327. package/node_modules/yargs/locales/it.json +0 -46
  328. package/node_modules/yargs/locales/ja.json +0 -51
  329. package/node_modules/yargs/locales/ko.json +0 -49
  330. package/node_modules/yargs/locales/nb.json +0 -44
  331. package/node_modules/yargs/locales/nl.json +0 -49
  332. package/node_modules/yargs/locales/nn.json +0 -44
  333. package/node_modules/yargs/locales/pirate.json +0 -13
  334. package/node_modules/yargs/locales/pl.json +0 -49
  335. package/node_modules/yargs/locales/pt.json +0 -45
  336. package/node_modules/yargs/locales/pt_BR.json +0 -48
  337. package/node_modules/yargs/locales/ru.json +0 -46
  338. package/node_modules/yargs/locales/th.json +0 -46
  339. package/node_modules/yargs/locales/tr.json +0 -48
  340. package/node_modules/yargs/locales/zh_CN.json +0 -48
  341. package/node_modules/yargs/locales/zh_TW.json +0 -47
  342. package/node_modules/yargs/package.json +0 -92
  343. package/node_modules/yargs/yargs.js +0 -14
  344. package/node_modules/yargs-parser/CHANGELOG.md +0 -601
  345. package/node_modules/yargs-parser/LICENSE.txt +0 -14
  346. package/node_modules/yargs-parser/README.md +0 -449
  347. package/node_modules/yargs-parser/index.js +0 -1032
  348. package/node_modules/yargs-parser/lib/tokenize-arg-string.js +0 -40
  349. package/node_modules/yargs-parser/package.json +0 -46
@@ -1,95 +0,0 @@
1
- // Admission owns the durable transaction and its lease; the worker consumes exactly the accepted release.
2
- import { homedir } from 'node:os';
3
- import { acquireLock, newOperationId, readTransaction, releaseLock, serverOperationPath, finishOwnedTerminal,
4
- transactionFile, updateLockPath, validOperationId, writeOwnedTransaction, convergeStaleTransaction } from './plugin-update-transaction.js';
5
- import { checkForUpdate, runSelfUpdate, isTerminalPhase, resolveManifestSource, UPDATE_SOURCE_KIND } from './plugin-self-update.js';
6
-
7
- /// 客户端可达视图:只改写属于**本机回环主机源**的 artifact 路由,外部发布源保持原样(F1)。
8
- export function clientReleaseView(release, { clientOrigin = '', basePath = '/m', loopback = false } = {}) {
9
- if (!release || !clientOrigin || !loopback) return release;
10
- const mount = basePath === '/' || basePath === '' ? '/m' : String(basePath).replace(/\/$/, '');
11
- return {
12
- ...release,
13
- manifestUrl: `${clientOrigin}${mount}/api/update/manifest`,
14
- app: release.app ? { ...release.app, url: `${clientOrigin}${mount}/api/update/apk` } : release.app,
15
- plugin: { ...release.plugin, url: `${clientOrigin}${mount}/api/update/plugin` },
16
- };
17
- }
18
- export function publicTransaction(tx, view = {}) {
19
- if (!tx) return null;
20
- const { opId, phase, targetVersion, targetContentSha256, rolledBack, attempts, result, startedAt, release } = tx;
21
- return { opId, phase, targetVersion, targetContentSha256, rolledBack: !!rolledBack, attempts: attempts ?? 0, result: result ?? null, startedAt,
22
- release: release ? clientReleaseView(release, view) : null };
23
- }
24
- export function createPluginUpdateController(options) {
25
- const { home = homedir(), configValue, profileDir, capabilities, localVersion, localContentSha256,
26
- status, log = () => {}, fetchImpl = fetch, auth = {}, basePath = '/m', workerOptions = {},
27
- schedule = fn => setImmediate(fn), runSelfUpdate: runner = runSelfUpdate, persist = writeOwnedTransaction } = options;
28
- const currentFile = transactionFile(home), lockPath = updateLockPath(home);
29
- const checking = () => checkForUpdate({ configValue, localVersion: typeof localVersion === 'function' ? localVersion() : localVersion, localContentSha256,
30
- capabilities: capabilities(), fetchImpl, auth });
31
- /// 手机视图:**只用于 HTTP 出口**,绝不写回内部事务(F1)。
32
- /// 内部 worker 必须继续用回环 locator 读受保护产物;手机看到的是自己可达的路由。
33
- const clientView = clientOrigin => ({
34
- clientOrigin, basePath, loopback: resolveManifestSource(configValue).loopback === true,
35
- });
36
- async function submit(body = {}, { clientOrigin = '' } = {}) {
37
- if (!body || typeof body !== 'object' || Array.isArray(body) ||
38
- ('opId' in body && !validOperationId(body.opId))) return { status: 400, body: { error: 'invalid-operation-id' } };
39
- const source = resolveManifestSource(configValue);
40
- if (source.kind === UPDATE_SOURCE_KIND.OFF) return { status: 503, body: { error: 'update-source-off' } };
41
- if (source.kind === UPDATE_SOURCE_KIND.INVALID) return { status: 400, body: { error: 'update-source-invalid' } };
42
- if (!profileDir) return { status: 409, body: { error: 'profile-not-found' } };
43
- if (!capabilities().canSelfUpdate) return { status: 409, body: { error: 'restart-unsupported' } };
44
- const view = clientView(clientOrigin);
45
- const old = readTransaction(currentFile);
46
- if (old && body.opId === old.opId) return { status: 200, body: { ok: true, action: 'accepted', opId: old.opId,
47
- transaction: publicTransaction(old, view), check: { ...status, release: clientReleaseView(status.release, view) } } };
48
- if (old && !isTerminalPhase(old.phase)) {
49
- const convergence = convergeStaleTransaction({ stateFile: currentFile, lockPath });
50
- if (!['converged','terminal'].includes(convergence.action)) return { status: 409, body: {
51
- error: convergence.action === 'recovery-required' ? 'recovery-required' : 'update-busy', transaction: publicTransaction(old, view) } };
52
- }
53
- const checked = await checking(); Object.assign(status, checked);
54
- // **内部 release 原样保留**(持久化与 worker 都用它);只有响应体走手机视图。
55
- if (checked.state !== 'update-available') {
56
- return { status: 200, body: { ok: true, action: 'none', check: { ...checked, release: clientReleaseView(checked.release, view) } } };
57
- }
58
- const opId = body.opId ?? newOperationId();
59
- const lock = acquireLock(lockPath, { opId, stateFile: currentFile });
60
- if (!lock.ok) return { status: 409, body: { error: lock.error, transaction: publicTransaction(readTransaction(currentFile)) } };
61
- const lease = lock.lease, stateFile = serverOperationPath(home, lease.generation);
62
- let tx;
63
- try {
64
- tx = persist(stateFile, { ...workerOptions, opId, phase: 'staging', startedAt: new Date().toISOString(),
65
- profileDir, release: checked.release, manifestUrl: checked.release.manifestUrl,
66
- targetVersion: checked.release.plugin.version, targetContentSha256: checked.release.plugin.contentSha256,
67
- currentFile, lockPath, lease, attempts: 0 }, { lockPath, lease, currentFile });
68
- } catch(e) {
69
- releaseLock(lockPath, lease, { stateFile: currentFile });
70
- log(`update admission persistence failed: ${e.message}`);
71
- return { status: 500, body: { error: 'update-state-write-failed' } };
72
- }
73
- // Only this lease schedules this worker. Same request retries return the saved operation above.
74
- schedule(async () => {
75
- try {
76
- const run = await runner({ ...workerOptions, home, profileDir, fetchImpl, auth, opId,
77
- release: tx.release, plugin: tx.release.plugin, manifestUrl: tx.manifestUrl,
78
- stateFile, currentFile, lockPath, lease, initialTransaction: tx, log });
79
- if (run.ok) Object.assign(status, { state: 'restarting', reason: 'update-staged', opId });
80
- else Object.assign(status, { state: run.transaction?.phase === 'rolling-back' ? 'rolling-back' : 'update-failed', reason: run.error, opId });
81
- } catch(e) {
82
- // Never clear an install/recovery lease as a generic catch. The armed supervisor owns recovery.
83
- const latest = readTransaction(stateFile);
84
- if (latest && latest.lease?.generation === lease.generation && latest.phase === 'staging') {
85
- try { finishOwnedTerminal(stateFile, { phase: 'failed', result: { ok: false, reason: e.message }, expectedPhases: ['staging'] }, { lockPath, lease, currentFile }); }
86
- catch { /* lost lease: do not overwrite a newer operation */ }
87
- }
88
- Object.assign(status, { state: 'update-failed', reason: e.message, opId }); log(`update worker failed: ${e.message}`);
89
- }
90
- });
91
- return { status: 200, body: { ok: true, action: 'accepted', opId,
92
- transaction: publicTransaction(tx, view), check: { ...checked, release: clientReleaseView(checked.release, view) } } };
93
- }
94
- return { submit, check: checking };
95
- }
@@ -1,322 +0,0 @@
1
- // 插件自更新的**事务**(ADR 0019「插件自更新」)。
2
- //
3
- // 评审(GitLab #32 note 1286)指出的根因是:原来的实现把"回滚"放在**新版插件自己的
4
- // apply() 里**,而新版插件一旦起不来就永远走不到那里;落位目录又只按版本号命名,
5
- // 同版本不同内容的更新会先删掉自己的回滚目标;profile 目录还是从模块路径"往上数两层"
6
- // 猜出来的,在 pnpm 的 virtual store 布局下必错。
7
- //
8
- // 本模块把这些前提一次性做对:
9
- // 1. **不可变产物目录**:按内容标识命名,绝不覆盖既有目录(回滚目标因此永远还在);
10
- // 2. **单事务 + 锁**:同一 profile 同时只允许一个更新事务,重复请求幂等返回同一 opId;
11
- // 3. **profile 目录靠"验证"而不是靠层级推断**:向上找第一个声明了本插件依赖的
12
- // package.json;找不到就返回空,调用方转降级指引,绝不动文件。
13
- import { existsSync, mkdirSync, readFileSync, readdirSync, realpathSync, renameSync, rmSync, statSync, writeFileSync } from "node:fs";
14
- import { dirname, join, resolve } from "node:path";
15
- import { freezePackage, frozenPackageReady } from "./runtime-dependency-snapshot.js";
16
- import { randomUUID } from "node:crypto";
17
- import { spawnSync } from "node:child_process";
18
- import { fileURLToPath } from "node:url";
19
-
20
- /** 事务阶段。`RESTART_PENDING` 是唯一需要外部监督器介入的阶段。 */
21
- export const TRANSACTION_PHASE = {
22
- /** 正在下载/解包/落位:还没动 profile,失败可安全放弃。 */
23
- STAGING: "staging",
24
- /** 依赖已切换、正在安装。 */
25
- INSTALLING: "installing",
26
- /** 已提交,等待宿主重启生效——**监督器接管**。 */
27
- RESTART_PENDING: "restart-pending",
28
- /** 正在回滚(**中间态**:App 不得据此判成功,F7)。 */
29
- ROLLING_BACK: "rolling-back",
30
- /** 新版本已确认健康并生效。 */
31
- SETTLED: "settled",
32
- /** 已回滚到上一版并确认可用。 */
33
- ROLLED_BACK: "rolled-back",
34
- /** 失败(含回滚失败)。 */
35
- FAILED: "failed",
36
- };
37
-
38
- /** 锁的默认失效时间:超过它视为持有者已死(宿主崩溃/被杀)。 */
39
- export const DEFAULT_LOCK_STALE_MS = 10 * 60 * 1000;
40
-
41
- export function newOperationId() {
42
- return randomUUID();
43
- }
44
-
45
- /** 事务状态文件(放在插件数据目录,与通知/队列同源)。 */
46
- export function transactionFile(home) {
47
- return join(home, ".dsh", "mobile-remote", "plugin-update-transaction.json");
48
- }
49
-
50
- /** 更新锁**目录**(mkdir 原子独占;见 acquireLock)。 */
51
- export function updateLockPath(home) {
52
- return join(home, ".dsh", "mobile-remote", "plugin-update.lock.d");
53
- }
54
-
55
- /** 兼容旧名(它指向的是一个目录,不再是文件)。 */
56
- export const updateLockFile = updateLockPath;
57
-
58
- /** 下载/解包的工作目录(事务独占)。 */
59
- export function workRoot(home) {
60
- return join(home, ".dsh", "mobile-remote", "update-work");
61
- }
62
-
63
- /** 不可变产物目录根。 */
64
- export function artifactRoot(home) {
65
- return join(home, ".dsh", "mobile-remote", "plugin-artifacts");
66
- }
67
-
68
- /** 不可变快照根(回滚目标)。 */
69
- export function snapshotRoot(home) {
70
- return join(home, ".dsh", "mobile-remote", "plugin-snapshots");
71
- }
72
-
73
- /** 按**内容标识**命名的不可变产物目录;同版本不同内容因此天然分属不同目录。 */
74
- export function artifactDir(root, contentSha256) {
75
- return join(root, String(contentSha256 || "unknown").toLowerCase());
76
- }
77
-
78
- /** 按**内容标识**命名的不可变快照目录(更新前的旧内容)。 */
79
- export function snapshotDir(root, contentSha256) {
80
- return join(root, String(contentSha256 || "unknown").toLowerCase());
81
- }
82
-
83
- export function readTransaction(file) {
84
- try {
85
- const doc = JSON.parse(readFileSync(file, "utf8"));
86
- return doc && typeof doc === "object" ? doc : null;
87
- } catch {
88
- return null;
89
- }
90
- }
91
-
92
- export function writeTransaction(file, tx) {
93
- mkdirSync(dirname(file), { recursive: true });
94
- const next = { ...tx, updatedAt: new Date().toISOString() };
95
- writeFileSync(file, `${JSON.stringify(next, null, 2)}\n`, "utf8");
96
- return next;
97
- }
98
-
99
- export function clearTransaction(file) {
100
- try {
101
- rmSync(file, { force: true });
102
- } catch {
103
- // 清不掉不影响正确性:下次事务会覆盖它
104
- }
105
- }
106
-
107
- /** Converge only under the same OS arbitration as acquire/release/state writes. */
108
- export function convergeStaleTransaction({ stateFile, lockPath, expectedLease, now = () => Date.now(), staleMs = 600_000 } = {}) {
109
- const result = arbitrate(lockPath, { operation: "converge", stateFile, expectedLease, now: now(), staleMs });
110
- if (!result.ok) return { action: "blocked", error: result.error, transaction: readTransaction(stateFile) };
111
- return result;
112
- }
113
-
114
- /**
115
- * 定位 profile 目录:从插件真实路径向上找**第一个声明了本插件依赖**的 package.json。
116
- *
117
- * 为什么不"往上数两层":Node 解析包链接时会走 realpath,pnpm 标准布局下插件位于
118
- * `profile/node_modules/.pnpm/<entry>/node_modules/dsh-mobile-remote`,往上两层得到的是
119
- * `.pnpm/<entry>` 而不是 profile。这里改成**验证式查找**:找到的目录必须真的把
120
- * `dsh-mobile-remote` 写在 dependencies 里,否则继续往上,全都不匹配就返回空串。
121
- */
122
- /** 旧键:早期安装用的包名(保持向后兼容)。 */
123
- export const LEGACY_DEPENDENCY_KEY = "dsh-mobile-remote";
124
-
125
- /**
126
- * 本插件在 profile 里可能出现的依赖键。
127
- * 包名一旦带 scope(npm 正式渠道),profile 的依赖键就变成 `@scope/name`——
128
- * 若还硬编码旧键,自更新会找不到 profile。因此键从**插件自己的 package.json** 推导。
129
- */
130
- export function dependencyKeysFor(pluginRoot, { readJson = readJsonFile } = {}) {
131
- const keys = [];
132
- try {
133
- const name = readJson(join(pluginRoot, "package.json"))?.name;
134
- if (typeof name === "string" && name.trim() !== "") keys.push(name.trim());
135
- } catch {
136
- // 读不到自己的包名时只留旧键
137
- }
138
- if (!keys.includes(LEGACY_DEPENDENCY_KEY)) keys.push(LEGACY_DEPENDENCY_KEY);
139
- return keys;
140
- }
141
-
142
- /** 在 profile 的 dependencies 里找出实际使用的那个依赖键(找不到返回空串)。 */
143
- export function dependencyKeyIn(doc, keys = [LEGACY_DEPENDENCY_KEY]) {
144
- for (const key of keys) {
145
- if (typeof doc?.dependencies?.[key] === "string") return key;
146
- }
147
- return "";
148
- }
149
-
150
- export function findProfileDir(startDir, { readJson = readJsonFile, maxDepth = 8, keys } = {}) {
151
- const dependencyKeys = keys ?? dependencyKeysFor(startDir, { readJson });
152
- let dir = resolve(startDir);
153
- for (let i = 0; i < maxDepth; i++) {
154
- try {
155
- const doc = readJson(join(dir, "package.json"));
156
- if (dependencyKeyIn(doc, dependencyKeys) !== "") return dir;
157
- } catch {
158
- // 该层没有 package.json 或不可读:继续向上
159
- }
160
- const parent = dirname(dir);
161
- if (parent === dir) break;
162
- dir = parent;
163
- }
164
- return "";
165
- }
166
-
167
- function readJsonFile(file) {
168
- return JSON.parse(readFileSync(file, "utf8"));
169
- }
170
-
171
- /** 读 profile 里本插件的依赖声明;找不到返回空串(调用方据此转降级指引)。 */
172
- export function profileSpecifierOf(profileDir, { readJson = readJsonFile, keys = [LEGACY_DEPENDENCY_KEY] } = {}) {
173
- if (!profileDir) return "";
174
- try {
175
- const doc = readJson(join(profileDir, "package.json"));
176
- const key = dependencyKeyIn(doc, keys);
177
- return key === "" ? "" : doc.dependencies[key];
178
- } catch {
179
- return "";
180
- }
181
- }
182
-
183
- // C3: stable arbitration inode, kernel flock, and an unguessable generation fence.
184
- // Metadata is never interpreted/removed by read->rename/rm outside this arbitration.
185
- const arbiter = fileURLToPath(new URL("./update-lock-arbiter.js", import.meta.url));
186
- function arbitrate(lockPath, request) {
187
- mkdirSync(dirname(lockPath), { recursive: true });
188
- const r = spawnSync("flock", ["--exclusive", "--wait", "5", `${lockPath}.arbitration`, process.execPath, arbiter], {
189
- input: JSON.stringify({ ...request, lockPath }), encoding: "utf8", timeout: 7000,
190
- });
191
- if (r.error || r.status !== 0) return { ok: false, error: "lock-arbitration-unavailable" };
192
- try { return JSON.parse(r.stdout); } catch { return { ok: false, error: "lock-arbitration-invalid" }; }
193
- }
194
- export function readLock(dir) {
195
- try { return JSON.parse(readFileSync(join(dir, "holder.json"), "utf8")); } catch { return null; }
196
- }
197
- export function defaultIsPidAlive(pid) {
198
- if (!Number.isInteger(pid) || pid <= 0) return false;
199
- try { process.kill(pid, 0); return true; } catch(e) { return e.code === "EPERM"; }
200
- }
201
- export function lockHeld(dir) { return readLock(dir) !== null; }
202
- export function acquireLock(dir, { opId, pid = process.pid, now = Date.now(), lease, stateFile } = {}) {
203
- if (!validOperationId(opId)) return { ok: false, error: "invalid-operation-id" };
204
- return arbitrate(dir, { operation: "acquire", opId, pid, now, lease, stateFile });
205
- }
206
- export function releaseLock(dir, lease, { stateFile } = {}) {
207
- // An opId alone is not ownership. Old workers need the exact generation too.
208
- if (!lease?.generation) return false;
209
- return arbitrate(dir, { operation: "release", lease, stateFile }).ok;
210
- }
211
- export function handOverLock(dir, { lease, toPid } = {}) {
212
- if (!lease?.generation) return false;
213
- return arbitrate(dir, { operation: "handover", lease, toPid }).ok;
214
- }
215
- export function assertUpdateLease(lockPath, lease) {
216
- const r = arbitrate(lockPath, { operation: "assert", lease });
217
- if (!r.ok) throw new Error(r.error);
218
- return r.holder;
219
- }
220
- export function writeOwnedTransaction(stateFile, tx, { lockPath, lease, currentFile, expectedPhases } = {}) {
221
- const r = arbitrate(lockPath, { operation: "state-write", lease, stateFile, tx, currentFile, expectedPhases });
222
- if (!r.ok) throw new Error(r.error);
223
- return r.transaction;
224
- }
225
- export function switchOwnedDependency({ profileDir, nextSpecifier, key, lockPath, lease } = {}) {
226
- return arbitrate(lockPath, { operation: "switch-profile", lease, profileDir, specifier: nextSpecifier, key });
227
- }
228
- export function claimOwnedRecovery(stateFile, { owner }, { lockPath, lease, currentFile } = {}) {
229
- return arbitrate(lockPath, { operation: 'claim-recovery', lease, stateFile, owner, currentFile });
230
- }
231
- export function finishOwnedTerminal(stateFile, { phase, result, expectedPhases }, { lockPath, lease, currentFile } = {}) {
232
- const r = arbitrate(lockPath, { operation: 'finish-terminal', lease, stateFile, phase, result, expectedPhases, currentFile });
233
- if (!r.ok) throw new Error(r.error);
234
- return r.transaction;
235
- }
236
- export function restoreOwnedProfile({ profileDir, snapshotDir, snapshot, key, lockPath, lease } = {}) {
237
- return arbitrate(lockPath, { operation: 'restore-profile', profileDir, snapshotDir, snapshot, key, lease });
238
- }
239
- export function publishOwnedSnapshotLink({ profileDir, snapshotDir, lockPath, lease } = {}) {
240
- return arbitrate(lockPath, { operation: 'publish-snapshot-link', profileDir, snapshotDir, lease });
241
- }
242
- export function validOperationId(opId) {
243
- return typeof opId === "string" && /^[A-Za-z0-9][A-Za-z0-9_-]{0,95}$/.test(opId);
244
- }
245
- export function serverOperationPath(home, id) {
246
- if (!/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/.test(id)) throw new Error("invalid-filesystem-id");
247
- return join(home, ".dsh", "mobile-remote", "transactions", `${id}.json`);
248
- }
249
-
250
- /**
251
- * 把当前已安装的插件内容快照成**自包含、可加载**的不可变副本(F4):
252
- * - **解引用 symlink**:pnpm 布局下副本里的依赖是符号链接,若原样复制会指向树外的
253
- * store;解引用后快照自己就是完整的依赖树;
254
- * - **原子发布**:全部复制完成后才写 `.complete` 标记;中途失败留下的半成品不会被
255
- * 当成可用快照(`snapshotReady` 会拒绝)。
256
- */
257
- export function snapshotInstalled({ installedRoot, destDir, copyFile } = {}) {
258
- if (!existsSync(installedRoot)) return { ok: false, error: "installed-root-missing" };
259
- return freezePackage({ sourceRoot: installedRoot, destination: destDir, copyFile });
260
- }
261
-
262
- /** 默认复制实现:**解引用符号链接**,得到自包含树。 */
263
- export function defaultCopyDir(src, dest) {
264
- try {
265
- mkdirSync(dest, { recursive: true });
266
- copyRecursive(src, dest, new Set());
267
- return { ok: true };
268
- } catch (e) {
269
- return { ok: false, error: String(e?.message ?? e) };
270
- }
271
- }
272
-
273
- function copyRecursive(src, dest, seen) {
274
- // 防环:symlink 解引用后可能回到祖先
275
- const key = `${src}->${dest}`;
276
- if (seen.has(key)) return;
277
- seen.add(key);
278
- for (const entry of readdirSync(src, { withFileTypes: true })) {
279
- const from = join(src, entry.name);
280
- const to = join(dest, entry.name);
281
- if (entry.isSymbolicLink()) {
282
- // 解引用:把链接目标的内容复制过来(目标缺失则跳过,不制造悬空链接)
283
- let real;
284
- try {
285
- real = realpathSync(from);
286
- } catch {
287
- throw new Error("required-link-broken");
288
- }
289
- const st = statSync(real);
290
- if (st.isDirectory()) {
291
- mkdirSync(to, { recursive: true });
292
- copyRecursive(real, to, seen);
293
- } else if (st.isFile()) {
294
- writeFileSync(to, readFileSync(real));
295
- }
296
- continue;
297
- }
298
- if (entry.isDirectory()) {
299
- mkdirSync(to, { recursive: true });
300
- copyRecursive(from, to, seen);
301
- } else if (entry.isFile()) {
302
- writeFileSync(to, readFileSync(from));
303
- }
304
- }
305
- }
306
-
307
- /** 快照完成标记(原子发布的凭据)。 */
308
- export const COMPLETE_MARKER = ".complete";
309
-
310
- /** 目录是否存在且非空(用于判断产物是否可用)。 */
311
- export function dirReady(dir) {
312
- try {
313
- return statSync(dir).isDirectory() && readdirSync(dir).length > 0;
314
- } catch {
315
- return false;
316
- }
317
- }
318
-
319
- /** 快照是否**完整可用**:非空且带完成标记(半复制不会被当成回滚目标)。 */
320
- export function snapshotReady(dir) {
321
- return frozenPackageReady(dir);
322
- }