@@ -33,6 +33,7 @@ import { ExtVersion } from "@App/app/const";
3333import { dayFormat } from "@App/pkg/utils/day_format" ;
3434import i18n , { i18nName } from "@App/locales/locales" ;
3535import { InfoNotification } from "./utils" ;
36+ import { stackAsyncTask } from "@App/pkg/utils/async_queue" ;
3637
3738// type SynchronizeTarget = "local";
3839
@@ -66,6 +67,8 @@ type ScriptcatSyncStatus = {
6667
6768type PushScriptParam = TInstallScriptParams ;
6869
70+ const SYNC_SERVICE_TASK_KEY = "cloud_sync" ;
71+
6972export class SynchronizeService {
7073 logger : Logger ;
7174
@@ -329,6 +332,10 @@ export class SynchronizeService {
329332
330333 // 同步一次
331334 async syncOnce ( syncConfig : CloudSyncConfig , fs : FileSystem ) {
335+ return stackAsyncTask ( SYNC_SERVICE_TASK_KEY , ( ) => this . syncOnceInternal ( syncConfig , fs ) ) ;
336+ }
337+
338+ private async syncOnceInternal ( syncConfig : CloudSyncConfig , fs : FileSystem ) {
332339 this . logger . info ( "start sync once" ) ;
333340 // 获取文件列表
334341 const list = await fs . list ( ) ;
@@ -402,15 +409,15 @@ export class SynchronizeService {
402409 const metaObj = JSON . parse ( metaJson ) as SyncMeta ;
403410 if ( metaObj . isDeleted ) {
404411 // 删除脚本
405- this . script . deleteScript ( script . uuid , "sync" ) ;
412+ await this . script . deleteScript ( script . uuid , "sync" ) ;
406413 InfoNotification (
407414 i18n . t ( "notification.script_sync_delete" ) ,
408415 i18n . t ( "notification.script_sync_delete_desc" , { scriptName : i18nName ( script ) } )
409416 ) ;
410417 } else {
411418 // 否则认为是一个无效的.meta文件,进行删除,并进行同步
412419 await fs . delete ( file . meta ! . name ) ;
413- result . push ( this . pushScript ( fs , script ) ) ;
420+ await this . pushScript ( fs , script ) ;
414421 }
415422 } ) ( )
416423 ) ;
@@ -436,8 +443,11 @@ export class SynchronizeService {
436443 // 如果脚本不存在,但文件存在,则安装脚本
437444 if ( file . script ) {
438445 if ( ! file . meta ) {
439- // 如果.meta文件不存在,则删除脚本文件,并跳过
440- result . push ( fs . delete ( file . script . name ) ) ;
446+ // .meta 文件可能尚未上传完成,跳过本次以避免误删云端脚本
447+ this . logger . warn ( "skip orphan cloud script without meta" , {
448+ uuid,
449+ file : file . script . name ,
450+ } ) ;
441451 return ;
442452 }
443453 updateScript . set ( uuid , true ) ;
@@ -616,7 +626,7 @@ export class SynchronizeService {
616626 script . status = status . enable ? SCRIPT_STATUS_ENABLE : SCRIPT_STATUS_DISABLE ;
617627 }
618628 }
619- this . script . installScript ( {
629+ await this . script . installScript ( {
620630 script,
621631 code,
622632 upsertBy : "sync" ,
@@ -630,33 +640,37 @@ export class SynchronizeService {
630640 cloudSyncConfigChange ( value : CloudSyncConfig ) {
631641 if ( value . enable ) {
632642 // 开启云同步同步
633- this . buildFileSystem ( value ) . then ( async ( fs ) => {
634- await this . syncOnce ( value , fs ) ;
635- // 开启定时器, 一小时一次
636- chrome . alarms . get ( "cloudSync" , ( alarm ) => {
637- const lastError = chrome . runtime . lastError ;
638- if ( lastError ) {
639- console . error ( "chrome.runtime.lastError in chrome.alarms.get:" , lastError ) ;
640- // 非预期的异常API错误,停止处理
641- }
642- if ( ! alarm ) {
643- chrome . alarms . create (
644- "cloudSync" ,
645- {
646- periodInMinutes : 60 ,
647- } ,
648- ( ) => {
649- const lastError = chrome . runtime . lastError ;
650- if ( lastError ) {
651- console . error ( "chrome.runtime.lastError in chrome.alarms.create:" , lastError ) ;
652- // Starting in Chrome 117, the number of active alarms is limited to 500. Once this limit is reached, chrome.alarms.create() will fail.
653- console . error ( "Chrome alarm is unable to create. Please check whether limit is reached." ) ;
643+ this . buildFileSystem ( value )
644+ . then ( async ( fs ) => {
645+ await this . syncOnce ( value , fs ) ;
646+ // 开启定时器, 一小时一次
647+ chrome . alarms . get ( "cloudSync" , ( alarm ) => {
648+ const lastError = chrome . runtime . lastError ;
649+ if ( lastError ) {
650+ console . error ( "chrome.runtime.lastError in chrome.alarms.get:" , lastError ) ;
651+ // 非预期的异常API错误,停止处理
652+ }
653+ if ( ! alarm ) {
654+ chrome . alarms . create (
655+ "cloudSync" ,
656+ {
657+ periodInMinutes : 60 ,
658+ } ,
659+ ( ) => {
660+ const lastError = chrome . runtime . lastError ;
661+ if ( lastError ) {
662+ console . error ( "chrome.runtime.lastError in chrome.alarms.create:" , lastError ) ;
663+ // Starting in Chrome 117, the number of active alarms is limited to 500. Once this limit is reached, chrome.alarms.create() will fail.
664+ console . error ( "Chrome alarm is unable to create. Please check whether limit is reached." ) ;
665+ }
654666 }
655- }
656- ) ;
657- }
667+ ) ;
668+ }
669+ } ) ;
670+ } )
671+ . catch ( ( e ) => {
672+ this . logger . error ( "cloud sync config change error" , Logger . E ( e ) ) ;
658673 } ) ;
659- } ) ;
660674 } else {
661675 // 停止计时器
662676 chrome . alarms . clear ( "cloudSync" ) ;
@@ -670,9 +684,12 @@ export class SynchronizeService {
670684 // 判断是否开启了同步
671685 const config = await this . systemConfig . getCloudSync ( ) ;
672686 if ( config . enable ) {
673- this . buildFileSystem ( config ) . then ( async ( fs ) => {
687+ stackAsyncTask ( SYNC_SERVICE_TASK_KEY , async ( ) => {
688+ const fs = await this . buildFileSystem ( config ) ;
674689 await this . pushScript ( fs , params . script ) ;
675- this . updateFileDigest ( fs ) ;
690+ await this . updateFileDigest ( fs ) ;
691+ } ) . catch ( ( e ) => {
692+ this . logger . error ( "push script on install error" , Logger . E ( e ) ) ;
676693 } ) ;
677694 }
678695 }
@@ -681,13 +698,17 @@ export class SynchronizeService {
681698 // 判断是否开启了同步
682699 const config = await this . systemConfig . getCloudSync ( ) ;
683700 if ( config . enable ) {
684- this . buildFileSystem ( config ) . then ( async ( fs ) => {
701+ stackAsyncTask ( SYNC_SERVICE_TASK_KEY , async ( ) => {
702+ const fs = await this . buildFileSystem ( config ) ;
685703 for ( const { uuid, deleteBy } of data ) {
686704 if ( deleteBy === "sync" ) {
687705 continue ;
688706 }
689707 await this . deleteCloudScript ( fs , uuid , config . syncDelete ) ;
690708 }
709+ await this . updateFileDigest ( fs ) ;
710+ } ) . catch ( ( e ) => {
711+ this . logger . error ( "delete cloud script error" , Logger . E ( e ) ) ;
691712 } ) ;
692713 }
693714 }
0 commit comments