@gjsify/fetch 0.18.0 → 0.20.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.
@@ -1 +1 @@
1
- import{XMLHttpRequest as e,XMLHttpRequestUpload as t}from"../xhr.js";globalThis.XMLHttpRequest===void 0&&(globalThis.XMLHttpRequest=e),globalThis.XMLHttpRequestUpload===void 0&&(globalThis.XMLHttpRequestUpload=t);
1
+ import{XMLHttpRequest as e,XMLHttpRequestUpload as t}from"../xhr.js";import n from"gi://GLib?version=2.0";globalThis.XMLHttpRequest===void 0&&(globalThis.XMLHttpRequest=e),globalThis.XMLHttpRequestUpload===void 0&&(globalThis.XMLHttpRequestUpload=t);const r=globalThis.URL;if(r&&r.__gjsify_objecturl!==!0){let e=new Map,t=r.createObjectURL?.bind(r),i=r.revokeObjectURL?.bind(r);r.createObjectURL=n=>{let r=n?._tmpPath;if(typeof r==`string`&&r.length>0){let t=`file://${r}`;return e.set(t,r),t}return t?t(n):`file:///dev/null`},r.revokeObjectURL=t=>{let r=e.get(t);if(r){try{n.unlink(r)}catch{}e.delete(t)}else i&&i(t)},r.__gjsify_objecturl=!0}
package/lib/esm/xhr.js CHANGED
@@ -1,2 +1,2 @@
1
- import"./_virtual/_rolldown/runtime.js";import e from"./index.js";import t from"gi://GLib?version=2.0";let n=0;function guessBlobExt(e){let t=e.toLowerCase().split(`?`)[0],n=t.lastIndexOf(`.`),r=n>-1?t.slice(n):``;switch(r){case`.png`:case`.jpg`:case`.jpeg`:case`.gif`:case`.webp`:case`.svg`:case`.bmp`:case`.ttf`:case`.otf`:case`.woff`:case`.woff2`:case`.mp3`:case`.wav`:case`.ogg`:case`.flac`:case`.m4a`:case`.mp4`:case`.webm`:case`.mkv`:case`.xml`:case`.tmx`:case`.json`:return r;default:return`.bin`}}function writeBlobToTempFile(e,r){let i=t.build_filenamev([t.get_tmp_dir(),`gjsify-blob-${n++}${guessBlobExt(r)}`]);return t.file_set_contents(i,e),i}const r=0,i=1,a=2,o=3,s=4;var XMLHttpRequest=class extends EventTarget{static UNSENT=0;static OPENED=1;static HEADERS_RECEIVED=2;static LOADING=3;static DONE=4;UNSENT=0;OPENED=1;HEADERS_RECEIVED=2;LOADING=3;DONE=4;readyState=0;status=0;statusText=``;responseType=``;responseText=``;response=null;responseURL=``;withCredentials=!1;timeout=0;upload=new XMLHttpRequestUpload;onreadystatechange=null;onload=null;onerror=null;onabort=null;ontimeout=null;onloadstart=null;onloadend=null;onprogress=null;_method=`GET`;_url=``;_headers=new Map;_responseHeaders=new Map;_controller=new AbortController;_aborted=!1;_timeoutId=null;open(e,t,n=!0,r,i){this._method=e.toUpperCase(),this._url=t,this._headers.clear(),this._responseHeaders.clear(),this._aborted=!1,this._controller=new AbortController,this._setReadyState(1)}setRequestHeader(e,t){if(this.readyState<1)throw new DOMException(`Must open first`,`InvalidStateError`);this._headers.set(e.toLowerCase(),t)}getResponseHeader(e){return this._responseHeaders.get(e.toLowerCase())??null}getAllResponseHeaders(){let e=[];return this._responseHeaders.forEach((t,n)=>e.push(`${n}: ${t}`)),e.join(`\r
2
- `)}send(t){if(this.readyState!==1)throw new DOMException(`Must open first`,`InvalidStateError`);if(this._aborted)return;let n={};this._headers.forEach((e,t)=>{n[t]=e});let r={method:this._method,headers:n,credentials:this.withCredentials?`include`:`omit`,signal:this._controller.signal};t!=null&&this._method!==`GET`&&this._method!==`HEAD`&&(r.body=t),this.timeout>0&&(this._timeoutId=setTimeout(()=>{this._controller.abort(),this._onTimeout()},this.timeout)),this.dispatchEvent(new Event(`loadstart`)),this.onloadstart&&this.onloadstart(new ProgressEvent(`loadstart`)),e(this._url,r).then(async e=>{if(!this._aborted){switch(this._timeoutId&&=(clearTimeout(this._timeoutId),null),this.status=e.status,this.statusText=e.statusText,this.responseURL=e.url,e.headers.forEach((e,t)=>{this._responseHeaders.set(t.toLowerCase(),e)}),this._setReadyState(2),this._setReadyState(3),this.responseType){case`arraybuffer`:{let t=await e.arrayBuffer();this.response=t,this.responseText=``;break}case`blob`:{let t=await e.arrayBuffer(),n=writeBlobToTempFile(new Uint8Array(t),this._url),r=new Blob([t],{type:this._responseHeaders.get(`content-type`)??``});r._tmpPath=n,this.response=r,this.responseText=``;break}case`json`:{let t=await e.text();this.responseText=``;try{this.response=t.length>0?JSON.parse(t):null}catch{this.response=null}break}case`document`:{let t=await e.text();this.responseText=t,this.response=t;break}default:{let t=await e.text(),n=t.charCodeAt(0)===65279?t.slice(1):t;this.responseText=n,this.response=n;break}}this._setReadyState(4),this.dispatchEvent(new ProgressEvent(`load`)),this.dispatchEvent(new ProgressEvent(`loadend`)),this.onload&&this.onload(new ProgressEvent(`load`)),this.onloadend&&this.onloadend(new ProgressEvent(`loadend`))}}).catch(e=>{if(this._timeoutId&&=(clearTimeout(this._timeoutId),null),this._aborted)return;this._setReadyState(4);let t=new ProgressEvent(`error`);this.dispatchEvent(t),this.onerror&&this.onerror(t),this.onloadend&&this.onloadend(new ProgressEvent(`loadend`))})}abort(){if(this._aborted)return;this._aborted=!0,this._timeoutId&&=(clearTimeout(this._timeoutId),null),this._controller.abort(),this.readyState!==0&&this.readyState!==4&&(this._setReadyState(4),this.status=0);let e=new ProgressEvent(`abort`);this.dispatchEvent(e),this.onabort&&this.onabort(e),this.onloadend&&this.onloadend(new ProgressEvent(`loadend`))}overrideMimeType(e){}_onTimeout(){if(this._aborted)return;this._aborted=!0,this._setReadyState(4);let e=new ProgressEvent(`timeout`);this.dispatchEvent(e),this.ontimeout&&this.ontimeout(e)}_setReadyState(e){this.readyState=e;let t=new Event(`readystatechange`);this.dispatchEvent(t),this.onreadystatechange&&this.onreadystatechange(t)}},XMLHttpRequestUpload=class extends EventTarget{onprogress=null;onloadstart=null;onloadend=null;onload=null;onerror=null;onabort=null;ontimeout=null};export{s as DONE,a as HEADERS_RECEIVED,o as LOADING,i as OPENED,r as UNSENT,XMLHttpRequest,XMLHttpRequestUpload};
1
+ import"./_virtual/_rolldown/runtime.js";import e from"./index.js";import t from"gi://GLib?version=2.0";import{Event as n,EventTarget as r,ProgressEvent as i}from"@gjsify/dom-events";let a=0;function guessBlobExt(e){let t=e.toLowerCase().split(`?`)[0],n=t.lastIndexOf(`.`),r=n>-1?t.slice(n):``;switch(r){case`.png`:case`.jpg`:case`.jpeg`:case`.gif`:case`.webp`:case`.svg`:case`.bmp`:case`.ttf`:case`.otf`:case`.woff`:case`.woff2`:case`.mp3`:case`.wav`:case`.ogg`:case`.flac`:case`.m4a`:case`.mp4`:case`.webm`:case`.mkv`:case`.xml`:case`.tmx`:case`.json`:return r;default:return`.bin`}}function writeBlobToTempFile(e,n){let r=t.build_filenamev([t.get_tmp_dir(),`gjsify-blob-${a++}${guessBlobExt(n)}`]);return t.file_set_contents(r,e),r}const o=0,s=1,c=2,l=3,u=4;var XMLHttpRequest=class extends r{static UNSENT=0;static OPENED=1;static HEADERS_RECEIVED=2;static LOADING=3;static DONE=4;UNSENT=0;OPENED=1;HEADERS_RECEIVED=2;LOADING=3;DONE=4;readyState=0;status=0;statusText=``;responseType=``;responseText=``;response=null;responseURL=``;withCredentials=!1;timeout=0;upload=new XMLHttpRequestUpload;onreadystatechange=null;onload=null;onerror=null;onabort=null;ontimeout=null;onloadstart=null;onloadend=null;onprogress=null;_method=`GET`;_url=``;_headers=new Map;_responseHeaders=new Map;_controller=new AbortController;_aborted=!1;_timeoutId=null;open(e,t,n=!0,r,i){this._method=e.toUpperCase(),this._url=t,this._headers.clear(),this._responseHeaders.clear(),this._aborted=!1,this._controller=new AbortController,this._setReadyState(1)}setRequestHeader(e,t){if(this.readyState<1)throw new DOMException(`Must open first`,`InvalidStateError`);this._headers.set(e.toLowerCase(),t)}getResponseHeader(e){return this._responseHeaders.get(e.toLowerCase())??null}getAllResponseHeaders(){let e=[];return this._responseHeaders.forEach((t,n)=>e.push(`${n}: ${t}`)),e.join(`\r
2
+ `)}send(t){if(this.readyState!==1)throw new DOMException(`Must open first`,`InvalidStateError`);if(this._aborted)return;let r={};this._headers.forEach((e,t)=>{r[t]=e});let a={method:this._method,headers:r,credentials:this.withCredentials?`include`:`omit`,signal:this._controller.signal};t!=null&&this._method!==`GET`&&this._method!==`HEAD`&&(a.body=t),this.timeout>0&&(this._timeoutId=setTimeout(()=>{this._controller.abort(),this._onTimeout()},this.timeout)),this.dispatchEvent(new n(`loadstart`)),this.onloadstart&&this.onloadstart(new i(`loadstart`)),e(this._url,a).then(async e=>{if(!this._aborted){switch(this._timeoutId&&=(clearTimeout(this._timeoutId),null),this.status=e.status,this.statusText=e.statusText,this.responseURL=e.url,e.headers.forEach((e,t)=>{this._responseHeaders.set(t.toLowerCase(),e)}),this._setReadyState(2),this._setReadyState(3),this.responseType){case`arraybuffer`:{let t=await e.arrayBuffer();this.response=t,this.responseText=``;break}case`blob`:{let t=await e.arrayBuffer(),n=writeBlobToTempFile(new Uint8Array(t),this._url),r=new Blob([t],{type:this._responseHeaders.get(`content-type`)??``});r._tmpPath=n,this.response=r,this.responseText=``;break}case`json`:{let t=await e.text();this.responseText=``;try{this.response=t.length>0?JSON.parse(t):null}catch{this.response=null}break}case`document`:{let t=await e.text();this.responseText=t,this.response=t;break}default:{let t=await e.text(),n=t.charCodeAt(0)===65279?t.slice(1):t;this.responseText=n,this.response=n;break}}this._setReadyState(4),this.dispatchEvent(new i(`load`)),this.dispatchEvent(new i(`loadend`)),this.onload&&this.onload(new i(`load`)),this.onloadend&&this.onloadend(new i(`loadend`))}}).catch(e=>{if(this._timeoutId&&=(clearTimeout(this._timeoutId),null),this._aborted)return;this._setReadyState(4);let t=new i(`error`);this.dispatchEvent(t),this.onerror&&this.onerror(t),this.onloadend&&this.onloadend(new i(`loadend`))})}abort(){if(this._aborted)return;this._aborted=!0,this._timeoutId&&=(clearTimeout(this._timeoutId),null),this._controller.abort(),this.readyState!==0&&this.readyState!==4&&(this._setReadyState(4),this.status=0);let e=new i(`abort`);this.dispatchEvent(e),this.onabort&&this.onabort(e),this.onloadend&&this.onloadend(new i(`loadend`))}overrideMimeType(e){}_onTimeout(){if(this._aborted)return;this._aborted=!0,this._setReadyState(4);let e=new i(`timeout`);this.dispatchEvent(e),this.ontimeout&&this.ontimeout(e)}_setReadyState(e){this.readyState=e;let t=new n(`readystatechange`);this.dispatchEvent(t),this.onreadystatechange&&this.onreadystatechange(t)}},XMLHttpRequestUpload=class extends r{onprogress=null;onloadstart=null;onloadend=null;onload=null;onerror=null;onabort=null;ontimeout=null};export{u as DONE,c as HEADERS_RECEIVED,l as LOADING,s as OPENED,o as UNSENT,XMLHttpRequest,XMLHttpRequestUpload};
@@ -9,6 +9,7 @@
9
9
  // and returns a `file://` URL that HTMLImageElement etc. can load.
10
10
  //
11
11
  // There is no URL monkey-patching here — URL owns createObjectURL natively.
12
+ import GLib from 'gi://GLib?version=2.0';
12
13
  import { XMLHttpRequest, XMLHttpRequestUpload } from '../xhr.js';
13
14
  if (typeof globalThis.XMLHttpRequest === 'undefined') {
14
15
  globalThis.XMLHttpRequest = XMLHttpRequest;
@@ -16,3 +17,36 @@ if (typeof globalThis.XMLHttpRequest === 'undefined') {
16
17
  if (typeof globalThis.XMLHttpRequestUpload === 'undefined') {
17
18
  globalThis.XMLHttpRequestUpload = XMLHttpRequestUpload;
18
19
  }
20
+ const urlCtor = globalThis.URL;
21
+ if (urlCtor && urlCtor.__gjsify_objecturl !== true) {
22
+ const objectUrlPaths = new Map();
23
+ const nativeCreate = urlCtor.createObjectURL?.bind(urlCtor);
24
+ const nativeRevoke = urlCtor.revokeObjectURL?.bind(urlCtor);
25
+ urlCtor.createObjectURL = (blob) => {
26
+ const tmp = blob?._tmpPath;
27
+ if (typeof tmp === 'string' && tmp.length > 0) {
28
+ const url = `file://${tmp}`;
29
+ objectUrlPaths.set(url, tmp);
30
+ return url;
31
+ }
32
+ // No temp-file backing — defer to the runtime-native impl if one exists
33
+ // (a real blob: URL is at least valid), else a fail-fast sentinel.
34
+ return nativeCreate ? nativeCreate(blob) : 'file:///dev/null';
35
+ };
36
+ urlCtor.revokeObjectURL = (url) => {
37
+ const path = objectUrlPaths.get(url);
38
+ if (path) {
39
+ try {
40
+ GLib.unlink(path);
41
+ }
42
+ catch {
43
+ // best-effort temp-file cleanup
44
+ }
45
+ objectUrlPaths.delete(url);
46
+ }
47
+ else if (nativeRevoke) {
48
+ nativeRevoke(url);
49
+ }
50
+ };
51
+ urlCtor.__gjsify_objecturl = true;
52
+ }
package/lib/xhr.d.ts CHANGED
@@ -1,3 +1,4 @@
1
+ import { Event, EventTarget, ProgressEvent } from '@gjsify/dom-events';
1
2
  export declare const UNSENT = 0;
2
3
  export declare const OPENED = 1;
3
4
  export declare const HEADERS_RECEIVED = 2;
package/lib/xhr.js CHANGED
@@ -8,6 +8,15 @@
8
8
  // Reference: https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest
9
9
  import GLib from 'gi://GLib?version=2.0';
10
10
  import fetch from './index.js';
11
+ // Use gjsify's OWN event classes, not whatever is on `globalThis`. This XHR runs
12
+ // on GJS and on the `--app node` reverse bridge; on the latter `globalThis`
13
+ // carries the runtime-native `Event`/`EventTarget` (Node) while `ProgressEvent`
14
+ // is gjsify's, so `nativeEventTarget.dispatchEvent(gjsifyProgressEvent)` threw
15
+ // `ERR_INVALID_ARG_TYPE`. Extending gjsify's `EventTarget` and dispatching
16
+ // gjsify's `Event`/`ProgressEvent` keeps the hierarchy internally consistent on
17
+ // every target (on GJS these ARE the globals the register installs, so no
18
+ // behaviour change). Same pattern @gjsify/dom-elements uses for its DOM classes.
19
+ import { Event, EventTarget, ProgressEvent } from '@gjsify/dom-events';
11
20
  let _blobCounter = 0;
12
21
  function guessBlobExt(url) {
13
22
  const lower = url.toLowerCase().split('?')[0];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gjsify/fetch",
3
- "version": "0.18.0",
3
+ "version": "0.20.0",
4
4
  "description": "Web and Node.js fetch module for Gjs",
5
5
  "module": "lib/esm/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -51,8 +51,8 @@
51
51
  "fetch"
52
52
  ],
53
53
  "devDependencies": {
54
- "@gjsify/cli": "^0.18.0",
55
- "@gjsify/unit": "^0.18.0",
54
+ "@gjsify/cli": "^0.20.0",
55
+ "@gjsify/unit": "^0.20.0",
56
56
  "@types/node": "^25.9.2",
57
57
  "typescript": "^6.0.3"
58
58
  },
@@ -61,10 +61,11 @@
61
61
  "@girs/gjs": "^4.1.0",
62
62
  "@girs/glib-2.0": "^4.1.0",
63
63
  "@girs/soup-3.0": "^4.1.0",
64
- "@gjsify/formdata": "^0.18.0",
65
- "@gjsify/http": "^0.18.0",
66
- "@gjsify/url": "^0.18.0",
67
- "@gjsify/utils": "^0.18.0"
64
+ "@gjsify/dom-events": "^0.20.0",
65
+ "@gjsify/formdata": "^0.20.0",
66
+ "@gjsify/http": "^0.20.0",
67
+ "@gjsify/url": "^0.20.0",
68
+ "@gjsify/utils": "^0.20.0"
68
69
  },
69
70
  "gjsify": {
70
71
  "runtimes": {