service-sync.mjs 2.0 KB

1234567891011121314151617181920212223242526272829303132
  1. import { spawn } from 'node:child_process'
  2. import { join } from 'node:path'
  3. /** A native helper owns the update until completion, even if the window closes.
  4. * The renderer never receives its configuration or a process-control bridge. */
  5. export const synchronizeLocalService = options => serviceCommand({...options,action:'sync'})
  6. export const stopLocalService = options => serviceCommand({...options,action:'stop'})
  7. export const migrateLocalData = options => serviceCommand({...options,action:'migrate'})
  8. function serviceCommand({ home, port, root, fixture, environment, onProgress = () => {}, action }) {
  9. return new Promise((done, reject) => {
  10. const runtimeRoot = join(root, 'web-service')
  11. const helper = spawn(join(runtimeRoot, 'node'), [join(runtimeRoot, 'bin', 'desktop-service-sync.mjs')], {
  12. cwd: runtimeRoot, detached: true, stdio: ['pipe', 'pipe', 'ignore'],
  13. env: { HOME: process.env.HOME, PATH: process.env.PATH || '/usr/bin:/bin:/usr/sbin:/sbin', NODE_USE_ENV_PROXY: '0' },
  14. })
  15. let buffer = '', result, failure, failureCode
  16. helper.stdout.on('data', bytes => {
  17. buffer += bytes
  18. if (buffer.length > 256 * 1024) { failure = '同步进程输出异常'; return }
  19. for (;;) {
  20. const index = buffer.indexOf('\n'); if (index < 0) break
  21. const line = buffer.slice(0, index); buffer = buffer.slice(index + 1)
  22. try { const value = JSON.parse(line); if (value.message) onProgress(value.message); if (value.result) result = value.result; if (value.error) { failure = value.error; failureCode = value.code } }
  23. catch { failure = '同步进程响应无效' }
  24. }
  25. })
  26. helper.once('error', reject)
  27. helper.once('exit', code => code === 0 && result ? done(result) : reject(Object.assign(new Error(failure || (action==='stop'?'后台服务停止未完成':'本机 Web 同步未完成,请重试')), { code: failureCode })))
  28. helper.stdin.on('error', () => {})
  29. helper.stdin.end(JSON.stringify({ home, port, runtimeRoot, fixture, environment, action }))
  30. })
  31. }