@filen/utils 0.0.6 → 0.0.8

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,49 +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
- (_a = options === null || options === void 0 ? void 0 : options.onError) === null || _a === void 0 ? void 0 : _a.call(options, e);
27
- if (options === null || options === void 0 ? void 0 : options.throw) {
28
- throw e;
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]?.();
29
29
  }
30
- return {
31
- success: false,
32
- data: null,
33
- error: e
34
- };
35
- }
36
- finally {
37
- for (let i = deferredFunctions.length - 1; i >= 0; i--) {
38
- try {
39
- yield ((_b = deferredFunctions[i]) === null || _b === void 0 ? void 0 : _b.call(deferredFunctions));
40
- }
41
- catch (e) {
42
- (_c = options === null || options === void 0 ? void 0 : options.onError) === null || _c === void 0 ? void 0 : _c.call(options, e);
43
- }
30
+ catch (e) {
31
+ options?.onError?.(e);
44
32
  }
45
33
  }
46
- });
34
+ }
47
35
  }
48
36
  export class AbortError extends Error {
49
37
  constructor(message = "Operation aborted") {
@@ -64,109 +52,103 @@ export function abortSignalReason(signal) {
64
52
  }
65
53
  return undefined;
66
54
  }
67
- catch (_a) {
55
+ catch {
68
56
  return undefined;
69
57
  }
70
58
  }
71
- export function runAbortable(fn, options) {
72
- return __awaiter(this, void 0, void 0, function* () {
73
- var _a, _b, _c, _d, _e, _f, _g;
74
- const deferredFunctions = [];
75
- const controller = (_a = options === null || options === void 0 ? void 0 : options.controller) !== null && _a !== void 0 ? _a : new AbortController();
76
- 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;
77
- const defer = deferFn => {
78
- deferredFunctions.push(deferFn);
79
- };
80
- const abortable = (abortableFn, opts) => __awaiter(this, void 0, void 0, function* () {
81
- if (signal.aborted) {
82
- throw new AbortError(abortSignalReason(signal));
83
- }
84
- return yield new Promise((resolve, reject) => {
85
- ;
86
- (() => __awaiter(this, void 0, void 0, function* () {
87
- var _a;
88
- const signal = (_a = opts === null || opts === void 0 ? void 0 : opts.signal) !== null && _a !== void 0 ? _a : controller.signal;
89
- 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) {
90
80
  reject(new AbortError(abortSignalReason(signal)));
91
- };
92
- signal.addEventListener("abort", abortHandler);
93
- try {
94
- if (signal.aborted) {
95
- reject(new AbortError(abortSignalReason(signal)));
96
- return;
97
- }
98
- const result = yield abortableFn();
99
- if (signal.aborted) {
100
- reject(new AbortError(abortSignalReason(signal)));
101
- return;
102
- }
103
- resolve(result);
104
- }
105
- catch (e) {
106
- reject(e);
81
+ return;
107
82
  }
108
- finally {
109
- signal.removeEventListener("abort", abortHandler);
83
+ const result = await abortableFn();
84
+ if (signal.aborted) {
85
+ reject(new AbortError(abortSignalReason(signal)));
86
+ return;
110
87
  }
111
- }))();
112
- });
113
- });
114
- try {
115
- if (signal.aborted) {
116
- throw new AbortError(abortSignalReason(signal));
117
- }
118
- const result = yield fn({
119
- abortable,
120
- defer,
121
- signal,
122
- controller
123
- });
124
- if (signal.aborted) {
125
- throw new AbortError(abortSignalReason(signal));
126
- }
127
- return {
128
- success: true,
129
- data: result,
130
- error: null
131
- };
132
- }
133
- catch (e) {
134
- (_e = options === null || options === void 0 ? void 0 : options.onError) === null || _e === void 0 ? void 0 : _e.call(options, e);
135
- if (options === null || options === void 0 ? void 0 : options.throw) {
136
- throw e;
137
- }
138
- return {
139
- success: false,
140
- data: null,
141
- error: e
142
- };
143
- }
144
- finally {
145
- for (let i = deferredFunctions.length - 1; i >= 0; i--) {
146
- try {
147
- yield ((_f = deferredFunctions[i]) === null || _f === void 0 ? void 0 : _f.call(deferredFunctions));
88
+ resolve(result);
148
89
  }
149
90
  catch (e) {
150
- (_g = options === null || options === void 0 ? void 0 : options.onError) === null || _g === void 0 ? void 0 : _g.call(options, e);
91
+ reject(e);
151
92
  }
93
+ finally {
94
+ signal.removeEventListener("abort", abortHandler);
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);
152
136
  }
153
137
  }
154
- });
138
+ }
155
139
  }
156
140
  export function runEffect(fn, options) {
157
- var _a;
158
141
  const deferredFunctions = [];
159
142
  const defer = deferFn => {
160
143
  deferredFunctions.push(deferFn);
161
144
  };
162
145
  const cleanup = () => {
163
- var _a, _b;
164
146
  for (let i = deferredFunctions.length - 1; i >= 0; i--) {
165
147
  try {
166
- (_a = deferredFunctions[i]) === null || _a === void 0 ? void 0 : _a.call(deferredFunctions);
148
+ deferredFunctions[i]?.();
167
149
  }
168
150
  catch (e) {
169
- (_b = options === null || options === void 0 ? void 0 : options.onError) === null || _b === void 0 ? void 0 : _b.call(options, e);
151
+ options?.onError?.(e);
170
152
  }
171
153
  }
172
154
  };
@@ -180,8 +162,8 @@ export function runEffect(fn, options) {
180
162
  };
181
163
  }
182
164
  catch (e) {
183
- (_a = options === null || options === void 0 ? void 0 : options.onError) === null || _a === void 0 ? void 0 : _a.call(options, e);
184
- if (options === null || options === void 0 ? void 0 : options.throw) {
165
+ options?.onError?.(e);
166
+ if (options?.throw) {
185
167
  throw e;
186
168
  }
187
169
  return {
@@ -192,44 +174,44 @@ export function runEffect(fn, options) {
192
174
  };
193
175
  }
194
176
  finally {
195
- if (options === null || options === void 0 ? void 0 : options.automaticCleanup) {
177
+ if (options?.automaticCleanup) {
196
178
  cleanup();
197
179
  }
198
180
  }
199
181
  }
200
- export function runRetry(fn, options) {
201
- return __awaiter(this, void 0, void 0, function* () {
202
- var _a, _b, _c, _d;
203
- const maxAttempts = (_a = options === null || options === void 0 ? void 0 : options.maxAttempts) !== null && _a !== void 0 ? _a : 3;
204
- const delayMs = (_b = options === null || options === void 0 ? void 0 : options.delayMs) !== null && _b !== void 0 ? _b : 1000;
205
- const backoff = (_c = options === null || options === void 0 ? void 0 : options.backoff) !== null && _c !== void 0 ? _c : "exponential";
206
- let lastError = null;
207
- for (let attempt = 1; attempt <= maxAttempts; attempt++) {
208
- const result = yield run(defer => fn(defer, attempt), Object.assign(Object.assign({}, options), { throw: false }));
209
- if (result.success) {
210
- return result;
211
- }
212
- lastError = result.error;
213
- if (attempt < maxAttempts) {
214
- const shouldRetry = typeof (options === null || options === void 0 ? void 0 : options.shouldRetry) === "boolean"
215
- ? options.shouldRetry
216
- : options && typeof options.shouldRetry === "function"
217
- ? options.shouldRetry(result.error, attempt)
218
- : true;
219
- if (!shouldRetry) {
220
- break;
221
- }
222
- (_d = options === null || options === void 0 ? void 0 : options.onRetry) === null || _d === void 0 ? void 0 : _d.call(options, result.error, attempt);
223
- const delay = backoff === "exponential" ? delayMs * Math.pow(2, attempt - 1) : delayMs * attempt;
224
- 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;
225
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));
226
208
  }
227
- return {
228
- success: false,
229
- data: null,
230
- error: lastError
231
- };
232
- });
209
+ }
210
+ return {
211
+ success: false,
212
+ data: null,
213
+ error: lastError
214
+ };
233
215
  }
234
216
  export class TimeoutError extends Error {
235
217
  constructor(message = "Operation timed out") {
@@ -237,54 +219,171 @@ export class TimeoutError extends Error {
237
219
  this.name = "TimeoutError";
238
220
  }
239
221
  }
240
- export function runTimeout(fn, timeoutMs, options) {
241
- return __awaiter(this, void 0, void 0, function* () {
242
- var _a;
243
- const controller = new AbortController();
244
- try {
245
- const result = yield Promise.race([
246
- run(fn, options),
247
- new Promise((_, reject) => {
248
- const timeoutId = setTimeout(() => {
249
- controller.abort();
250
- reject(new TimeoutError(`Operation timed out after ${timeoutMs}ms`));
251
- }, timeoutMs);
252
- controller.signal.addEventListener("abort", () => clearTimeout(timeoutId));
253
- })
254
- ]);
255
- return result;
222
+ export async function runTimeout(fn, timeoutMs, options) {
223
+ let timeoutId = null;
224
+ try {
225
+ const result = await Promise.race([
226
+ run(fn, options),
227
+ new Promise((_, reject) => {
228
+ timeoutId = setTimeout(() => {
229
+ timeoutId = null;
230
+ reject(new TimeoutError(`Operation timed out after ${timeoutMs}ms`));
231
+ }, timeoutMs);
232
+ })
233
+ ]);
234
+ return result;
235
+ }
236
+ catch (e) {
237
+ options?.onError?.(e);
238
+ if (options?.throw) {
239
+ throw e;
256
240
  }
257
- catch (e) {
258
- (_a = options === null || options === void 0 ? void 0 : options.onError) === null || _a === void 0 ? void 0 : _a.call(options, e);
259
- if (options === null || options === void 0 ? void 0 : options.throw) {
260
- throw e;
261
- }
262
- return {
263
- success: false,
264
- data: null,
265
- error: e
266
- };
241
+ return {
242
+ success: false,
243
+ data: null,
244
+ error: e
245
+ };
246
+ }
247
+ finally {
248
+ if (timeoutId !== null) {
249
+ clearTimeout(timeoutId);
267
250
  }
268
- });
251
+ }
269
252
  }
270
253
  export function runDebounced(fn, delayMs, options) {
271
254
  let timeoutId = null;
255
+ let pendingResolve = null;
272
256
  let pendingPromise = null;
257
+ let executing = false;
273
258
  return (...args) => {
274
259
  if (timeoutId) {
275
260
  clearTimeout(timeoutId);
276
261
  }
277
262
  if (!pendingPromise) {
278
263
  pendingPromise = new Promise(resolve => {
279
- timeoutId = setTimeout(() => __awaiter(this, void 0, void 0, function* () {
280
- const result = yield run(defer => fn(defer, ...args), options);
281
- resolve(result);
282
- pendingPromise = null;
283
- timeoutId = null;
284
- }), delayMs);
264
+ pendingResolve = resolve;
285
265
  });
286
266
  }
267
+ timeoutId = setTimeout(async () => {
268
+ if (executing || !pendingResolve) {
269
+ return;
270
+ }
271
+ executing = true;
272
+ const result = await run(defer => fn(defer, ...args), options);
273
+ executing = false;
274
+ if (pendingResolve) {
275
+ pendingResolve(result);
276
+ }
277
+ pendingPromise = null;
278
+ pendingResolve = null;
279
+ timeoutId = null;
280
+ }, delayMs);
287
281
  return pendingPromise;
288
282
  };
289
283
  }
284
+ export function createAbortablePipeline(signal) {
285
+ const controller = new AbortController();
286
+ const controllerSignal = controller.signal;
287
+ if (signal) {
288
+ if (signal.aborted) {
289
+ controller.abort(signal.reason);
290
+ }
291
+ else {
292
+ signal.addEventListener("abort", () => controller.abort(signal.reason), {
293
+ once: true
294
+ });
295
+ }
296
+ }
297
+ let chain = Promise.resolve();
298
+ let halted = false;
299
+ const step = (fn) => {
300
+ let resolve;
301
+ let reject;
302
+ const promise = new Promise((res, rej) => {
303
+ resolve = res;
304
+ reject = rej;
305
+ });
306
+ chain = chain.then(async () => {
307
+ if (halted || controllerSignal.aborted) {
308
+ reject(new AbortError(controllerSignal.aborted ? abortSignalReason(controllerSignal) : "Pipeline halted"));
309
+ return;
310
+ }
311
+ const stepDeferred = [];
312
+ const defer = deferFn => {
313
+ stepDeferred.push(deferFn);
314
+ };
315
+ const runCleanups = async () => {
316
+ for (let i = stepDeferred.length - 1; i >= 0; i--) {
317
+ try {
318
+ await stepDeferred[i]?.();
319
+ }
320
+ catch {
321
+ }
322
+ }
323
+ };
324
+ let fnSucceeded = false;
325
+ let fnValue;
326
+ let fnError;
327
+ const fnPromise = (async () => {
328
+ try {
329
+ fnValue = await fn(defer, controllerSignal);
330
+ fnSucceeded = true;
331
+ }
332
+ catch (e) {
333
+ fnError = e;
334
+ fnSucceeded = false;
335
+ }
336
+ })();
337
+ if (controllerSignal.aborted) {
338
+ await fnPromise;
339
+ await runCleanups();
340
+ if (fnSucceeded) {
341
+ resolve(fnValue);
342
+ }
343
+ else {
344
+ halted = true;
345
+ reject(fnError);
346
+ }
347
+ return;
348
+ }
349
+ try {
350
+ await new Promise((res, rej) => {
351
+ const onAbort = () => {
352
+ rej(new AbortError(abortSignalReason(controllerSignal)));
353
+ };
354
+ controllerSignal.addEventListener("abort", onAbort, {
355
+ once: true
356
+ });
357
+ fnPromise.then(() => {
358
+ controllerSignal.removeEventListener("abort", onAbort);
359
+ res();
360
+ });
361
+ });
362
+ }
363
+ catch (e) {
364
+ await runCleanups();
365
+ halted = true;
366
+ reject(e);
367
+ return;
368
+ }
369
+ await runCleanups();
370
+ if (fnSucceeded) {
371
+ resolve(fnValue);
372
+ }
373
+ else {
374
+ halted = true;
375
+ reject(fnError);
376
+ }
377
+ });
378
+ return {
379
+ then: promise.then.bind(promise),
380
+ catch: promise.catch.bind(promise),
381
+ finally: promise.finally.bind(promise)
382
+ };
383
+ };
384
+ return {
385
+ step,
386
+ signal: controllerSignal
387
+ };
388
+ }
290
389
  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) {
package/dist/time.js CHANGED
@@ -1,11 +1,7 @@
1
1
  export function isTimestampSameDay(timestamp1, timestamp2) {
2
2
  const diff = timestamp1 - timestamp2;
3
- if (diff >= -86400000 && diff <= 86400000) {
4
- const day1 = Math.floor(timestamp1 / 86400000);
5
- const day2 = Math.floor(timestamp2 / 86400000);
6
- if (day1 === day2) {
7
- return true;
8
- }
3
+ if (diff < -86400000 || diff > 86400000) {
4
+ return false;
9
5
  }
10
6
  const date1 = new Date(timestamp1);
11
7
  const date2 = new Date(timestamp2);
@@ -51,4 +51,14 @@ export declare class TimeoutError extends Error {
51
51
  }
52
52
  export declare function runTimeout<TResult, E = unknown>(fn: (deferFn: DeferFn) => Promise<TResult> | TResult, timeoutMs: number, options?: Options): Promise<Result<TResult, E>>;
53
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.6",
3
+ "version": "0.0.8",
4
4
  "description": "A collection of utils for Filen",
5
5
  "private": false,
6
6
  "repository": {