@filen/utils 0.0.5 → 0.0.7

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.
@@ -22,7 +22,7 @@ export class ChecklistParser {
22
22
  }
23
23
  return checklist;
24
24
  }
25
- catch (_a) {
25
+ catch {
26
26
  return [];
27
27
  }
28
28
  }
package/dist/misc.js CHANGED
@@ -57,48 +57,53 @@ export function chunkArray(array, chunkSize) {
57
57
  }
58
58
  return chunks;
59
59
  }
60
+ const ZERO_WIDTH_AND_CONTROL_RE = /[\u200B-\u200D\uFEFF\u00AD\u0000-\u001F\u007F-\u009F]/g;
61
+ const NON_ASCII_RE = /[^\x00-\x7F]/g;
62
+ const ILLEGAL_CHARS_WINDOWS_RE = /[<>:"/\\|?*]/g;
63
+ const ILLEGAL_CHARS_UNIX_RE = /\//g;
64
+ const TRAILING_DOTS_SPACES_RE = /[. ]+$/;
65
+ const WHITESPACE_RE = /\s+/g;
66
+ const RESERVED_NAMES_WINDOWS = new Set([
67
+ "CON",
68
+ "PRN",
69
+ "AUX",
70
+ "NUL",
71
+ "COM1",
72
+ "COM2",
73
+ "COM3",
74
+ "COM4",
75
+ "COM5",
76
+ "COM6",
77
+ "COM7",
78
+ "COM8",
79
+ "COM9",
80
+ "LPT1",
81
+ "LPT2",
82
+ "LPT3",
83
+ "LPT4",
84
+ "LPT5",
85
+ "LPT6",
86
+ "LPT7",
87
+ "LPT8",
88
+ "LPT9"
89
+ ]);
90
+ const textEncoder = new TextEncoder();
60
91
  export function sanitizeFileName(filename, replacement = "_") {
61
92
  let sanitizedFilename = filename.normalize("NFC");
62
- sanitizedFilename = sanitizedFilename.replace(/[\u200B-\u200D\uFEFF\u00AD\u0000-\u001F\u007F-\u009F]/g, "");
63
- sanitizedFilename = sanitizedFilename.replace(/[^\x00-\x7F]/g, replacement);
64
- const illegalCharsWindows = /[<>:"/\\|?*]/g;
65
- const illegalCharsUnix = /\//g;
66
- const reservedNamesWindows = new Set([
67
- "CON",
68
- "PRN",
69
- "AUX",
70
- "NUL",
71
- "COM1",
72
- "COM2",
73
- "COM3",
74
- "COM4",
75
- "COM5",
76
- "COM6",
77
- "COM7",
78
- "COM8",
79
- "COM9",
80
- "LPT1",
81
- "LPT2",
82
- "LPT3",
83
- "LPT4",
84
- "LPT5",
85
- "LPT6",
86
- "LPT7",
87
- "LPT8",
88
- "LPT9"
89
- ]);
90
- sanitizedFilename = sanitizedFilename.replace(illegalCharsWindows, replacement);
91
- sanitizedFilename = sanitizedFilename.replace(illegalCharsUnix, replacement);
92
- sanitizedFilename = sanitizedFilename.replace(/[. ]+$/, "");
93
- sanitizedFilename = sanitizedFilename.replace(/\s+/g, replacement);
94
- if (reservedNamesWindows.has(sanitizedFilename.toUpperCase())) {
93
+ sanitizedFilename = sanitizedFilename.replace(ZERO_WIDTH_AND_CONTROL_RE, "");
94
+ sanitizedFilename = sanitizedFilename.replace(NON_ASCII_RE, replacement);
95
+ sanitizedFilename = sanitizedFilename.replace(ILLEGAL_CHARS_WINDOWS_RE, replacement);
96
+ sanitizedFilename = sanitizedFilename.replace(ILLEGAL_CHARS_UNIX_RE, replacement);
97
+ sanitizedFilename = sanitizedFilename.replace(TRAILING_DOTS_SPACES_RE, "");
98
+ sanitizedFilename = sanitizedFilename.replace(WHITESPACE_RE, replacement);
99
+ if (RESERVED_NAMES_WINDOWS.has(sanitizedFilename.toUpperCase())) {
95
100
  sanitizedFilename += replacement;
96
101
  }
97
102
  const maxByteLength = 255;
98
- let byteLength = new TextEncoder().encode(sanitizedFilename).length;
103
+ let byteLength = textEncoder.encode(sanitizedFilename).length;
99
104
  while (byteLength > maxByteLength && sanitizedFilename.length > 0) {
100
105
  sanitizedFilename = sanitizedFilename.slice(0, -1);
101
- byteLength = new TextEncoder().encode(sanitizedFilename).length;
106
+ byteLength = textEncoder.encode(sanitizedFilename).length;
102
107
  }
103
108
  if (!sanitizedFilename) {
104
109
  return "file";
@@ -158,7 +163,7 @@ export function parseFilenPublicLink(url) {
158
163
  try {
159
164
  key = Buffer.from(key, "hex").toString("utf8");
160
165
  }
161
- catch (_a) {
166
+ catch {
162
167
  return null;
163
168
  }
164
169
  }
@@ -222,7 +227,7 @@ export function jsonBigIntReplacer(_, value) {
222
227
  }
223
228
  export function jsonBigIntReviver(_, value) {
224
229
  if (typeof value === "string" && value.startsWith("$bigint:") && value.endsWith("n")) {
225
- return BigInt(value.substring(8, -1));
230
+ return BigInt(value.slice(8, -1));
226
231
  }
227
232
  return value;
228
233
  }
@@ -314,20 +319,20 @@ export function bpsToReadable(bps) {
314
319
  if (!(bps > 0 && bps < 1099511627776)) {
315
320
  return "0.1 B/s";
316
321
  }
317
- let i = 0;
322
+ let i = -1;
318
323
  let value = bps;
319
324
  if (value >= 1024) {
320
325
  value /= 1024;
321
- i = 1;
326
+ i = 0;
322
327
  if (value >= 1024) {
323
328
  value /= 1024;
324
- i = 2;
329
+ i = 1;
325
330
  if (value >= 1024) {
326
331
  value /= 1024;
327
- i = 3;
332
+ i = 2;
328
333
  if (value >= 1024) {
329
334
  value /= 1024;
330
- i = 4;
335
+ i = 3;
331
336
  }
332
337
  }
333
338
  }
@@ -335,6 +340,9 @@ export function bpsToReadable(bps) {
335
340
  if (value < 0.1) {
336
341
  value = 0.1;
337
342
  }
343
+ if (i < 0) {
344
+ return value.toFixed(1) + " B";
345
+ }
338
346
  return value.toFixed(1) + " " + BPS_TO_READABLE_UNITS[i];
339
347
  }
340
348
  export const FORMAT_BYTES_SIZES = ["B", "KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"];
package/dist/notes.js CHANGED
@@ -1,15 +1,14 @@
1
1
  import striptags from "striptags";
2
2
  export function createNotePreviewFromContentText(type, content) {
3
- var _a, _b, _c;
4
3
  try {
5
4
  if (!content || content.length === 0) {
6
5
  return "";
7
6
  }
8
7
  if (type === "rich") {
9
8
  if (content.indexOf("<p><br></p>") === -1) {
10
- return striptags((_a = content.split("\n")[0]) !== null && _a !== void 0 ? _a : "").slice(0, 128);
9
+ return striptags(content.split("\n")[0] ?? "").slice(0, 128);
11
10
  }
12
- return striptags((_b = content.split("<p><br></p>")[0]) !== null && _b !== void 0 ? _b : "").slice(0, 128);
11
+ return striptags(content.split("<p><br></p>")[0] ?? "").slice(0, 128);
13
12
  }
14
13
  if (type === "checklist") {
15
14
  const ex = content
@@ -31,9 +30,9 @@ export function createNotePreviewFromContentText(type, content) {
31
30
  }
32
31
  return "";
33
32
  }
34
- return striptags((_c = content.split("\n")[0]) !== null && _c !== void 0 ? _c : "").slice(0, 128);
33
+ return striptags(content.split("\n")[0] ?? "").slice(0, 128);
35
34
  }
36
- catch (_d) {
35
+ catch {
37
36
  return "";
38
37
  }
39
38
  }
package/dist/run.js CHANGED
@@ -1,50 +1,37 @@
1
- var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
- function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
- return new (P || (P = Promise))(function (resolve, reject) {
4
- function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
- function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
- function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
- step((generator = generator.apply(thisArg, _arguments || [])).next());
8
- });
9
- };
10
- export function run(fn, options) {
11
- return __awaiter(this, void 0, void 0, function* () {
12
- var _a, _b, _c;
13
- const deferredFunctions = [];
14
- const defer = deferFn => {
15
- deferredFunctions.push(deferFn);
1
+ export async function run(fn, options) {
2
+ const deferredFunctions = [];
3
+ const defer = deferFn => {
4
+ deferredFunctions.push(deferFn);
5
+ };
6
+ try {
7
+ const result = await fn(defer);
8
+ return {
9
+ success: true,
10
+ data: result,
11
+ error: null
16
12
  };
17
- try {
18
- const result = yield fn(defer);
19
- return {
20
- success: true,
21
- data: result,
22
- error: null
23
- };
13
+ }
14
+ catch (e) {
15
+ options?.onError?.(e);
16
+ if (options?.throw) {
17
+ throw e;
24
18
  }
25
- catch (e) {
26
- const error = e instanceof Error ? e : new Error("Unknown error");
27
- (_a = options === null || options === void 0 ? void 0 : options.onError) === null || _a === void 0 ? void 0 : _a.call(options, error);
28
- if (options === null || options === void 0 ? void 0 : options.throw) {
29
- throw error;
19
+ return {
20
+ success: false,
21
+ data: null,
22
+ error: e
23
+ };
24
+ }
25
+ finally {
26
+ for (let i = deferredFunctions.length - 1; i >= 0; i--) {
27
+ try {
28
+ await deferredFunctions[i]?.();
30
29
  }
31
- return {
32
- success: false,
33
- data: null,
34
- error: error
35
- };
36
- }
37
- finally {
38
- for (let i = deferredFunctions.length - 1; i >= 0; i--) {
39
- try {
40
- yield ((_b = deferredFunctions[i]) === null || _b === void 0 ? void 0 : _b.call(deferredFunctions));
41
- }
42
- catch (e) {
43
- (_c = options === null || options === void 0 ? void 0 : options.onError) === null || _c === void 0 ? void 0 : _c.call(options, e instanceof Error ? e : new Error("Unknown error"));
44
- }
30
+ catch (e) {
31
+ options?.onError?.(e);
45
32
  }
46
33
  }
47
- });
34
+ }
48
35
  }
49
36
  export class AbortError extends Error {
50
37
  constructor(message = "Operation aborted") {
@@ -65,110 +52,103 @@ export function abortSignalReason(signal) {
65
52
  }
66
53
  return undefined;
67
54
  }
68
- catch (_a) {
55
+ catch {
69
56
  return undefined;
70
57
  }
71
58
  }
72
- export function runAbortable(fn, options) {
73
- return __awaiter(this, void 0, void 0, function* () {
74
- var _a, _b, _c, _d, _e, _f, _g;
75
- const deferredFunctions = [];
76
- const controller = (_a = options === null || options === void 0 ? void 0 : options.controller) !== null && _a !== void 0 ? _a : new AbortController();
77
- const signal = (_d = (_b = options === null || options === void 0 ? void 0 : options.signal) !== null && _b !== void 0 ? _b : (_c = options === null || options === void 0 ? void 0 : options.controller) === null || _c === void 0 ? void 0 : _c.signal) !== null && _d !== void 0 ? _d : controller.signal;
78
- const defer = deferFn => {
79
- deferredFunctions.push(deferFn);
80
- };
81
- const abortable = (abortableFn, opts) => __awaiter(this, void 0, void 0, function* () {
82
- if (signal.aborted) {
83
- throw new AbortError(abortSignalReason(signal));
84
- }
85
- return yield new Promise((resolve, reject) => {
86
- ;
87
- (() => __awaiter(this, void 0, void 0, function* () {
88
- var _a;
89
- const signal = (_a = opts === null || opts === void 0 ? void 0 : opts.signal) !== null && _a !== void 0 ? _a : controller.signal;
90
- const abortHandler = () => {
59
+ export async function runAbortable(fn, options) {
60
+ const deferredFunctions = [];
61
+ const controller = options?.controller ?? new AbortController();
62
+ const signal = options?.signal ?? options?.controller?.signal ?? controller.signal;
63
+ const defer = deferFn => {
64
+ deferredFunctions.push(deferFn);
65
+ };
66
+ const abortable = async (abortableFn, opts) => {
67
+ if (signal.aborted) {
68
+ throw new AbortError(abortSignalReason(signal));
69
+ }
70
+ return await new Promise((resolve, reject) => {
71
+ ;
72
+ (async () => {
73
+ const signal = opts?.signal ?? controller.signal;
74
+ const abortHandler = () => {
75
+ reject(new AbortError(abortSignalReason(signal)));
76
+ };
77
+ signal.addEventListener("abort", abortHandler);
78
+ try {
79
+ if (signal.aborted) {
91
80
  reject(new AbortError(abortSignalReason(signal)));
92
- };
93
- signal.addEventListener("abort", abortHandler);
94
- try {
95
- if (signal.aborted) {
96
- reject(new AbortError(abortSignalReason(signal)));
97
- return;
98
- }
99
- const result = yield abortableFn();
100
- if (signal.aborted) {
101
- reject(new AbortError(abortSignalReason(signal)));
102
- return;
103
- }
104
- resolve(result);
105
- }
106
- catch (error) {
107
- reject(error);
81
+ return;
108
82
  }
109
- finally {
110
- signal.removeEventListener("abort", abortHandler);
83
+ const result = await abortableFn();
84
+ if (signal.aborted) {
85
+ reject(new AbortError(abortSignalReason(signal)));
86
+ return;
111
87
  }
112
- }))();
113
- });
114
- });
115
- try {
116
- if (signal.aborted) {
117
- throw new AbortError(abortSignalReason(signal));
118
- }
119
- const result = yield fn({
120
- abortable,
121
- defer,
122
- signal,
123
- controller
124
- });
125
- if (signal.aborted) {
126
- throw new AbortError(abortSignalReason(signal));
127
- }
128
- return {
129
- success: true,
130
- data: result,
131
- error: null
132
- };
133
- }
134
- catch (e) {
135
- const error = e instanceof Error ? e : new Error("Unknown error");
136
- (_e = options === null || options === void 0 ? void 0 : options.onError) === null || _e === void 0 ? void 0 : _e.call(options, error);
137
- if (options === null || options === void 0 ? void 0 : options.throw) {
138
- throw error;
139
- }
140
- return {
141
- success: false,
142
- data: null,
143
- error: error
144
- };
145
- }
146
- finally {
147
- for (let i = deferredFunctions.length - 1; i >= 0; i--) {
148
- try {
149
- yield ((_f = deferredFunctions[i]) === null || _f === void 0 ? void 0 : _f.call(deferredFunctions));
88
+ resolve(result);
150
89
  }
151
90
  catch (e) {
152
- (_g = options === null || options === void 0 ? void 0 : options.onError) === null || _g === void 0 ? void 0 : _g.call(options, e instanceof Error ? e : new Error("Unknown error"));
91
+ reject(e);
92
+ }
93
+ finally {
94
+ signal.removeEventListener("abort", abortHandler);
153
95
  }
96
+ })();
97
+ });
98
+ };
99
+ try {
100
+ if (signal.aborted) {
101
+ throw new AbortError(abortSignalReason(signal));
102
+ }
103
+ const result = await fn({
104
+ abortable,
105
+ defer,
106
+ signal,
107
+ controller
108
+ });
109
+ if (signal.aborted) {
110
+ throw new AbortError(abortSignalReason(signal));
111
+ }
112
+ return {
113
+ success: true,
114
+ data: result,
115
+ error: null
116
+ };
117
+ }
118
+ catch (e) {
119
+ options?.onError?.(e);
120
+ if (options?.throw) {
121
+ throw e;
122
+ }
123
+ return {
124
+ success: false,
125
+ data: null,
126
+ error: e
127
+ };
128
+ }
129
+ finally {
130
+ for (let i = deferredFunctions.length - 1; i >= 0; i--) {
131
+ try {
132
+ await deferredFunctions[i]?.();
133
+ }
134
+ catch (e) {
135
+ options?.onError?.(e);
154
136
  }
155
137
  }
156
- });
138
+ }
157
139
  }
158
140
  export function runEffect(fn, options) {
159
- var _a;
160
141
  const deferredFunctions = [];
161
142
  const defer = deferFn => {
162
143
  deferredFunctions.push(deferFn);
163
144
  };
164
145
  const cleanup = () => {
165
- var _a, _b;
166
146
  for (let i = deferredFunctions.length - 1; i >= 0; i--) {
167
147
  try {
168
- (_a = deferredFunctions[i]) === null || _a === void 0 ? void 0 : _a.call(deferredFunctions);
148
+ deferredFunctions[i]?.();
169
149
  }
170
150
  catch (e) {
171
- (_b = options === null || options === void 0 ? void 0 : options.onError) === null || _b === void 0 ? void 0 : _b.call(options, e instanceof Error ? e : new Error("Unknown error"));
151
+ options?.onError?.(e);
172
152
  }
173
153
  }
174
154
  };
@@ -182,57 +162,56 @@ export function runEffect(fn, options) {
182
162
  };
183
163
  }
184
164
  catch (e) {
185
- const error = e instanceof Error ? e : new Error("Unknown error");
186
- (_a = options === null || options === void 0 ? void 0 : options.onError) === null || _a === void 0 ? void 0 : _a.call(options, error);
187
- if (options === null || options === void 0 ? void 0 : options.throw) {
188
- throw error;
165
+ options?.onError?.(e);
166
+ if (options?.throw) {
167
+ throw e;
189
168
  }
190
169
  return {
191
170
  success: false,
192
171
  data: null,
193
- error: error,
172
+ error: e,
194
173
  cleanup
195
174
  };
196
175
  }
197
176
  finally {
198
- if (options === null || options === void 0 ? void 0 : options.automaticCleanup) {
177
+ if (options?.automaticCleanup) {
199
178
  cleanup();
200
179
  }
201
180
  }
202
181
  }
203
- export function runRetry(fn, options) {
204
- return __awaiter(this, void 0, void 0, function* () {
205
- var _a, _b, _c, _d;
206
- const maxAttempts = (_a = options === null || options === void 0 ? void 0 : options.maxAttempts) !== null && _a !== void 0 ? _a : 3;
207
- const delayMs = (_b = options === null || options === void 0 ? void 0 : options.delayMs) !== null && _b !== void 0 ? _b : 1000;
208
- const backoff = (_c = options === null || options === void 0 ? void 0 : options.backoff) !== null && _c !== void 0 ? _c : "exponential";
209
- let lastError = null;
210
- for (let attempt = 1; attempt <= maxAttempts; attempt++) {
211
- const result = yield run(defer => fn(defer, attempt), Object.assign(Object.assign({}, options), { throw: false }));
212
- if (result.success) {
213
- return result;
214
- }
215
- lastError = result.error;
216
- if (attempt < maxAttempts) {
217
- const shouldRetry = typeof (options === null || options === void 0 ? void 0 : options.shouldRetry) === "boolean"
218
- ? options.shouldRetry
219
- : options && typeof options.shouldRetry === "function"
220
- ? options.shouldRetry(result.error, attempt)
221
- : true;
222
- if (!shouldRetry) {
223
- break;
224
- }
225
- (_d = options === null || options === void 0 ? void 0 : options.onRetry) === null || _d === void 0 ? void 0 : _d.call(options, result.error, attempt);
226
- const delay = backoff === "exponential" ? delayMs * Math.pow(2, attempt - 1) : delayMs * attempt;
227
- yield new Promise(resolve => setTimeout(resolve, delay));
182
+ export async function runRetry(fn, options) {
183
+ const maxAttempts = options?.maxAttempts ?? 3;
184
+ const delayMs = options?.delayMs ?? 1000;
185
+ const backoff = options?.backoff ?? "exponential";
186
+ let lastError = null;
187
+ for (let attempt = 1; attempt <= maxAttempts; attempt++) {
188
+ const result = await run(defer => fn(defer, attempt), {
189
+ ...options,
190
+ throw: false
191
+ });
192
+ if (result.success) {
193
+ return result;
194
+ }
195
+ lastError = result.error;
196
+ if (attempt < maxAttempts) {
197
+ const shouldRetry = typeof options?.shouldRetry === "boolean"
198
+ ? options.shouldRetry
199
+ : options && typeof options.shouldRetry === "function"
200
+ ? options.shouldRetry(result.error, attempt)
201
+ : true;
202
+ if (!shouldRetry) {
203
+ break;
228
204
  }
205
+ options?.onRetry?.(result.error, attempt);
206
+ const delay = backoff === "exponential" ? delayMs * Math.pow(2, attempt - 1) : delayMs * attempt;
207
+ await new Promise(resolve => setTimeout(resolve, delay));
229
208
  }
230
- return {
231
- success: false,
232
- data: null,
233
- error: lastError
234
- };
235
- });
209
+ }
210
+ return {
211
+ success: false,
212
+ data: null,
213
+ error: lastError
214
+ };
236
215
  }
237
216
  export class TimeoutError extends Error {
238
217
  constructor(message = "Operation timed out") {
@@ -240,39 +219,36 @@ export class TimeoutError extends Error {
240
219
  this.name = "TimeoutError";
241
220
  }
242
221
  }
243
- export function runTimeout(fn, timeoutMs, options) {
244
- return __awaiter(this, void 0, void 0, function* () {
245
- var _a;
246
- const controller = new AbortController();
247
- try {
248
- const result = yield Promise.race([
249
- run(fn, options),
250
- new Promise((_, reject) => {
251
- const timeoutId = setTimeout(() => {
252
- controller.abort();
253
- reject(new TimeoutError(`Operation timed out after ${timeoutMs}ms`));
254
- }, timeoutMs);
255
- controller.signal.addEventListener("abort", () => clearTimeout(timeoutId));
256
- })
257
- ]);
258
- return result;
259
- }
260
- catch (e) {
261
- const error = e instanceof Error ? e : new Error("Unknown error");
262
- (_a = options === null || options === void 0 ? void 0 : options.onError) === null || _a === void 0 ? void 0 : _a.call(options, error);
263
- if (options === null || options === void 0 ? void 0 : options.throw) {
264
- throw error;
265
- }
266
- return {
267
- success: false,
268
- data: null,
269
- error: error
270
- };
222
+ export async function runTimeout(fn, timeoutMs, options) {
223
+ const controller = new AbortController();
224
+ try {
225
+ const result = await Promise.race([
226
+ run(fn, options),
227
+ new Promise((_, reject) => {
228
+ const timeoutId = setTimeout(() => {
229
+ controller.abort();
230
+ reject(new TimeoutError(`Operation timed out after ${timeoutMs}ms`));
231
+ }, timeoutMs);
232
+ controller.signal.addEventListener("abort", () => clearTimeout(timeoutId));
233
+ })
234
+ ]);
235
+ return result;
236
+ }
237
+ catch (e) {
238
+ options?.onError?.(e);
239
+ if (options?.throw) {
240
+ throw e;
271
241
  }
272
- });
242
+ return {
243
+ success: false,
244
+ data: null,
245
+ error: e
246
+ };
247
+ }
273
248
  }
274
249
  export function runDebounced(fn, delayMs, options) {
275
250
  let timeoutId = null;
251
+ let pendingResolve = null;
276
252
  let pendingPromise = null;
277
253
  return (...args) => {
278
254
  if (timeoutId) {
@@ -280,15 +256,122 @@ export function runDebounced(fn, delayMs, options) {
280
256
  }
281
257
  if (!pendingPromise) {
282
258
  pendingPromise = new Promise(resolve => {
283
- timeoutId = setTimeout(() => __awaiter(this, void 0, void 0, function* () {
284
- const result = yield run(defer => fn(defer, ...args), options);
285
- resolve(result);
286
- pendingPromise = null;
287
- timeoutId = null;
288
- }), delayMs);
259
+ pendingResolve = resolve;
289
260
  });
290
261
  }
262
+ timeoutId = setTimeout(async () => {
263
+ const result = await run(defer => fn(defer, ...args), options);
264
+ pendingResolve(result);
265
+ pendingPromise = null;
266
+ pendingResolve = null;
267
+ timeoutId = null;
268
+ }, delayMs);
291
269
  return pendingPromise;
292
270
  };
293
271
  }
272
+ export function createAbortablePipeline(signal) {
273
+ const controller = new AbortController();
274
+ const controllerSignal = controller.signal;
275
+ if (signal) {
276
+ if (signal.aborted) {
277
+ controller.abort(signal.reason);
278
+ }
279
+ else {
280
+ signal.addEventListener("abort", () => controller.abort(signal.reason), {
281
+ once: true
282
+ });
283
+ }
284
+ }
285
+ let chain = Promise.resolve();
286
+ let halted = false;
287
+ const step = (fn) => {
288
+ let resolve;
289
+ let reject;
290
+ const promise = new Promise((res, rej) => {
291
+ resolve = res;
292
+ reject = rej;
293
+ });
294
+ chain = chain.then(async () => {
295
+ if (halted || controllerSignal.aborted) {
296
+ reject(new AbortError(controllerSignal.aborted ? abortSignalReason(controllerSignal) : "Pipeline halted"));
297
+ return;
298
+ }
299
+ const stepDeferred = [];
300
+ const defer = deferFn => {
301
+ stepDeferred.push(deferFn);
302
+ };
303
+ const runCleanups = async () => {
304
+ for (let i = stepDeferred.length - 1; i >= 0; i--) {
305
+ try {
306
+ await stepDeferred[i]?.();
307
+ }
308
+ catch {
309
+ }
310
+ }
311
+ };
312
+ let fnSucceeded = false;
313
+ let fnValue;
314
+ let fnError;
315
+ const fnPromise = (async () => {
316
+ try {
317
+ fnValue = await fn(defer, controllerSignal);
318
+ fnSucceeded = true;
319
+ }
320
+ catch (e) {
321
+ fnError = e;
322
+ fnSucceeded = false;
323
+ }
324
+ })();
325
+ if (controllerSignal.aborted) {
326
+ await fnPromise;
327
+ await runCleanups();
328
+ if (fnSucceeded) {
329
+ resolve(fnValue);
330
+ }
331
+ else {
332
+ halted = true;
333
+ reject(fnError);
334
+ }
335
+ return;
336
+ }
337
+ try {
338
+ await new Promise((res, rej) => {
339
+ const onAbort = () => {
340
+ rej(new AbortError(abortSignalReason(controllerSignal)));
341
+ };
342
+ controllerSignal.addEventListener("abort", onAbort, {
343
+ once: true
344
+ });
345
+ fnPromise.then(() => {
346
+ controllerSignal.removeEventListener("abort", onAbort);
347
+ res();
348
+ });
349
+ });
350
+ }
351
+ catch (e) {
352
+ await runCleanups();
353
+ halted = true;
354
+ reject(e);
355
+ return;
356
+ }
357
+ await runCleanups();
358
+ if (fnSucceeded) {
359
+ resolve(fnValue);
360
+ }
361
+ else {
362
+ halted = true;
363
+ reject(fnError);
364
+ }
365
+ });
366
+ return {
367
+ then: promise.then.bind(promise),
368
+ catch: promise.catch.bind(promise),
369
+ finally: promise.finally.bind(promise)
370
+ };
371
+ };
372
+ return {
373
+ step,
374
+ signal: controllerSignal
375
+ };
376
+ }
294
377
  export default run;
package/dist/semaphore.js CHANGED
@@ -40,7 +40,7 @@ export class Semaphore {
40
40
  return unresolved;
41
41
  }
42
42
  processQueue() {
43
- if (this.waiting.length > 0 && this.counter < this.maxCount) {
43
+ while (this.waiting.length > 0 && this.counter < this.maxCount) {
44
44
  this.counter++;
45
45
  const waiter = this.waiting.shift();
46
46
  if (waiter) {
@@ -3,21 +3,21 @@ export type Success<T> = {
3
3
  data: T;
4
4
  error: null;
5
5
  };
6
- export type Failure<E = Error> = {
6
+ export type Failure<E = unknown> = {
7
7
  success: false;
8
8
  data: null;
9
9
  error: E;
10
10
  };
11
- export type Result<T, E = Error> = Success<T> | Failure<E>;
11
+ export type Result<T, E = unknown> = Success<T> | Failure<E>;
12
12
  export type GenericFnResult = number | boolean | string | object | null | undefined | symbol | bigint | void | Promise<number | boolean | string | object | null | undefined | symbol | bigint | void> | Array<number | boolean | string | object | null | undefined | symbol | bigint | void>;
13
13
  export type DeferFn = (fn: () => GenericFnResult) => void;
14
14
  export type DeferredFunction = () => GenericFnResult;
15
15
  export type DeferredFunctions = Array<DeferredFunction>;
16
16
  export type Options = {
17
17
  throw?: boolean;
18
- onError?: (err: Error) => void;
18
+ onError?: (err: unknown) => void;
19
19
  };
20
- export declare function run<TResult, E = Error>(fn: (deferFn: DeferFn) => Promise<TResult> | TResult, options?: Options): Promise<Result<TResult, E>>;
20
+ export declare function run<TResult, E = unknown>(fn: (deferFn: DeferFn) => Promise<TResult> | TResult, options?: Options): Promise<Result<TResult, E>>;
21
21
  export type AbortableFn = (abortableFn: () => GenericFnResult, opts?: {
22
22
  signal?: AbortSignal;
23
23
  }) => GenericFnResult;
@@ -25,7 +25,7 @@ export declare class AbortError extends Error {
25
25
  constructor(message?: string);
26
26
  }
27
27
  export declare function abortSignalReason(signal: AbortSignal): string | undefined;
28
- export declare function runAbortable<TResult, E = Error>(fn: ({ abortable, defer, signal, controller }: {
28
+ export declare function runAbortable<TResult, E = unknown>(fn: ({ abortable, defer, signal, controller }: {
29
29
  abortable: AbortableFn;
30
30
  defer: DeferFn;
31
31
  signal: AbortSignal;
@@ -34,12 +34,12 @@ export declare function runAbortable<TResult, E = Error>(fn: ({ abortable, defer
34
34
  controller?: AbortController;
35
35
  signal?: AbortSignal;
36
36
  }): Promise<Result<TResult, E>>;
37
- export declare function runEffect<TResult, E = Error>(fn: (deferFn: DeferFn) => TResult, options?: Options & {
37
+ export declare function runEffect<TResult, E = unknown>(fn: (deferFn: DeferFn) => TResult, options?: Options & {
38
38
  automaticCleanup?: boolean;
39
39
  }): Result<TResult, E> & {
40
40
  cleanup: () => void;
41
41
  };
42
- export declare function runRetry<TResult, E = Error>(fn: (deferFn: DeferFn, attempt: number) => Promise<TResult> | TResult, options?: Options & {
42
+ export declare function runRetry<TResult, E = unknown>(fn: (deferFn: DeferFn, attempt: number) => Promise<TResult> | TResult, options?: Options & {
43
43
  maxAttempts?: number;
44
44
  delayMs?: number;
45
45
  backoff?: "linear" | "exponential";
@@ -49,6 +49,16 @@ export declare function runRetry<TResult, E = Error>(fn: (deferFn: DeferFn, atte
49
49
  export declare class TimeoutError extends Error {
50
50
  constructor(message?: string);
51
51
  }
52
- export declare function runTimeout<TResult, E = Error>(fn: (deferFn: DeferFn) => Promise<TResult> | TResult, timeoutMs: number, options?: Options): Promise<Result<TResult, E>>;
53
- export declare function runDebounced<TResult, TArgs extends unknown[]>(fn: (defer: DeferFn, ...args: TArgs) => Promise<TResult> | TResult, delayMs: number, options?: Options): (...args: TArgs) => Promise<Result<TResult, Error>>;
52
+ export declare function runTimeout<TResult, E = unknown>(fn: (deferFn: DeferFn) => Promise<TResult> | TResult, timeoutMs: number, options?: Options): Promise<Result<TResult, E>>;
53
+ export declare function runDebounced<TResult, TArgs extends unknown[]>(fn: (defer: DeferFn, ...args: TArgs) => Promise<TResult> | TResult, delayMs: number, options?: Options): (...args: TArgs) => Promise<Result<TResult, unknown>>;
54
+ export type StepFn<T> = (defer: DeferFn, signal: AbortSignal) => Promise<T> | T;
55
+ export type StepHandle<T> = {
56
+ then: Promise<T>["then"];
57
+ catch: Promise<T>["catch"];
58
+ finally: Promise<T>["finally"];
59
+ };
60
+ export declare function createAbortablePipeline(signal?: AbortSignal): {
61
+ step: <T>(fn: StepFn<T>) => StepHandle<T>;
62
+ signal: AbortSignal;
63
+ };
54
64
  export default run;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@filen/utils",
3
- "version": "0.0.5",
3
+ "version": "0.0.7",
4
4
  "description": "A collection of utils for Filen",
5
5
  "private": false,
6
6
  "repository": {