@@ -7,8 +7,11 @@ import {
77} from '../types.js'
88import { errors , jsonError } from './errors.js'
99import { StateUpdateEvent } from './state-update-event.js'
10+ import { throttle } from './throttle.js'
1011import { addTrailingSlash , generateId , getErrorCode } from './utils.js'
1112
13+ const PROGRESS_THROTTLE_MS = 100
14+
1215export type MapShareOptions = MapInfo & {
1316 /**
1417 * Base URLs to construct the download URLs for the map share. Multiple URLs
@@ -69,6 +72,10 @@ export class MapShare extends TypedEventTarget<
6972 this . #download. addEventListener ( 'update' , ( event ) => {
7073 this . #updateState( event )
7174 } )
75+ // Synchronously transition to 'downloading' so that any concurrent
76+ // download attempt observes the non-pending state immediately, without
77+ // waiting for the DownloadResponse's async transform start callback.
78+ this . #updateState( { status : 'downloading' , bytesDownloaded : 0 } )
7279 return this . #download. response
7380 }
7481
@@ -119,7 +126,7 @@ export class MapShare extends TypedEventTarget<
119126 * share in the future (multiple downloads per share will make the "state" of a
120127 * MapShare harder to reason about and define).
121128 */
122- export class DownloadResponse extends TypedEventTarget <
129+ class DownloadResponse extends TypedEventTarget <
123130 InstanceType < typeof StateUpdateEvent < DownloadStateUpdate > >
124131> {
125132 #stream: TransformStream
@@ -181,8 +188,19 @@ export class DownloadResponse extends TypedEventTarget<
181188 this . #abortController. abort ( )
182189 }
183190
191+ #dispatchProgress = throttle ( ( update : DownloadStateUpdate ) => {
192+ this . dispatchEvent ( new StateUpdateEvent ( update ) )
193+ } , PROGRESS_THROTTLE_MS )
194+
184195 #updateState( update : DownloadStateUpdate ) {
185196 this . #state = update
186- this . dispatchEvent ( new StateUpdateEvent ( update ) )
197+ if ( update . status === 'downloading' ) {
198+ this . #dispatchProgress( update )
199+ } else {
200+ // Emit any pending progress update before the terminal state so
201+ // consumers always see the final bytesDownloaded value.
202+ this . #dispatchProgress. flush ( )
203+ this . dispatchEvent ( new StateUpdateEvent ( update ) )
204+ }
187205 }
188206}
0 commit comments