@gjsify/utils 0.3.13 → 0.3.14
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 +63 -61
- package/lib/esm/byte-array.js +10 -4
- package/lib/esm/callable.js +23 -13
- package/lib/esm/cli.js +8 -6
- package/lib/esm/defer.js +9 -4
- package/lib/esm/encoding.js +40 -31
- package/lib/esm/error.js +30 -19
- package/lib/esm/file.js +11 -9
- package/lib/esm/fs.js +18 -16
- package/lib/esm/gio-errors.js +106 -125
- package/lib/esm/gio.js +44 -31
- package/lib/esm/globals.js +11 -6
- package/lib/esm/index.js +20 -18
- package/lib/esm/main-loop.js +40 -22
- package/lib/esm/message.js +9 -9
- package/lib/esm/microtask.js +5 -4
- package/lib/esm/next-tick.js +53 -48
- package/lib/esm/path.js +34 -36
- package/lib/esm/structured-clone.js +187 -157
- package/package.json +6 -6
package/lib/esm/path.js
CHANGED
|
@@ -1,50 +1,48 @@
|
|
|
1
|
-
import Gio from "@girs/gio-2.0";
|
|
2
1
|
import GLib from "@girs/glib-2.0";
|
|
2
|
+
import Gio from "@girs/gio-2.0";
|
|
3
|
+
|
|
4
|
+
//#region src/path.ts
|
|
3
5
|
const { File } = Gio;
|
|
4
6
|
const _getProgramDir = (programFile) => {
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
const info = programFile.query_info("standard::", Gio.FileQueryInfoFlags.NOFOLLOW_SYMLINKS, null);
|
|
8
|
+
if (info.get_is_symlink()) {
|
|
9
|
+
const symlinkFile = programFile.get_parent().resolve_relative_path(info.get_symlink_target());
|
|
10
|
+
return symlinkFile.get_parent();
|
|
11
|
+
} else {
|
|
12
|
+
return programFile.get_parent();
|
|
13
|
+
}
|
|
12
14
|
};
|
|
13
15
|
const resolve = (dir, ...filenames) => {
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
16
|
+
let file = File.new_for_path(dir);
|
|
17
|
+
for (const filename of filenames) {
|
|
18
|
+
file = file.resolve_relative_path(filename);
|
|
19
|
+
}
|
|
20
|
+
return file;
|
|
19
21
|
};
|
|
20
22
|
const getProgramExe = () => {
|
|
21
|
-
|
|
22
|
-
|
|
23
|
+
const currentDir = GLib.get_current_dir();
|
|
24
|
+
return File.new_for_path(currentDir).resolve_relative_path(imports.system.programInvocationName);
|
|
23
25
|
};
|
|
24
26
|
const getProgramDir = () => {
|
|
25
|
-
|
|
27
|
+
return _getProgramDir(getProgramExe()).get_path();
|
|
26
28
|
};
|
|
27
29
|
const getPathSeparator = () => {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
+
const currentDir = GLib.get_current_dir();
|
|
31
|
+
return /^\//.test(currentDir) ? "/" : "\\";
|
|
30
32
|
};
|
|
31
33
|
const getNodeModulesPath = () => {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
};
|
|
44
|
-
export {
|
|
45
|
-
getNodeModulesPath,
|
|
46
|
-
getPathSeparator,
|
|
47
|
-
getProgramDir,
|
|
48
|
-
getProgramExe,
|
|
49
|
-
resolve
|
|
34
|
+
let dir = File.new_for_path(getProgramDir());
|
|
35
|
+
let found = false;
|
|
36
|
+
do {
|
|
37
|
+
dir = dir.resolve_relative_path("..");
|
|
38
|
+
const nodeModulesDir = dir.resolve_relative_path("node_modules");
|
|
39
|
+
found = nodeModulesDir.query_exists(null);
|
|
40
|
+
if (found) {
|
|
41
|
+
dir = nodeModulesDir;
|
|
42
|
+
}
|
|
43
|
+
} while (dir.has_parent(null) && !found);
|
|
44
|
+
return dir;
|
|
50
45
|
};
|
|
46
|
+
|
|
47
|
+
//#endregion
|
|
48
|
+
export { getNodeModulesPath, getPathSeparator, getProgramDir, getProgramExe, resolve };
|
|
@@ -1,169 +1,199 @@
|
|
|
1
|
+
//#region src/structured-clone.ts
|
|
1
2
|
const { toString } = Object.prototype;
|
|
3
|
+
/**
|
|
4
|
+
* Get the internal [[Class]] tag of a value via Object.prototype.toString.
|
|
5
|
+
* Returns e.g. "Array", "Date", "RegExp", "Map", "Error", "Uint8Array", etc.
|
|
6
|
+
*/
|
|
2
7
|
function classOf(value) {
|
|
3
|
-
|
|
8
|
+
return toString.call(value).slice(8, -1);
|
|
4
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* Throw a DataCloneError. Uses DOMException if available, otherwise a plain Error.
|
|
12
|
+
*/
|
|
5
13
|
function throwDataCloneError(message) {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
14
|
+
const DOMExceptionCtor = globalThis.DOMException;
|
|
15
|
+
if (typeof DOMExceptionCtor === "function") {
|
|
16
|
+
throw new DOMExceptionCtor(message, "DataCloneError");
|
|
17
|
+
}
|
|
18
|
+
const error = new Error(message);
|
|
19
|
+
error.name = "DataCloneError";
|
|
20
|
+
throw error;
|
|
13
21
|
}
|
|
22
|
+
/** Error constructors that can be cloned per the HTML spec. */
|
|
14
23
|
const ERROR_CONSTRUCTORS = {
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
24
|
+
Error,
|
|
25
|
+
EvalError,
|
|
26
|
+
RangeError,
|
|
27
|
+
ReferenceError,
|
|
28
|
+
SyntaxError,
|
|
29
|
+
TypeError,
|
|
30
|
+
URIError
|
|
22
31
|
};
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
/** TypedArray constructors for reconstruction. */
|
|
33
|
+
const TYPED_ARRAY_TAGS = new Set([
|
|
34
|
+
"Int8Array",
|
|
35
|
+
"Uint8Array",
|
|
36
|
+
"Uint8ClampedArray",
|
|
37
|
+
"Int16Array",
|
|
38
|
+
"Uint16Array",
|
|
39
|
+
"Int32Array",
|
|
40
|
+
"Uint32Array",
|
|
41
|
+
"Float32Array",
|
|
42
|
+
"Float64Array",
|
|
43
|
+
"BigInt64Array",
|
|
44
|
+
"BigUint64Array"
|
|
35
45
|
]);
|
|
46
|
+
/**
|
|
47
|
+
* Internal recursive clone with circular/shared reference tracking.
|
|
48
|
+
* The `seen` map stores original→clone mappings. It must be populated
|
|
49
|
+
* with the clone BEFORE recursing into children to handle circular refs.
|
|
50
|
+
*/
|
|
36
51
|
function internalClone(value, seen) {
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
52
|
+
if (value === null || value === undefined) return value;
|
|
53
|
+
const type = typeof value;
|
|
54
|
+
if (type === "boolean" || type === "number" || type === "string" || type === "bigint") {
|
|
55
|
+
return value;
|
|
56
|
+
}
|
|
57
|
+
if (type === "symbol") {
|
|
58
|
+
throwDataCloneError("Symbol cannot be cloned");
|
|
59
|
+
}
|
|
60
|
+
if (type === "function") {
|
|
61
|
+
throwDataCloneError("Function cannot be cloned");
|
|
62
|
+
}
|
|
63
|
+
const obj = value;
|
|
64
|
+
if (seen.has(obj)) return seen.get(obj);
|
|
65
|
+
const tag = classOf(obj);
|
|
66
|
+
if (tag === "Date") {
|
|
67
|
+
return new Date(obj.getTime());
|
|
68
|
+
}
|
|
69
|
+
if (tag === "RegExp") {
|
|
70
|
+
return new RegExp(obj.source, obj.flags);
|
|
71
|
+
}
|
|
72
|
+
if (tag === "Boolean") return Object(obj.valueOf());
|
|
73
|
+
if (tag === "Number") return Object(obj.valueOf());
|
|
74
|
+
if (tag === "String") return Object(obj.valueOf());
|
|
75
|
+
if (tag === "BigInt") return Object(BigInt.prototype.valueOf.call(obj));
|
|
76
|
+
if (obj instanceof Error) {
|
|
77
|
+
const src = obj;
|
|
78
|
+
const ctorName = src.constructor?.name;
|
|
79
|
+
const Ctor = ctorName && ERROR_CONSTRUCTORS[ctorName] || ERROR_CONSTRUCTORS[src.name] || Error;
|
|
80
|
+
const cloned = new Ctor(src.message);
|
|
81
|
+
cloned.name = src.name;
|
|
82
|
+
if ("cause" in src) {
|
|
83
|
+
Object.defineProperty(cloned, "cause", {
|
|
84
|
+
value: internalClone(src.cause, seen),
|
|
85
|
+
writable: true,
|
|
86
|
+
enumerable: false,
|
|
87
|
+
configurable: true
|
|
88
|
+
});
|
|
89
|
+
}
|
|
90
|
+
return cloned;
|
|
91
|
+
}
|
|
92
|
+
if (tag === "DOMException") {
|
|
93
|
+
const DOMExceptionCtor = globalThis.DOMException;
|
|
94
|
+
if (typeof DOMExceptionCtor === "function") {
|
|
95
|
+
const src = obj;
|
|
96
|
+
return new DOMExceptionCtor(src.message, src.name);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
if (tag === "ArrayBuffer") {
|
|
100
|
+
const src = obj;
|
|
101
|
+
const cloned = src.slice(0);
|
|
102
|
+
seen.set(obj, cloned);
|
|
103
|
+
return cloned;
|
|
104
|
+
}
|
|
105
|
+
if (tag === "SharedArrayBuffer") {
|
|
106
|
+
return obj;
|
|
107
|
+
}
|
|
108
|
+
if (tag === "DataView") {
|
|
109
|
+
const src = obj;
|
|
110
|
+
const bufferClone = internalClone(src.buffer, seen);
|
|
111
|
+
const cloned = new DataView(bufferClone, src.byteOffset, src.byteLength);
|
|
112
|
+
seen.set(obj, cloned);
|
|
113
|
+
return cloned;
|
|
114
|
+
}
|
|
115
|
+
if (TYPED_ARRAY_TAGS.has(tag)) {
|
|
116
|
+
const src = obj;
|
|
117
|
+
const bufferClone = internalClone(src.buffer, seen);
|
|
118
|
+
const Ctor = src.constructor;
|
|
119
|
+
const cloned = new Ctor(bufferClone, src.byteOffset, src.length);
|
|
120
|
+
seen.set(obj, cloned);
|
|
121
|
+
return cloned;
|
|
122
|
+
}
|
|
123
|
+
if (tag === "Map") {
|
|
124
|
+
const cloned = new Map();
|
|
125
|
+
seen.set(obj, cloned);
|
|
126
|
+
for (const [k, v] of obj) {
|
|
127
|
+
cloned.set(internalClone(k, seen), internalClone(v, seen));
|
|
128
|
+
}
|
|
129
|
+
return cloned;
|
|
130
|
+
}
|
|
131
|
+
if (tag === "Set") {
|
|
132
|
+
const cloned = new Set();
|
|
133
|
+
seen.set(obj, cloned);
|
|
134
|
+
for (const v of obj) {
|
|
135
|
+
cloned.add(internalClone(v, seen));
|
|
136
|
+
}
|
|
137
|
+
return cloned;
|
|
138
|
+
}
|
|
139
|
+
{
|
|
140
|
+
const g = globalThis;
|
|
141
|
+
const BlobCtor = g.Blob;
|
|
142
|
+
const FileCtor = g.File;
|
|
143
|
+
if (typeof FileCtor === "function" && obj instanceof FileCtor) {
|
|
144
|
+
const src = obj;
|
|
145
|
+
return new FileCtor([obj], src.name, {
|
|
146
|
+
type: src.type,
|
|
147
|
+
lastModified: src.lastModified
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
if (typeof BlobCtor === "function" && obj instanceof BlobCtor) {
|
|
151
|
+
const src = obj;
|
|
152
|
+
return new BlobCtor([obj], { type: src.type });
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
if (obj instanceof WeakMap) throwDataCloneError("WeakMap cannot be cloned");
|
|
156
|
+
if (obj instanceof WeakSet) throwDataCloneError("WeakSet cannot be cloned");
|
|
157
|
+
if (obj instanceof WeakRef) throwDataCloneError("WeakRef cannot be cloned");
|
|
158
|
+
if (typeof globalThis.Promise === "function" && obj instanceof Promise) {
|
|
159
|
+
throwDataCloneError("Promise cannot be cloned");
|
|
160
|
+
}
|
|
161
|
+
if (tag === "Array") {
|
|
162
|
+
const src = obj;
|
|
163
|
+
const cloned = [];
|
|
164
|
+
seen.set(obj, cloned);
|
|
165
|
+
for (let i = 0; i < src.length; i++) {
|
|
166
|
+
if (i in src) {
|
|
167
|
+
cloned[i] = internalClone(src[i], seen);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return cloned;
|
|
171
|
+
}
|
|
172
|
+
if (tag === "Object" || typeof obj === "object") {
|
|
173
|
+
const cloned = {};
|
|
174
|
+
seen.set(obj, cloned);
|
|
175
|
+
for (const key of Object.keys(obj)) {
|
|
176
|
+
cloned[key] = internalClone(obj[key], seen);
|
|
177
|
+
}
|
|
178
|
+
return cloned;
|
|
179
|
+
}
|
|
180
|
+
throwDataCloneError(`${tag} cannot be cloned`);
|
|
163
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* structuredClone polyfill implementing the HTML structured clone algorithm.
|
|
184
|
+
*
|
|
185
|
+
* Supports: primitives (incl. -0, NaN, Infinity, BigInt), wrapper objects,
|
|
186
|
+
* Date, RegExp, Error types, ArrayBuffer, TypedArrays, DataView, Map, Set,
|
|
187
|
+
* Blob, File, circular/shared references, plain objects and arrays.
|
|
188
|
+
*
|
|
189
|
+
* Throws DataCloneError for: functions, symbols, WeakMap, WeakSet, WeakRef, Promise.
|
|
190
|
+
*
|
|
191
|
+
* @param value The value to clone
|
|
192
|
+
* @param _options Reserved for future transfer list support (currently ignored)
|
|
193
|
+
*/
|
|
164
194
|
function structuredClone(value, _options) {
|
|
165
|
-
|
|
195
|
+
return internalClone(value, new Map());
|
|
166
196
|
}
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
};
|
|
197
|
+
|
|
198
|
+
//#endregion
|
|
199
|
+
export { structuredClone };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gjsify/utils",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.14",
|
|
4
4
|
"description": "Utils module for gjsify",
|
|
5
5
|
"module": "lib/esm/index.js",
|
|
6
6
|
"types": "lib/types/index.d.ts",
|
|
@@ -32,13 +32,13 @@
|
|
|
32
32
|
"fs"
|
|
33
33
|
],
|
|
34
34
|
"devDependencies": {
|
|
35
|
-
"@gjsify/cli": "^0.3.
|
|
35
|
+
"@gjsify/cli": "^0.3.14",
|
|
36
36
|
"typescript": "^6.0.3"
|
|
37
37
|
},
|
|
38
38
|
"dependencies": {
|
|
39
|
-
"@girs/gio-2.0": "
|
|
40
|
-
"@girs/giounix-2.0": "
|
|
41
|
-
"@girs/gjs": "
|
|
42
|
-
"@girs/glib-2.0": "
|
|
39
|
+
"@girs/gio-2.0": "2.88.0-4.0.0-rc.9",
|
|
40
|
+
"@girs/giounix-2.0": "2.0.0-4.0.0-rc.9",
|
|
41
|
+
"@girs/gjs": "4.0.0-rc.9",
|
|
42
|
+
"@girs/glib-2.0": "2.88.0-4.0.0-rc.9"
|
|
43
43
|
}
|
|
44
44
|
}
|