@gjsify/utils 0.3.13 → 0.3.15

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/lib/esm/base64.js CHANGED
@@ -1,72 +1,74 @@
1
+ //#region src/base64.ts
1
2
  const B64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
2
3
  const B64_LOOKUP = new Uint8Array(256);
3
4
  for (let i = 0; i < B64_CHARS.length; i++) B64_LOOKUP[B64_CHARS.charCodeAt(i)] = i;
5
+ /** Decode a base64 string to a binary string. Uses native atob when available. */
4
6
  function atobPolyfill(str) {
5
- if (typeof globalThis.atob === "function") return globalThis.atob(str);
6
- const cleaned = str.replace(/[=\s]/g, "");
7
- let result = "";
8
- let bits = 0;
9
- let collected = 0;
10
- for (let i = 0; i < cleaned.length; i++) {
11
- bits = bits << 6 | B64_LOOKUP[cleaned.charCodeAt(i)];
12
- collected += 6;
13
- if (collected >= 8) {
14
- collected -= 8;
15
- result += String.fromCharCode(bits >> collected & 255);
16
- }
17
- }
18
- return result;
7
+ if (typeof globalThis.atob === "function") return globalThis.atob(str);
8
+ const cleaned = str.replace(/[=\s]/g, "");
9
+ let result = "";
10
+ let bits = 0;
11
+ let collected = 0;
12
+ for (let i = 0; i < cleaned.length; i++) {
13
+ bits = bits << 6 | B64_LOOKUP[cleaned.charCodeAt(i)];
14
+ collected += 6;
15
+ if (collected >= 8) {
16
+ collected -= 8;
17
+ result += String.fromCharCode(bits >> collected & 255);
18
+ }
19
+ }
20
+ return result;
19
21
  }
22
+ /** Encode a binary string to base64. Uses native btoa when available. */
20
23
  function btoaPolyfill(str) {
21
- if (typeof globalThis.btoa === "function") return globalThis.btoa(str);
22
- let result = "";
23
- let i = 0;
24
- for (; i + 2 < str.length; i += 3) {
25
- const n = str.charCodeAt(i) << 16 | str.charCodeAt(i + 1) << 8 | str.charCodeAt(i + 2);
26
- result += B64_CHARS[n >> 18 & 63] + B64_CHARS[n >> 12 & 63] + B64_CHARS[n >> 6 & 63] + B64_CHARS[n & 63];
27
- }
28
- if (i + 1 === str.length) {
29
- const n = str.charCodeAt(i) << 16;
30
- result += B64_CHARS[n >> 18 & 63] + B64_CHARS[n >> 12 & 63] + "==";
31
- } else if (i + 2 === str.length) {
32
- const n = str.charCodeAt(i) << 16 | str.charCodeAt(i + 1) << 8;
33
- result += B64_CHARS[n >> 18 & 63] + B64_CHARS[n >> 12 & 63] + B64_CHARS[n >> 6 & 63] + "=";
34
- }
35
- return result;
24
+ if (typeof globalThis.btoa === "function") return globalThis.btoa(str);
25
+ let result = "";
26
+ let i = 0;
27
+ for (; i + 2 < str.length; i += 3) {
28
+ const n = str.charCodeAt(i) << 16 | str.charCodeAt(i + 1) << 8 | str.charCodeAt(i + 2);
29
+ result += B64_CHARS[n >> 18 & 63] + B64_CHARS[n >> 12 & 63] + B64_CHARS[n >> 6 & 63] + B64_CHARS[n & 63];
30
+ }
31
+ if (i + 1 === str.length) {
32
+ const n = str.charCodeAt(i) << 16;
33
+ result += B64_CHARS[n >> 18 & 63] + B64_CHARS[n >> 12 & 63] + "==";
34
+ } else if (i + 2 === str.length) {
35
+ const n = str.charCodeAt(i) << 16 | str.charCodeAt(i + 1) << 8;
36
+ result += B64_CHARS[n >> 18 & 63] + B64_CHARS[n >> 12 & 63] + B64_CHARS[n >> 6 & 63] + "=";
37
+ }
38
+ return result;
36
39
  }
40
+ /** Decode a base64 string directly to Uint8Array (avoids lossy atob string round-trip). */
37
41
  function base64Decode(str) {
38
- const cleaned = str.replace(/[=\s]/g, "");
39
- const bytes = new Uint8Array(cleaned.length * 3 >> 2);
40
- let bits = 0;
41
- let collected = 0;
42
- let pos = 0;
43
- for (let i = 0; i < cleaned.length; i++) {
44
- bits = bits << 6 | B64_LOOKUP[cleaned.charCodeAt(i)];
45
- collected += 6;
46
- if (collected >= 8) {
47
- collected -= 8;
48
- bytes[pos++] = bits >> collected & 255;
49
- }
50
- }
51
- return bytes.subarray(0, pos);
42
+ const cleaned = str.replace(/[=\s]/g, "");
43
+ const bytes = new Uint8Array(cleaned.length * 3 >> 2);
44
+ let bits = 0;
45
+ let collected = 0;
46
+ let pos = 0;
47
+ for (let i = 0; i < cleaned.length; i++) {
48
+ bits = bits << 6 | B64_LOOKUP[cleaned.charCodeAt(i)];
49
+ collected += 6;
50
+ if (collected >= 8) {
51
+ collected -= 8;
52
+ bytes[pos++] = bits >> collected & 255;
53
+ }
54
+ }
55
+ return bytes.subarray(0, pos);
52
56
  }
57
+ /** Encode a Uint8Array to base64 string. */
53
58
  function base64Encode(bytes) {
54
- let result = "";
55
- const len = bytes.length;
56
- for (let i = 0; i < len; i += 3) {
57
- const b0 = bytes[i];
58
- const b1 = i + 1 < len ? bytes[i + 1] : 0;
59
- const b2 = i + 2 < len ? bytes[i + 2] : 0;
60
- result += B64_CHARS[b0 >> 2];
61
- result += B64_CHARS[(b0 & 3) << 4 | b1 >> 4];
62
- result += i + 1 < len ? B64_CHARS[(b1 & 15) << 2 | b2 >> 6] : "=";
63
- result += i + 2 < len ? B64_CHARS[b2 & 63] : "=";
64
- }
65
- return result;
59
+ let result = "";
60
+ const len = bytes.length;
61
+ for (let i = 0; i < len; i += 3) {
62
+ const b0 = bytes[i];
63
+ const b1 = i + 1 < len ? bytes[i + 1] : 0;
64
+ const b2 = i + 2 < len ? bytes[i + 2] : 0;
65
+ result += B64_CHARS[b0 >> 2];
66
+ result += B64_CHARS[(b0 & 3) << 4 | b1 >> 4];
67
+ result += i + 1 < len ? B64_CHARS[(b1 & 15) << 2 | b2 >> 6] : "=";
68
+ result += i + 2 < len ? B64_CHARS[b2 & 63] : "=";
69
+ }
70
+ return result;
66
71
  }
67
- export {
68
- atobPolyfill,
69
- base64Decode,
70
- base64Encode,
71
- btoaPolyfill
72
- };
72
+
73
+ //#endregion
74
+ export { atobPolyfill, base64Decode, base64Encode, btoaPolyfill };
@@ -1,6 +1,12 @@
1
+ //#region src/byte-array.ts
2
+ /**
3
+ * Convert GLib.Bytes to Uint8Array using GJS's byteArray module.
4
+ * This wraps the GJS-specific `imports.byteArray.fromGBytes()` API
5
+ * with proper typing to eliminate `as any` casts throughout the codebase.
6
+ */
1
7
  function gbytesToUint8Array(bytes) {
2
- return imports.byteArray.fromGBytes(bytes);
8
+ return imports.byteArray.fromGBytes(bytes);
3
9
  }
4
- export {
5
- gbytesToUint8Array
6
- };
10
+
11
+ //#endregion
12
+ export { gbytesToUint8Array };
@@ -1,15 +1,25 @@
1
+ //#region src/callable.ts
2
+ /**
3
+ * Wrap an ES6 class so it supports both the modern `new Cls(...)` pattern and
4
+ * the legacy `Cls.call(thisArg, ...)` pattern.
5
+ *
6
+ * The `apply` trap materialises a temporary instance via `Reflect.construct`
7
+ * (so field initializers and constructor bodies run normally), then transplants
8
+ * its own property descriptors onto `thisArg`. The default Proxy traps pass
9
+ * `construct`, `get` and `getPrototypeOf` straight through, so `new Wrapped()`,
10
+ * `Wrapped.prototype` (consulted by `util.inherits`) and `instance instanceof
11
+ * Wrapped` all behave identically to the underlying class.
12
+ */
1
13
  function makeCallable(Cls) {
2
- return new Proxy(Cls, {
3
- apply(target, thisArg, args) {
4
- const tmp = Reflect.construct(target, args, target);
5
- for (const key of Reflect.ownKeys(tmp)) {
6
- const desc = Object.getOwnPropertyDescriptor(tmp, key);
7
- if (desc) Object.defineProperty(thisArg, key, desc);
8
- }
9
- return thisArg;
10
- }
11
- });
14
+ return new Proxy(Cls, { apply(target, thisArg, args) {
15
+ const tmp = Reflect.construct(target, args, target);
16
+ for (const key of Reflect.ownKeys(tmp)) {
17
+ const desc = Object.getOwnPropertyDescriptor(tmp, key);
18
+ if (desc) Object.defineProperty(thisArg, key, desc);
19
+ }
20
+ return thisArg;
21
+ } });
12
22
  }
13
- export {
14
- makeCallable
15
- };
23
+
24
+ //#endregion
25
+ export { makeCallable };
package/lib/esm/cli.js CHANGED
@@ -1,10 +1,12 @@
1
1
  import GLib from "@girs/glib-2.0";
2
+
3
+ //#region src/cli.ts
2
4
  const byteArray = imports.byteArray;
3
5
  const cli = (commandLine) => {
4
- const [res, out, err, status] = GLib.spawn_command_line_sync(commandLine);
5
- if (err.byteLength) throw new Error(byteArray.toString(err));
6
- return byteArray.toString(out);
7
- };
8
- export {
9
- cli
6
+ const [res, out, err, status] = GLib.spawn_command_line_sync(commandLine);
7
+ if (err.byteLength) throw new Error(byteArray.toString(err));
8
+ return byteArray.toString(out);
10
9
  };
10
+
11
+ //#endregion
12
+ export { cli };
package/lib/esm/defer.js CHANGED
@@ -1,6 +1,11 @@
1
+ //#region src/defer.ts
2
+ /**
3
+ * Defer an event emission to the next macrotask, matching Node.js behavior
4
+ * for server 'listening', 'close', and 'error' events.
5
+ */
1
6
  function deferEmit(emitter, event, ...args) {
2
- setTimeout(() => emitter.emit(event, ...args), 0);
7
+ setTimeout(() => emitter.emit(event, ...args), 0);
3
8
  }
4
- export {
5
- deferEmit
6
- };
9
+
10
+ //#endregion
11
+ export { deferEmit };
@@ -1,35 +1,44 @@
1
- const VALID_ENCODINGS = ["utf8", "ascii", "latin1", "binary", "base64", "base64url", "hex", "ucs2", "utf16le"];
1
+ //#region src/encoding.ts
2
+ const VALID_ENCODINGS = [
3
+ "utf8",
4
+ "ascii",
5
+ "latin1",
6
+ "binary",
7
+ "base64",
8
+ "base64url",
9
+ "hex",
10
+ "ucs2",
11
+ "utf16le"
12
+ ];
13
+ /**
14
+ * Normalize an encoding string to a canonical encoding value.
15
+ * Returns 'utf8' as default for undefined/null/empty input.
16
+ */
2
17
  function normalizeEncoding(enc) {
3
- if (!enc || enc === "utf8" || enc === "utf-8") return "utf8";
4
- const lower = ("" + enc).toLowerCase().replace(/-/g, "");
5
- switch (lower) {
6
- case "utf8":
7
- return "utf8";
8
- case "ascii":
9
- return "ascii";
10
- case "latin1":
11
- case "binary":
12
- return "latin1";
13
- case "base64":
14
- return "base64";
15
- case "base64url":
16
- return "base64url";
17
- case "hex":
18
- return "hex";
19
- case "ucs2":
20
- case "utf16le":
21
- return "utf16le";
22
- default:
23
- return "utf8";
24
- }
18
+ if (!enc || enc === "utf8" || enc === "utf-8") return "utf8";
19
+ const lower = ("" + enc).toLowerCase().replace(/-/g, "");
20
+ switch (lower) {
21
+ case "utf8": return "utf8";
22
+ case "ascii": return "ascii";
23
+ case "latin1":
24
+ case "binary": return "latin1";
25
+ case "base64": return "base64";
26
+ case "base64url": return "base64url";
27
+ case "hex": return "hex";
28
+ case "ucs2":
29
+ case "utf16le": return "utf16le";
30
+ default: return "utf8";
31
+ }
25
32
  }
33
+ /**
34
+ * Check that an encoding string is valid. Throws TypeError if not.
35
+ */
26
36
  function checkEncoding(encoding) {
27
- const lower = ("" + encoding).toLowerCase().replace(/-/g, "");
28
- if (!VALID_ENCODINGS.includes(lower)) {
29
- throw new TypeError(`Unknown encoding: ${encoding}`);
30
- }
37
+ const lower = ("" + encoding).toLowerCase().replace(/-/g, "");
38
+ if (!VALID_ENCODINGS.includes(lower)) {
39
+ throw new TypeError(`Unknown encoding: ${encoding}`);
40
+ }
31
41
  }
32
- export {
33
- checkEncoding,
34
- normalizeEncoding
35
- };
42
+
43
+ //#endregion
44
+ export { checkEncoding, normalizeEncoding };
package/lib/esm/error.js CHANGED
@@ -1,21 +1,32 @@
1
+ //#region src/error.ts
2
+ /**
3
+ * Defines the static Error.captureStackTrace method,
4
+ * this is not present in SpiderMonkey because it comes from V8
5
+ * @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error#static_methods
6
+ * @see https://nodejs.org/dist/latest-v18.x/docs/api/errors.html#errorcapturestacktracetargetobject-constructoropt
7
+ */
1
8
  const initErrorV8Methods = (ErrorConstructor) => {
2
- if (!Error.captureStackTrace) {
3
- Error.captureStackTrace = function(targetObject, constructorOpt) {
4
- const container = new Error();
5
- const target = constructorOpt || targetObject;
6
- Object.defineProperty(target, "stack", {
7
- configurable: true,
8
- get: function getStack() {
9
- var stack = container.stack;
10
- Object.defineProperty(this, "stack", {
11
- value: stack
12
- });
13
- return stack;
14
- }
15
- });
16
- };
17
- }
18
- };
19
- export {
20
- initErrorV8Methods
9
+ if (!Error.captureStackTrace) {
10
+ /**
11
+ * A non-standard V8 function.
12
+ * Creates a .stack property on targetObject, which when accessed returns a string representing the location in the code at which Error.captureStackTrace() was called.
13
+ * @param targetObject
14
+ * @param constructorOpt
15
+ */
16
+ Error.captureStackTrace = function(targetObject, constructorOpt) {
17
+ const container = new Error();
18
+ const target = constructorOpt || targetObject;
19
+ Object.defineProperty(target, "stack", {
20
+ configurable: true,
21
+ get: function getStack() {
22
+ var stack = container.stack;
23
+ Object.defineProperty(this, "stack", { value: stack });
24
+ return stack;
25
+ }
26
+ });
27
+ };
28
+ }
21
29
  };
30
+
31
+ //#endregion
32
+ export { initErrorV8Methods };
package/lib/esm/file.js CHANGED
@@ -1,13 +1,15 @@
1
1
  import GLib from "@girs/glib-2.0";
2
+
3
+ //#region src/file.ts
2
4
  const byteArray = imports.byteArray;
3
5
  const readJSON = (path) => {
4
- const [ok, contents] = GLib.file_get_contents(path);
5
- if (ok) {
6
- const map = JSON.parse(byteArray.toString(contents));
7
- return map;
8
- }
9
- throw new Error(`Error on require "${path}"`);
10
- };
11
- export {
12
- readJSON
6
+ const [ok, contents] = GLib.file_get_contents(path);
7
+ if (ok) {
8
+ const map = JSON.parse(byteArray.toString(contents));
9
+ return map;
10
+ }
11
+ throw new Error(`Error on require "${path}"`);
13
12
  };
13
+
14
+ //#endregion
15
+ export { readJSON };
package/lib/esm/fs.js CHANGED
@@ -1,22 +1,24 @@
1
1
  import Gio from "@girs/gio-2.0";
2
2
  import GioUnix from "@girs/giounix-2.0";
3
+
4
+ //#region src/fs.ts
5
+ /** Check if a file descriptor exists */
3
6
  const existsFD = (fd) => {
4
- try {
5
- let stream = GioUnix.InputStream.new(fd, false);
6
- stream.close(null);
7
- return true;
8
- } catch (error) {
9
- return false;
10
- }
7
+ try {
8
+ let stream = GioUnix.InputStream.new(fd, false);
9
+ stream.close(null);
10
+ return true;
11
+ } catch (error) {
12
+ return false;
13
+ }
11
14
  };
12
15
  function existsSync(path) {
13
- if (typeof path !== "string" || path === "") {
14
- return false;
15
- }
16
- const file = Gio.File.new_for_path(path);
17
- return file.query_exists(null);
16
+ if (typeof path !== "string" || path === "") {
17
+ return false;
18
+ }
19
+ const file = Gio.File.new_for_path(path);
20
+ return file.query_exists(null);
18
21
  }
19
- export {
20
- existsFD,
21
- existsSync
22
- };
22
+
23
+ //#endregion
24
+ export { existsFD, existsSync };