@tearleads/client-sdk 0.1.33 → 0.1.34
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/data/blobs/transferPool.js +53 -0
- package/data/blobs/transferPool.js.map +1 -0
- package/data/documents/blob/shared/types.d.ts +2 -2
- package/data/documents/blob/shared/types.js.map +1 -1
- package/data/sync/coordinatorLaneRun.js +154 -0
- package/data/sync/coordinatorLaneRun.js.map +1 -0
- package/data/sync/coordinatorPump.js +72 -169
- package/data/sync/coordinatorPump.js.map +1 -1
- package/data/sync/coordinatorState.d.ts +6 -0
- package/data/sync/coordinatorState.js +3 -1
- package/data/sync/coordinatorState.js.map +1 -1
- package/data/sync/syncCoordinator.js +4 -3
- package/data/sync/syncCoordinator.js.map +1 -1
- package/data/sync/syncLaneConfig.d.ts +2 -0
- package/data/sync/syncLaneConfig.js.map +1 -1
- package/internal/api-client/ApiClient.d.ts +2 -2
- package/internal/api-client/ApiClient.js +4 -4
- package/internal/api-client/ApiClient.js.map +1 -1
- package/internal/api-client/routes/blobs/get.d.ts +2 -2
- package/internal/api-client/routes/blobs/get.js +24 -21
- package/internal/api-client/routes/blobs/get.js.map +1 -1
- package/internal/api-client/routes/blobs/multipartUpload.js +16 -9
- package/internal/api-client/routes/blobs/multipartUpload.js.map +1 -1
- package/internal/api-client/routes/blobs/storageFetchOptions.js +11 -0
- package/internal/api-client/routes/blobs/storageFetchOptions.js.map +1 -0
- package/package.json +1 -1
- package/stores/documents/documentStore/attachmentHydration.js +33 -0
- package/stores/documents/documentStore/attachmentHydration.js.map +1 -1
- package/stores/documents/documentStore/remoteWork.js +1 -1
- package/stores/documents/documentStore/remoteWork.js.map +1 -1
- package/stores/documents/documentStore/sync.js +3 -0
- package/stores/documents/documentStore/sync.js.map +1 -1
- package/sync/reconciliation/documentContentPull.js +7 -3
- package/sync/reconciliation/documentContentPull.js.map +1 -1
- package/sync/reconciliation/idleBackfill.js +14 -2
- package/sync/reconciliation/idleBackfill.js.map +1 -1
- package/sync/reconciliation/knownContainerSweep.js +5 -2
- package/sync/reconciliation/knownContainerSweep.js.map +1 -1
- package/sync/reconciliation/reconcileContainer.js +3 -3
- package/sync/reconciliation/reconcileContainer.js.map +1 -1
- package/sync/reconciliation/service.js +9 -4
- package/sync/reconciliation/service.js.map +1 -1
- package/sync/reconciliation/serviceTypes.d.ts +5 -3
- package/sync/reconciliation/serviceTypes.js.map +1 -1
- package/sync/reconciliation/triggers.d.ts +2 -1
- package/sync/reconciliation/triggers.js +5 -2
- package/sync/reconciliation/triggers.js.map +1 -1
- package/workflows/blobs/hydrate.d.ts +4 -2
- package/workflows/blobs/hydrate.js +21 -7
- package/workflows/blobs/hydrate.js.map +1 -1
- package/workflows/blobs/multipartUpload.js +57 -30
- package/workflows/blobs/multipartUpload.js.map +1 -1
- package/workflows/blobs/readAttachmentTransfer.js +42 -0
- package/workflows/blobs/readAttachmentTransfer.js.map +1 -0
- package/workflows/documents/syncLane.d.ts +1 -0
- package/workflows/documents/syncLane.js +1 -0
- package/workflows/documents/syncLane.js.map +1 -1
- package/workflows/registration/persistRegistrationBootstrap.js +3 -0
- package/workflows/registration/persistRegistrationBootstrap.js.map +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coordinatorPump.js","sourceRoot":"","sources":["coordinatorPump.ts"],"names":[],"mappings":"AAIA,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,8BAA8B,GAC/B,MAAM,oBAAoB,CAAC;AAE5B,OAAO,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,iBAAiB,CAAC;AAQ5E,MAAM,6BAA6B,GAAG,EAAE,CAAC;AACzC,MAAM,0BAA0B,GAAG,CAAC,CAAC;AACrC,MAAM,4BAA4B,GAAG,GAAG,CAAC;AACzC,8EAA8E;AAC9E,0EAA0E;AAC1E,MAAM,4BAA4B,GAAG,IAAI,CAAC;AAC1C,mEAAmE;AACnE,MAAM,kCAAkC,GAAG,EAAE,CAAC;AAC9C,6EAA6E;AAC7E,0CAA0C;AAC1C,MAAM,qBAAqB,GAAG,OAAO,CAAC;AAMtC,qEAAqE;AACrE,MAAM,2BAA2B,GAAG,IAAI,OAAO,EAA0B,CAAC;AAE1E,2EAA2E;AAC3E,8EAA8E;AAC9E,2EAA2E;AAC3E,oCAAoC;AACpC,SAAS,gCAAgC,CAAC,KAAc;IACtD,MAAM,IAAI,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,KAAK,CAAC;IAChE,OAAO,IAAI,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,qBAAqB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,gFAAgF;AAChF,6EAA6E;AAC7E,+EAA+E;AAC/E,0EAA0E;AAC1E,2EAA2E;AAC3E,qCAAqC;AACrC,SAAS,+BAA+B,CACtC,KAAoB,EACpB,KAAc;IAEd,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC,qBAAqB,CAAC;IAClD,IAAI,CAAC,MAAM;QAAE,OAAO;IACpB,MAAM,SAAS,GAAG,gCAAgC,CAAC,KAAK,CAAC,CAAC;IAC1D,IAAI,2BAA2B,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,KAAK,SAAS;QAAE,OAAO;IACxE,2BAA2B,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IACzD,IAAI,CAAC;QACH,KAAK,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC7D,CAAC;IAAC,MAAM,CAAC;QACP,8DAA8D;IAChE,CAAC;AACH,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,KAAoB;IAC7C,IAAI,CAAC;QACH,MAAM,KAAK,CAAC,MAAM,CAAC,GAAG,EAAE,CAAC;QACzB,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;IACjC,CAAC;IAAC,OAAO,KAAc,EAAE,CAAC;QACxB,IAAI,KAAK,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;YAC5C,OAAO,EAAE,MAAM,EAAE,WAAW,EAAE,CAAC;QACjC,CAAC;QACD,+BAA+B,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QAE9C,IAAI,KAAK,CAAC,MAAM,CAAC,iBAAiB,EAAE,CAAC;YACnC,KAAK,CAAC,MAAM,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC;YACtC,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;QACrC,CAAC;QAED,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC;AAED,4EAA4E;AAC5E,gFAAgF;AAChF,+EAA+E;AAC/E,sEAAsE;AACtE,2EAA2E;AAC3E,SAAS,6BAA6B,CAAC,KAAoB,EAAE,KAAc;IACzE,OAAO,CAAC,KAAK,CAAC,2BAA2B,KAAK,CAAC,GAAG,GAAG,EAAE,KAAK,CAAC,CAAC;AAChE,CAAC;AAED,SAAS,KAAK,CAAC,EAAU;IACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,6EAA6E;AAC7E,wEAAwE;AACxE,SAAS,wBAAwB,CAAC,IAAmB;IACnD,OAAO,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,cAAc,KAAK,IAAI,CAAC;AAC3E,CAAC;AAED,SAAS,oBAAoB,CAAC,KAA8B;IAC1D,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IACE,wBAAwB,CAAC,IAAI,CAAC;YAC9B,CAAC,IAAI,CAAC,aAAa,KAAK,IAAI,IAAI,IAAI,CAAC,aAAa,IAAI,GAAG,CAAC,EAC1D,CAAC;YACD,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,uBAAuB,CAC9B,KAA8B;IAE9B,IAAI,YAAY,GAAyB,IAAI,CAAC;IAC9C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEvB,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IACE,CAAC,wBAAwB,CAAC,IAAI,CAAC;YAC/B,CAAC,IAAI,CAAC,aAAa,KAAK,IAAI,IAAI,IAAI,CAAC,aAAa,GAAG,GAAG,CAAC,EACzD,CAAC;YACD,SAAS;QACX,CAAC;QACD,IAAI,CAAC,YAAY,IAAI,oBAAoB,CAAC,IAAI,EAAE,YAAY,CAAC,GAAG,CAAC,EAAE,CAAC;YAClE,YAAY,GAAG,IAAI,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO,YAAY,CAAC;AACtB,CAAC;AAED,SAAS,uBAAuB,CAC9B,IAAmB,EACnB,SAA4B;IAE5B,IAAI,CAAC,YAAY,GAAG,mBAAmB,EAAE,CAAC;IAC1C,IAAI,SAAS,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QAClC,IAAI,CAAC,UAAU,IAAI,CAAC,CAAC;QACrB,IAAI,CAAC,UAAU,GAAG,QAAQ,CAAC;QAC3B,IAAI,CAAC,SAAS,GAAG,qBAAqB,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;QACxD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,YAAY,CAAC;IACxC,CAAC;SAAM,CAAC;QACN,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC;QAC9B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,YAAY,CAAC;QACzC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACxB,CAAC;AACH,CAAC;AAED,+EAA+E;AAC/E,SAAS,0BAA0B,CACjC,gBAA4C,EAC5C,IAAmB,EACnB,QAAgB,EAChB,SAA4B;IAE5B,IAAI,IAAI,CAAC,cAAc,KAAK,QAAQ,EAAE,CAAC;QACrC,OAAO;IACT,CAAC;IACD,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;IAC3B,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;IAC1B,uBAAuB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IACzC,8BAA8B,CAAC,gBAAgB,CAAC,CAAC;IACjD,IACE,CAAC,gBAAgB,CAAC,QAAQ;QAC1B,oBAAoB,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EACrD,CAAC;QACD,uBAAuB,CAAC,gBAAgB,CAAC,CAAC;IAC5C,CAAC;AACH,CAAC;AAED,SAAS,gBAAgB,CACvB,gBAA4C,EAC5C,IAAmB;IAEnB,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;IACvB,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;IAC1B,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACpB,IAAI,CAAC,QAAQ,IAAI,CAAC,CAAC;IACnB,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;IAC5B,IAAI,CAAC,YAAY,GAAG,mBAAmB,EAAE,CAAC;IAC1C,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC,YAAY,CAAC;IACvC,IAAI,CAAC,YAAY,GAAG,KAAK,CAAC;IAC1B,MAAM,QAAQ,GAAG,EAAE,CAAC;IACpB,IAAI,CAAC,cAAc,GAAG,QAAQ,CAAC;IAC/B,8BAA8B,CAAC,gBAAgB,CAAC,CAAC;IAEjD,0EAA0E;IAC1E,gCAAgC;IAChC,wEAAwE;IACxE,MAAM,gBAAgB,GAA+B,WAAW,CAAC,IAAI,CAAC,CAAC,IAAI,CACzE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,EAClB,CAAC,KAAc,EAAE,EAAE;QACjB,6BAA6B,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;QAC3C,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,EAAE,CAAC;IACrC,CAAC,CACF,CAAC;IAEF,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,CAAC;AACxC,CAAC;AAED,KAAK,UAAU,qBAAqB,CAClC,gBAA4C;IAE5C,IAAI,uBAAuB,GAAG,CAAC,CAAC;IAChC,0EAA0E;IAC1E,OAAO,CAAC,gBAAgB,CAAC,QAAQ,EAAE,CAAC;QAClC,MAAM,IAAI,GAAG,uBAAuB,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC;QACtE,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO;QACT,CAAC;QAED,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,GAAG,gBAAgB,CACrD,gBAAgB,EAChB,IAAI,CACL,CAAC;QACF,yEAAyE;QACzE,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CACzB,CAAC,EACD,IAAI,CAAC,MAAM,CAAC,UAAU,IAAI,qBAAqB,CAChD,CAAC;QACF,IAAI,aAAa,GAAyC,IAAI,CAAC;QAC/D,MAAM,WAAW,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC;YACrC,gBAAgB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBACjC,IAAI,EAAE,SAAkB;gBACxB,MAAM;aACP,CAAC,CAAC;YACH,IAAI,OAAO,CAAwB,CAAC,OAAO,EAAE,EAAE;gBAC7C,aAAa,GAAG,UAAU,CACxB,GAAG,EAAE,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,EACpC,UAAU,CACX,CAAC;YACJ,CAAC,CAAC;SACH,CAAC,CAAC;QACH,IAAI,aAAa,KAAK,IAAI,EAAE,CAAC;YAC3B,YAAY,CAAC,aAAa,CAAC,CAAC;QAC9B,CAAC;QAED,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QACrB,IAAI,SAA4B,CAAC;QACjC,IAAI,WAAW,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YACnC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC;YAC3B,SAAS,GAAG,WAAW,CAAC,MAAM,CAAC;QACjC,CAAC;aAAM,CAAC;YACN,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;YACzB,SAAS,GAAG;gBACV,MAAM,EAAE,QAAQ;gBAChB,KAAK,EAAE,IAAI,KAAK,CACd,oCAAoC,UAAU,iCAAiC,CAChF;aACF,CAAC;YACF,KAAK,gBAAgB,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,EAAE,CACpC,0BAA0B,CAAC,gBAAgB,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,CAAC,CACrE,CAAC;QACJ,CAAC;QACD,uBAAuB,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;QACzC,8BAA8B,CAAC,gBAAgB,CAAC,CAAC;QAEjD,uBAAuB,IAAI,CAAC,CAAC;QAE7B,IACE,SAAS,CAAC,MAAM,KAAK,QAAQ;YAC7B,IAAI,CAAC,SAAS;YACd,WAAW,CAAC,IAAI,KAAK,SAAS,EAC9B,CAAC;YACD,sEAAsE;YACtE,yEAAyE;YACzE,MAAM,KAAK,CAAC,4BAA4B,CAAC,CAAC;YAC1C,uBAAuB,GAAG,CAAC,CAAC;QAC9B,CAAC;aAAM,IAAI,uBAAuB,IAAI,kCAAkC,EAAE,CAAC;YACzE,uEAAuE;YACvE,gEAAgE;YAChE,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC;YACf,uBAAuB,GAAG,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;AACH,CAAC;AAED,SAAS,uBAAuB,CAAC,gBAA4C;IAC3E,IAAI,gBAAgB,CAAC,IAAI,IAAI,gBAAgB,CAAC,QAAQ,EAAE,CAAC;QACvD,OAAO;IACT,CAAC;IAED,gBAAgB,CAAC,IAAI,GAAG,OAAO,CAAC,OAAO,EAAE;SACtC,IAAI,CAAC,GAAG,EAAE,CAAC,qBAAqB,CAAC,gBAAgB,CAAC,CAAC;SACnD,OAAO,CAAC,GAAG,EAAE;QACZ,gBAAgB,CAAC,IAAI,GAAG,IAAI,CAAC;QAC7B,8BAA8B,CAAC,gBAAgB,CAAC,CAAC;QAEjD,IACE,CAAC,gBAAgB,CAAC,QAAQ;YAC1B,oBAAoB,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EACrD,CAAC;YACD,uBAAuB,CAAC,gBAAgB,CAAC,CAAC;QAC5C,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAmB,EAAE,WAAmB;IACjE,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;IACtB,IAAI,CAAC,YAAY,IAAI,CAAC,CAAC;IACvB,IAAI,CAAC,UAAU,GAAG,WAAW,CAAC;IAC9B,IAAI,CAAC,YAAY,GAAG,WAAW,CAAC;IAChC,IAAI,CAAC,eAAe,GAAG,WAAW,CAAC;AACrC,CAAC;AAED,MAAM,UAAU,eAAe,CAC7B,gBAA4C,EAC5C,IAAmB;IAEnB,IAAI,gBAAgB,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QAClD,OAAO;IACT,CAAC;IACD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;IAC1B,iBAAiB,CAAC,IAAI,EAAE,mBAAmB,EAAE,CAAC,CAAC;IAC/C,8BAA8B,CAAC,gBAAgB,CAAC,CAAC;IACjD,uBAAuB,CAAC,gBAAgB,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,gBAA4C,EAC5C,IAAmB,EACnB,OAAe;IAEf,IAAI,gBAAgB,CAAC,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QAClD,OAAO;IACT,CAAC;IACD,IAAI,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;QAClD,OAAO;IACT,CAAC;IACD,MAAM,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IACxD,IAAI,CAAC,aAAa;QAChB,IAAI,CAAC,aAAa,KAAK,IAAI;YACzB,CAAC,CAAC,aAAa;YACf,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,aAAa,EAAE,aAAa,CAAC,CAAC;IAClD,iBAAiB,CAAC,IAAI,EAAE,mBAAmB,EAAE,CAAC,CAAC;IAC/C,8BAA8B,CAAC,gBAAgB,CAAC,CAAC;IACjD,MAAM,aAAa,GAAG,IAAI,CAAC,aAAa,CAAC;IACzC,UAAU,CACR,GAAG,EAAE;QACH,IAAI,gBAAgB,CAAC,QAAQ,IAAI,IAAI,CAAC,aAAa,KAAK,aAAa,EAAE,CAAC;YACtE,OAAO;QACT,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,8BAA8B,CAAC,gBAAgB,CAAC,CAAC;QACjD,uBAAuB,CAAC,gBAAgB,CAAC,CAAC;IAC5C,CAAC,EACD,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,aAAa,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CACxC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,gBAA4C;IAE5C,IAAI,gBAAgB,CAAC,QAAQ,IAAI,gBAAgB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACnE,OAAO;IACT,CAAC;IAED,0EAA0E;IAC1E,+DAA+D;IAC/D,MAAM,WAAW,GAAG,mBAAmB,EAAE,CAAC;IAC1C,IAAI,cAAc,GAAG,KAAK,CAAC;IAC3B,KAAK,MAAM,IAAI,IAAI,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;QACnD,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;YACrB,SAAS;QACX,CAAC;QACD,IAAI,CAAC,aAAa,GAAG,IAAI,CAAC;QAC1B,iBAAiB,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACrC,cAAc,GAAG,IAAI,CAAC;IACxB,CAAC;IACD,IAAI,CAAC,cAAc,EAAE,CAAC;QACpB,OAAO;IACT,CAAC;IAED,8BAA8B,CAAC,gBAAgB,CAAC,CAAC;IACjD,uBAAuB,CAAC,gBAAgB,CAAC,CAAC;AAC5C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,gBAA4C,EAC5C,UAA2B,EAAE;IAE7B,MAAM,UAAU,GAAG,OAAO,CAAC,UAAU,IAAI,6BAA6B,CAAC;IACvE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,IAAI,0BAA0B,CAAC;IAC9D,MAAM,SAAS,GAAG,OAAO,CAAC,SAAS,IAAI,4BAA4B,CAAC;IACpE,MAAM,QAAQ,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,CAAC;IACxC,IAAI,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAEhC,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,QAAQ,EAAE,CAAC;QAC9B,IACE,CAAC,gBAAgB,CAAC,IAAI;YACtB,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EACpD,CAAC;YACD,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,cAAc,IAAI,OAAO,EAAE,CAAC;gBAC3C,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;aAAM,CAAC;YACN,cAAc,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC9B,CAAC;QAED,MAAM,KAAK,CAAC,UAAU,CAAC,CAAC;IAC1B,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["import type {\n DomainSyncCoordinatorState,\n SyncLaneState,\n} from \"./coordinatorState\";\nimport {\n describeSyncLaneError,\n hasPendingLaneWork,\n publishSyncCoordinatorSnapshot,\n} from \"./coordinatorState\";\nimport type { SyncLaneConfig } from \"./syncLaneConfig\";\nimport { compareSyncLaneOrder, createSyncTimestamp } from \"./syncTelemetry\";\n\nexport interface SyncIdleOptions {\n intervalMs?: number;\n quietMs?: number;\n timeoutMs?: number;\n}\n\nconst DEFAULT_SYNC_IDLE_INTERVAL_MS = 10;\nconst DEFAULT_SYNC_IDLE_QUIET_MS = 0;\nconst DEFAULT_SYNC_IDLE_TIMEOUT_MS = 500;\n// Slow down repeated failures and yield periodically during successful bursts\n// so lanes that keep requesting work cannot starve timers or other tasks.\nconst FAILED_LANE_REARM_BACKOFF_MS = 1000;\n// Allow normal convergence bursts to finish without a timer delay.\nconst SYNC_PUMP_MACROTASK_YIELD_INTERVAL = 16;\n// A timed-out run keeps its lane occupied until it settles, but releases the\n// serial pump so other lanes can proceed.\nconst SYNC_LANE_WATCHDOG_MS = 120_000;\n\ntype SyncLaneRunResult =\n | { status: \"completed\" }\n | { status: \"failed\"; error: unknown };\n\n// Keyed on the registered config so a discarded lane is collectable.\nconst lastReportedFailureByConfig = new WeakMap<SyncLaneConfig, string>();\n\n// Local-only dedup key. describeSyncLaneError joins messages without their\n// types, so the name keeps a swallowed DatabaseUnavailableError distinct from\n// a plain Error carrying the same text; the cause chain keeps a re-wrapped\n// failure distinct from its origin.\nfunction describeSyncLaneFailureSignature(error: unknown): string {\n const name = error instanceof Error ? error.name : typeof error;\n return JSON.stringify([name, describeSyncLaneError(error)]);\n}\n\n// Observability only: a failing lane re-arms every FAILED_LANE_REARM_BACKOFF_MS\n// for the rest of the session, and mobile WebViews are never reloaded, so an\n// unrecoverable lane would report once a second. The signature is deliberately\n// never cleared on a completed run: alternating success and failure would\n// re-admit the same report every pass and evict the surrounding diagnostic\n// trail from the host's bounded log.\nfunction reportUnexpectedSyncLaneFailure(\n state: SyncLaneState,\n error: unknown,\n): void {\n const report = state.config.reportUnexpectedError;\n if (!report) return;\n const signature = describeSyncLaneFailureSignature(error);\n if (lastReportedFailureByConfig.get(state.config) === signature) return;\n lastReportedFailureByConfig.set(state.config, signature);\n try {\n void Promise.resolve(report(error)).catch(() => undefined);\n } catch {\n // Hosts may throw synchronously or return a rejected promise.\n }\n}\n\nasync function runSyncLane(state: SyncLaneState): Promise<SyncLaneRunResult> {\n try {\n await state.config.run();\n return { status: \"completed\" };\n } catch (error: unknown) {\n if (state.config.shouldIgnoreError?.(error)) {\n return { status: \"completed\" };\n }\n reportUnexpectedSyncLaneFailure(state, error);\n\n if (state.config.onUnexpectedError) {\n state.config.onUnexpectedError(error);\n return { status: \"failed\", error };\n }\n\n throw error;\n }\n}\n\n// Console-only on purpose. This runs only when the lane's OWN error handler\n// already threw, so it must never route through reportUnexpectedSyncLaneFailure\n// as well: re-entering a handler that just threw would reject runResultPromise\n// from inside its own onRejected callback, leaving `running` true and\n// `activeRunToken` set, which wedges the lane for the rest of the session.\nfunction reportUnexpectedSyncLaneError(state: SyncLaneState, error: unknown) {\n console.error(`Failed to run sync lane ${state.key}:`, error);\n}\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// An abandoned run still owns its lane. Its eventual settlement will restart\n// the pump; trying to restart earlier would spin without runnable work.\nfunction isRequestedLaneAvailable(lane: SyncLaneState): boolean {\n return lane.pumpDriven && lane.requested && lane.activeRunToken === null;\n}\n\nfunction hasRequestedLaneWork(lanes: Iterable<SyncLaneState>): boolean {\n const now = Date.now();\n for (const lane of lanes) {\n if (\n isRequestedLaneAvailable(lane) &&\n (lane.notBeforeAtMs === null || lane.notBeforeAtMs <= now)\n ) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction selectNextRequestedLane(\n lanes: Iterable<SyncLaneState>,\n): SyncLaneState | null {\n let selectedLane: SyncLaneState | null = null;\n const now = Date.now();\n\n for (const lane of lanes) {\n if (\n !isRequestedLaneAvailable(lane) ||\n (lane.notBeforeAtMs !== null && lane.notBeforeAtMs > now)\n ) {\n continue;\n }\n if (!selectedLane || compareSyncLaneOrder(lane, selectedLane) < 0) {\n selectedLane = lane;\n }\n }\n\n return selectedLane;\n}\n\nfunction recordSyncLaneRunResult(\n lane: SyncLaneState,\n runResult: SyncLaneRunResult,\n): void {\n lane.lastActionAt = createSyncTimestamp();\n if (runResult.status === \"failed\") {\n lane.errorCount += 1;\n lane.lastAction = \"failed\";\n lane.lastError = describeSyncLaneError(runResult.error);\n lane.lastFailedAt = lane.lastActionAt;\n } else {\n lane.lastAction = \"completed\";\n lane.lastCompletedAt = lane.lastActionAt;\n lane.lastError = null;\n }\n}\n\n// Replace the watchdog failure with the late result, then release queued work.\nfunction settleAbandonedSyncLaneRun(\n coordinatorState: DomainSyncCoordinatorState,\n lane: SyncLaneState,\n runToken: object,\n runResult: SyncLaneRunResult,\n): void {\n if (lane.activeRunToken !== runToken) {\n return;\n }\n lane.activeRunToken = null;\n lane.runAbandoned = false;\n recordSyncLaneRunResult(lane, runResult);\n publishSyncCoordinatorSnapshot(coordinatorState);\n if (\n !coordinatorState.disposed &&\n hasRequestedLaneWork(coordinatorState.lanes.values())\n ) {\n scheduleCoordinatorPump(coordinatorState);\n }\n}\n\nfunction startSyncLaneRun(\n coordinatorState: DomainSyncCoordinatorState,\n lane: SyncLaneState,\n) {\n lane.requested = false;\n lane.notBeforeAtMs = null;\n lane.running = true;\n lane.runCount += 1;\n lane.lastAction = \"started\";\n lane.lastActionAt = createSyncTimestamp();\n lane.lastStartedAt = lane.lastActionAt;\n lane.runAbandoned = false;\n const runToken = {};\n lane.activeRunToken = runToken;\n publishSyncCoordinatorSnapshot(coordinatorState);\n\n // Keep follow-up requests even on failure to preserve phase ordering; see\n // docs/client-sync-ordering.md.\n // The fallback also catches errors thrown by the lane's error handlers.\n const runResultPromise: Promise<SyncLaneRunResult> = runSyncLane(lane).then(\n (result) => result,\n (error: unknown) => {\n reportUnexpectedSyncLaneError(lane, error);\n return { status: \"failed\", error };\n },\n );\n\n return { runToken, runResultPromise };\n}\n\nasync function runRequestedSyncLanes(\n coordinatorState: DomainSyncCoordinatorState,\n): Promise<void> {\n let runsSinceMacrotaskYield = 0;\n // Disposal can happen during a run. Finish it before selecting more work.\n while (!coordinatorState.disposed) {\n const lane = selectNextRequestedLane(coordinatorState.lanes.values());\n if (!lane) {\n return;\n }\n\n const { runToken, runResultPromise } = startSyncLaneRun(\n coordinatorState,\n lane,\n );\n // Clamp overrides to at least 1ms so every run has a chance to complete.\n const watchdogMs = Math.max(\n 1,\n lane.config.watchdogMs ?? SYNC_LANE_WATCHDOG_MS,\n );\n let watchdogTimer: ReturnType<typeof setTimeout> | null = null;\n const raceOutcome = await Promise.race([\n runResultPromise.then((result) => ({\n kind: \"settled\" as const,\n result,\n })),\n new Promise<{ kind: \"timed-out\" }>((resolve) => {\n watchdogTimer = setTimeout(\n () => resolve({ kind: \"timed-out\" }),\n watchdogMs,\n );\n }),\n ]);\n if (watchdogTimer !== null) {\n clearTimeout(watchdogTimer);\n }\n\n lane.running = false;\n let runResult: SyncLaneRunResult;\n if (raceOutcome.kind === \"settled\") {\n lane.activeRunToken = null;\n runResult = raceOutcome.result;\n } else {\n lane.runAbandoned = true;\n runResult = {\n status: \"failed\",\n error: new Error(\n `Sync lane watchdog: run exceeded ${watchdogMs}ms; continuing with other lanes`,\n ),\n };\n void runResultPromise.then((result) =>\n settleAbandonedSyncLaneRun(coordinatorState, lane, runToken, result),\n );\n }\n recordSyncLaneRunResult(lane, runResult);\n publishSyncCoordinatorSnapshot(coordinatorState);\n\n runsSinceMacrotaskYield += 1;\n\n if (\n runResult.status === \"failed\" &&\n lane.requested &&\n raceOutcome.kind === \"settled\"\n ) {\n // Timed-out runs cannot run again until they settle, so only ordinary\n // failures need backoff. Other lanes can proceed immediately on timeout.\n await delay(FAILED_LANE_REARM_BACKOFF_MS);\n runsSinceMacrotaskYield = 0;\n } else if (runsSinceMacrotaskYield >= SYNC_PUMP_MACROTASK_YIELD_INTERVAL) {\n // Awaiting resolved promises only yields microtasks. A timer also lets\n // the event loop advance when lanes keep requesting each other.\n await delay(0);\n runsSinceMacrotaskYield = 0;\n }\n }\n}\n\nfunction scheduleCoordinatorPump(coordinatorState: DomainSyncCoordinatorState) {\n if (coordinatorState.pump || coordinatorState.disposed) {\n return;\n }\n\n coordinatorState.pump = Promise.resolve()\n .then(() => runRequestedSyncLanes(coordinatorState))\n .finally(() => {\n coordinatorState.pump = null;\n publishSyncCoordinatorSnapshot(coordinatorState);\n\n if (\n !coordinatorState.disposed &&\n hasRequestedLaneWork(coordinatorState.lanes.values())\n ) {\n scheduleCoordinatorPump(coordinatorState);\n }\n });\n}\n\nfunction markLaneRequested(lane: SyncLaneState, requestedAt: string): void {\n lane.requested = true;\n lane.requestCount += 1;\n lane.lastAction = \"requested\";\n lane.lastActionAt = requestedAt;\n lane.lastRequestedAt = requestedAt;\n}\n\nexport function requestLaneSync(\n coordinatorState: DomainSyncCoordinatorState,\n lane: SyncLaneState,\n) {\n if (coordinatorState.disposed || !lane.pumpDriven) {\n return;\n }\n lane.notBeforeAtMs = null;\n markLaneRequested(lane, createSyncTimestamp());\n publishSyncCoordinatorSnapshot(coordinatorState);\n scheduleCoordinatorPump(coordinatorState);\n}\n\nexport function requestLaneSyncAfter(\n coordinatorState: DomainSyncCoordinatorState,\n lane: SyncLaneState,\n delayMs: number,\n): void {\n if (coordinatorState.disposed || !lane.pumpDriven) {\n return;\n }\n if (lane.requested && lane.notBeforeAtMs === null) {\n return;\n }\n const requestedAtMs = Date.now() + Math.max(0, delayMs);\n lane.notBeforeAtMs =\n lane.notBeforeAtMs === null\n ? requestedAtMs\n : Math.min(lane.notBeforeAtMs, requestedAtMs);\n markLaneRequested(lane, createSyncTimestamp());\n publishSyncCoordinatorSnapshot(coordinatorState);\n const scheduledAtMs = lane.notBeforeAtMs;\n setTimeout(\n () => {\n if (coordinatorState.disposed || lane.notBeforeAtMs !== scheduledAtMs) {\n return;\n }\n lane.notBeforeAtMs = null;\n publishSyncCoordinatorSnapshot(coordinatorState);\n scheduleCoordinatorPump(coordinatorState);\n },\n Math.max(0, scheduledAtMs - Date.now()),\n );\n}\n\nexport function requestAllPumpDrivenLanes(\n coordinatorState: DomainSyncCoordinatorState,\n): void {\n if (coordinatorState.disposed || coordinatorState.lanes.size === 0) {\n return;\n }\n\n // Publish all requests together. Observational upload lanes report actual\n // uploads and must never be driven through their no-op runner.\n const requestedAt = createSyncTimestamp();\n let didRequestLane = false;\n for (const lane of coordinatorState.lanes.values()) {\n if (!lane.pumpDriven) {\n continue;\n }\n lane.notBeforeAtMs = null;\n markLaneRequested(lane, requestedAt);\n didRequestLane = true;\n }\n if (!didRequestLane) {\n return;\n }\n\n publishSyncCoordinatorSnapshot(coordinatorState);\n scheduleCoordinatorPump(coordinatorState);\n}\n\nexport async function waitForIdleLanes(\n coordinatorState: DomainSyncCoordinatorState,\n options: SyncIdleOptions = {},\n): Promise<boolean> {\n const intervalMs = options.intervalMs ?? DEFAULT_SYNC_IDLE_INTERVAL_MS;\n const quietMs = options.quietMs ?? DEFAULT_SYNC_IDLE_QUIET_MS;\n const timeoutMs = options.timeoutMs ?? DEFAULT_SYNC_IDLE_TIMEOUT_MS;\n const deadline = Date.now() + timeoutMs;\n let quietStartedAt = Date.now();\n\n while (Date.now() <= deadline) {\n if (\n !coordinatorState.pump &&\n !hasPendingLaneWork(coordinatorState.lanes.values())\n ) {\n if (Date.now() - quietStartedAt >= quietMs) {\n return true;\n }\n } else {\n quietStartedAt = Date.now();\n }\n\n await delay(intervalMs);\n }\n\n return false;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"coordinatorPump.js","sourceRoot":"","sources":["coordinatorPump.ts"],"names":[],"mappings":"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","sourcesContent":["import { runCoordinatorLane } from \"./coordinatorLaneRun\";\nimport type {\n DomainSyncCoordinatorState,\n SyncLaneState,\n} from \"./coordinatorState\";\nimport {\n hasPendingLaneWork,\n publishSyncCoordinatorSnapshot,\n} from \"./coordinatorState\";\nimport { compareSyncLaneOrder, createSyncTimestamp } from \"./syncTelemetry\";\n\nexport interface SyncIdleOptions {\n intervalMs?: number;\n quietMs?: number;\n timeoutMs?: number;\n}\n\nconst DEFAULT_SYNC_IDLE_INTERVAL_MS = 10;\nconst DEFAULT_SYNC_IDLE_QUIET_MS = 0;\nconst DEFAULT_SYNC_IDLE_TIMEOUT_MS = 500;\nconst DOCUMENT_LANE_CONCURRENCY = 4;\nconst SYNC_PUMP_MACROTASK_YIELD_INTERVAL = 16;\n\nfunction delay(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n// Priority is a scheduling hint, never permission to abandon active workers.\nfunction readLanePriority(lane: SyncLaneState): number {\n try {\n const priority = lane.config.priority?.() ?? 0;\n return Number.isFinite(priority) ? priority : 0;\n } catch {\n return 0;\n }\n}\n\nfunction compareRequestedLanes(\n left: SyncLaneState,\n right: SyncLaneState,\n): number {\n if (\n (left.config.phase ?? \"document\") !== (right.config.phase ?? \"document\")\n ) {\n return compareSyncLaneOrder(left, right);\n }\n return (\n readLanePriority(left) - readLanePriority(right) ||\n left.lastRunOrder - right.lastRunOrder ||\n compareSyncLaneOrder(left, right)\n );\n}\n\n// An abandoned run still owns its lane. Its eventual settlement will restart\n// the pump; trying to restart earlier would spin without runnable work.\nfunction isRequestedLaneAvailable(lane: SyncLaneState): boolean {\n return lane.pumpDriven && lane.requested && lane.activeRunToken === null;\n}\n\nfunction hasRunnableLaneWork(laneValues: Iterable<SyncLaneState>): boolean {\n const lanes = Array.from(laneValues);\n const structuralPending = lanes.some(\n (lane) =>\n lane.config.phase === \"structural\" && isRequestedLaneAvailable(lane),\n );\n const now = Date.now();\n for (const lane of lanes) {\n if (\n (!structuralPending || lane.config.phase === \"structural\") &&\n isRequestedLaneAvailable(lane) &&\n (lane.notBeforeAtMs === null || lane.notBeforeAtMs <= now) &&\n !lane.backingOff\n ) {\n return true;\n }\n }\n\n return false;\n}\n\nfunction selectNextRequestedLane(\n lanes: Iterable<SyncLaneState>,\n): SyncLaneState | null {\n let selectedLane: SyncLaneState | null = null;\n const now = Date.now();\n\n for (const lane of lanes) {\n if (\n !isRequestedLaneAvailable(lane) ||\n (lane.notBeforeAtMs !== null && lane.notBeforeAtMs > now) ||\n lane.backingOff\n ) {\n continue;\n }\n if (!selectedLane || compareRequestedLanes(lane, selectedLane) < 0) {\n selectedLane = lane;\n }\n }\n\n return selectedLane;\n}\n\nasync function runRequestedSyncLanes(\n state: DomainSyncCoordinatorState,\n): Promise<void> {\n const running = new Map<SyncLaneState, Promise<void>>();\n let startsSinceYield = 0;\n while (!state.disposed || running.size > 0) {\n // Install the wake-up before selecting or starting work. New requests can\n // fill unused workers even while another document is waiting on the network.\n const wakeup = new Promise<void>((resolve) => {\n state.wakePump = resolve;\n });\n let lane = state.disposed\n ? null\n : selectNextRequestedLane(state.lanes.values());\n const structuralPending = Array.from(state.lanes.values()).some(\n (candidate) =>\n candidate.pumpDriven &&\n candidate.config.phase === \"structural\" &&\n (candidate.running ||\n (candidate.requested && candidate.activeRunToken === null)),\n );\n const structuralRunning = Array.from(running.keys()).some(\n (candidate) => candidate.config.phase === \"structural\",\n );\n if (\n lane &&\n (running.size >= DOCUMENT_LANE_CONCURRENCY ||\n structuralRunning ||\n (lane.config.phase === \"structural\"\n ? running.size > 0\n : structuralPending))\n )\n lane = null;\n if (lane) {\n const startedLane = lane;\n lane.lastRunOrder = ++state.nextRunOrder;\n const run = runCoordinatorLane(state, lane, () =>\n scheduleCoordinatorPump(state),\n ).finally(() => {\n running.delete(startedLane);\n state.wakePump?.();\n });\n running.set(lane, run);\n if (++startsSinceYield >= SYNC_PUMP_MACROTASK_YIELD_INTERVAL) {\n await delay(0);\n startsSinceYield = 0;\n }\n continue;\n }\n if (running.size === 0) break;\n await wakeup;\n }\n state.wakePump = null;\n}\n\nfunction scheduleCoordinatorPump(coordinatorState: DomainSyncCoordinatorState) {\n if (coordinatorState.disposed) return;\n if (coordinatorState.pump) {\n coordinatorState.wakePump?.();\n return;\n }\n\n coordinatorState.pump = Promise.resolve()\n .then(() => runRequestedSyncLanes(coordinatorState))\n .finally(() => {\n coordinatorState.pump = null;\n publishSyncCoordinatorSnapshot(coordinatorState);\n\n if (\n !coordinatorState.disposed &&\n hasRunnableLaneWork(coordinatorState.lanes.values())\n ) {\n scheduleCoordinatorPump(coordinatorState);\n }\n });\n}\n\nfunction markLaneRequested(lane: SyncLaneState, requestedAt: string): void {\n lane.requested = true;\n lane.requestCount += 1;\n lane.lastAction = \"requested\";\n lane.lastActionAt = requestedAt;\n lane.lastRequestedAt = requestedAt;\n}\n\nexport function requestLaneSync(\n coordinatorState: DomainSyncCoordinatorState,\n lane: SyncLaneState,\n) {\n if (coordinatorState.disposed || !lane.pumpDriven) {\n return;\n }\n lane.notBeforeAtMs = null;\n markLaneRequested(lane, createSyncTimestamp());\n publishSyncCoordinatorSnapshot(coordinatorState);\n scheduleCoordinatorPump(coordinatorState);\n}\n\nexport function requestLaneSyncAfter(\n coordinatorState: DomainSyncCoordinatorState,\n lane: SyncLaneState,\n delayMs: number,\n): void {\n if (coordinatorState.disposed || !lane.pumpDriven) {\n return;\n }\n if (lane.requested && lane.notBeforeAtMs === null) {\n return;\n }\n const requestedAtMs = Date.now() + Math.max(0, delayMs);\n lane.notBeforeAtMs =\n lane.notBeforeAtMs === null\n ? requestedAtMs\n : Math.min(lane.notBeforeAtMs, requestedAtMs);\n markLaneRequested(lane, createSyncTimestamp());\n publishSyncCoordinatorSnapshot(coordinatorState);\n const scheduledAtMs = lane.notBeforeAtMs;\n setTimeout(\n () => {\n if (coordinatorState.disposed || lane.notBeforeAtMs !== scheduledAtMs) {\n return;\n }\n lane.notBeforeAtMs = null;\n publishSyncCoordinatorSnapshot(coordinatorState);\n scheduleCoordinatorPump(coordinatorState);\n },\n Math.max(0, scheduledAtMs - Date.now()),\n );\n}\n\nexport function requestAllPumpDrivenLanes(\n coordinatorState: DomainSyncCoordinatorState,\n): void {\n if (coordinatorState.disposed || coordinatorState.lanes.size === 0) {\n return;\n }\n\n // Publish all requests together. Observational upload lanes report actual\n // uploads and must never be driven through their no-op runner.\n const requestedAt = createSyncTimestamp();\n let didRequestLane = false;\n for (const lane of coordinatorState.lanes.values()) {\n if (!lane.pumpDriven) {\n continue;\n }\n lane.notBeforeAtMs = null;\n markLaneRequested(lane, requestedAt);\n didRequestLane = true;\n }\n if (!didRequestLane) {\n return;\n }\n\n publishSyncCoordinatorSnapshot(coordinatorState);\n scheduleCoordinatorPump(coordinatorState);\n}\n\nexport async function waitForIdleLanes(\n coordinatorState: DomainSyncCoordinatorState,\n options: SyncIdleOptions = {},\n): Promise<boolean> {\n const intervalMs = options.intervalMs ?? DEFAULT_SYNC_IDLE_INTERVAL_MS;\n const quietMs = options.quietMs ?? DEFAULT_SYNC_IDLE_QUIET_MS;\n const timeoutMs = options.timeoutMs ?? DEFAULT_SYNC_IDLE_TIMEOUT_MS;\n const deadline = Date.now() + timeoutMs;\n let quietStartedAt = Date.now();\n\n while (Date.now() <= deadline) {\n if (\n !coordinatorState.pump &&\n !hasPendingLaneWork(coordinatorState.lanes.values())\n ) {\n if (Date.now() - quietStartedAt >= quietMs) {\n return true;\n }\n } else {\n quietStartedAt = Date.now();\n }\n\n await delay(intervalMs);\n }\n\n return false;\n}\n"]}
|
|
@@ -2,6 +2,8 @@ import type { SyncLaneConfig } from "./syncLaneConfig.js";
|
|
|
2
2
|
import type { DomainSyncSnapshot, SyncLaneLastAction, SyncLaneProgress } from "./syncTelemetry.js";
|
|
3
3
|
export interface SyncLaneState {
|
|
4
4
|
activeRunToken: object | null;
|
|
5
|
+
backingOff: boolean;
|
|
6
|
+
lastRunOrder: number;
|
|
5
7
|
blobStorageKey: string | null;
|
|
6
8
|
config: SyncLaneConfig;
|
|
7
9
|
errorCount: number;
|
|
@@ -28,11 +30,15 @@ export interface DomainSyncCoordinatorState {
|
|
|
28
30
|
lanes: Map<string, SyncLaneState>;
|
|
29
31
|
listeners: Set<() => void>;
|
|
30
32
|
nextRegistrationIndex: number;
|
|
33
|
+
nextRunOrder: number;
|
|
34
|
+
wakePump: (() => void) | null;
|
|
31
35
|
pump: Promise<void> | null;
|
|
32
36
|
snapshot: DomainSyncSnapshot;
|
|
33
37
|
}
|
|
34
38
|
export declare const INITIAL_SYNC_LANE_RUN_STATE: {
|
|
35
39
|
readonly activeRunToken: null;
|
|
40
|
+
readonly backingOff: false;
|
|
41
|
+
readonly lastRunOrder: 0;
|
|
36
42
|
readonly runAbandoned: false;
|
|
37
43
|
readonly runCount: 0;
|
|
38
44
|
readonly running: false;
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { createDomainSyncSnapshot } from "./syncTelemetry.js";
|
|
2
2
|
export const INITIAL_SYNC_LANE_RUN_STATE = {
|
|
3
3
|
activeRunToken: null,
|
|
4
|
+
backingOff: false,
|
|
5
|
+
lastRunOrder: 0,
|
|
4
6
|
runAbandoned: false,
|
|
5
7
|
runCount: 0,
|
|
6
8
|
running: false,
|
|
@@ -42,7 +44,7 @@ export function describeSyncLaneError(error) {
|
|
|
42
44
|
export function noopLaneRun() {
|
|
43
45
|
return Promise.resolve();
|
|
44
46
|
}
|
|
45
|
-
// Deliberately ignores activeRunToken (unlike the pump's
|
|
47
|
+
// Deliberately ignores activeRunToken (unlike the pump's hasRunnableLaneWork):
|
|
46
48
|
// a watchdog-abandoned run is detached background work, and idle/pending-work
|
|
47
49
|
// reporting must not block on a hung run that may never settle. Its late
|
|
48
50
|
// settle still publishes a snapshot and re-pumps any queued re-request.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coordinatorState.js","sourceRoot":"","sources":["coordinatorState.ts"],"names":[],"mappings":"AAMA,OAAO,EAAE,wBAAwB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"coordinatorState.js","sourceRoot":"","sources":["coordinatorState.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SyncLaneConfig } from \"./syncLaneConfig\";\nimport type {\n DomainSyncSnapshot,\n SyncLaneLastAction,\n SyncLaneProgress,\n} from \"./syncTelemetry\";\nimport { createDomainSyncSnapshot } from \"./syncTelemetry\";\n\nexport interface SyncLaneState {\n // Identity of the lane's live run, set for the duration of a run INCLUDING\n // after a watchdog timeout abandons it. Selection skips lanes whose token is\n // set, so a lane can never run concurrently with its own abandoned run; the\n // late-settle continuation clears it (matching on identity) and re-pumps.\n activeRunToken: object | null;\n backingOff: boolean;\n lastRunOrder: number;\n blobStorageKey: string | null;\n config: SyncLaneConfig;\n errorCount: number;\n key: string;\n lastAction: SyncLaneLastAction;\n lastActionAt: string;\n lastCompletedAt: string | null;\n lastError: string | null;\n lastFailedAt: string | null;\n lastRequestedAt: string | null;\n lastStartedAt: string | null;\n notBeforeAtMs: number | null;\n progress: SyncLaneProgress | null;\n // Registered lanes are driven by the coordinator pump. Blob upload lanes\n // are observational telemetry driven directly by the upload workflow.\n pumpDriven: boolean;\n registrationIndex: number;\n requestCount: number;\n requested: boolean;\n runAbandoned: boolean;\n runCount: number;\n running: boolean;\n}\n\nexport interface DomainSyncCoordinatorState {\n // Set by dispose(): stop admitting work and drain already-running callbacks\n // (or their watchdogs). No new pump can be scheduled after runtime teardown.\n disposed: boolean;\n lanes: Map<string, SyncLaneState>;\n listeners: Set<() => void>;\n nextRegistrationIndex: number;\n nextRunOrder: number;\n wakePump: (() => void) | null;\n pump: Promise<void> | null;\n snapshot: DomainSyncSnapshot;\n}\n\nexport const INITIAL_SYNC_LANE_RUN_STATE = {\n activeRunToken: null,\n backingOff: false,\n lastRunOrder: 0,\n runAbandoned: false,\n runCount: 0,\n running: false,\n} as const;\n\nfunction describeSingleSyncLaneError(error: unknown): string {\n if (error instanceof Error) {\n return error.message;\n }\n if (\n typeof error === \"object\" &&\n error !== null &&\n \"message\" in error &&\n typeof error.message === \"string\"\n ) {\n return error.message;\n }\n\n return String(error);\n}\n\nfunction readErrorCause(error: unknown): unknown {\n if (typeof error !== \"object\" || error === null) {\n return undefined;\n }\n\n return Reflect.get(error, \"cause\");\n}\n\nexport function describeSyncLaneError(error: unknown): string {\n const messages: string[] = [];\n const seen = new Set<unknown>();\n let current: unknown = error;\n\n while (current !== undefined && current !== null && !seen.has(current)) {\n seen.add(current);\n const message = describeSingleSyncLaneError(current);\n if (message.length > 0) {\n messages.push(message);\n }\n current = readErrorCause(current);\n }\n\n return messages.length > 0 ? messages.join(\" Caused by: \") : String(error);\n}\n\n// Observational upload lanes never enter the pump, so their run is never\n// invoked; this satisfies the SyncLaneConfig contract without behavior.\nexport function noopLaneRun(): Promise<void> {\n return Promise.resolve();\n}\n\n// Deliberately ignores activeRunToken (unlike the pump's hasRunnableLaneWork):\n// a watchdog-abandoned run is detached background work, and idle/pending-work\n// reporting must not block on a hung run that may never settle. Its late\n// settle still publishes a snapshot and re-pumps any queued re-request.\nexport function hasPendingLaneWork(lanes: Iterable<SyncLaneState>): boolean {\n for (const lane of lanes) {\n if (lane.requested || lane.running) {\n return true;\n }\n }\n\n return false;\n}\n\nexport function publishSyncCoordinatorSnapshot(\n state: DomainSyncCoordinatorState,\n) {\n state.snapshot = createDomainSyncSnapshot({\n hasPendingWork: !!state.pump || hasPendingLaneWork(state.lanes.values()),\n lanes: state.lanes.values(),\n pumpActive: !!state.pump,\n });\n for (const listener of [...state.listeners]) {\n try {\n listener();\n } catch {\n // Keep one observer failure from blocking sync or later observers.\n }\n }\n}\n"]}
|
|
@@ -21,6 +21,8 @@ function createDomainSyncCoordinator() {
|
|
|
21
21
|
lanes: new Map(),
|
|
22
22
|
listeners: new Set(),
|
|
23
23
|
nextRegistrationIndex: 0,
|
|
24
|
+
nextRunOrder: 0,
|
|
25
|
+
wakePump: null,
|
|
24
26
|
pump: null,
|
|
25
27
|
snapshot: createDomainSyncSnapshot({
|
|
26
28
|
hasPendingWork: false,
|
|
@@ -133,9 +135,8 @@ export function requestAllDomainSyncLanes(domainScope) {
|
|
|
133
135
|
export function requestDomainSyncLane(domainScope, key) {
|
|
134
136
|
coordinatorsByScope.get(domainScope)?.requestLane(key);
|
|
135
137
|
}
|
|
136
|
-
//
|
|
137
|
-
//
|
|
138
|
-
// getOrCreate for the same scope builds a fresh coordinator.
|
|
138
|
+
// Stop admitting work and remove this scope's coordinator. Active callbacks
|
|
139
|
+
// drain under their existing watchdogs; getOrCreate builds a fresh coordinator.
|
|
139
140
|
export function disposeDomainSyncCoordinator(domainScope) {
|
|
140
141
|
const coordinator = coordinatorsByScope.get(domainScope);
|
|
141
142
|
if (!coordinator) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syncCoordinator.js","sourceRoot":"","sources":["syncCoordinator.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DomainScope } from \"../domainScope\";\nimport {\n requestAllPumpDrivenLanes,\n requestLaneSync,\n requestLaneSyncAfter,\n type SyncIdleOptions,\n waitForIdleLanes,\n} from \"./coordinatorPump\";\nimport type {\n DomainSyncCoordinatorState,\n SyncLaneState,\n} from \"./coordinatorState\";\nimport {\n hasPendingLaneWork,\n INITIAL_SYNC_LANE_RUN_STATE,\n publishSyncCoordinatorSnapshot,\n} from \"./coordinatorState\";\nimport type { SyncLane, SyncLaneConfig } from \"./syncLaneConfig\";\nimport type { DomainSyncSnapshot } from \"./syncTelemetry\";\nimport { createDomainSyncSnapshot, createSyncTimestamp } from \"./syncTelemetry\";\nimport type { UploadSyncLane, UploadSyncLaneOptions } from \"./uploadLane\";\nimport { beginUploadLane } from \"./uploadLane\";\n\nexport type { SyncIdleOptions } from \"./coordinatorPump\";\n// Re-exported here because lanes reach it as a shouldIgnoreError alongside the\n// rest of the coordinator surface; it lives beside this coordinator with the\n// error type it discriminates on.\nexport { isDatabaseUnavailableError } from \"./databaseUnavailable\";\nexport type { SyncLane, SyncLaneConfig } from \"./syncLaneConfig\";\nexport {\n didRegainSyncPrerequisites,\n type SyncRuntimeStatus,\n} from \"./syncPrerequisites\";\nexport type {\n DomainSyncSnapshot,\n SyncLaneLastAction,\n SyncLanePhase,\n SyncLaneProgress,\n SyncLaneSnapshot,\n SyncLaneStatus,\n} from \"./syncTelemetry\";\nexport type { UploadSyncLane, UploadSyncLaneOptions } from \"./uploadLane\";\n\nexport interface DomainSyncCoordinator {\n beginUploadLane: (\n key: string,\n options?: UploadSyncLaneOptions,\n ) => UploadSyncLane;\n // Force-stop the pump, drop all queued lane work, and refuse further runs.\n dispose: () => void;\n getSnapshot: () => DomainSyncSnapshot;\n registerLane: (key: string, config: SyncLaneConfig) => SyncLane;\n // Re-request every pump-driven lane — a manual \"sync now\" that re-drives\n // durable owners stranded by a transient failure. Observational upload rows\n // are updated only by those owners' real attachment upload attempts.\n requestAllLanes: () => void;\n // Request one registered pump lane without re-driving unrelated owners.\n requestLane: (key: string) => void;\n hasPendingWork: () => boolean;\n isDisposed: () => boolean;\n subscribe: (listener: () => void) => () => void;\n waitForIdle: (options?: SyncIdleOptions) => Promise<boolean>;\n}\n\nconst coordinatorsByScope = new WeakMap<DomainScope, DomainSyncCoordinator>();\n\nfunction createSyncLaneHandle(\n coordinatorState: DomainSyncCoordinatorState,\n lane: SyncLaneState,\n): SyncLane {\n return {\n isDisposed: () => coordinatorState.disposed,\n requestSync: () => requestLaneSync(coordinatorState, lane),\n requestSyncAfter: (delayMs) =>\n requestLaneSyncAfter(coordinatorState, lane, delayMs),\n };\n}\n\nfunction createDomainSyncCoordinator(): DomainSyncCoordinator {\n const coordinatorState: DomainSyncCoordinatorState = {\n disposed: false,\n lanes: new Map<string, SyncLaneState>(),\n listeners: new Set(),\n nextRegistrationIndex: 0,\n pump: null,\n snapshot: createDomainSyncSnapshot({\n hasPendingWork: false,\n lanes: [],\n pumpActive: false,\n }),\n };\n\n return {\n beginUploadLane(key: string, options: UploadSyncLaneOptions = {}) {\n return beginUploadLane(coordinatorState, key, options);\n },\n dispose() {\n coordinatorState.disposed = true;\n // Drop queued work so waitForIdle reports settled immediately and a\n // lane left re-requested by an in-flight run does not survive teardown.\n for (const lane of coordinatorState.lanes.values()) {\n lane.requested = false;\n lane.notBeforeAtMs = null;\n }\n // Publish the final settled snapshot, then release listener closures:\n // the coordinator is dropped from the registry and a remount subscribes\n // to a fresh one.\n publishSyncCoordinatorSnapshot(coordinatorState);\n coordinatorState.listeners.clear();\n },\n getSnapshot() {\n return coordinatorState.snapshot;\n },\n hasPendingWork() {\n return (\n !!coordinatorState.pump ||\n hasPendingLaneWork(coordinatorState.lanes.values())\n );\n },\n isDisposed() {\n return coordinatorState.disposed;\n },\n registerLane(key: string, config: SyncLaneConfig): SyncLane {\n const existingLane = coordinatorState.lanes.get(key);\n if (existingLane) {\n existingLane.config = config;\n existingLane.blobStorageKey = null;\n existingLane.pumpDriven = true;\n publishSyncCoordinatorSnapshot(coordinatorState);\n return createSyncLaneHandle(coordinatorState, existingLane);\n }\n\n const registeredAt = createSyncTimestamp();\n const nextLane: SyncLaneState = {\n ...INITIAL_SYNC_LANE_RUN_STATE,\n blobStorageKey: null,\n config,\n errorCount: 0,\n key,\n lastAction: \"registered\",\n lastActionAt: registeredAt,\n lastCompletedAt: null,\n lastError: null,\n lastFailedAt: null,\n lastRequestedAt: null,\n lastStartedAt: null,\n notBeforeAtMs: null,\n progress: null,\n pumpDriven: true,\n registrationIndex: coordinatorState.nextRegistrationIndex,\n requestCount: 0,\n requested: false,\n };\n coordinatorState.nextRegistrationIndex += 1;\n coordinatorState.lanes.set(key, nextLane);\n publishSyncCoordinatorSnapshot(coordinatorState);\n return createSyncLaneHandle(coordinatorState, nextLane);\n },\n requestAllLanes() {\n requestAllPumpDrivenLanes(coordinatorState);\n },\n requestLane(key: string) {\n const lane = coordinatorState.lanes.get(key);\n if (lane?.pumpDriven) {\n requestLaneSync(coordinatorState, lane);\n }\n },\n subscribe(listener: () => void) {\n coordinatorState.listeners.add(listener);\n return () => {\n coordinatorState.listeners.delete(listener);\n };\n },\n waitForIdle(options?: SyncIdleOptions) {\n return waitForIdleLanes(coordinatorState, options);\n },\n };\n}\n\nexport function getOrCreateDomainSyncCoordinator(\n domainScope: DomainScope,\n): DomainSyncCoordinator {\n const existingCoordinator = coordinatorsByScope.get(domainScope);\n if (existingCoordinator) {\n return existingCoordinator;\n }\n\n const nextCoordinator = createDomainSyncCoordinator();\n coordinatorsByScope.set(domainScope, nextCoordinator);\n return nextCoordinator;\n}\n\nexport function hasDomainSyncCoordinatorPendingWork(\n domainScope: DomainScope,\n): boolean {\n return coordinatorsByScope.get(domainScope)?.hasPendingWork() ?? false;\n}\n\n// Re-request every pump-driven lane for a scope: a user-driven \"sync now\" that\n// retries durable work stranded by a transient failure. Observational upload\n// telemetry is never directly pumped. A no-op when no coordinator exists yet\n// (nothing has been synced) or it has been disposed.\nexport function requestAllDomainSyncLanes(domainScope: DomainScope): void {\n coordinatorsByScope.get(domainScope)?.requestAllLanes();\n}\n\nexport function requestDomainSyncLane(\n domainScope: DomainScope,\n key: string,\n): void {\n coordinatorsByScope.get(domainScope)?.requestLane(key);\n}\n\n// Force-stop the coordinator for a scope and drop it from the registry, so a\n// pump cannot outlive the runtime/React tree that created it. A later\n// getOrCreate for the same scope builds a fresh coordinator.\nexport function disposeDomainSyncCoordinator(domainScope: DomainScope): void {\n const coordinator = coordinatorsByScope.get(domainScope);\n if (!coordinator) {\n return;\n }\n\n coordinator.dispose();\n coordinatorsByScope.delete(domainScope);\n}\n\nexport function getDomainSyncCoordinatorSnapshot(\n domainScope: DomainScope,\n): DomainSyncSnapshot {\n return getOrCreateDomainSyncCoordinator(domainScope).getSnapshot();\n}\n\nexport function subscribeToDomainSyncCoordinator(\n domainScope: DomainScope,\n listener: () => void,\n): () => void {\n return getOrCreateDomainSyncCoordinator(domainScope).subscribe(listener);\n}\n\nexport function beginDomainSyncUploadLane(\n domainScope: DomainScope,\n key: string,\n options?: UploadSyncLaneOptions,\n): UploadSyncLane {\n return getOrCreateDomainSyncCoordinator(domainScope).beginUploadLane(\n key,\n options,\n );\n}\n\nexport function waitForDomainSyncCoordinatorToSettle(\n domainScope: DomainScope,\n options?: SyncIdleOptions,\n): Promise<boolean> {\n return (\n coordinatorsByScope.get(domainScope)?.waitForIdle(options) ??\n Promise.resolve(true)\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"syncCoordinator.js","sourceRoot":"","sources":["syncCoordinator.ts"],"names":[],"mappings":"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","sourcesContent":["import type { DomainScope } from \"../domainScope\";\nimport {\n requestAllPumpDrivenLanes,\n requestLaneSync,\n requestLaneSyncAfter,\n type SyncIdleOptions,\n waitForIdleLanes,\n} from \"./coordinatorPump\";\nimport type {\n DomainSyncCoordinatorState,\n SyncLaneState,\n} from \"./coordinatorState\";\nimport {\n hasPendingLaneWork,\n INITIAL_SYNC_LANE_RUN_STATE,\n publishSyncCoordinatorSnapshot,\n} from \"./coordinatorState\";\nimport type { SyncLane, SyncLaneConfig } from \"./syncLaneConfig\";\nimport type { DomainSyncSnapshot } from \"./syncTelemetry\";\nimport { createDomainSyncSnapshot, createSyncTimestamp } from \"./syncTelemetry\";\nimport type { UploadSyncLane, UploadSyncLaneOptions } from \"./uploadLane\";\nimport { beginUploadLane } from \"./uploadLane\";\n\nexport type { SyncIdleOptions } from \"./coordinatorPump\";\n// Re-exported here because lanes reach it as a shouldIgnoreError alongside the\n// rest of the coordinator surface; it lives beside this coordinator with the\n// error type it discriminates on.\nexport { isDatabaseUnavailableError } from \"./databaseUnavailable\";\nexport type { SyncLane, SyncLaneConfig } from \"./syncLaneConfig\";\nexport {\n didRegainSyncPrerequisites,\n type SyncRuntimeStatus,\n} from \"./syncPrerequisites\";\nexport type {\n DomainSyncSnapshot,\n SyncLaneLastAction,\n SyncLanePhase,\n SyncLaneProgress,\n SyncLaneSnapshot,\n SyncLaneStatus,\n} from \"./syncTelemetry\";\nexport type { UploadSyncLane, UploadSyncLaneOptions } from \"./uploadLane\";\n\nexport interface DomainSyncCoordinator {\n beginUploadLane: (\n key: string,\n options?: UploadSyncLaneOptions,\n ) => UploadSyncLane;\n // Drop queued work and refuse new runs; active callbacks retain ownership.\n dispose: () => void;\n getSnapshot: () => DomainSyncSnapshot;\n registerLane: (key: string, config: SyncLaneConfig) => SyncLane;\n // Re-request every pump-driven lane — a manual \"sync now\" that re-drives\n // durable owners stranded by a transient failure. Observational upload rows\n // are updated only by those owners' real attachment upload attempts.\n requestAllLanes: () => void;\n // Request one registered pump lane without re-driving unrelated owners.\n requestLane: (key: string) => void;\n hasPendingWork: () => boolean;\n isDisposed: () => boolean;\n subscribe: (listener: () => void) => () => void;\n waitForIdle: (options?: SyncIdleOptions) => Promise<boolean>;\n}\n\nconst coordinatorsByScope = new WeakMap<DomainScope, DomainSyncCoordinator>();\n\nfunction createSyncLaneHandle(\n coordinatorState: DomainSyncCoordinatorState,\n lane: SyncLaneState,\n): SyncLane {\n return {\n isDisposed: () => coordinatorState.disposed,\n requestSync: () => requestLaneSync(coordinatorState, lane),\n requestSyncAfter: (delayMs) =>\n requestLaneSyncAfter(coordinatorState, lane, delayMs),\n };\n}\n\nfunction createDomainSyncCoordinator(): DomainSyncCoordinator {\n const coordinatorState: DomainSyncCoordinatorState = {\n disposed: false,\n lanes: new Map<string, SyncLaneState>(),\n listeners: new Set(),\n nextRegistrationIndex: 0,\n nextRunOrder: 0,\n wakePump: null,\n pump: null,\n snapshot: createDomainSyncSnapshot({\n hasPendingWork: false,\n lanes: [],\n pumpActive: false,\n }),\n };\n\n return {\n beginUploadLane(key: string, options: UploadSyncLaneOptions = {}) {\n return beginUploadLane(coordinatorState, key, options);\n },\n dispose() {\n coordinatorState.disposed = true;\n // Drop queued work so waitForIdle reports settled immediately and a\n // lane left re-requested by an in-flight run does not survive teardown.\n for (const lane of coordinatorState.lanes.values()) {\n lane.requested = false;\n lane.notBeforeAtMs = null;\n }\n // Publish the final settled snapshot, then release listener closures:\n // the coordinator is dropped from the registry and a remount subscribes\n // to a fresh one.\n publishSyncCoordinatorSnapshot(coordinatorState);\n coordinatorState.listeners.clear();\n },\n getSnapshot() {\n return coordinatorState.snapshot;\n },\n hasPendingWork() {\n return (\n !!coordinatorState.pump ||\n hasPendingLaneWork(coordinatorState.lanes.values())\n );\n },\n isDisposed() {\n return coordinatorState.disposed;\n },\n registerLane(key: string, config: SyncLaneConfig): SyncLane {\n const existingLane = coordinatorState.lanes.get(key);\n if (existingLane) {\n existingLane.config = config;\n existingLane.blobStorageKey = null;\n existingLane.pumpDriven = true;\n publishSyncCoordinatorSnapshot(coordinatorState);\n return createSyncLaneHandle(coordinatorState, existingLane);\n }\n\n const registeredAt = createSyncTimestamp();\n const nextLane: SyncLaneState = {\n ...INITIAL_SYNC_LANE_RUN_STATE,\n blobStorageKey: null,\n config,\n errorCount: 0,\n key,\n lastAction: \"registered\",\n lastActionAt: registeredAt,\n lastCompletedAt: null,\n lastError: null,\n lastFailedAt: null,\n lastRequestedAt: null,\n lastStartedAt: null,\n notBeforeAtMs: null,\n progress: null,\n pumpDriven: true,\n registrationIndex: coordinatorState.nextRegistrationIndex,\n requestCount: 0,\n requested: false,\n };\n coordinatorState.nextRegistrationIndex += 1;\n coordinatorState.lanes.set(key, nextLane);\n publishSyncCoordinatorSnapshot(coordinatorState);\n return createSyncLaneHandle(coordinatorState, nextLane);\n },\n requestAllLanes() {\n requestAllPumpDrivenLanes(coordinatorState);\n },\n requestLane(key: string) {\n const lane = coordinatorState.lanes.get(key);\n if (lane?.pumpDriven) {\n requestLaneSync(coordinatorState, lane);\n }\n },\n subscribe(listener: () => void) {\n coordinatorState.listeners.add(listener);\n return () => {\n coordinatorState.listeners.delete(listener);\n };\n },\n waitForIdle(options?: SyncIdleOptions) {\n return waitForIdleLanes(coordinatorState, options);\n },\n };\n}\n\nexport function getOrCreateDomainSyncCoordinator(\n domainScope: DomainScope,\n): DomainSyncCoordinator {\n const existingCoordinator = coordinatorsByScope.get(domainScope);\n if (existingCoordinator) {\n return existingCoordinator;\n }\n\n const nextCoordinator = createDomainSyncCoordinator();\n coordinatorsByScope.set(domainScope, nextCoordinator);\n return nextCoordinator;\n}\n\nexport function hasDomainSyncCoordinatorPendingWork(\n domainScope: DomainScope,\n): boolean {\n return coordinatorsByScope.get(domainScope)?.hasPendingWork() ?? false;\n}\n\n// Re-request every pump-driven lane for a scope: a user-driven \"sync now\" that\n// retries durable work stranded by a transient failure. Observational upload\n// telemetry is never directly pumped. A no-op when no coordinator exists yet\n// (nothing has been synced) or it has been disposed.\nexport function requestAllDomainSyncLanes(domainScope: DomainScope): void {\n coordinatorsByScope.get(domainScope)?.requestAllLanes();\n}\n\nexport function requestDomainSyncLane(\n domainScope: DomainScope,\n key: string,\n): void {\n coordinatorsByScope.get(domainScope)?.requestLane(key);\n}\n\n// Stop admitting work and remove this scope's coordinator. Active callbacks\n// drain under their existing watchdogs; getOrCreate builds a fresh coordinator.\nexport function disposeDomainSyncCoordinator(domainScope: DomainScope): void {\n const coordinator = coordinatorsByScope.get(domainScope);\n if (!coordinator) {\n return;\n }\n\n coordinator.dispose();\n coordinatorsByScope.delete(domainScope);\n}\n\nexport function getDomainSyncCoordinatorSnapshot(\n domainScope: DomainScope,\n): DomainSyncSnapshot {\n return getOrCreateDomainSyncCoordinator(domainScope).getSnapshot();\n}\n\nexport function subscribeToDomainSyncCoordinator(\n domainScope: DomainScope,\n listener: () => void,\n): () => void {\n return getOrCreateDomainSyncCoordinator(domainScope).subscribe(listener);\n}\n\nexport function beginDomainSyncUploadLane(\n domainScope: DomainScope,\n key: string,\n options?: UploadSyncLaneOptions,\n): UploadSyncLane {\n return getOrCreateDomainSyncCoordinator(domainScope).beginUploadLane(\n key,\n options,\n );\n}\n\nexport function waitForDomainSyncCoordinatorToSettle(\n domainScope: DomainScope,\n options?: SyncIdleOptions,\n): Promise<boolean> {\n return (\n coordinatorsByScope.get(domainScope)?.waitForIdle(options) ??\n Promise.resolve(true)\n );\n}\n"]}
|
|
@@ -8,6 +8,8 @@ export interface SyncLaneConfig {
|
|
|
8
8
|
label?: string | undefined;
|
|
9
9
|
onUnexpectedError?: (error: unknown) => void;
|
|
10
10
|
phase?: SyncLanePhase;
|
|
11
|
+
/** Lower values run first within a phase; evaluated at selection time. */
|
|
12
|
+
priority?: (() => number) | undefined;
|
|
11
13
|
/** Observability only. Must not change lane behavior. */
|
|
12
14
|
reportUnexpectedError?: (error: unknown) => void;
|
|
13
15
|
run: () => Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"syncLaneConfig.js","sourceRoot":"","sources":["syncLaneConfig.ts"],"names":[],"mappings":"","sourcesContent":["import type { SyncLanePhase } from \"./syncTelemetry\";\n\nexport interface SyncLane {\n isDisposed?: () => boolean;\n requestSync: () => void;\n requestSyncAfter: (delayMs: number) => void;\n}\n\nexport interface SyncLaneConfig {\n label?: string | undefined;\n onUnexpectedError?: (error: unknown) => void;\n phase?: SyncLanePhase;\n /** Observability only. Must not change lane behavior. */\n reportUnexpectedError?: (error: unknown) => void;\n run: () => Promise<void>;\n shouldIgnoreError?: (error: unknown) => boolean;\n // Per-run liveness bound. When a run exceeds it, the pump records a watchdog\n // failure and moves on to other lanes instead of head-of-line blocking the\n // whole queue; the abandoned run is not cancelled, and its real outcome\n // overwrites the watchdog verdict when it eventually settles. Defaults to\n // the coordinator's SYNC_LANE_WATCHDOG_MS.\n watchdogMs?: number;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"syncLaneConfig.js","sourceRoot":"","sources":["syncLaneConfig.ts"],"names":[],"mappings":"","sourcesContent":["import type { SyncLanePhase } from \"./syncTelemetry\";\n\nexport interface SyncLane {\n isDisposed?: () => boolean;\n requestSync: () => void;\n requestSyncAfter: (delayMs: number) => void;\n}\n\nexport interface SyncLaneConfig {\n label?: string | undefined;\n onUnexpectedError?: (error: unknown) => void;\n phase?: SyncLanePhase;\n /** Lower values run first within a phase; evaluated at selection time. */\n priority?: (() => number) | undefined;\n /** Observability only. Must not change lane behavior. */\n reportUnexpectedError?: (error: unknown) => void;\n run: () => Promise<void>;\n shouldIgnoreError?: (error: unknown) => boolean;\n // Per-run liveness bound. When a run exceeds it, the pump records a watchdog\n // failure and moves on to other lanes instead of head-of-line blocking the\n // whole queue; the abandoned run is not cancelled, and its real outcome\n // overwrites the watchdog verdict when it eventually settles. Defaults to\n // the coordinator's SYNC_LANE_WATCHDOG_MS.\n watchdogMs?: number;\n}\n"]}
|
|
@@ -3975,7 +3975,7 @@ export declare class ApiClient {
|
|
|
3975
3975
|
}[];
|
|
3976
3976
|
uploadId: string;
|
|
3977
3977
|
} | null>;
|
|
3978
|
-
uploadMultipartBlobPartBytes(stageId: string, partNumber: number, input: UploadMultipartBlobPartBytesRequest): Promise<{
|
|
3978
|
+
uploadMultipartBlobPartBytes(stageId: string, partNumber: number, input: UploadMultipartBlobPartBytesRequest, options?: RequestResultOptions): Promise<{
|
|
3979
3979
|
part: {
|
|
3980
3980
|
byteLength: number;
|
|
3981
3981
|
etag: string;
|
|
@@ -3991,7 +3991,7 @@ export declare class ApiClient {
|
|
|
3991
3991
|
sha256: string;
|
|
3992
3992
|
stageId: string;
|
|
3993
3993
|
} | null>;
|
|
3994
|
-
getBlobBytes(blobId: string): Promise<import("./index.js").BlobBytesResponse | null>;
|
|
3994
|
+
getBlobBytes(blobId: string, options?: RequestResultOptions): Promise<import("./index.js").BlobBytesResponse | null>;
|
|
3995
3995
|
bindBlobAttachment(blobId: string, input: BlobAttachmentBindRequest, options?: RequestResultOptions): Promise<{
|
|
3996
3996
|
bindingEvent: {
|
|
3997
3997
|
body: unknown;
|
|
@@ -761,14 +761,14 @@ export class ApiClient {
|
|
|
761
761
|
getMultipartBlobStage(stageId) {
|
|
762
762
|
return this.request(multipartGet.path(stageId), multipartGet.isResponse, multipartGet.method, undefined, undefined, getMultipartBlobStageOperation);
|
|
763
763
|
}
|
|
764
|
-
uploadMultipartBlobPartBytes(stageId, partNumber, input) {
|
|
765
|
-
return uploadMultipartBlobPartBytes(this.transport, stageId, partNumber, input);
|
|
764
|
+
uploadMultipartBlobPartBytes(stageId, partNumber, input, options = {}) {
|
|
765
|
+
return uploadMultipartBlobPartBytes(this.transport, stageId, partNumber, input, undefined, options);
|
|
766
766
|
}
|
|
767
767
|
completeMultipartBlobStage(stageId, input) {
|
|
768
768
|
return this.request(multipartComplete.path(stageId), multipartComplete.isResponse, multipartComplete.method, JSON.stringify(input), undefined, completeMultipartBlobStageOperation);
|
|
769
769
|
}
|
|
770
|
-
getBlobBytes(blobId) {
|
|
771
|
-
return getBlobBytes(this.transport, blobId);
|
|
770
|
+
getBlobBytes(blobId, options = {}) {
|
|
771
|
+
return getBlobBytes(this.transport, blobId, undefined, options);
|
|
772
772
|
}
|
|
773
773
|
bindBlobAttachment(blobId, input, options = {}) {
|
|
774
774
|
return this.request(blobAttachmentBind.path(blobId), blobAttachmentBind.isResponse, blobAttachmentBind.method, JSON.stringify(input), options, bindBlobAttachmentOperation)
|