@kumwe/studio-media 0.1.0-beta.2 → 0.1.0-beta.4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"upload-controller.d.ts","sourceRoot":"","sources":["../src/upload-controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACpB,KAAK,4BAA4B,EACjC,KAAK,kBAAkB,EAEvB,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAC;AAEhC,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,gBAAgB,CAG1D,CAAC;AAEH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,gBAAgB,CAG5D,CAAC;AAEH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,oEAAoE;IACpE,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,SAAS,CAAC,OAAO,EAAE,4BAA4B,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACjG,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;IACrF,QAAQ,CAAC,KAAK,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxE;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,4BAA4B,KAAK,MAAM,CAAC;CAC/D;AAED,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAC;AASxE,qBAAa,qBAAqB;;gBAQb,SAAS,EAAE,oBAAoB,EAAE,OAAO,CAAC,EAAE,4BAA4B;IAK1F,IAAW,OAAO,IAAI,kBAAkB,CAKvC;IAEM,MAAM,IAAI,IAAI;IAUR,KAAK,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAS1C,SAAS,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,IAAI;IAU9C,MAAM,CACjB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,IAAI,CAAC,4BAA4B,EAAE,UAAU,CAAC,GACtD,OAAO,CAAC,kBAAkB,CAAC;CAiJ/B"}
1
+ {"version":3,"file":"upload-controller.d.ts","sourceRoot":"","sources":["../src/upload-controller.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,KAAK,wBAAwB,EAC7B,KAAK,eAAe,EACpB,KAAK,4BAA4B,EACjC,KAAK,kBAAkB,EAEvB,KAAK,gBAAgB,EACtB,MAAM,wBAAwB,CAAC;AAEhC,eAAO,MAAM,oBAAoB,EAAE,QAAQ,CAAC,gBAAgB,CAG1D,CAAC;AAEH,eAAO,MAAM,sBAAsB,EAAE,QAAQ,CAAC,gBAAgB,CAG5D,CAAC;AAEH,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,IAAI,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,oEAAoE;IACpE,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACxC,SAAS,CAAC,OAAO,EAAE,4BAA4B,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;IACjG,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;IACrF,QAAQ,CAAC,KAAK,EAAE,gBAAgB,EAAE,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxE;AAED,MAAM,WAAW,4BAA4B;IAC3C,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,4BAA4B,KAAK,MAAM,CAAC;CAC/D;AAED,MAAM,MAAM,mBAAmB,GAAG,CAAC,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAC;AASxE,qBAAa,qBAAqB;;gBAQb,SAAS,EAAE,oBAAoB,EAAE,OAAO,CAAC,EAAE,4BAA4B;IAK1F,IAAW,OAAO,IAAI,kBAAkB,CAKvC;IAEM,MAAM,IAAI,IAAI;IAUR,KAAK,IAAI,OAAO,CAAC,kBAAkB,CAAC;IAS1C,SAAS,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,IAAI;IAU9C,MAAM,CACjB,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,IAAI,CAAC,4BAA4B,EAAE,UAAU,CAAC,GACtD,OAAO,CAAC,kBAAkB,CAAC;CAkJ/B"}
@@ -1 +1 @@
1
- import{STUDIO_CONTRACT_VERSION as e}from"@kumwe/studio-protocol";export const MEDIA_UPLOAD_FAILURE=Object.freeze({defaultMessage:`The upload could not be completed.`,key:`studio.media/upload-failed`});export const MEDIA_UPLOAD_TOO_LARGE=Object.freeze({defaultMessage:`The file is larger than the host allows for this upload.`,key:`studio.media/upload-too-large`});const r=new Set([`authorized`,`requested`,`transferring`,`verifying`]);export class MediaUploadController{#listeners=new Set;#sessionId;#transport;#abortController;#file;#session;constructor(e,t){this.#transport=e,this.#sessionId=t?.sessionId??(()=>crypto.randomUUID())}get session(){if(this.#session===void 0)throw Error(`No upload session has been started.`);return structuredClone(this.#session)}cancel(){let e=this.#session;e===void 0||!r.has(e.state)||(this.#abortController?.abort(),this.#setSession({...structuredClone(e),state:`cancelled`}),this.#transport.abort(e.id).catch(()=>void 0))}async retry(){let e=this.#session,t=this.#file;if(e?.state!==`failed`||t===void 0)throw Error(`Only a failed upload session can be retried.`);return this.#run(t,structuredClone(e.request))}subscribe(e){return this.#listeners.add(e),this.#session!==void 0&&e(this.session),()=>{this.#listeners.delete(e)}}async upload(e,t){if(this.#session!==void 0&&r.has(this.#session.state))throw Error(`An upload session is already in progress.`);if(e.size<1)throw Error(`Cannot upload an empty file.`);let n={byteSize:e.size,filename:t.filename,mediaType:t.mediaType,purpose:t.purpose};return t.checksum!==void 0&&(n.checksum=t.checksum),this.#file=e,this.#run(e,n)}#fail(){let e=this.#session;if(e===void 0)return;let n={contractVersion:e.contractVersion,failure:{code:`studio.media/upload-failed`,message:{...MEDIA_UPLOAD_FAILURE},severity:`error`},id:e.id,kind:`media-upload-session`,progress:{...e.progress},request:{...e.request},state:`failed`};e.plan!==void 0&&(n.plan={...e.plan}),this.#setSession(n)}async#run(t,r){let i=new AbortController;this.#abortController=i;let a=r.byteSize,o={contractVersion:e,id:this.#sessionId(r),kind:`media-upload-session`,request:r};this.#setSession({...o,progress:{totalBytes:a,transferredBytes:0},state:`requested`});try{let e=await this.#transport.authorize(r,i.signal);if(i.signal.aborted)return this.session;if(a>e.maximumBytes)return this.#setSession({...o,failure:{code:`studio.media/upload-too-large`,message:{...MEDIA_UPLOAD_TOO_LARGE},parameters:{byteSize:a,maximumBytes:e.maximumBytes},severity:`error`},plan:e,progress:{totalBytes:a,transferredBytes:0},state:`failed`}),this.session;this.#setSession({...o,plan:e,progress:{totalBytes:a,transferredBytes:0},state:`authorized`}),this.#setSession({...o,plan:e,progress:{totalBytes:a,transferredBytes:0},state:`transferring`});let s=Math.max(1,e.chunkBytes??a),c=0;for(;c<a;){let n=t.slice(c,Math.min(c+s,a));if(await this.#transport.transfer({data:n,offset:c,sessionId:o.id},i.signal),i.signal.aborted)return this.session;c=Math.min(c+n.size,a),this.#setSession({...o,plan:e,progress:{totalBytes:a,transferredBytes:c},state:`transferring`})}this.#setSession({...o,plan:e,progress:{totalBytes:a,transferredBytes:a},state:`verifying`});let l=await this.#transport.finalize(o.id,i.signal);if(i.signal.aborted)return this.session;this.#setSession({...o,asset:l,plan:e,progress:{totalBytes:a,transferredBytes:a},state:`complete`})}catch{i.signal.aborted||this.#fail()}return this.session}#setSession(e){this.#session=e;for(let e of this.#listeners)e(this.session)}}
1
+ import{STUDIO_CONTRACT_VERSION as e}from"@kumwe/studio-protocol";export const MEDIA_UPLOAD_FAILURE=Object.freeze({defaultMessage:`The upload could not be completed.`,key:`studio.media/upload-failed`});export const MEDIA_UPLOAD_TOO_LARGE=Object.freeze({defaultMessage:`The file is larger than the host allows for this upload.`,key:`studio.media/upload-too-large`});const r=new Set([`authorized`,`requested`,`transferring`,`verifying`]);export class MediaUploadController{#listeners=new Set;#sessionId;#transport;#abortController;#file;#session;constructor(e,t){this.#transport=e,this.#sessionId=t?.sessionId??(()=>crypto.randomUUID())}get session(){if(this.#session===void 0)throw Error(`No upload session has been started.`);return structuredClone(this.#session)}cancel(){let e=this.#session;e===void 0||!r.has(e.state)||(this.#abortController?.abort(),this.#setSession({...structuredClone(e),state:`cancelled`}),this.#transport.abort(e.id).catch(()=>void 0))}async retry(){let e=this.#session,t=this.#file;if(e?.state!==`failed`||t===void 0)throw Error(`Only a failed upload session can be retried.`);return this.#run(t,structuredClone(e.request))}subscribe(e){return this.#listeners.add(e),this.#session!==void 0&&e(this.session),()=>{this.#listeners.delete(e)}}async upload(e,t){if(this.#session!==void 0&&r.has(this.#session.state))throw Error(`An upload session is already in progress.`);if(e.size<1)throw Error(`Cannot upload an empty file.`);let n={byteSize:e.size,filename:t.filename,mediaType:t.mediaType,purpose:t.purpose};return t.checksum!==void 0&&(n.checksum=t.checksum),this.#file=e,this.#run(e,n)}#fail(){let e=this.#session;if(e===void 0)return;let n={contractVersion:e.contractVersion,failure:{code:`studio.media/upload-failed`,message:{...MEDIA_UPLOAD_FAILURE},severity:`error`},id:e.id,kind:`media-upload-session`,progress:{...e.progress},request:{...e.request},state:`failed`};e.plan!==void 0&&(n.plan={...e.plan}),this.#setSession(n)}async#run(t,r){let i=new AbortController;this.#abortController=i;let o=r.byteSize,s={contractVersion:e,id:this.#sessionId(r),kind:`media-upload-session`,request:r};this.#setSession({...s,progress:{totalBytes:o,transferredBytes:0},state:`requested`});try{let e=await this.#transport.authorize(r,i.signal);if(i.signal.aborted)return this.session;let c=a(e);if(o>c.maximumBytes)return this.#setSession({...s,failure:{code:`studio.media/upload-too-large`,message:{...MEDIA_UPLOAD_TOO_LARGE},parameters:{byteSize:o,maximumBytes:c.maximumBytes},severity:`error`},plan:c,progress:{totalBytes:o,transferredBytes:0},state:`failed`}),this.session;this.#setSession({...s,plan:c,progress:{totalBytes:o,transferredBytes:0},state:`authorized`}),this.#setSession({...s,plan:c,progress:{totalBytes:o,transferredBytes:0},state:`transferring`});let l=c.chunkBytes??o,u=0;for(;u<o;){let e=t.slice(u,Math.min(u+l,o));if(await this.#transport.transfer({data:e,offset:u,sessionId:s.id},i.signal),i.signal.aborted)return this.session;u=Math.min(u+e.size,o),this.#setSession({...s,plan:c,progress:{totalBytes:o,transferredBytes:u},state:`transferring`})}this.#setSession({...s,plan:c,progress:{totalBytes:o,transferredBytes:o},state:`verifying`});let d=await this.#transport.finalize(s.id,i.signal);if(i.signal.aborted)return this.session;this.#setSession({...s,asset:d,plan:c,progress:{totalBytes:o,transferredBytes:o},state:`complete`})}catch{i.signal.aborted||this.#fail()}return this.session}#setSession(e){this.#session=e;for(let e of this.#listeners)e(this.session)}}function a(e){if(typeof e!=`object`||!e||Array.isArray(e))throw TypeError(`The host returned an invalid bounded upload plan.`);let t=Object.getPrototypeOf(e);if(t!==Object.prototype&&t!==null||Object.getOwnPropertySymbols(e).length!==0)throw TypeError(`The host returned an invalid bounded upload plan.`);let n=Object.getOwnPropertyDescriptors(e);if(!Object.hasOwn(n,`maximumBytes`)||!Object.hasOwn(n,`resumable`)||Object.keys(n).some(e=>![`chunkBytes`,`maximumBytes`,`resumable`].includes(e))||Object.values(n).some(e=>!(`value`in e)||!e.enumerable))throw TypeError(`The host returned an invalid bounded upload plan.`);let r=n.maximumBytes?.value,i=n.resumable?.value,a=Object.hasOwn(n,`chunkBytes`)?n.chunkBytes?.value:void 0;if(typeof r!=`number`||!Number.isInteger(r)||r<1||r>1099511627776||typeof i!=`boolean`||Object.hasOwn(n,`chunkBytes`)&&(typeof a!=`number`||!Number.isInteger(a)||a<1024||a>1073741824))throw TypeError(`The host returned an invalid bounded upload plan.`);return{maximumBytes:r,resumable:i,...typeof a==`number`?{chunkBytes:a}:{}}}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kumwe/studio-media",
3
- "version": "0.1.0-beta.2",
3
+ "version": "0.1.0-beta.4",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/kumwe/studio.git",
@@ -28,7 +28,7 @@
28
28
  "build": "tsc -b && node ../../scripts/minify-package-dist.mjs --package packages/media"
29
29
  },
30
30
  "dependencies": {
31
- "@kumwe/studio-protocol": "0.1.0-beta.2"
31
+ "@kumwe/studio-protocol": "0.1.0-beta.4"
32
32
  },
33
33
  "publishConfig": {
34
34
  "access": "public",