@backblaze-labs/b2-sdk 0.2.0 → 0.4.0
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/CHANGELOG.md +86 -1
- package/README.md +38 -7
- package/dist/_virtual/_b2-sdk-version-json.cjs +1 -1
- package/dist/_virtual/_b2-sdk-version-json.js +1 -1
- package/dist/auth/file.cjs.map +1 -1
- package/dist/auth/reauth-coalescer.cjs +65 -0
- package/dist/auth/reauth-coalescer.cjs.map +1 -0
- package/dist/auth/reauth-coalescer.d.cts +34 -0
- package/dist/auth/reauth-coalescer.d.cts.map +1 -0
- package/dist/auth/reauth-coalescer.d.ts +34 -0
- package/dist/auth/reauth-coalescer.d.ts.map +1 -0
- package/dist/auth/reauth-coalescer.js +65 -0
- package/dist/auth/reauth-coalescer.js.map +1 -0
- package/dist/backup/client.cjs +206 -0
- package/dist/backup/client.cjs.map +1 -0
- package/dist/backup/client.d.cts +238 -0
- package/dist/backup/client.d.cts.map +1 -0
- package/dist/backup/client.d.ts +238 -0
- package/dist/backup/client.d.ts.map +1 -0
- package/dist/backup/client.js +206 -0
- package/dist/backup/client.js.map +1 -0
- package/dist/backup/index.cjs +15 -0
- package/dist/backup/index.d.cts +22 -0
- package/dist/backup/index.d.cts.map +1 -0
- package/dist/backup/index.d.ts +22 -0
- package/dist/backup/index.d.ts.map +1 -0
- package/dist/backup/index.js +7 -0
- package/dist/backup/raw.cjs +168 -0
- package/dist/backup/raw.cjs.map +1 -0
- package/dist/backup/raw.d.cts +122 -0
- package/dist/backup/raw.d.cts.map +1 -0
- package/dist/backup/raw.d.ts +122 -0
- package/dist/backup/raw.d.ts.map +1 -0
- package/dist/backup/raw.js +168 -0
- package/dist/backup/raw.js.map +1 -0
- package/dist/bucket-validation.cjs +111 -0
- package/dist/bucket-validation.cjs.map +1 -0
- package/dist/bucket-validation.d.cts +27 -0
- package/dist/bucket-validation.d.cts.map +1 -0
- package/dist/bucket-validation.d.ts +27 -0
- package/dist/bucket-validation.d.ts.map +1 -0
- package/dist/bucket-validation.js +109 -0
- package/dist/bucket-validation.js.map +1 -0
- package/dist/bucket.cjs +125 -74
- package/dist/bucket.cjs.map +1 -1
- package/dist/bucket.d.cts +156 -61
- package/dist/bucket.d.cts.map +1 -1
- package/dist/bucket.d.ts +156 -61
- package/dist/bucket.d.ts.map +1 -1
- package/dist/bucket.js +125 -74
- package/dist/bucket.js.map +1 -1
- package/dist/client.cjs +29 -8
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +30 -9
- package/dist/client.d.cts.map +1 -1
- package/dist/client.d.ts +30 -9
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +29 -8
- package/dist/client.js.map +1 -1
- package/dist/copy/large.cjs +5 -3
- package/dist/copy/large.cjs.map +1 -1
- package/dist/copy/large.d.cts.map +1 -1
- package/dist/copy/large.d.ts.map +1 -1
- package/dist/copy/large.js +5 -3
- package/dist/copy/large.js.map +1 -1
- package/dist/download/checksum.cjs +6 -2
- package/dist/download/checksum.cjs.map +1 -1
- package/dist/download/checksum.js +6 -2
- package/dist/download/checksum.js.map +1 -1
- package/dist/download/parallel.cjs +52 -15
- package/dist/download/parallel.cjs.map +1 -1
- package/dist/download/parallel.d.cts +8 -1
- package/dist/download/parallel.d.cts.map +1 -1
- package/dist/download/parallel.d.ts +8 -1
- package/dist/download/parallel.d.ts.map +1 -1
- package/dist/download/parallel.js +52 -15
- package/dist/download/parallel.js.map +1 -1
- package/dist/download/single.cjs +179 -19
- package/dist/download/single.cjs.map +1 -1
- package/dist/download/single.d.cts +10 -4
- package/dist/download/single.d.cts.map +1 -1
- package/dist/download/single.d.ts +10 -4
- package/dist/download/single.d.ts.map +1 -1
- package/dist/download/single.js +179 -19
- package/dist/download/single.js.map +1 -1
- package/dist/errors/index.cjs +196 -3
- package/dist/errors/index.cjs.map +1 -1
- package/dist/errors/index.d.cts +134 -0
- package/dist/errors/index.d.cts.map +1 -1
- package/dist/errors/index.d.ts +134 -0
- package/dist/errors/index.d.ts.map +1 -1
- package/dist/errors/index.js +183 -4
- package/dist/errors/index.js.map +1 -1
- package/dist/http/non-idempotent-mutations.cjs +38 -0
- package/dist/http/non-idempotent-mutations.cjs.map +1 -0
- package/dist/http/non-idempotent-mutations.d.cts +25 -0
- package/dist/http/non-idempotent-mutations.d.cts.map +1 -0
- package/dist/http/non-idempotent-mutations.d.ts +25 -0
- package/dist/http/non-idempotent-mutations.d.ts.map +1 -0
- package/dist/http/non-idempotent-mutations.js +35 -0
- package/dist/http/non-idempotent-mutations.js.map +1 -0
- package/dist/http/retry.cjs +1 -1
- package/dist/http/retry.cjs.map +1 -1
- package/dist/http/retry.js +1 -1
- package/dist/http/retry.js.map +1 -1
- package/dist/http/transport.cjs +62 -23
- package/dist/http/transport.cjs.map +1 -1
- package/dist/http/transport.d.cts +30 -3
- package/dist/http/transport.d.cts.map +1 -1
- package/dist/http/transport.d.ts +30 -3
- package/dist/http/transport.d.ts.map +1 -1
- package/dist/http/transport.js +60 -22
- package/dist/http/transport.js.map +1 -1
- package/dist/http/user-agent.cjs +12 -1
- package/dist/http/user-agent.cjs.map +1 -1
- package/dist/http/user-agent.d.cts +8 -0
- package/dist/http/user-agent.d.cts.map +1 -1
- package/dist/http/user-agent.d.ts +8 -0
- package/dist/http/user-agent.d.ts.map +1 -1
- package/dist/http/user-agent.js +13 -3
- package/dist/http/user-agent.js.map +1 -1
- package/dist/index.cjs +50 -2
- package/dist/index.d.cts +15 -12
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.ts +15 -12
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -10
- package/dist/notifications/index.cjs +3 -0
- package/dist/notifications/index.d.cts +2 -0
- package/dist/notifications/index.d.cts.map +1 -1
- package/dist/notifications/index.d.ts +2 -0
- package/dist/notifications/index.d.ts.map +1 -1
- package/dist/notifications/index.js +2 -1
- package/dist/object.cjs +13 -2
- package/dist/object.cjs.map +1 -1
- package/dist/object.d.cts +11 -3
- package/dist/object.d.cts.map +1 -1
- package/dist/object.d.ts +11 -3
- package/dist/object.d.ts.map +1 -1
- package/dist/object.js +13 -2
- package/dist/object.js.map +1 -1
- package/dist/partner/account-info.d.cts +43 -0
- package/dist/partner/account-info.d.cts.map +1 -0
- package/dist/partner/account-info.d.ts +43 -0
- package/dist/partner/account-info.d.ts.map +1 -0
- package/dist/partner/auth-clone.cjs +64 -0
- package/dist/partner/auth-clone.cjs.map +1 -0
- package/dist/partner/auth-clone.d.cts +27 -0
- package/dist/partner/auth-clone.d.cts.map +1 -0
- package/dist/partner/auth-clone.d.ts +27 -0
- package/dist/partner/auth-clone.d.ts.map +1 -0
- package/dist/partner/auth-clone.js +63 -0
- package/dist/partner/auth-clone.js.map +1 -0
- package/dist/partner/auth-core.cjs +156 -0
- package/dist/partner/auth-core.cjs.map +1 -0
- package/dist/partner/auth-core.d.cts +111 -0
- package/dist/partner/auth-core.d.cts.map +1 -0
- package/dist/partner/auth-core.d.ts +111 -0
- package/dist/partner/auth-core.d.ts.map +1 -0
- package/dist/partner/auth-core.js +156 -0
- package/dist/partner/auth-core.js.map +1 -0
- package/dist/partner/auth-shape.cjs +36 -0
- package/dist/partner/auth-shape.cjs.map +1 -0
- package/dist/partner/auth-shape.d.cts +12 -0
- package/dist/partner/auth-shape.d.cts.map +1 -0
- package/dist/partner/auth-shape.d.ts +12 -0
- package/dist/partner/auth-shape.d.ts.map +1 -0
- package/dist/partner/auth-shape.js +36 -0
- package/dist/partner/auth-shape.js.map +1 -0
- package/dist/partner/client.cjs +270 -0
- package/dist/partner/client.cjs.map +1 -0
- package/dist/partner/client.d.cts +357 -0
- package/dist/partner/client.d.cts.map +1 -0
- package/dist/partner/client.d.ts +357 -0
- package/dist/partner/client.d.ts.map +1 -0
- package/dist/partner/client.js +270 -0
- package/dist/partner/client.js.map +1 -0
- package/dist/partner/endpoint-url.cjs +109 -0
- package/dist/partner/endpoint-url.cjs.map +1 -0
- package/dist/partner/endpoint-url.d.cts +74 -0
- package/dist/partner/endpoint-url.d.cts.map +1 -0
- package/dist/partner/endpoint-url.d.ts +74 -0
- package/dist/partner/endpoint-url.d.ts.map +1 -0
- package/dist/partner/endpoint-url.js +106 -0
- package/dist/partner/endpoint-url.js.map +1 -0
- package/dist/partner/in-memory.cjs +135 -0
- package/dist/partner/in-memory.cjs.map +1 -0
- package/dist/partner/in-memory.d.cts +99 -0
- package/dist/partner/in-memory.d.cts.map +1 -0
- package/dist/partner/in-memory.d.ts +99 -0
- package/dist/partner/in-memory.d.ts.map +1 -0
- package/dist/partner/in-memory.js +135 -0
- package/dist/partner/in-memory.js.map +1 -0
- package/dist/partner/index.cjs +27 -0
- package/dist/partner/index.d.cts +32 -0
- package/dist/partner/index.d.cts.map +1 -0
- package/dist/partner/index.d.ts +32 -0
- package/dist/partner/index.d.ts.map +1 -0
- package/dist/partner/index.js +9 -0
- package/dist/partner/raw.cjs +400 -0
- package/dist/partner/raw.cjs.map +1 -0
- package/dist/partner/raw.d.cts +220 -0
- package/dist/partner/raw.d.cts.map +1 -0
- package/dist/partner/raw.d.ts +220 -0
- package/dist/partner/raw.d.ts.map +1 -0
- package/dist/partner/raw.js +398 -0
- package/dist/partner/raw.js.map +1 -0
- package/dist/partner/redaction-placeholders.cjs +10 -0
- package/dist/partner/redaction-placeholders.cjs.map +1 -0
- package/dist/partner/redaction-placeholders.d.cts +5 -0
- package/dist/partner/redaction-placeholders.d.cts.map +1 -0
- package/dist/partner/redaction-placeholders.d.ts +5 -0
- package/dist/partner/redaction-placeholders.d.ts.map +1 -0
- package/dist/partner/redaction-placeholders.js +9 -0
- package/dist/partner/redaction-placeholders.js.map +1 -0
- package/dist/partner/redaction.cjs +292 -0
- package/dist/partner/redaction.cjs.map +1 -0
- package/dist/partner/redaction.d.cts +158 -0
- package/dist/partner/redaction.d.cts.map +1 -0
- package/dist/partner/redaction.d.ts +158 -0
- package/dist/partner/redaction.d.ts.map +1 -0
- package/dist/partner/redaction.js +281 -0
- package/dist/partner/redaction.js.map +1 -0
- package/dist/raw/encoding.cjs +29 -10
- package/dist/raw/encoding.cjs.map +1 -1
- package/dist/raw/encoding.d.cts +3 -2
- package/dist/raw/encoding.d.cts.map +1 -1
- package/dist/raw/encoding.d.ts +3 -2
- package/dist/raw/encoding.d.ts.map +1 -1
- package/dist/raw/encoding.js +29 -10
- package/dist/raw/encoding.js.map +1 -1
- package/dist/raw/index.cjs +131 -44
- package/dist/raw/index.cjs.map +1 -1
- package/dist/raw/index.d.cts +21 -15
- package/dist/raw/index.d.cts.map +1 -1
- package/dist/raw/index.d.ts +21 -15
- package/dist/raw/index.d.ts.map +1 -1
- package/dist/raw/index.js +114 -45
- package/dist/raw/index.js.map +1 -1
- package/dist/raw/url.cjs +111 -0
- package/dist/raw/url.cjs.map +1 -0
- package/dist/raw/url.d.cts +41 -0
- package/dist/raw/url.d.cts.map +1 -0
- package/dist/raw/url.d.ts +41 -0
- package/dist/raw/url.d.ts.map +1 -0
- package/dist/raw/url.js +110 -0
- package/dist/raw/url.js.map +1 -0
- package/dist/s3/sigv4.cjs +15 -10
- package/dist/s3/sigv4.cjs.map +1 -1
- package/dist/s3/sigv4.js +15 -10
- package/dist/s3/sigv4.js.map +1 -1
- package/dist/simulator/index.cjs +1579 -257
- package/dist/simulator/index.cjs.map +1 -1
- package/dist/simulator/index.d.cts +124 -11
- package/dist/simulator/index.d.cts.map +1 -1
- package/dist/simulator/index.d.ts +124 -11
- package/dist/simulator/index.d.ts.map +1 -1
- package/dist/simulator/index.js +1568 -262
- package/dist/simulator/index.js.map +1 -1
- package/dist/simulator/partner-capabilities.cjs +77 -0
- package/dist/simulator/partner-capabilities.cjs.map +1 -0
- package/dist/simulator/partner-capabilities.d.cts +53 -0
- package/dist/simulator/partner-capabilities.d.cts.map +1 -0
- package/dist/simulator/partner-capabilities.d.ts +53 -0
- package/dist/simulator/partner-capabilities.d.ts.map +1 -0
- package/dist/simulator/partner-capabilities.js +73 -0
- package/dist/simulator/partner-capabilities.js.map +1 -0
- package/dist/simulator/partner.cjs +713 -0
- package/dist/simulator/partner.cjs.map +1 -0
- package/dist/simulator/partner.d.cts +186 -0
- package/dist/simulator/partner.d.cts.map +1 -0
- package/dist/simulator/partner.d.ts +186 -0
- package/dist/simulator/partner.d.ts.map +1 -0
- package/dist/simulator/partner.js +713 -0
- package/dist/simulator/partner.js.map +1 -0
- package/dist/simulator/validation.cjs +732 -25
- package/dist/simulator/validation.cjs.map +1 -1
- package/dist/simulator/validation.d.cts +145 -6
- package/dist/simulator/validation.d.cts.map +1 -1
- package/dist/simulator/validation.d.ts +145 -6
- package/dist/simulator/validation.d.ts.map +1 -1
- package/dist/simulator/validation.js +705 -26
- package/dist/simulator/validation.js.map +1 -1
- package/dist/streams/file-source.cjs +2 -2
- package/dist/streams/file-source.cjs.map +1 -1
- package/dist/streams/file-source.js +2 -2
- package/dist/streams/file-source.js.map +1 -1
- package/dist/streams/hash.cjs +246 -13
- package/dist/streams/hash.cjs.map +1 -1
- package/dist/streams/hash.d.cts +37 -12
- package/dist/streams/hash.d.cts.map +1 -1
- package/dist/streams/hash.d.ts +37 -12
- package/dist/streams/hash.d.ts.map +1 -1
- package/dist/streams/hash.js +246 -15
- package/dist/streams/hash.js.map +1 -1
- package/dist/streams/index.cjs +3 -1
- package/dist/streams/index.d.cts +1 -1
- package/dist/streams/index.d.cts.map +1 -1
- package/dist/streams/index.d.ts +1 -1
- package/dist/streams/index.d.ts.map +1 -1
- package/dist/streams/index.js +3 -3
- package/dist/streams/progress.cjs +63 -4
- package/dist/streams/progress.cjs.map +1 -1
- package/dist/streams/progress.d.cts +28 -2
- package/dist/streams/progress.d.cts.map +1 -1
- package/dist/streams/progress.d.ts +28 -2
- package/dist/streams/progress.d.ts.map +1 -1
- package/dist/streams/progress.js +63 -4
- package/dist/streams/progress.js.map +1 -1
- package/dist/streams/source.cjs +2 -1
- package/dist/streams/source.cjs.map +1 -1
- package/dist/streams/source.js +2 -1
- package/dist/streams/source.js.map +1 -1
- package/dist/sync/b2-sha1-reader.cjs +6 -2
- package/dist/sync/b2-sha1-reader.cjs.map +1 -1
- package/dist/sync/b2-sha1-reader.d.cts.map +1 -1
- package/dist/sync/b2-sha1-reader.d.ts.map +1 -1
- package/dist/sync/b2-sha1-reader.js +6 -2
- package/dist/sync/b2-sha1-reader.js.map +1 -1
- package/dist/sync/download-staging.cjs +156 -43
- package/dist/sync/download-staging.cjs.map +1 -1
- package/dist/sync/download-staging.d.cts +26 -2
- package/dist/sync/download-staging.d.cts.map +1 -1
- package/dist/sync/download-staging.d.ts +26 -2
- package/dist/sync/download-staging.d.ts.map +1 -1
- package/dist/sync/download-staging.js +155 -44
- package/dist/sync/download-staging.js.map +1 -1
- package/dist/sync/filters.cjs.map +1 -1
- package/dist/sync/filters.js.map +1 -1
- package/dist/sync/index.d.cts +1 -1
- package/dist/sync/index.d.cts.map +1 -1
- package/dist/sync/index.d.ts +1 -1
- package/dist/sync/index.d.ts.map +1 -1
- package/dist/sync/local-file-io.cjs +15 -6
- package/dist/sync/local-file-io.cjs.map +1 -1
- package/dist/sync/local-file-io.d.cts +3 -0
- package/dist/sync/local-file-io.d.cts.map +1 -1
- package/dist/sync/local-file-io.d.ts +3 -0
- package/dist/sync/local-file-io.d.ts.map +1 -1
- package/dist/sync/local-file-io.js +15 -6
- package/dist/sync/local-file-io.js.map +1 -1
- package/dist/sync/local-sha1.cjs +6 -15
- package/dist/sync/local-sha1.cjs.map +1 -1
- package/dist/sync/local-sha1.d.cts +0 -8
- package/dist/sync/local-sha1.d.cts.map +1 -1
- package/dist/sync/local-sha1.d.ts +0 -8
- package/dist/sync/local-sha1.d.ts.map +1 -1
- package/dist/sync/local-sha1.js +7 -15
- package/dist/sync/local-sha1.js.map +1 -1
- package/dist/sync/pairing.cjs +1 -0
- package/dist/sync/pairing.cjs.map +1 -1
- package/dist/sync/pairing.js +1 -0
- package/dist/sync/pairing.js.map +1 -1
- package/dist/sync/policies/compare.cjs +5 -3
- package/dist/sync/policies/compare.cjs.map +1 -1
- package/dist/sync/policies/compare.d.cts.map +1 -1
- package/dist/sync/policies/compare.d.ts.map +1 -1
- package/dist/sync/policies/compare.js +6 -4
- package/dist/sync/policies/compare.js.map +1 -1
- package/dist/sync/policies/index.cjs +4 -10
- package/dist/sync/policies/index.cjs.map +1 -1
- package/dist/sync/policies/index.js +4 -10
- package/dist/sync/policies/index.js.map +1 -1
- package/dist/sync/scanners/b2.cjs +4 -2
- package/dist/sync/scanners/b2.cjs.map +1 -1
- package/dist/sync/scanners/b2.d.cts.map +1 -1
- package/dist/sync/scanners/b2.d.ts.map +1 -1
- package/dist/sync/scanners/b2.js +4 -2
- package/dist/sync/scanners/b2.js.map +1 -1
- package/dist/sync/scanners/local.cjs +150 -33
- package/dist/sync/scanners/local.cjs.map +1 -1
- package/dist/sync/scanners/local.d.cts +6 -0
- package/dist/sync/scanners/local.d.cts.map +1 -1
- package/dist/sync/scanners/local.d.ts +6 -0
- package/dist/sync/scanners/local.d.ts.map +1 -1
- package/dist/sync/scanners/local.js +150 -33
- package/dist/sync/scanners/local.js.map +1 -1
- package/dist/sync/synchronizer.cjs +79 -31
- package/dist/sync/synchronizer.cjs.map +1 -1
- package/dist/sync/synchronizer.d.cts +1 -0
- package/dist/sync/synchronizer.d.cts.map +1 -1
- package/dist/sync/synchronizer.d.ts +1 -0
- package/dist/sync/synchronizer.d.ts.map +1 -1
- package/dist/sync/synchronizer.js +79 -31
- package/dist/sync/synchronizer.js.map +1 -1
- package/dist/sync/types.d.cts +19 -3
- package/dist/sync/types.d.cts.map +1 -1
- package/dist/sync/types.d.ts +19 -3
- package/dist/sync/types.d.ts.map +1 -1
- package/dist/types/auth.cjs +4 -0
- package/dist/types/auth.cjs.map +1 -1
- package/dist/types/auth.d.cts +4 -0
- package/dist/types/auth.d.cts.map +1 -1
- package/dist/types/auth.d.ts +4 -0
- package/dist/types/auth.d.ts.map +1 -1
- package/dist/types/auth.js +4 -0
- package/dist/types/auth.js.map +1 -1
- package/dist/types/backup.d.cts +85 -0
- package/dist/types/backup.d.cts.map +1 -0
- package/dist/types/backup.d.ts +85 -0
- package/dist/types/backup.d.ts.map +1 -0
- package/dist/types/bucket.cjs +81 -11
- package/dist/types/bucket.cjs.map +1 -1
- package/dist/types/bucket.d.cts +194 -41
- package/dist/types/bucket.d.cts.map +1 -1
- package/dist/types/bucket.d.ts +194 -41
- package/dist/types/bucket.d.ts.map +1 -1
- package/dist/types/bucket.js +67 -12
- package/dist/types/bucket.js.map +1 -1
- package/dist/types/download.cjs +62 -0
- package/dist/types/download.cjs.map +1 -0
- package/dist/types/download.d.cts +100 -16
- package/dist/types/download.d.cts.map +1 -1
- package/dist/types/download.d.ts +100 -16
- package/dist/types/download.d.ts.map +1 -1
- package/dist/types/download.js +61 -0
- package/dist/types/download.js.map +1 -0
- package/dist/types/encryption.cjs +76 -229
- package/dist/types/encryption.cjs.map +1 -1
- package/dist/types/encryption.d.cts +48 -6
- package/dist/types/encryption.d.cts.map +1 -1
- package/dist/types/encryption.d.ts +48 -6
- package/dist/types/encryption.d.ts.map +1 -1
- package/dist/types/encryption.js +74 -229
- package/dist/types/encryption.js.map +1 -1
- package/dist/types/errors.cjs +9 -0
- package/dist/types/errors.cjs.map +1 -1
- package/dist/types/errors.d.cts +1 -1
- package/dist/types/errors.d.cts.map +1 -1
- package/dist/types/errors.d.ts +1 -1
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/errors.js +9 -0
- package/dist/types/errors.js.map +1 -1
- package/dist/types/file.cjs +3 -0
- package/dist/types/file.cjs.map +1 -1
- package/dist/types/file.d.cts +140 -18
- package/dist/types/file.d.cts.map +1 -1
- package/dist/types/file.d.ts +140 -18
- package/dist/types/file.d.ts.map +1 -1
- package/dist/types/file.js +3 -1
- package/dist/types/file.js.map +1 -1
- package/dist/types/ids.cjs +30 -0
- package/dist/types/ids.cjs.map +1 -1
- package/dist/types/ids.d.cts +32 -0
- package/dist/types/ids.d.cts.map +1 -1
- package/dist/types/ids.d.ts +32 -0
- package/dist/types/ids.d.ts.map +1 -1
- package/dist/types/ids.js +28 -1
- package/dist/types/ids.js.map +1 -1
- package/dist/types/index.d.cts +16 -12
- package/dist/types/index.d.cts.map +1 -1
- package/dist/types/index.d.ts +16 -12
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/key.d.cts +4 -3
- package/dist/types/key.d.cts.map +1 -1
- package/dist/types/key.d.ts +4 -3
- package/dist/types/key.d.ts.map +1 -1
- package/dist/types/lock.cjs.map +1 -1
- package/dist/types/lock.d.cts +14 -0
- package/dist/types/lock.d.cts.map +1 -1
- package/dist/types/lock.d.ts +14 -0
- package/dist/types/lock.d.ts.map +1 -1
- package/dist/types/lock.js.map +1 -1
- package/dist/types/notifications.cjs +31 -1
- package/dist/types/notifications.cjs.map +1 -1
- package/dist/types/notifications.d.cts +31 -4
- package/dist/types/notifications.d.cts.map +1 -1
- package/dist/types/notifications.d.ts +31 -4
- package/dist/types/notifications.d.ts.map +1 -1
- package/dist/types/notifications.js +30 -2
- package/dist/types/notifications.js.map +1 -1
- package/dist/types/partner.cjs +32 -0
- package/dist/types/partner.cjs.map +1 -0
- package/dist/types/partner.d.cts +386 -0
- package/dist/types/partner.d.cts.map +1 -0
- package/dist/types/partner.d.ts +386 -0
- package/dist/types/partner.d.ts.map +1 -0
- package/dist/types/partner.js +29 -0
- package/dist/types/partner.js.map +1 -0
- package/dist/types/upload.d.cts +35 -18
- package/dist/types/upload.d.cts.map +1 -1
- package/dist/types/upload.d.ts +35 -18
- package/dist/types/upload.d.ts.map +1 -1
- package/dist/upload/abort-scope.cjs +0 -45
- package/dist/upload/abort-scope.cjs.map +1 -1
- package/dist/upload/abort-scope.d.cts +0 -22
- package/dist/upload/abort-scope.d.cts.map +1 -1
- package/dist/upload/abort-scope.d.ts +0 -22
- package/dist/upload/abort-scope.d.ts.map +1 -1
- package/dist/upload/abort-scope.js +1 -44
- package/dist/upload/abort-scope.js.map +1 -1
- package/dist/upload/finish.cjs +3 -8
- package/dist/upload/finish.cjs.map +1 -1
- package/dist/upload/finish.d.cts.map +1 -1
- package/dist/upload/finish.d.ts.map +1 -1
- package/dist/upload/finish.js +1 -6
- package/dist/upload/finish.js.map +1 -1
- package/dist/upload/large.cjs +15 -8
- package/dist/upload/large.cjs.map +1 -1
- package/dist/upload/large.d.cts +31 -8
- package/dist/upload/large.d.cts.map +1 -1
- package/dist/upload/large.d.ts +31 -8
- package/dist/upload/large.d.ts.map +1 -1
- package/dist/upload/large.js +15 -8
- package/dist/upload/large.js.map +1 -1
- package/dist/upload/options.cjs.map +1 -1
- package/dist/upload/options.d.cts +24 -0
- package/dist/upload/options.d.cts.map +1 -1
- package/dist/upload/options.d.ts +24 -0
- package/dist/upload/options.d.ts.map +1 -1
- package/dist/upload/options.js.map +1 -1
- package/dist/upload/resume.cjs +6 -4
- package/dist/upload/resume.cjs.map +1 -1
- package/dist/upload/resume.d.cts +9 -5
- package/dist/upload/resume.d.cts.map +1 -1
- package/dist/upload/resume.d.ts +9 -5
- package/dist/upload/resume.d.ts.map +1 -1
- package/dist/upload/resume.js +6 -4
- package/dist/upload/resume.js.map +1 -1
- package/dist/upload/retry.cjs +25 -13
- package/dist/upload/retry.cjs.map +1 -1
- package/dist/upload/retry.d.cts.map +1 -1
- package/dist/upload/retry.d.ts.map +1 -1
- package/dist/upload/retry.js +25 -13
- package/dist/upload/retry.js.map +1 -1
- package/dist/upload/single.cjs +35 -30
- package/dist/upload/single.cjs.map +1 -1
- package/dist/upload/single.d.cts +12 -0
- package/dist/upload/single.d.cts.map +1 -1
- package/dist/upload/single.d.ts +12 -0
- package/dist/upload/single.d.ts.map +1 -1
- package/dist/upload/single.js +35 -30
- package/dist/upload/single.js.map +1 -1
- package/dist/upload/stream.cjs +18 -5
- package/dist/upload/stream.cjs.map +1 -1
- package/dist/upload/stream.d.cts +12 -0
- package/dist/upload/stream.d.cts.map +1 -1
- package/dist/upload/stream.d.ts +12 -0
- package/dist/upload/stream.d.ts.map +1 -1
- package/dist/upload/stream.js +15 -2
- package/dist/upload/stream.js.map +1 -1
- package/dist/util/abort.cjs +114 -0
- package/dist/util/abort.cjs.map +1 -0
- package/dist/util/abort.d.cts +65 -0
- package/dist/util/abort.d.cts.map +1 -0
- package/dist/util/abort.d.ts +65 -0
- package/dist/util/abort.d.ts.map +1 -0
- package/dist/util/abort.js +109 -0
- package/dist/util/abort.js.map +1 -0
- package/dist/util/defaults.cjs +3 -0
- package/dist/util/defaults.cjs.map +1 -1
- package/dist/util/defaults.d.cts +2 -0
- package/dist/util/defaults.d.cts.map +1 -1
- package/dist/util/defaults.d.ts +2 -0
- package/dist/util/defaults.d.ts.map +1 -1
- package/dist/util/defaults.js +3 -1
- package/dist/util/defaults.js.map +1 -1
- package/dist/util/md5.cjs +211 -0
- package/dist/util/md5.cjs.map +1 -0
- package/dist/util/md5.d.cts +43 -0
- package/dist/util/md5.d.cts.map +1 -0
- package/dist/util/md5.d.ts +43 -0
- package/dist/util/md5.d.ts.map +1 -0
- package/dist/util/md5.js +209 -0
- package/dist/util/md5.js.map +1 -0
- package/dist/util/normalize.cjs +5 -5
- package/dist/util/normalize.cjs.map +1 -1
- package/dist/util/normalize.d.cts +7 -7
- package/dist/util/normalize.d.cts.map +1 -1
- package/dist/util/normalize.d.ts +7 -7
- package/dist/util/normalize.d.ts.map +1 -1
- package/dist/util/normalize.js +5 -5
- package/dist/util/normalize.js.map +1 -1
- package/dist/util/paginator.cjs +7 -1
- package/dist/util/paginator.cjs.map +1 -1
- package/dist/util/paginator.d.cts +3 -1
- package/dist/util/paginator.d.cts.map +1 -1
- package/dist/util/paginator.d.ts +3 -1
- package/dist/util/paginator.d.ts.map +1 -1
- package/dist/util/paginator.js +7 -1
- package/dist/util/paginator.js.map +1 -1
- package/dist/version.cjs +56 -4
- package/dist/version.cjs.map +1 -1
- package/dist/version.d.cts +53 -4
- package/dist/version.d.cts.map +1 -1
- package/dist/version.d.ts +53 -4
- package/dist/version.d.ts.map +1 -1
- package/dist/version.js +52 -5
- package/dist/version.js.map +1 -1
- package/package.json +47 -18
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stream.js","names":[],"sources":["../../src/upload/stream.ts"],"sourcesContent":["import type { AccountInfo } from '../auth/account-info.ts'\nimport type { RawClient } from '../raw/index.ts'\nimport { IncrementalSha1 } from '../streams/hash.ts'\nimport type { ProgressListener } from '../streams/progress.ts'\nimport { ProgressTracker } from '../streams/progress.ts'\nimport type { EncryptionSetting } from '../types/encryption.ts'\nimport type { FileVersion } from '../types/file.ts'\nimport type { BucketId, LargeFileId } from '../types/ids.ts'\nimport { DEFAULT_CONTENT_TYPE, DEFAULT_TRANSFER_CONCURRENCY } from '../util/defaults.ts'\nimport { toError } from '../util/to-error.ts'\nimport { abortReason, createAbortScope, raceWithAbort } from './abort-scope.ts'\nimport {\n type CleanupFailureOptions,\n cancelLargeFileBestEffort,\n DEFAULT_CLEANUP_TIMEOUT_MS,\n resolveLargeFileErrorAfterCleanup,\n} from './cancel.ts'\nimport { Semaphore } from './concurrency.ts'\nimport { finishLargeFileWithAbortReconciliation } from './finish.ts'\nimport {\n resolveRetryResponseBodyFailures,\n type UploadRetryOptions,\n uploadPartWithFreshUrl,\n} from './retry.ts'\n\n/** Options for creating a streaming multipart upload sink. */\nexport interface CreateWriteStreamOptions extends UploadRetryOptions, CleanupFailureOptions {\n /** Target bucket for the upload. */\n readonly bucketId: BucketId\n /** Destination file name in the bucket. */\n readonly fileName: string\n /** MIME type. Defaults to `b2/x-auto`. */\n readonly contentType?: string\n /** Custom file info stored with the file. */\n readonly fileInfo?: Record<string, string>\n /** Server-side encryption applied to each part. */\n readonly serverSideEncryption?: EncryptionSetting\n /**\n * Target part size in bytes. The stream buffers writes until this many bytes\n * are accumulated, then ships a part. Must be at least the account's\n * absolute minimum part size; the implementation will raise it if too small.\n */\n readonly partSize?: number\n /** Maximum number of parts uploaded in parallel. Defaults to 4. */\n readonly concurrency?: number\n /** Callback invoked with upload progress events. `totalBytes` is `null` (size unknown). */\n readonly onProgress?: ProgressListener\n /** Aborts the upload and cancels the unfinished large file. */\n readonly signal?: AbortSignal\n}\n\n/**\n * Handle returned by `B2Object.createWriteStream`: the Web `WritableStream` to\n * pipe data into, plus a promise that resolves with the finished\n * {@link FileVersion} once the stream is closed and all parts have been\n * uploaded.\n */\nexport interface UploadWriteHandle {\n /** Web `WritableStream` sink to pipe data into. */\n readonly writable: WritableStream<Uint8Array>\n /** Resolves with the finalized file version when the stream closes successfully. */\n readonly done: Promise<FileVersion>\n}\n\n/**\n * Creates a {@link WritableStream} that streams data into a B2 multipart upload.\n *\n * Buffers incoming chunks until `partSize` bytes are accumulated, ships each\n * complete part through the standard multipart engine, and finalizes the file\n * once the stream is closed. Honours backpressure via the queue's bounded\n * concurrency. Streaming uploads do not support resume because the total size\n * and per-part hashes aren't known in advance; use {@link uploadLargeFile} with\n * a buffered source when resume is required.\n *\n * @param raw - Low-level B2 API client.\n * @param accountInfo - Authorized account state (tokens, URLs, part URL pool).\n * @param options - Streaming upload parameters.\n *\n * @returns A {@link UploadWriteHandle} with the writable sink and a completion promise.\n */\nexport function createWriteStream(\n raw: RawClient,\n accountInfo: AccountInfo,\n options: CreateWriteStreamOptions,\n): UploadWriteHandle {\n const minPartSize = accountInfo.getAbsoluteMinimumPartSize()\n const recommendedPartSize = accountInfo.getRecommendedPartSize()\n const partSize = Math.max(options.partSize ?? recommendedPartSize, minPartSize)\n const concurrency = options.concurrency ?? DEFAULT_TRANSFER_CONCURRENCY\n const tracker = new ProgressTracker(options.onProgress, null, null)\n const sem = new Semaphore(concurrency)\n const abortScope = createAbortScope(options.signal)\n\n let largeFileId: LargeFileId | null = null\n let startPromise: Promise<LargeFileId> | null = null\n let cancelAfterStartScheduled = false\n let nextPartNumber = 1\n let pendingBytes = 0\n const pending: Uint8Array[] = []\n const partSha1s: string[] = []\n const inflight: Promise<void>[] = []\n let errored: Error | null = null\n\n // ES2024 `Promise.withResolvers()` exposes the resolve/reject pair as\n // properties of the returned object, avoiding the `let resolve!:` /\n // `let reject!:` non-null-assertion pattern needed before this API\n // existed. Available in Node 22 (our minimum), Bun, Deno, modern\n // browsers, and Cloudflare Workers.\n const {\n promise: done,\n resolve: resolveDone,\n reject: rejectDone,\n } = Promise.withResolvers<FileVersion>()\n // Attach a no-op rejection handler so a `done` that rejects before the\n // caller observes it never surfaces as a process-level unhandled rejection.\n // The error is not swallowed: `close()`/`abort()` also reject the writable\n // (so `pipeTo`/`getWriter().close()` throw), and any later `await done` /\n // `done.then(onRejected)` the caller attaches still sees the rejection —\n // extra handlers on the same promise all fire. Mirrors the\n // `task.catch(() => {})` pattern used for inflight part uploads below, and\n // keeps the engine well-behaved under Bun and Node's strict\n // unhandled-rejection mode.\n done.catch(() => {})\n\n function ensureStarted(): Promise<LargeFileId> {\n if (largeFileId !== null) return Promise.resolve(largeFileId)\n if (startPromise === null) {\n const rawStart = raw.startLargeFile(\n accountInfo.getApiUrl(),\n accountInfo.getAuthToken(),\n {\n bucketId: options.bucketId,\n fileName: options.fileName,\n contentType: options.contentType ?? DEFAULT_CONTENT_TYPE,\n fileInfo: options.fileInfo ?? {},\n ...(options.serverSideEncryption !== undefined\n ? { serverSideEncryption: options.serverSideEncryption }\n : {}),\n },\n {\n signal: abortScope.signal,\n ...(options.retry !== undefined ? { retry: options.retry } : {}),\n },\n )\n startPromise = rawStart.then((resp) => {\n largeFileId = resp.fileId\n if (abortScope.signal.aborted || errored !== null) {\n cancelStartedLargeFile(largeFileId)\n }\n return largeFileId\n })\n }\n const started = startPromise\n return raceWithAbort(started, abortScope.signal).catch((err) => {\n if (abortScope.signal.aborted) scheduleCancelLargeFileAfterStart(started)\n throw err\n })\n }\n\n async function shipPart(data: Uint8Array, partNumber: number): Promise<void> {\n if (errored !== null) throw errored\n abortScope.signal.throwIfAborted()\n const fileId = await ensureStarted()\n if (errored !== null) throw errored\n abortScope.signal.throwIfAborted()\n\n const sha1 = new IncrementalSha1()\n await sha1.update(data)\n const sha1Hex = await sha1.digest()\n abortScope.signal.throwIfAborted()\n\n const result = await uploadPartWithFreshUrl(raw, accountInfo, fileId, {\n fileName: options.fileName,\n partNumber,\n data: data as BodyInit,\n contentLength: data.byteLength,\n contentSha1: sha1Hex,\n retry: options.retry,\n signal: abortScope.signal,\n onUploadRetry: options.onUploadRetry,\n retryResponseBodyFailures: resolveRetryResponseBodyFailures(\n options.retryResponseBodyFailures,\n ),\n ...(options.serverSideEncryption !== undefined\n ? { serverSideEncryption: options.serverSideEncryption }\n : {}),\n })\n partSha1s[partNumber - 1] = result.contentSha1\n tracker.addBytes(data.byteLength)\n tracker.completePart()\n }\n\n function markErrored(err: unknown): Error {\n const error = toError(err)\n errored = error\n abortScope.abort(error)\n return error\n }\n\n function cancelStartedLargeFile(fileId: LargeFileId): void {\n if (cancelAfterStartScheduled) return\n cancelAfterStartScheduled = true\n void cancelLargeFileBestEffort(raw, accountInfo, fileId, cleanupWriteStreamOptions(options))\n }\n\n function scheduleCancelLargeFileAfterStart(started: Promise<LargeFileId>): void {\n void started\n .then((fileId) => cancelStartedLargeFile(fileId))\n .catch(() => {\n // If start failed, no file ID is available to cancel.\n })\n }\n\n async function settleInflightForClose(): Promise<PromiseSettledResult<void>[]> {\n const settled = Promise.allSettled(inflight)\n if (startPromise === null || largeFileId !== null) return await settled\n\n const abortWaiter = waitForAbort(abortScope.signal)\n try {\n const first = await Promise.race([\n settled.then(() => 'settled' as const),\n startPromise.then(\n () => 'start-settled' as const,\n () => 'start-settled' as const,\n ),\n abortWaiter.promise.then(() => 'aborted' as const),\n ])\n if (first === 'aborted' && largeFileId === null) {\n throw abortReason(abortScope.signal)\n }\n return await settled\n } finally {\n abortWaiter.dispose()\n }\n }\n\n function startPartWithAcquiredSlot(data: Uint8Array, partNumber: number): void {\n const task = (async () => {\n try {\n await shipPart(data, partNumber)\n } catch (err) {\n markErrored(err)\n throw err\n } finally {\n sem.release()\n }\n })()\n inflight.push(task)\n // Swallow rejection here; we check `errored` later.\n task.catch(() => {})\n }\n\n async function acquirePartSlot(): Promise<void> {\n await sem.acquire()\n if (errored !== null) {\n sem.release()\n throw errored\n }\n try {\n abortScope.signal.throwIfAborted()\n } catch (err) {\n sem.release()\n throw err\n }\n }\n\n async function waitForInflightPartsToSettle(\n timeoutMs = DEFAULT_CLEANUP_TIMEOUT_MS,\n ): Promise<void> {\n if (inflight.length === 0) return\n let timeout: ReturnType<typeof setTimeout> | undefined\n try {\n await Promise.race([\n Promise.allSettled(inflight).then(() => undefined),\n new Promise<void>((resolve) => {\n timeout = setTimeout(resolve, timeoutMs)\n }),\n ])\n } finally {\n if (timeout !== undefined) clearTimeout(timeout)\n }\n }\n\n async function dispatchPart(): Promise<void> {\n if (pending.length === 0) return\n await acquirePartSlot()\n let data: Uint8Array\n if (pending.length === 1) {\n const head = pending[0]\n if (!head) {\n sem.release()\n return\n }\n data = head\n } else {\n const total = pending.reduce((sum, chunk) => sum + chunk.byteLength, 0)\n data = new Uint8Array(total)\n let offset = 0\n for (const chunk of pending) {\n data.set(chunk, offset)\n offset += chunk.byteLength\n }\n }\n pending.length = 0\n pendingBytes = 0\n const partNumber = nextPartNumber++\n startPartWithAcquiredSlot(data, partNumber)\n }\n\n const writable = new WritableStream<Uint8Array>({\n async write(chunk: Uint8Array): Promise<void> {\n if (errored) throw errored\n abortScope.signal.throwIfAborted()\n if (chunk.byteLength === 0) return\n\n pending.push(chunk)\n pendingBytes += chunk.byteLength\n while (pendingBytes >= partSize) {\n await acquirePartSlot()\n if (errored) {\n sem.release()\n throw errored\n }\n // Pull exactly partSize bytes off the front\n const carved = carveExact(pending, partSize)\n const partNumber = nextPartNumber++\n pendingBytes -= partSize\n startPartWithAcquiredSlot(carved, partNumber)\n }\n },\n\n async close(): Promise<void> {\n try {\n if (errored) throw errored\n abortScope.signal.throwIfAborted()\n\n // Ship any remaining bytes as the last part. If the total fit in one\n // single buffered batch (no parts shipped yet), we have to use the\n // multipart path anyway since we already called startLargeFile lazily.\n if (pendingBytes > 0) {\n await dispatchPart()\n }\n\n const settled = await settleInflightForClose()\n const rejected = settled.find(\n (result): result is PromiseRejectedResult => result.status === 'rejected',\n )\n if (rejected !== undefined && errored === null) {\n markErrored(rejected.reason)\n }\n if (errored) throw errored\n\n if (largeFileId === null) {\n // Stream closed before any data was written. Start an empty large\n // file? B2 requires at least 2 parts. Reject — callers shouldn't\n // close an empty stream.\n throw new Error('createWriteStream closed without any data written.')\n }\n\n const result = await finishLargeFileWithAbortReconciliation(raw, accountInfo, {\n fileId: largeFileId,\n bucketId: options.bucketId,\n fileName: options.fileName,\n partSha1s,\n signal: abortScope.signal,\n ...(options.retry !== undefined ? { retry: options.retry } : {}),\n })\n abortScope.dispose()\n resolveDone(result)\n } catch (err) {\n const closeError = toError(err)\n if (errored === null) errored = closeError\n abortScope.abort(errored)\n const observedError = errored\n const fileIdToCancel = largeFileId\n if (fileIdToCancel === null && startPromise !== null) {\n // Mirror writer.abort(): close() must not wait for non-abortable\n // b2_start_large_file. If a file ID arrives later, cancel it in the\n // background.\n scheduleCancelLargeFileAfterStart(startPromise)\n abortScope.dispose()\n rejectDone(observedError)\n throw observedError\n }\n await Promise.allSettled(inflight)\n // Capture into a const so the cancel closure sees a non-null\n // `fileId`; closures don't observe the outer `!== null` narrowing\n // because the variable is mutable across the lambda boundary.\n let finalError: unknown = observedError\n if (fileIdToCancel !== null) {\n finalError = await resolveLargeFileErrorAfterCleanup(observedError, raw, accountInfo, {\n fileId: fileIdToCancel,\n bucketId: options.bucketId,\n fileName: options.fileName,\n signal: options.signal,\n onCleanupFailure: options.onCleanupFailure,\n })\n }\n abortScope.dispose()\n rejectDone(finalError)\n throw finalError\n }\n },\n\n async abort(reason: unknown): Promise<void> {\n const abortError = markErrored(reason)\n pending.length = 0\n pendingBytes = 0\n const fileIdToCancel = largeFileId\n if (fileIdToCancel === null && startPromise !== null) {\n // Do not await an in-flight start request here. A stalled\n // b2_start_large_file must not make writer.abort() hang; if it later\n // returns a file ID, cancel it best-effort in the background.\n scheduleCancelLargeFileAfterStart(startPromise)\n }\n if (fileIdToCancel !== null) {\n await waitForInflightPartsToSettle()\n await cancelLargeFileBestEffort(\n raw,\n accountInfo,\n fileIdToCancel,\n cleanupWriteStreamOptions(options),\n )\n }\n abortScope.dispose()\n rejectDone(abortError)\n },\n })\n\n return { writable, done }\n}\n\nfunction cleanupWriteStreamOptions(options: CreateWriteStreamOptions): {\n readonly signal?: AbortSignal\n} & CleanupFailureOptions {\n return {\n ...(options.signal !== undefined ? { signal: options.signal } : {}),\n ...(options.onCleanupFailure !== undefined\n ? { onCleanupFailure: options.onCleanupFailure }\n : {}),\n }\n}\n\n/**\n * Removes exactly `size` bytes from the front of `chunks` (mutates) and returns\n * them as a contiguous Uint8Array. Any trailing remainder of the last chunk\n * stays at the front of `chunks` for the next part.\n *\n * @param chunks - Queue of pending chunks. Modified in place.\n * @param size - Number of bytes to carve off the front.\n *\n * @returns A new Uint8Array containing exactly `size` bytes.\n */\nfunction carveExact(chunks: Uint8Array[], size: number): Uint8Array {\n const out = new Uint8Array(size)\n let written = 0\n while (written < size && chunks.length > 0) {\n const head = chunks[0]\n if (!head) break\n const need = size - written\n if (head.byteLength <= need) {\n out.set(head, written)\n written += head.byteLength\n chunks.shift()\n } else {\n out.set(head.subarray(0, need), written)\n chunks[0] = head.subarray(need)\n written += need\n }\n }\n return out\n}\n\nfunction waitForAbort(signal: AbortSignal): {\n readonly promise: Promise<unknown>\n dispose(): void\n} {\n if (signal.aborted) {\n return {\n promise: Promise.resolve(abortReason(signal)),\n dispose() {},\n }\n }\n\n let onAbort: (() => void) | undefined\n const promise = new Promise<unknown>((resolve) => {\n onAbort = () => resolve(abortReason(signal))\n signal.addEventListener('abort', onAbort, { once: true })\n })\n\n return {\n promise,\n dispose() {\n if (onAbort !== undefined) signal.removeEventListener('abort', onAbort)\n },\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"stream.js","names":[],"sources":["../../src/upload/stream.ts"],"sourcesContent":["import type { AccountInfo } from '../auth/account-info.ts'\nimport type { RawClient } from '../raw/index.ts'\nimport { IncrementalSha1 } from '../streams/hash.ts'\nimport type { ProgressListener } from '../streams/progress.ts'\nimport { ProgressTracker } from '../streams/progress.ts'\nimport type { EncryptionSetting } from '../types/encryption.ts'\nimport type { FileVersion } from '../types/file.ts'\nimport type { BucketId, LargeFileId } from '../types/ids.ts'\nimport { abortReason, raceWithAbort } from '../util/abort.ts'\nimport { DEFAULT_CONTENT_TYPE, DEFAULT_TRANSFER_CONCURRENCY } from '../util/defaults.ts'\nimport { toError } from '../util/to-error.ts'\nimport { createAbortScope } from './abort-scope.ts'\nimport {\n type CleanupFailureOptions,\n cancelLargeFileBestEffort,\n DEFAULT_CLEANUP_TIMEOUT_MS,\n resolveLargeFileErrorAfterCleanup,\n} from './cancel.ts'\nimport { Semaphore } from './concurrency.ts'\nimport { finishLargeFileWithAbortReconciliation } from './finish.ts'\nimport {\n resolveRetryResponseBodyFailures,\n type UploadRetryOptions,\n uploadPartWithFreshUrl,\n} from './retry.ts'\n\n/** Options for creating a streaming multipart upload sink. */\nexport interface CreateWriteStreamOptions extends UploadRetryOptions, CleanupFailureOptions {\n /** Target bucket for the upload. */\n readonly bucketId: BucketId\n /** Destination file name in the bucket. */\n readonly fileName: string\n /** MIME type. Defaults to `b2/x-auto`. */\n readonly contentType?: string\n /** Custom file info stored with the file. */\n readonly fileInfo?: Record<string, string>\n /** Server-side encryption applied to each part. */\n readonly serverSideEncryption?: EncryptionSetting\n /**\n * B2 upload timestamp override in milliseconds since epoch.\n * Sets the file version `uploadTimestamp`; distinct from `src_last_modified_millis` metadata.\n * Requires B2 account enablement for Custom Upload Timestamp.\n */\n readonly customUploadTimestamp?: number\n /**\n * Target part size in bytes. The stream buffers writes until this many bytes\n * are accumulated, then ships a part. Must be at least the account's\n * absolute minimum part size; the implementation will raise it if too small.\n */\n readonly partSize?: number\n /** Maximum number of parts uploaded in parallel. Defaults to 4. */\n readonly concurrency?: number\n /** Callback invoked with upload progress events. `totalBytes` is `null` (size unknown). */\n readonly onProgress?: ProgressListener\n /**\n * Minimum milliseconds between byte-only progress callbacks. Defaults to\n * the SDK's 100 ms progress interval; set to 0 for per-chunk callbacks.\n * Part-completion progress callbacks are always emitted immediately.\n */\n readonly progressIntervalMillis?: number\n /** Aborts the upload and cancels the unfinished large file. */\n readonly signal?: AbortSignal\n}\n\n/**\n * Handle returned by `B2Object.createWriteStream`: the Web `WritableStream` to\n * pipe data into, plus a promise that resolves with the finished\n * {@link FileVersion} once the stream is closed and all parts have been\n * uploaded.\n */\nexport interface UploadWriteHandle {\n /** Web `WritableStream` sink to pipe data into. */\n readonly writable: WritableStream<Uint8Array>\n /** Resolves with the finalized file version when the stream closes successfully. */\n readonly done: Promise<FileVersion>\n}\n\n/**\n * Creates a {@link WritableStream} that streams data into a B2 multipart upload.\n *\n * Buffers incoming chunks until `partSize` bytes are accumulated, ships each\n * complete part through the standard multipart engine, and finalizes the file\n * once the stream is closed. Honours backpressure via the queue's bounded\n * concurrency. Streaming uploads do not support resume because the total size\n * and per-part hashes aren't known in advance; use {@link uploadLargeFile} with\n * a buffered source when resume is required.\n *\n * @param raw - Low-level B2 API client.\n * @param accountInfo - Authorized account state (tokens, URLs, part URL pool).\n * @param options - Streaming upload parameters.\n *\n * @returns A {@link UploadWriteHandle} with the writable sink and a completion promise.\n */\nexport function createWriteStream(\n raw: RawClient,\n accountInfo: AccountInfo,\n options: CreateWriteStreamOptions,\n): UploadWriteHandle {\n const minPartSize = accountInfo.getAbsoluteMinimumPartSize()\n const recommendedPartSize = accountInfo.getRecommendedPartSize()\n const partSize = Math.max(options.partSize ?? recommendedPartSize, minPartSize)\n const concurrency = options.concurrency ?? DEFAULT_TRANSFER_CONCURRENCY\n const tracker = new ProgressTracker(options.onProgress, null, null, {\n ...(options.progressIntervalMillis !== undefined\n ? { minIntervalMs: options.progressIntervalMillis }\n : {}),\n })\n const sem = new Semaphore(concurrency)\n const abortScope = createAbortScope(options.signal)\n\n let largeFileId: LargeFileId | null = null\n let startPromise: Promise<LargeFileId> | null = null\n let cancelAfterStartScheduled = false\n let nextPartNumber = 1\n let pendingBytes = 0\n const pending: Uint8Array[] = []\n const partSha1s: string[] = []\n const inflight: Promise<void>[] = []\n let errored: Error | null = null\n\n // ES2024 `Promise.withResolvers()` exposes the resolve/reject pair as\n // properties of the returned object, avoiding the `let resolve!:` /\n // `let reject!:` non-null-assertion pattern needed before this API\n // existed. Available in Node 22 (our minimum), Bun, Deno, modern\n // browsers, and Cloudflare Workers.\n const {\n promise: done,\n resolve: resolveDone,\n reject: rejectDone,\n } = Promise.withResolvers<FileVersion>()\n // Attach a no-op rejection handler so a `done` that rejects before the\n // caller observes it never surfaces as a process-level unhandled rejection.\n // The error is not swallowed: `close()`/`abort()` also reject the writable\n // (so `pipeTo`/`getWriter().close()` throw), and any later `await done` /\n // `done.then(onRejected)` the caller attaches still sees the rejection —\n // extra handlers on the same promise all fire. Mirrors the\n // `task.catch(() => {})` pattern used for inflight part uploads below, and\n // keeps the engine well-behaved under Bun and Node's strict\n // unhandled-rejection mode.\n done.catch(() => {})\n\n function ensureStarted(): Promise<LargeFileId> {\n if (largeFileId !== null) return Promise.resolve(largeFileId)\n if (startPromise === null) {\n const rawStart = raw.startLargeFile(\n accountInfo.getApiUrl(),\n accountInfo.getAuthToken(),\n {\n bucketId: options.bucketId,\n fileName: options.fileName,\n contentType: options.contentType ?? DEFAULT_CONTENT_TYPE,\n fileInfo: options.fileInfo ?? {},\n ...(options.customUploadTimestamp !== undefined\n ? { customUploadTimestamp: String(options.customUploadTimestamp) }\n : {}),\n ...(options.serverSideEncryption !== undefined\n ? { serverSideEncryption: options.serverSideEncryption }\n : {}),\n },\n {\n signal: abortScope.signal,\n ...(options.retry !== undefined ? { retry: options.retry } : {}),\n },\n )\n startPromise = rawStart.then((resp) => {\n largeFileId = resp.fileId\n if (abortScope.signal.aborted || errored !== null) {\n cancelStartedLargeFile(largeFileId)\n }\n return largeFileId\n })\n }\n const started = startPromise\n return raceWithAbort(started, abortScope.signal).catch((err) => {\n if (abortScope.signal.aborted) scheduleCancelLargeFileAfterStart(started)\n throw err\n })\n }\n\n async function shipPart(data: Uint8Array, partNumber: number): Promise<void> {\n if (errored !== null) throw errored\n abortScope.signal.throwIfAborted()\n const fileId = await ensureStarted()\n if (errored !== null) throw errored\n abortScope.signal.throwIfAborted()\n\n const sha1 = new IncrementalSha1()\n await sha1.update(data)\n const sha1Hex = await sha1.digest()\n abortScope.signal.throwIfAborted()\n\n const result = await uploadPartWithFreshUrl(raw, accountInfo, fileId, {\n fileName: options.fileName,\n partNumber,\n data: data as BodyInit,\n contentLength: data.byteLength,\n contentSha1: sha1Hex,\n retry: options.retry,\n signal: abortScope.signal,\n onUploadRetry: options.onUploadRetry,\n retryResponseBodyFailures: resolveRetryResponseBodyFailures(\n options.retryResponseBodyFailures,\n ),\n ...(options.serverSideEncryption !== undefined\n ? { serverSideEncryption: options.serverSideEncryption }\n : {}),\n })\n partSha1s[partNumber - 1] = result.contentSha1\n tracker.addBytes(data.byteLength)\n tracker.completePart()\n }\n\n function markErrored(err: unknown): Error {\n const error = toError(err)\n errored = error\n tracker.dispose()\n abortScope.abort(error)\n return error\n }\n\n function cancelStartedLargeFile(fileId: LargeFileId): void {\n if (cancelAfterStartScheduled) return\n cancelAfterStartScheduled = true\n void cancelLargeFileBestEffort(raw, accountInfo, fileId, cleanupWriteStreamOptions(options))\n }\n\n function scheduleCancelLargeFileAfterStart(started: Promise<LargeFileId>): void {\n void started\n .then((fileId) => cancelStartedLargeFile(fileId))\n .catch(() => {\n // If start failed, no file ID is available to cancel.\n })\n }\n\n async function settleInflightForClose(): Promise<PromiseSettledResult<void>[]> {\n const settled = Promise.allSettled(inflight)\n if (startPromise === null || largeFileId !== null) return await settled\n\n const abortWaiter = waitForAbort(abortScope.signal)\n try {\n const first = await Promise.race([\n settled.then(() => 'settled' as const),\n startPromise.then(\n () => 'start-settled' as const,\n () => 'start-settled' as const,\n ),\n abortWaiter.promise.then(() => 'aborted' as const),\n ])\n if (first === 'aborted' && largeFileId === null) {\n throw abortReason(abortScope.signal)\n }\n return await settled\n } finally {\n abortWaiter.dispose()\n }\n }\n\n function startPartWithAcquiredSlot(data: Uint8Array, partNumber: number): void {\n const task = (async () => {\n try {\n await shipPart(data, partNumber)\n } catch (err) {\n markErrored(err)\n throw err\n } finally {\n sem.release()\n }\n })()\n inflight.push(task)\n // Swallow rejection here; we check `errored` later.\n task.catch(() => {})\n }\n\n async function acquirePartSlot(): Promise<void> {\n await sem.acquire()\n if (errored !== null) {\n sem.release()\n throw errored\n }\n try {\n abortScope.signal.throwIfAborted()\n } catch (err) {\n sem.release()\n throw err\n }\n }\n\n async function waitForInflightPartsToSettle(\n timeoutMs = DEFAULT_CLEANUP_TIMEOUT_MS,\n ): Promise<void> {\n /* v8 ignore next -- only called after a large file exists, which requires at least one part */\n if (inflight.length === 0) return\n let timeout: ReturnType<typeof setTimeout> | undefined\n try {\n await Promise.race([\n Promise.allSettled(inflight).then(() => undefined),\n new Promise<void>((resolve) => {\n timeout = setTimeout(resolve, timeoutMs)\n }),\n ])\n } finally {\n /* v8 ignore next -- setTimeout is assigned synchronously when the race promise is built */\n if (timeout !== undefined) clearTimeout(timeout)\n }\n }\n\n async function dispatchPart(): Promise<void> {\n /* v8 ignore next -- callers guard on pendingBytes before dispatching the final part */\n if (pending.length === 0) return\n await acquirePartSlot()\n let data: Uint8Array\n if (pending.length === 1) {\n const head = pending[0]\n /* v8 ignore next -- pending is never sparse; this narrows noUncheckedIndexedAccess */\n if (!head) {\n sem.release()\n return\n }\n data = head\n } else {\n const total = pending.reduce((sum, chunk) => sum + chunk.byteLength, 0)\n data = new Uint8Array(total)\n let offset = 0\n for (const chunk of pending) {\n data.set(chunk, offset)\n offset += chunk.byteLength\n }\n }\n pending.length = 0\n pendingBytes = 0\n const partNumber = nextPartNumber++\n startPartWithAcquiredSlot(data, partNumber)\n }\n\n const writable = new WritableStream<Uint8Array>({\n async write(chunk: Uint8Array): Promise<void> {\n if (errored) throw errored\n abortScope.signal.throwIfAborted()\n if (chunk.byteLength === 0) return\n\n pending.push(chunk)\n pendingBytes += chunk.byteLength\n while (pendingBytes >= partSize) {\n await acquirePartSlot()\n if (errored) {\n sem.release()\n throw errored\n }\n // Pull exactly partSize bytes off the front\n const carved = carveExact(pending, partSize)\n const partNumber = nextPartNumber++\n pendingBytes -= partSize\n startPartWithAcquiredSlot(carved, partNumber)\n }\n },\n\n async close(): Promise<void> {\n try {\n if (errored) throw errored\n abortScope.signal.throwIfAborted()\n\n // Ship any remaining bytes as the last part. If the total fit in one\n // single buffered batch (no parts shipped yet), we have to use the\n // multipart path anyway since we already called startLargeFile lazily.\n if (pendingBytes > 0) {\n await dispatchPart()\n }\n\n const settled = await settleInflightForClose()\n const rejected = settled.find(\n (result): result is PromiseRejectedResult => result.status === 'rejected',\n )\n if (rejected !== undefined && errored === null) {\n markErrored(rejected.reason)\n }\n if (errored) throw errored\n\n if (largeFileId === null) {\n // Stream closed before any data was written. Start an empty large\n // file? B2 requires at least 2 parts. Reject — callers shouldn't\n // close an empty stream.\n throw new Error('createWriteStream closed without any data written.')\n }\n\n const result = await finishLargeFileWithAbortReconciliation(raw, accountInfo, {\n fileId: largeFileId,\n bucketId: options.bucketId,\n fileName: options.fileName,\n partSha1s,\n signal: abortScope.signal,\n ...(options.retry !== undefined ? { retry: options.retry } : {}),\n })\n tracker.dispose()\n abortScope.dispose()\n resolveDone(result)\n } catch (err) {\n const closeError = toError(err)\n if (errored === null) errored = closeError\n tracker.dispose()\n abortScope.abort(errored)\n const observedError = errored\n const fileIdToCancel = largeFileId\n if (fileIdToCancel === null && startPromise !== null) {\n // Mirror writer.abort(): close() must not wait for non-abortable\n // b2_start_large_file. If a file ID arrives later, cancel it in the\n // background.\n scheduleCancelLargeFileAfterStart(startPromise)\n abortScope.dispose()\n rejectDone(observedError)\n throw observedError\n }\n await Promise.allSettled(inflight)\n // Capture into a const so the cancel closure sees a non-null\n // `fileId`; closures don't observe the outer `!== null` narrowing\n // because the variable is mutable across the lambda boundary.\n let finalError: unknown = observedError\n if (fileIdToCancel !== null) {\n finalError = await resolveLargeFileErrorAfterCleanup(observedError, raw, accountInfo, {\n fileId: fileIdToCancel,\n bucketId: options.bucketId,\n fileName: options.fileName,\n signal: options.signal,\n onCleanupFailure: options.onCleanupFailure,\n })\n }\n abortScope.dispose()\n rejectDone(finalError)\n throw finalError\n }\n },\n\n async abort(reason: unknown): Promise<void> {\n const abortError = markErrored(reason)\n pending.length = 0\n pendingBytes = 0\n const fileIdToCancel = largeFileId\n if (fileIdToCancel === null && startPromise !== null) {\n // Do not await an in-flight start request here. A stalled\n // b2_start_large_file must not make writer.abort() hang; if it later\n // returns a file ID, cancel it best-effort in the background.\n scheduleCancelLargeFileAfterStart(startPromise)\n }\n if (fileIdToCancel !== null) {\n await waitForInflightPartsToSettle()\n await cancelLargeFileBestEffort(\n raw,\n accountInfo,\n fileIdToCancel,\n cleanupWriteStreamOptions(options),\n )\n }\n tracker.dispose()\n abortScope.dispose()\n rejectDone(abortError)\n },\n })\n\n return { writable, done }\n}\n\nfunction cleanupWriteStreamOptions(options: CreateWriteStreamOptions): {\n readonly signal?: AbortSignal\n} & CleanupFailureOptions {\n return {\n ...(options.signal !== undefined ? { signal: options.signal } : {}),\n ...(options.onCleanupFailure !== undefined\n ? { onCleanupFailure: options.onCleanupFailure }\n : {}),\n }\n}\n\n/**\n * Removes exactly `size` bytes from the front of `chunks` (mutates) and returns\n * them as a contiguous Uint8Array. Any trailing remainder of the last chunk\n * stays at the front of `chunks` for the next part.\n *\n * @param chunks - Queue of pending chunks. Modified in place.\n * @param size - Number of bytes to carve off the front.\n *\n * @returns A new Uint8Array containing exactly `size` bytes.\n */\nfunction carveExact(chunks: Uint8Array[], size: number): Uint8Array {\n const out = new Uint8Array(size)\n let written = 0\n while (written < size && chunks.length > 0) {\n const head = chunks[0]\n /* v8 ignore next -- chunks is never sparse; this narrows noUncheckedIndexedAccess */\n if (!head) break\n const need = size - written\n if (head.byteLength <= need) {\n out.set(head, written)\n written += head.byteLength\n chunks.shift()\n } else {\n out.set(head.subarray(0, need), written)\n chunks[0] = head.subarray(need)\n written += need\n }\n }\n return out\n}\n\nfunction waitForAbort(signal: AbortSignal): {\n readonly promise: Promise<unknown>\n dispose(): void\n} {\n /* v8 ignore next -- callers check abort before entering the start/close wait race */\n if (signal.aborted) {\n return {\n promise: Promise.resolve(abortReason(signal)),\n dispose() {},\n }\n }\n\n let onAbort: (() => void) | undefined\n const promise = new Promise<unknown>((resolve) => {\n onAbort = () => resolve(abortReason(signal))\n signal.addEventListener('abort', onAbort, { once: true })\n })\n\n return {\n promise,\n dispose() {\n /* v8 ignore next -- listener is assigned synchronously with promise construction */\n if (onAbort !== undefined) signal.removeEventListener('abort', onAbort)\n },\n }\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
//#region src/util/abort.ts
|
|
2
|
+
/**
|
|
3
|
+
* Abort-signal and cancellation-error helpers shared across SDK operations.
|
|
4
|
+
*
|
|
5
|
+
* @packageDocumentation
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Resolves the abort reason for a signal, defaulting to a standard `AbortError`.
|
|
9
|
+
*
|
|
10
|
+
* @param signal - The aborted signal whose reason should be resolved.
|
|
11
|
+
*
|
|
12
|
+
* @returns The signal's `reason`, or a fresh `AbortError` DOMException when unset.
|
|
13
|
+
*/
|
|
14
|
+
function abortReason(signal) {
|
|
15
|
+
return signal.reason ?? new DOMException("Aborted", "AbortError");
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Returns whether an error represents an abort.
|
|
19
|
+
*
|
|
20
|
+
* @param err - Unknown thrown value.
|
|
21
|
+
*
|
|
22
|
+
* @returns True for `Error` or `DOMException` instances named `AbortError`.
|
|
23
|
+
*/
|
|
24
|
+
function isAbortError(err) {
|
|
25
|
+
return isNamedError(err, "AbortError");
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Returns whether an error should be treated as the given signal's abort.
|
|
29
|
+
*
|
|
30
|
+
* @param signal - Controlling signal for the operation.
|
|
31
|
+
* @param err - Unknown thrown value.
|
|
32
|
+
*
|
|
33
|
+
* @returns True when the signal is aborted and `err` is either the signal's
|
|
34
|
+
* reason or a trusted `AbortError` instance.
|
|
35
|
+
*/
|
|
36
|
+
function isSignalAbortError(signal, err) {
|
|
37
|
+
if (signal?.aborted !== true) return false;
|
|
38
|
+
if (signal.reason !== void 0 && Object.is(err, signal.reason)) return true;
|
|
39
|
+
return isAbortError(err);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Returns whether an error represents a timeout.
|
|
43
|
+
*
|
|
44
|
+
* @param err - Unknown thrown value.
|
|
45
|
+
*
|
|
46
|
+
* @returns True for `Error` or `DOMException` instances named `TimeoutError`.
|
|
47
|
+
*/
|
|
48
|
+
function isTimeoutError(err) {
|
|
49
|
+
return isNamedError(err, "TimeoutError");
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Throws the abort reason if the signal is already aborted; otherwise returns.
|
|
53
|
+
*
|
|
54
|
+
* @param signal - The signal to check, or undefined to skip the check.
|
|
55
|
+
*
|
|
56
|
+
* @throws The signal's abort reason when the signal is already aborted.
|
|
57
|
+
*/
|
|
58
|
+
function throwIfSignalAborted(signal) {
|
|
59
|
+
if (signal?.aborted === true) throw abortReason(signal);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Races a promise against an abort signal. Rejects with the signal's abort
|
|
63
|
+
* reason if the signal fires first, detaching the listener and suppressing the
|
|
64
|
+
* losing promise's rejection so it never surfaces as an unhandled rejection.
|
|
65
|
+
*
|
|
66
|
+
* The underlying work must still receive the same signal so transports can
|
|
67
|
+
* cancel their network activity. This helper only makes callers stop waiting
|
|
68
|
+
* promptly even when a test double or custom transport ignores the signal.
|
|
69
|
+
*
|
|
70
|
+
* @param promise - The work to await.
|
|
71
|
+
* @param signal - Abort signal, or undefined to await the promise directly.
|
|
72
|
+
*
|
|
73
|
+
* @returns The resolved value of `promise` when it settles before the signal aborts.
|
|
74
|
+
*
|
|
75
|
+
* @throws The abort reason if the signal aborts first, or the promise's rejection.
|
|
76
|
+
*/
|
|
77
|
+
async function raceWithAbort(promise, signal) {
|
|
78
|
+
if (signal === void 0) return promise;
|
|
79
|
+
if (signal.aborted) {
|
|
80
|
+
promise.catch(() => {});
|
|
81
|
+
throw abortReason(signal);
|
|
82
|
+
}
|
|
83
|
+
let removeAbortListener;
|
|
84
|
+
const aborted = new Promise((_, reject) => {
|
|
85
|
+
const onAbort = () => {
|
|
86
|
+
promise.catch(() => {});
|
|
87
|
+
reject(abortReason(signal));
|
|
88
|
+
};
|
|
89
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
90
|
+
removeAbortListener = () => signal.removeEventListener("abort", onAbort);
|
|
91
|
+
if (signal.aborted) onAbort();
|
|
92
|
+
});
|
|
93
|
+
try {
|
|
94
|
+
return await Promise.race([promise, aborted]);
|
|
95
|
+
} finally {
|
|
96
|
+
removeAbortListener?.();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function isNamedError(err, name) {
|
|
100
|
+
try {
|
|
101
|
+
return (err instanceof DOMException || err instanceof Error) && err.name === name;
|
|
102
|
+
} catch {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//#endregion
|
|
107
|
+
exports.abortReason = abortReason;
|
|
108
|
+
exports.isAbortError = isAbortError;
|
|
109
|
+
exports.isSignalAbortError = isSignalAbortError;
|
|
110
|
+
exports.isTimeoutError = isTimeoutError;
|
|
111
|
+
exports.raceWithAbort = raceWithAbort;
|
|
112
|
+
exports.throwIfSignalAborted = throwIfSignalAborted;
|
|
113
|
+
|
|
114
|
+
//# sourceMappingURL=abort.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abort.cjs","names":[],"sources":["../../src/util/abort.ts"],"sourcesContent":["/**\n * Abort-signal and cancellation-error helpers shared across SDK operations.\n *\n * @packageDocumentation\n */\n\n/**\n * Resolves the abort reason for a signal, defaulting to a standard `AbortError`.\n *\n * @param signal - The aborted signal whose reason should be resolved.\n *\n * @returns The signal's `reason`, or a fresh `AbortError` DOMException when unset.\n */\nexport function abortReason(signal: AbortSignal): unknown {\n return signal.reason ?? new DOMException('Aborted', 'AbortError')\n}\n\n/**\n * Returns whether an error represents an abort.\n *\n * @param err - Unknown thrown value.\n *\n * @returns True for `Error` or `DOMException` instances named `AbortError`.\n */\nexport function isAbortError(err: unknown): boolean {\n return isNamedError(err, 'AbortError')\n}\n\n/**\n * Returns whether an error should be treated as the given signal's abort.\n *\n * @param signal - Controlling signal for the operation.\n * @param err - Unknown thrown value.\n *\n * @returns True when the signal is aborted and `err` is either the signal's\n * reason or a trusted `AbortError` instance.\n */\nexport function isSignalAbortError(signal: AbortSignal | undefined, err: unknown): boolean {\n if (signal?.aborted !== true) return false\n if (signal.reason !== undefined && Object.is(err, signal.reason)) return true\n return isAbortError(err)\n}\n\n/**\n * Returns whether an error represents a timeout.\n *\n * @param err - Unknown thrown value.\n *\n * @returns True for `Error` or `DOMException` instances named `TimeoutError`.\n */\nexport function isTimeoutError(err: unknown): boolean {\n return isNamedError(err, 'TimeoutError')\n}\n\n/**\n * Throws the abort reason if the signal is already aborted; otherwise returns.\n *\n * @param signal - The signal to check, or undefined to skip the check.\n *\n * @throws The signal's abort reason when the signal is already aborted.\n */\nexport function throwIfSignalAborted(signal: AbortSignal | undefined): void {\n if (signal?.aborted === true) {\n throw abortReason(signal)\n }\n}\n\n/**\n * Races a promise against an abort signal. Rejects with the signal's abort\n * reason if the signal fires first, detaching the listener and suppressing the\n * losing promise's rejection so it never surfaces as an unhandled rejection.\n *\n * The underlying work must still receive the same signal so transports can\n * cancel their network activity. This helper only makes callers stop waiting\n * promptly even when a test double or custom transport ignores the signal.\n *\n * @param promise - The work to await.\n * @param signal - Abort signal, or undefined to await the promise directly.\n *\n * @returns The resolved value of `promise` when it settles before the signal aborts.\n *\n * @throws The abort reason if the signal aborts first, or the promise's rejection.\n */\nexport async function raceWithAbort<T>(\n promise: Promise<T>,\n signal: AbortSignal | undefined,\n): Promise<T> {\n if (signal === undefined) return promise\n if (signal.aborted) {\n void promise.catch(() => {})\n throw abortReason(signal)\n }\n\n let removeAbortListener: (() => void) | undefined\n const aborted = new Promise<never>((_, reject) => {\n const onAbort = (): void => {\n void promise.catch(() => {})\n reject(abortReason(signal))\n }\n signal.addEventListener('abort', onAbort, { once: true })\n removeAbortListener = () => signal.removeEventListener('abort', onAbort)\n if (signal.aborted) onAbort()\n })\n\n try {\n return await Promise.race([promise, aborted])\n } finally {\n removeAbortListener?.()\n }\n}\n\nfunction isNamedError(err: unknown, name: string): boolean {\n try {\n return (\n (err instanceof DOMException || err instanceof Error) &&\n (err as { readonly name: string }).name === name\n )\n } catch {\n return false\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAaA,SAAgB,YAAY,QAA8B;CACxD,OAAO,OAAO,UAAU,IAAI,aAAa,WAAW,YAAY;AAClE;;;;;;;;AASA,SAAgB,aAAa,KAAuB;CAClD,OAAO,aAAa,KAAK,YAAY;AACvC;;;;;;;;;;AAWA,SAAgB,mBAAmB,QAAiC,KAAuB;CACzF,IAAI,QAAQ,YAAY,MAAM,OAAO;CACrC,IAAI,OAAO,WAAW,KAAA,KAAa,OAAO,GAAG,KAAK,OAAO,MAAM,GAAG,OAAO;CACzE,OAAO,aAAa,GAAG;AACzB;;;;;;;;AASA,SAAgB,eAAe,KAAuB;CACpD,OAAO,aAAa,KAAK,cAAc;AACzC;;;;;;;;AASA,SAAgB,qBAAqB,QAAuC;CAC1E,IAAI,QAAQ,YAAY,MACtB,MAAM,YAAY,MAAM;AAE5B;;;;;;;;;;;;;;;;;AAkBA,eAAsB,cACpB,SACA,QACY;CACZ,IAAI,WAAW,KAAA,GAAW,OAAO;CACjC,IAAI,OAAO,SAAS;EAClB,QAAa,YAAY,CAAC,CAAC;EAC3B,MAAM,YAAY,MAAM;CAC1B;CAEA,IAAI;CACJ,MAAM,UAAU,IAAI,SAAgB,GAAG,WAAW;EAChD,MAAM,gBAAsB;GAC1B,QAAa,YAAY,CAAC,CAAC;GAC3B,OAAO,YAAY,MAAM,CAAC;EAC5B;EACA,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;EACxD,4BAA4B,OAAO,oBAAoB,SAAS,OAAO;EACvE,IAAI,OAAO,SAAS,QAAQ;CAC9B,CAAC;CAED,IAAI;EACF,OAAO,MAAM,QAAQ,KAAK,CAAC,SAAS,OAAO,CAAC;CAC9C,UAAU;EACR,sBAAsB;CACxB;AACF;AAEA,SAAS,aAAa,KAAc,MAAuB;CACzD,IAAI;EACF,QACG,eAAe,gBAAgB,eAAe,UAC9C,IAAkC,SAAS;CAEhD,QAAQ;EACN,OAAO;CACT;AACF"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abort-signal and cancellation-error helpers shared across SDK operations.
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Resolves the abort reason for a signal, defaulting to a standard `AbortError`.
|
|
8
|
+
*
|
|
9
|
+
* @param signal - The aborted signal whose reason should be resolved.
|
|
10
|
+
*
|
|
11
|
+
* @returns The signal's `reason`, or a fresh `AbortError` DOMException when unset.
|
|
12
|
+
*/
|
|
13
|
+
export declare function abortReason(signal: AbortSignal): unknown;
|
|
14
|
+
/**
|
|
15
|
+
* Returns whether an error represents an abort.
|
|
16
|
+
*
|
|
17
|
+
* @param err - Unknown thrown value.
|
|
18
|
+
*
|
|
19
|
+
* @returns True for `Error` or `DOMException` instances named `AbortError`.
|
|
20
|
+
*/
|
|
21
|
+
export declare function isAbortError(err: unknown): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Returns whether an error should be treated as the given signal's abort.
|
|
24
|
+
*
|
|
25
|
+
* @param signal - Controlling signal for the operation.
|
|
26
|
+
* @param err - Unknown thrown value.
|
|
27
|
+
*
|
|
28
|
+
* @returns True when the signal is aborted and `err` is either the signal's
|
|
29
|
+
* reason or a trusted `AbortError` instance.
|
|
30
|
+
*/
|
|
31
|
+
export declare function isSignalAbortError(signal: AbortSignal | undefined, err: unknown): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Returns whether an error represents a timeout.
|
|
34
|
+
*
|
|
35
|
+
* @param err - Unknown thrown value.
|
|
36
|
+
*
|
|
37
|
+
* @returns True for `Error` or `DOMException` instances named `TimeoutError`.
|
|
38
|
+
*/
|
|
39
|
+
export declare function isTimeoutError(err: unknown): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Throws the abort reason if the signal is already aborted; otherwise returns.
|
|
42
|
+
*
|
|
43
|
+
* @param signal - The signal to check, or undefined to skip the check.
|
|
44
|
+
*
|
|
45
|
+
* @throws The signal's abort reason when the signal is already aborted.
|
|
46
|
+
*/
|
|
47
|
+
export declare function throwIfSignalAborted(signal: AbortSignal | undefined): void;
|
|
48
|
+
/**
|
|
49
|
+
* Races a promise against an abort signal. Rejects with the signal's abort
|
|
50
|
+
* reason if the signal fires first, detaching the listener and suppressing the
|
|
51
|
+
* losing promise's rejection so it never surfaces as an unhandled rejection.
|
|
52
|
+
*
|
|
53
|
+
* The underlying work must still receive the same signal so transports can
|
|
54
|
+
* cancel their network activity. This helper only makes callers stop waiting
|
|
55
|
+
* promptly even when a test double or custom transport ignores the signal.
|
|
56
|
+
*
|
|
57
|
+
* @param promise - The work to await.
|
|
58
|
+
* @param signal - Abort signal, or undefined to await the promise directly.
|
|
59
|
+
*
|
|
60
|
+
* @returns The resolved value of `promise` when it settles before the signal aborts.
|
|
61
|
+
*
|
|
62
|
+
* @throws The abort reason if the signal aborts first, or the promise's rejection.
|
|
63
|
+
*/
|
|
64
|
+
export declare function raceWithAbort<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T>;
|
|
65
|
+
//# sourceMappingURL=abort.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abort.d.ts","sourceRoot":"","sources":["../../src/util/abort.js"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAExD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAElD;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAIzF;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAEpD;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,IAAI,CAI1E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,aAAa,CAAC,CAAC,EACnC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,MAAM,EAAE,WAAW,GAAG,SAAS,GAC9B,OAAO,CAAC,CAAC,CAAC,CAuBZ"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Abort-signal and cancellation-error helpers shared across SDK operations.
|
|
3
|
+
*
|
|
4
|
+
* @packageDocumentation
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Resolves the abort reason for a signal, defaulting to a standard `AbortError`.
|
|
8
|
+
*
|
|
9
|
+
* @param signal - The aborted signal whose reason should be resolved.
|
|
10
|
+
*
|
|
11
|
+
* @returns The signal's `reason`, or a fresh `AbortError` DOMException when unset.
|
|
12
|
+
*/
|
|
13
|
+
export declare function abortReason(signal: AbortSignal): unknown;
|
|
14
|
+
/**
|
|
15
|
+
* Returns whether an error represents an abort.
|
|
16
|
+
*
|
|
17
|
+
* @param err - Unknown thrown value.
|
|
18
|
+
*
|
|
19
|
+
* @returns True for `Error` or `DOMException` instances named `AbortError`.
|
|
20
|
+
*/
|
|
21
|
+
export declare function isAbortError(err: unknown): boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Returns whether an error should be treated as the given signal's abort.
|
|
24
|
+
*
|
|
25
|
+
* @param signal - Controlling signal for the operation.
|
|
26
|
+
* @param err - Unknown thrown value.
|
|
27
|
+
*
|
|
28
|
+
* @returns True when the signal is aborted and `err` is either the signal's
|
|
29
|
+
* reason or a trusted `AbortError` instance.
|
|
30
|
+
*/
|
|
31
|
+
export declare function isSignalAbortError(signal: AbortSignal | undefined, err: unknown): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Returns whether an error represents a timeout.
|
|
34
|
+
*
|
|
35
|
+
* @param err - Unknown thrown value.
|
|
36
|
+
*
|
|
37
|
+
* @returns True for `Error` or `DOMException` instances named `TimeoutError`.
|
|
38
|
+
*/
|
|
39
|
+
export declare function isTimeoutError(err: unknown): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Throws the abort reason if the signal is already aborted; otherwise returns.
|
|
42
|
+
*
|
|
43
|
+
* @param signal - The signal to check, or undefined to skip the check.
|
|
44
|
+
*
|
|
45
|
+
* @throws The signal's abort reason when the signal is already aborted.
|
|
46
|
+
*/
|
|
47
|
+
export declare function throwIfSignalAborted(signal: AbortSignal | undefined): void;
|
|
48
|
+
/**
|
|
49
|
+
* Races a promise against an abort signal. Rejects with the signal's abort
|
|
50
|
+
* reason if the signal fires first, detaching the listener and suppressing the
|
|
51
|
+
* losing promise's rejection so it never surfaces as an unhandled rejection.
|
|
52
|
+
*
|
|
53
|
+
* The underlying work must still receive the same signal so transports can
|
|
54
|
+
* cancel their network activity. This helper only makes callers stop waiting
|
|
55
|
+
* promptly even when a test double or custom transport ignores the signal.
|
|
56
|
+
*
|
|
57
|
+
* @param promise - The work to await.
|
|
58
|
+
* @param signal - Abort signal, or undefined to await the promise directly.
|
|
59
|
+
*
|
|
60
|
+
* @returns The resolved value of `promise` when it settles before the signal aborts.
|
|
61
|
+
*
|
|
62
|
+
* @throws The abort reason if the signal aborts first, or the promise's rejection.
|
|
63
|
+
*/
|
|
64
|
+
export declare function raceWithAbort<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T>;
|
|
65
|
+
//# sourceMappingURL=abort.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abort.d.ts","sourceRoot":"","sources":["../../src/util/abort.js"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;;;;;GAMG;AACH,wBAAgB,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAExD;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAElD;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAIzF;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAEpD;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,GAAG,IAAI,CAI1E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,aAAa,CAAC,CAAC,EACnC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,MAAM,EAAE,WAAW,GAAG,SAAS,GAC9B,OAAO,CAAC,CAAC,CAAC,CAuBZ"}
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
//#region src/util/abort.ts
|
|
2
|
+
/**
|
|
3
|
+
* Abort-signal and cancellation-error helpers shared across SDK operations.
|
|
4
|
+
*
|
|
5
|
+
* @packageDocumentation
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Resolves the abort reason for a signal, defaulting to a standard `AbortError`.
|
|
9
|
+
*
|
|
10
|
+
* @param signal - The aborted signal whose reason should be resolved.
|
|
11
|
+
*
|
|
12
|
+
* @returns The signal's `reason`, or a fresh `AbortError` DOMException when unset.
|
|
13
|
+
*/
|
|
14
|
+
function abortReason(signal) {
|
|
15
|
+
return signal.reason ?? new DOMException("Aborted", "AbortError");
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Returns whether an error represents an abort.
|
|
19
|
+
*
|
|
20
|
+
* @param err - Unknown thrown value.
|
|
21
|
+
*
|
|
22
|
+
* @returns True for `Error` or `DOMException` instances named `AbortError`.
|
|
23
|
+
*/
|
|
24
|
+
function isAbortError(err) {
|
|
25
|
+
return isNamedError(err, "AbortError");
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Returns whether an error should be treated as the given signal's abort.
|
|
29
|
+
*
|
|
30
|
+
* @param signal - Controlling signal for the operation.
|
|
31
|
+
* @param err - Unknown thrown value.
|
|
32
|
+
*
|
|
33
|
+
* @returns True when the signal is aborted and `err` is either the signal's
|
|
34
|
+
* reason or a trusted `AbortError` instance.
|
|
35
|
+
*/
|
|
36
|
+
function isSignalAbortError(signal, err) {
|
|
37
|
+
if (signal?.aborted !== true) return false;
|
|
38
|
+
if (signal.reason !== void 0 && Object.is(err, signal.reason)) return true;
|
|
39
|
+
return isAbortError(err);
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Returns whether an error represents a timeout.
|
|
43
|
+
*
|
|
44
|
+
* @param err - Unknown thrown value.
|
|
45
|
+
*
|
|
46
|
+
* @returns True for `Error` or `DOMException` instances named `TimeoutError`.
|
|
47
|
+
*/
|
|
48
|
+
function isTimeoutError(err) {
|
|
49
|
+
return isNamedError(err, "TimeoutError");
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Throws the abort reason if the signal is already aborted; otherwise returns.
|
|
53
|
+
*
|
|
54
|
+
* @param signal - The signal to check, or undefined to skip the check.
|
|
55
|
+
*
|
|
56
|
+
* @throws The signal's abort reason when the signal is already aborted.
|
|
57
|
+
*/
|
|
58
|
+
function throwIfSignalAborted(signal) {
|
|
59
|
+
if (signal?.aborted === true) throw abortReason(signal);
|
|
60
|
+
}
|
|
61
|
+
/**
|
|
62
|
+
* Races a promise against an abort signal. Rejects with the signal's abort
|
|
63
|
+
* reason if the signal fires first, detaching the listener and suppressing the
|
|
64
|
+
* losing promise's rejection so it never surfaces as an unhandled rejection.
|
|
65
|
+
*
|
|
66
|
+
* The underlying work must still receive the same signal so transports can
|
|
67
|
+
* cancel their network activity. This helper only makes callers stop waiting
|
|
68
|
+
* promptly even when a test double or custom transport ignores the signal.
|
|
69
|
+
*
|
|
70
|
+
* @param promise - The work to await.
|
|
71
|
+
* @param signal - Abort signal, or undefined to await the promise directly.
|
|
72
|
+
*
|
|
73
|
+
* @returns The resolved value of `promise` when it settles before the signal aborts.
|
|
74
|
+
*
|
|
75
|
+
* @throws The abort reason if the signal aborts first, or the promise's rejection.
|
|
76
|
+
*/
|
|
77
|
+
async function raceWithAbort(promise, signal) {
|
|
78
|
+
if (signal === void 0) return promise;
|
|
79
|
+
if (signal.aborted) {
|
|
80
|
+
promise.catch(() => {});
|
|
81
|
+
throw abortReason(signal);
|
|
82
|
+
}
|
|
83
|
+
let removeAbortListener;
|
|
84
|
+
const aborted = new Promise((_, reject) => {
|
|
85
|
+
const onAbort = () => {
|
|
86
|
+
promise.catch(() => {});
|
|
87
|
+
reject(abortReason(signal));
|
|
88
|
+
};
|
|
89
|
+
signal.addEventListener("abort", onAbort, { once: true });
|
|
90
|
+
removeAbortListener = () => signal.removeEventListener("abort", onAbort);
|
|
91
|
+
if (signal.aborted) onAbort();
|
|
92
|
+
});
|
|
93
|
+
try {
|
|
94
|
+
return await Promise.race([promise, aborted]);
|
|
95
|
+
} finally {
|
|
96
|
+
removeAbortListener?.();
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
function isNamedError(err, name) {
|
|
100
|
+
try {
|
|
101
|
+
return (err instanceof DOMException || err instanceof Error) && err.name === name;
|
|
102
|
+
} catch {
|
|
103
|
+
return false;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
//#endregion
|
|
107
|
+
export { abortReason, isAbortError, isSignalAbortError, isTimeoutError, raceWithAbort, throwIfSignalAborted };
|
|
108
|
+
|
|
109
|
+
//# sourceMappingURL=abort.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"abort.js","names":[],"sources":["../../src/util/abort.ts"],"sourcesContent":["/**\n * Abort-signal and cancellation-error helpers shared across SDK operations.\n *\n * @packageDocumentation\n */\n\n/**\n * Resolves the abort reason for a signal, defaulting to a standard `AbortError`.\n *\n * @param signal - The aborted signal whose reason should be resolved.\n *\n * @returns The signal's `reason`, or a fresh `AbortError` DOMException when unset.\n */\nexport function abortReason(signal: AbortSignal): unknown {\n return signal.reason ?? new DOMException('Aborted', 'AbortError')\n}\n\n/**\n * Returns whether an error represents an abort.\n *\n * @param err - Unknown thrown value.\n *\n * @returns True for `Error` or `DOMException` instances named `AbortError`.\n */\nexport function isAbortError(err: unknown): boolean {\n return isNamedError(err, 'AbortError')\n}\n\n/**\n * Returns whether an error should be treated as the given signal's abort.\n *\n * @param signal - Controlling signal for the operation.\n * @param err - Unknown thrown value.\n *\n * @returns True when the signal is aborted and `err` is either the signal's\n * reason or a trusted `AbortError` instance.\n */\nexport function isSignalAbortError(signal: AbortSignal | undefined, err: unknown): boolean {\n if (signal?.aborted !== true) return false\n if (signal.reason !== undefined && Object.is(err, signal.reason)) return true\n return isAbortError(err)\n}\n\n/**\n * Returns whether an error represents a timeout.\n *\n * @param err - Unknown thrown value.\n *\n * @returns True for `Error` or `DOMException` instances named `TimeoutError`.\n */\nexport function isTimeoutError(err: unknown): boolean {\n return isNamedError(err, 'TimeoutError')\n}\n\n/**\n * Throws the abort reason if the signal is already aborted; otherwise returns.\n *\n * @param signal - The signal to check, or undefined to skip the check.\n *\n * @throws The signal's abort reason when the signal is already aborted.\n */\nexport function throwIfSignalAborted(signal: AbortSignal | undefined): void {\n if (signal?.aborted === true) {\n throw abortReason(signal)\n }\n}\n\n/**\n * Races a promise against an abort signal. Rejects with the signal's abort\n * reason if the signal fires first, detaching the listener and suppressing the\n * losing promise's rejection so it never surfaces as an unhandled rejection.\n *\n * The underlying work must still receive the same signal so transports can\n * cancel their network activity. This helper only makes callers stop waiting\n * promptly even when a test double or custom transport ignores the signal.\n *\n * @param promise - The work to await.\n * @param signal - Abort signal, or undefined to await the promise directly.\n *\n * @returns The resolved value of `promise` when it settles before the signal aborts.\n *\n * @throws The abort reason if the signal aborts first, or the promise's rejection.\n */\nexport async function raceWithAbort<T>(\n promise: Promise<T>,\n signal: AbortSignal | undefined,\n): Promise<T> {\n if (signal === undefined) return promise\n if (signal.aborted) {\n void promise.catch(() => {})\n throw abortReason(signal)\n }\n\n let removeAbortListener: (() => void) | undefined\n const aborted = new Promise<never>((_, reject) => {\n const onAbort = (): void => {\n void promise.catch(() => {})\n reject(abortReason(signal))\n }\n signal.addEventListener('abort', onAbort, { once: true })\n removeAbortListener = () => signal.removeEventListener('abort', onAbort)\n if (signal.aborted) onAbort()\n })\n\n try {\n return await Promise.race([promise, aborted])\n } finally {\n removeAbortListener?.()\n }\n}\n\nfunction isNamedError(err: unknown, name: string): boolean {\n try {\n return (\n (err instanceof DOMException || err instanceof Error) &&\n (err as { readonly name: string }).name === name\n )\n } catch {\n return false\n }\n}\n"],"mappings":";;;;;;;;;;;;;AAaA,SAAgB,YAAY,QAA8B;CACxD,OAAO,OAAO,UAAU,IAAI,aAAa,WAAW,YAAY;AAClE;;;;;;;;AASA,SAAgB,aAAa,KAAuB;CAClD,OAAO,aAAa,KAAK,YAAY;AACvC;;;;;;;;;;AAWA,SAAgB,mBAAmB,QAAiC,KAAuB;CACzF,IAAI,QAAQ,YAAY,MAAM,OAAO;CACrC,IAAI,OAAO,WAAW,KAAA,KAAa,OAAO,GAAG,KAAK,OAAO,MAAM,GAAG,OAAO;CACzE,OAAO,aAAa,GAAG;AACzB;;;;;;;;AASA,SAAgB,eAAe,KAAuB;CACpD,OAAO,aAAa,KAAK,cAAc;AACzC;;;;;;;;AASA,SAAgB,qBAAqB,QAAuC;CAC1E,IAAI,QAAQ,YAAY,MACtB,MAAM,YAAY,MAAM;AAE5B;;;;;;;;;;;;;;;;;AAkBA,eAAsB,cACpB,SACA,QACY;CACZ,IAAI,WAAW,KAAA,GAAW,OAAO;CACjC,IAAI,OAAO,SAAS;EAClB,QAAa,YAAY,CAAC,CAAC;EAC3B,MAAM,YAAY,MAAM;CAC1B;CAEA,IAAI;CACJ,MAAM,UAAU,IAAI,SAAgB,GAAG,WAAW;EAChD,MAAM,gBAAsB;GAC1B,QAAa,YAAY,CAAC,CAAC;GAC3B,OAAO,YAAY,MAAM,CAAC;EAC5B;EACA,OAAO,iBAAiB,SAAS,SAAS,EAAE,MAAM,KAAK,CAAC;EACxD,4BAA4B,OAAO,oBAAoB,SAAS,OAAO;EACvE,IAAI,OAAO,SAAS,QAAQ;CAC9B,CAAC;CAED,IAAI;EACF,OAAO,MAAM,QAAQ,KAAK,CAAC,SAAS,OAAO,CAAC;CAC9C,UAAU;EACR,sBAAsB;CACxB;AACF;AAEA,SAAS,aAAa,KAAc,MAAuB;CACzD,IAAI;EACF,QACG,eAAe,gBAAgB,eAAe,UAC9C,IAAkC,SAAS;CAEhD,QAAQ;EACN,OAAO;CACT;AACF"}
|
package/dist/util/defaults.cjs
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
//#region src/util/defaults.ts
|
|
2
|
+
/** Default byte size for each ranged request in a parallel download. */
|
|
3
|
+
var DEFAULT_DOWNLOAD_RANGE_SIZE = 10485760;
|
|
2
4
|
/**
|
|
3
5
|
* Default `maxFileCount` for list-style endpoints
|
|
4
6
|
* (`b2_list_file_names`, `b2_list_file_versions`, `b2_list_parts`). B2
|
|
@@ -22,6 +24,7 @@ var DEFAULT_PAGE_SIZE = 1e3;
|
|
|
22
24
|
var DEFAULT_CONTENT_TYPE = "b2/x-auto";
|
|
23
25
|
//#endregion
|
|
24
26
|
exports.DEFAULT_CONTENT_TYPE = DEFAULT_CONTENT_TYPE;
|
|
27
|
+
exports.DEFAULT_DOWNLOAD_RANGE_SIZE = DEFAULT_DOWNLOAD_RANGE_SIZE;
|
|
25
28
|
exports.DEFAULT_PAGE_SIZE = DEFAULT_PAGE_SIZE;
|
|
26
29
|
|
|
27
30
|
//# sourceMappingURL=defaults.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaults.cjs","names":[],"sources":["../../src/util/defaults.ts"],"sourcesContent":["/**\n * Shared SDK-wide default values.\n *\n * Centralising defaults here makes the trade-offs visible and prevents the\n * drift that creeps in when each module hard-codes its own magic number.\n *\n * @packageDocumentation\n */\n\n/**\n * Default parallel-task count for **data-transfer** operations: uploads\n * (multipart parts), downloads (byte ranges), server-side copies (parts),\n * and sync (file-by-file). Each in-flight task occupies one transport\n * slot and at least one part-worth of memory, so we keep this\n * conservative.\n *\n * Empirically `4` saturates a typical home / office uplink without\n * starving the event loop or risking B2's per-account upload-URL\n * rate-limit. Callers that have measured their environment can override\n * via the `concurrency` option on every transfer method.\n */\nexport const DEFAULT_TRANSFER_CONCURRENCY = 4\n\n/**\n * Default parallel-task count for **bulk metadata** operations:\n * `Bucket.deleteMany` (per-version delete calls), and the action loop in\n * `synchronize` when it dispatches mixed actions in batches.\n *\n * Higher than the transfer default because each task is a tiny API\n * round-trip (no payload), so concurrency is bound by API latency rather\n * than bandwidth or local memory. `10` keeps a delete-of-thousands\n * snappy without overwhelming a single account's request budget.\n */\nexport const DEFAULT_BULK_CONCURRENCY = 10\n\n/**\n * Default `maxFileCount` for list-style endpoints\n * (`b2_list_file_names`, `b2_list_file_versions`, `b2_list_parts`). B2\n * caps `maxFileCount` at `10000` for these endpoints; the SDK requests\n * `1000` per page so a single network blip doesn't lose 10× the work and\n * so callers see results sooner.\n *\n * `b2_list_unfinished_large_files` is capped at `100` server-side and is\n * not affected by this constant.\n */\nexport const DEFAULT_PAGE_SIZE = 1000\n\n/**\n * Default MIME type for uploads when the caller omits `contentType`.\n * B2 documents `b2/x-auto` as the magic value that asks the service to\n * sniff the file's content and pick a sensible `Content-Type` itself.\n * Centralising the literal here keeps the upload, copy, and create-write\n * paths in sync.\n *\n * @see https://www.backblaze.com/apidocs/b2-upload-file\n */\nexport const DEFAULT_CONTENT_TYPE = 'b2/x-auto'\n"],"mappings":";;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"defaults.cjs","names":[],"sources":["../../src/util/defaults.ts"],"sourcesContent":["/**\n * Shared SDK-wide default values.\n *\n * Centralising defaults here makes the trade-offs visible and prevents the\n * drift that creeps in when each module hard-codes its own magic number.\n *\n * @packageDocumentation\n */\n\n/**\n * Default parallel-task count for **data-transfer** operations: uploads\n * (multipart parts), downloads (byte ranges), server-side copies (parts),\n * and sync (file-by-file). Each in-flight task occupies one transport\n * slot and at least one part-worth of memory, so we keep this\n * conservative.\n *\n * Empirically `4` saturates a typical home / office uplink without\n * starving the event loop or risking B2's per-account upload-URL\n * rate-limit. Callers that have measured their environment can override\n * via the `concurrency` option on every transfer method.\n */\nexport const DEFAULT_TRANSFER_CONCURRENCY = 4\n\n/** Default byte size for each ranged request in a parallel download. */\nexport const DEFAULT_DOWNLOAD_RANGE_SIZE = 10 * 1024 * 1024\n\n/**\n * Default parallel-task count for **bulk metadata** operations:\n * `Bucket.deleteMany` (per-version delete calls), and the action loop in\n * `synchronize` when it dispatches mixed actions in batches.\n *\n * Higher than the transfer default because each task is a tiny API\n * round-trip (no payload), so concurrency is bound by API latency rather\n * than bandwidth or local memory. `10` keeps a delete-of-thousands\n * snappy without overwhelming a single account's request budget.\n */\nexport const DEFAULT_BULK_CONCURRENCY = 10\n\n/**\n * Default `maxFileCount` for list-style endpoints\n * (`b2_list_file_names`, `b2_list_file_versions`, `b2_list_parts`). B2\n * caps `maxFileCount` at `10000` for these endpoints; the SDK requests\n * `1000` per page so a single network blip doesn't lose 10× the work and\n * so callers see results sooner.\n *\n * `b2_list_unfinished_large_files` is capped at `100` server-side and is\n * not affected by this constant.\n */\nexport const DEFAULT_PAGE_SIZE = 1000\n\n/**\n * Default MIME type for uploads when the caller omits `contentType`.\n * B2 documents `b2/x-auto` as the magic value that asks the service to\n * sniff the file's content and pick a sensible `Content-Type` itself.\n * Centralising the literal here keeps the upload, copy, and create-write\n * paths in sync.\n *\n * @see https://www.backblaze.com/apidocs/b2-upload-file\n */\nexport const DEFAULT_CONTENT_TYPE = 'b2/x-auto'\n"],"mappings":";;AAwBA,IAAa,8BAA8B;;;;;;;;;;;AAwB3C,IAAa,oBAAoB;;;;;;;;;;AAWjC,IAAa,uBAAuB"}
|
package/dist/util/defaults.d.cts
CHANGED
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
* via the `concurrency` option on every transfer method.
|
|
20
20
|
*/
|
|
21
21
|
export declare const DEFAULT_TRANSFER_CONCURRENCY = 4;
|
|
22
|
+
/** Default byte size for each ranged request in a parallel download. */
|
|
23
|
+
export declare const DEFAULT_DOWNLOAD_RANGE_SIZE: number;
|
|
22
24
|
/**
|
|
23
25
|
* Default parallel-task count for **bulk metadata** operations:
|
|
24
26
|
* `Bucket.deleteMany` (per-version delete calls), and the action loop in
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/util/defaults.js"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,4BAA4B,IAAI,CAAA;AAE7C;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,KAAK,CAAA;AAE1C;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,OAAO,CAAA;AAErC;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,cAAc,CAAA"}
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/util/defaults.js"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,4BAA4B,IAAI,CAAA;AAE7C,wEAAwE;AACxE,eAAO,MAAM,2BAA2B,QAAmB,CAAA;AAE3D;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,KAAK,CAAA;AAE1C;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,OAAO,CAAA;AAErC;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,cAAc,CAAA"}
|
package/dist/util/defaults.d.ts
CHANGED
|
@@ -19,6 +19,8 @@
|
|
|
19
19
|
* via the `concurrency` option on every transfer method.
|
|
20
20
|
*/
|
|
21
21
|
export declare const DEFAULT_TRANSFER_CONCURRENCY = 4;
|
|
22
|
+
/** Default byte size for each ranged request in a parallel download. */
|
|
23
|
+
export declare const DEFAULT_DOWNLOAD_RANGE_SIZE: number;
|
|
22
24
|
/**
|
|
23
25
|
* Default parallel-task count for **bulk metadata** operations:
|
|
24
26
|
* `Bucket.deleteMany` (per-version delete calls), and the action loop in
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/util/defaults.js"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,4BAA4B,IAAI,CAAA;AAE7C;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,KAAK,CAAA;AAE1C;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,OAAO,CAAA;AAErC;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,cAAc,CAAA"}
|
|
1
|
+
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/util/defaults.js"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,4BAA4B,IAAI,CAAA;AAE7C,wEAAwE;AACxE,eAAO,MAAM,2BAA2B,QAAmB,CAAA;AAE3D;;;;;;;;;GASG;AACH,eAAO,MAAM,wBAAwB,KAAK,CAAA;AAE1C;;;;;;;;;GASG;AACH,eAAO,MAAM,iBAAiB,OAAO,CAAA;AAErC;;;;;;;;GAQG;AACH,eAAO,MAAM,oBAAoB,cAAc,CAAA"}
|
package/dist/util/defaults.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
//#region src/util/defaults.ts
|
|
2
|
+
/** Default byte size for each ranged request in a parallel download. */
|
|
3
|
+
var DEFAULT_DOWNLOAD_RANGE_SIZE = 10485760;
|
|
2
4
|
/**
|
|
3
5
|
* Default `maxFileCount` for list-style endpoints
|
|
4
6
|
* (`b2_list_file_names`, `b2_list_file_versions`, `b2_list_parts`). B2
|
|
@@ -21,6 +23,6 @@ var DEFAULT_PAGE_SIZE = 1e3;
|
|
|
21
23
|
*/
|
|
22
24
|
var DEFAULT_CONTENT_TYPE = "b2/x-auto";
|
|
23
25
|
//#endregion
|
|
24
|
-
export { DEFAULT_CONTENT_TYPE, DEFAULT_PAGE_SIZE };
|
|
26
|
+
export { DEFAULT_CONTENT_TYPE, DEFAULT_DOWNLOAD_RANGE_SIZE, DEFAULT_PAGE_SIZE };
|
|
25
27
|
|
|
26
28
|
//# sourceMappingURL=defaults.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"defaults.js","names":[],"sources":["../../src/util/defaults.ts"],"sourcesContent":["/**\n * Shared SDK-wide default values.\n *\n * Centralising defaults here makes the trade-offs visible and prevents the\n * drift that creeps in when each module hard-codes its own magic number.\n *\n * @packageDocumentation\n */\n\n/**\n * Default parallel-task count for **data-transfer** operations: uploads\n * (multipart parts), downloads (byte ranges), server-side copies (parts),\n * and sync (file-by-file). Each in-flight task occupies one transport\n * slot and at least one part-worth of memory, so we keep this\n * conservative.\n *\n * Empirically `4` saturates a typical home / office uplink without\n * starving the event loop or risking B2's per-account upload-URL\n * rate-limit. Callers that have measured their environment can override\n * via the `concurrency` option on every transfer method.\n */\nexport const DEFAULT_TRANSFER_CONCURRENCY = 4\n\n/**\n * Default parallel-task count for **bulk metadata** operations:\n * `Bucket.deleteMany` (per-version delete calls), and the action loop in\n * `synchronize` when it dispatches mixed actions in batches.\n *\n * Higher than the transfer default because each task is a tiny API\n * round-trip (no payload), so concurrency is bound by API latency rather\n * than bandwidth or local memory. `10` keeps a delete-of-thousands\n * snappy without overwhelming a single account's request budget.\n */\nexport const DEFAULT_BULK_CONCURRENCY = 10\n\n/**\n * Default `maxFileCount` for list-style endpoints\n * (`b2_list_file_names`, `b2_list_file_versions`, `b2_list_parts`). B2\n * caps `maxFileCount` at `10000` for these endpoints; the SDK requests\n * `1000` per page so a single network blip doesn't lose 10× the work and\n * so callers see results sooner.\n *\n * `b2_list_unfinished_large_files` is capped at `100` server-side and is\n * not affected by this constant.\n */\nexport const DEFAULT_PAGE_SIZE = 1000\n\n/**\n * Default MIME type for uploads when the caller omits `contentType`.\n * B2 documents `b2/x-auto` as the magic value that asks the service to\n * sniff the file's content and pick a sensible `Content-Type` itself.\n * Centralising the literal here keeps the upload, copy, and create-write\n * paths in sync.\n *\n * @see https://www.backblaze.com/apidocs/b2-upload-file\n */\nexport const DEFAULT_CONTENT_TYPE = 'b2/x-auto'\n"],"mappings":";;;;;;;;;;;
|
|
1
|
+
{"version":3,"file":"defaults.js","names":[],"sources":["../../src/util/defaults.ts"],"sourcesContent":["/**\n * Shared SDK-wide default values.\n *\n * Centralising defaults here makes the trade-offs visible and prevents the\n * drift that creeps in when each module hard-codes its own magic number.\n *\n * @packageDocumentation\n */\n\n/**\n * Default parallel-task count for **data-transfer** operations: uploads\n * (multipart parts), downloads (byte ranges), server-side copies (parts),\n * and sync (file-by-file). Each in-flight task occupies one transport\n * slot and at least one part-worth of memory, so we keep this\n * conservative.\n *\n * Empirically `4` saturates a typical home / office uplink without\n * starving the event loop or risking B2's per-account upload-URL\n * rate-limit. Callers that have measured their environment can override\n * via the `concurrency` option on every transfer method.\n */\nexport const DEFAULT_TRANSFER_CONCURRENCY = 4\n\n/** Default byte size for each ranged request in a parallel download. */\nexport const DEFAULT_DOWNLOAD_RANGE_SIZE = 10 * 1024 * 1024\n\n/**\n * Default parallel-task count for **bulk metadata** operations:\n * `Bucket.deleteMany` (per-version delete calls), and the action loop in\n * `synchronize` when it dispatches mixed actions in batches.\n *\n * Higher than the transfer default because each task is a tiny API\n * round-trip (no payload), so concurrency is bound by API latency rather\n * than bandwidth or local memory. `10` keeps a delete-of-thousands\n * snappy without overwhelming a single account's request budget.\n */\nexport const DEFAULT_BULK_CONCURRENCY = 10\n\n/**\n * Default `maxFileCount` for list-style endpoints\n * (`b2_list_file_names`, `b2_list_file_versions`, `b2_list_parts`). B2\n * caps `maxFileCount` at `10000` for these endpoints; the SDK requests\n * `1000` per page so a single network blip doesn't lose 10× the work and\n * so callers see results sooner.\n *\n * `b2_list_unfinished_large_files` is capped at `100` server-side and is\n * not affected by this constant.\n */\nexport const DEFAULT_PAGE_SIZE = 1000\n\n/**\n * Default MIME type for uploads when the caller omits `contentType`.\n * B2 documents `b2/x-auto` as the magic value that asks the service to\n * sniff the file's content and pick a sensible `Content-Type` itself.\n * Centralising the literal here keeps the upload, copy, and create-write\n * paths in sync.\n *\n * @see https://www.backblaze.com/apidocs/b2-upload-file\n */\nexport const DEFAULT_CONTENT_TYPE = 'b2/x-auto'\n"],"mappings":";;AAwBA,IAAa,8BAA8B;;;;;;;;;;;AAwB3C,IAAa,oBAAoB;;;;;;;;;;AAWjC,IAAa,uBAAuB"}
|