orgnote-api 0.50.0 → 0.50.2
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/constants/i18n-keys.d.ts +0 -1
- package/models/default-commands.d.ts +0 -1
- package/models/default-commands.js +0 -1
- package/models/file-index.d.ts +1 -0
- package/package.json +1 -1
- package/utils/__tests__/run-with-concurrency.spec.d.ts +1 -0
- package/utils/__tests__/run-with-concurrency.spec.js +63 -0
- package/utils/index.d.ts +1 -0
- package/utils/index.js +1 -0
- package/utils/run-with-concurrency.d.ts +7 -0
- package/utils/run-with-concurrency.js +31 -0
package/constants/i18n-keys.d.ts
CHANGED
|
@@ -382,7 +382,6 @@ export declare const I18N: {
|
|
|
382
382
|
EDITOR_INSERT_CHECK_LIST: DefaultCommands.EDITOR_INSERT_CHECK_LIST;
|
|
383
383
|
EDITOR_INSERT_HORIZONTAL_RULE: DefaultCommands.EDITOR_INSERT_HORIZONTAL_RULE;
|
|
384
384
|
EDITOR_INSERT_HTML_BLOCK: DefaultCommands.EDITOR_INSERT_HTML_BLOCK;
|
|
385
|
-
EDITOR_INSERT_CHECKBOX: DefaultCommands.EDITOR_INSERT_CHECKBOX;
|
|
386
385
|
EDITOR_INSERT_TABLE: DefaultCommands.EDITOR_INSERT_TABLE;
|
|
387
386
|
EDITOR_INSERT_TAG: DefaultCommands.EDITOR_INSERT_TAG;
|
|
388
387
|
EDITOR_INSERT_DATETIME: DefaultCommands.EDITOR_INSERT_DATETIME;
|
|
@@ -137,7 +137,6 @@ export declare enum DefaultCommands {
|
|
|
137
137
|
EDITOR_INSERT_CHECK_LIST = "insert check list",
|
|
138
138
|
EDITOR_INSERT_HORIZONTAL_RULE = "insert horizontal rule",
|
|
139
139
|
EDITOR_INSERT_HTML_BLOCK = "insert html block",
|
|
140
|
-
EDITOR_INSERT_CHECKBOX = "insert checkbox",
|
|
141
140
|
EDITOR_INSERT_TABLE = "insert table",
|
|
142
141
|
EDITOR_INSERT_TAG = "insert tag",
|
|
143
142
|
EDITOR_INSERT_DATETIME = "insert datetime",
|
|
@@ -162,7 +162,6 @@ export var DefaultCommands;
|
|
|
162
162
|
DefaultCommands["EDITOR_INSERT_CHECK_LIST"] = "insert check list";
|
|
163
163
|
DefaultCommands["EDITOR_INSERT_HORIZONTAL_RULE"] = "insert horizontal rule";
|
|
164
164
|
DefaultCommands["EDITOR_INSERT_HTML_BLOCK"] = "insert html block";
|
|
165
|
-
DefaultCommands["EDITOR_INSERT_CHECKBOX"] = "insert checkbox";
|
|
166
165
|
DefaultCommands["EDITOR_INSERT_TABLE"] = "insert table";
|
|
167
166
|
DefaultCommands["EDITOR_INSERT_TAG"] = "insert tag";
|
|
168
167
|
DefaultCommands["EDITOR_INSERT_DATETIME"] = "insert datetime";
|
package/models/file-index.d.ts
CHANGED
package/package.json
CHANGED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { expect, expectTypeOf, test, vi } from 'vitest';
|
|
2
|
+
import { runWithConcurrency } from "../run-with-concurrency.js";
|
|
3
|
+
const sleep = (ms) => new Promise((resolve) => {
|
|
4
|
+
setTimeout(resolve, ms);
|
|
5
|
+
});
|
|
6
|
+
test('runWithConcurrency returns results in input order', async () => {
|
|
7
|
+
const result = await runWithConcurrency([3, 1, 2], 2, async (value) => {
|
|
8
|
+
await sleep(value * 2);
|
|
9
|
+
return `item-${value}`;
|
|
10
|
+
});
|
|
11
|
+
expect(result).toEqual(['item-3', 'item-1', 'item-2']);
|
|
12
|
+
});
|
|
13
|
+
test('runWithConcurrency does not exceed the concurrency limit', async () => {
|
|
14
|
+
let activeCount = 0;
|
|
15
|
+
let maxActiveCount = 0;
|
|
16
|
+
await runWithConcurrency([1, 2, 3, 4, 5, 6], 3, async (value) => {
|
|
17
|
+
activeCount += 1;
|
|
18
|
+
maxActiveCount = Math.max(maxActiveCount, activeCount);
|
|
19
|
+
await sleep(value === 1 ? 15 : 5);
|
|
20
|
+
activeCount -= 1;
|
|
21
|
+
return value;
|
|
22
|
+
});
|
|
23
|
+
expect(maxActiveCount).toBeLessThanOrEqual(3);
|
|
24
|
+
});
|
|
25
|
+
test('runWithConcurrency supports synchronous workers', async () => {
|
|
26
|
+
const result = await runWithConcurrency([1, 2, 3], 2, (value) => value * 10);
|
|
27
|
+
expect(result).toEqual([10, 20, 30]);
|
|
28
|
+
});
|
|
29
|
+
test('runWithConcurrency returns empty array for empty input', async () => {
|
|
30
|
+
const worker = vi.fn();
|
|
31
|
+
const result = await runWithConcurrency([], 4, worker);
|
|
32
|
+
expect(result).toEqual([]);
|
|
33
|
+
expect(worker).not.toHaveBeenCalled();
|
|
34
|
+
});
|
|
35
|
+
test('runWithConcurrency handles concurrency larger than input length', async () => {
|
|
36
|
+
const result = await runWithConcurrency([1, 2], 100, async (value) => value * 2);
|
|
37
|
+
expect(result).toEqual([2, 4]);
|
|
38
|
+
});
|
|
39
|
+
test('runWithConcurrency rejects invalid concurrency values', async () => {
|
|
40
|
+
await expect(runWithConcurrency([1], 0, async (value) => value)).rejects.toThrow(RangeError);
|
|
41
|
+
await expect(runWithConcurrency([1], -1, async (value) => value)).rejects.toThrow(RangeError);
|
|
42
|
+
await expect(runWithConcurrency([1], 1.5, async (value) => value)).rejects.toThrow(RangeError);
|
|
43
|
+
await expect(runWithConcurrency([1], Number.POSITIVE_INFINITY, async (value) => value)).rejects.toThrow(RangeError);
|
|
44
|
+
await expect(runWithConcurrency([1], Number.NaN, async (value) => value)).rejects.toThrow(RangeError);
|
|
45
|
+
});
|
|
46
|
+
test('runWithConcurrency rejects when worker fails', async () => {
|
|
47
|
+
const failure = new Error('boom');
|
|
48
|
+
await expect(runWithConcurrency([1, 2, 3], 2, async (value) => {
|
|
49
|
+
if (value === 2)
|
|
50
|
+
throw failure;
|
|
51
|
+
await sleep(5);
|
|
52
|
+
return value;
|
|
53
|
+
})).rejects.toBe(failure);
|
|
54
|
+
});
|
|
55
|
+
test('runWithConcurrency infers resolved result types', async () => {
|
|
56
|
+
const promise = runWithConcurrency([1, 2, 3], 2, async (value) => ({
|
|
57
|
+
id: value,
|
|
58
|
+
label: `item-${value}`,
|
|
59
|
+
}));
|
|
60
|
+
expectTypeOf(promise).toEqualTypeOf();
|
|
61
|
+
const result = await promise;
|
|
62
|
+
expect(result[0]).toEqual({ id: 1, label: 'item-1' });
|
|
63
|
+
});
|
package/utils/index.d.ts
CHANGED
package/utils/index.js
CHANGED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run workers with a bounded concurrency level while preserving input order.
|
|
3
|
+
* If one worker rejects, the returned promise rejects immediately. Other
|
|
4
|
+
* in-flight workers may still finish their current item because promises are
|
|
5
|
+
* not cancellable.
|
|
6
|
+
*/
|
|
7
|
+
export declare const runWithConcurrency: <TItem, TResult>(items: readonly TItem[], concurrency: number, worker: (item: TItem, index: number) => TResult | PromiseLike<TResult>) => Promise<Array<Awaited<TResult>>>;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
const assertConcurrency = (concurrency) => {
|
|
2
|
+
if (Number.isInteger(concurrency) && concurrency > 0)
|
|
3
|
+
return;
|
|
4
|
+
throw new RangeError('concurrency must be a positive integer');
|
|
5
|
+
};
|
|
6
|
+
const createWorkers = (items, concurrency, worker, results) => {
|
|
7
|
+
let nextIndex = 0;
|
|
8
|
+
const runWorker = async () => {
|
|
9
|
+
while (nextIndex < items.length) {
|
|
10
|
+
const currentIndex = nextIndex;
|
|
11
|
+
nextIndex += 1;
|
|
12
|
+
results[currentIndex] = await worker(items[currentIndex], currentIndex);
|
|
13
|
+
}
|
|
14
|
+
};
|
|
15
|
+
return Array.from({ length: Math.min(concurrency, items.length) }, () => runWorker());
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Run workers with a bounded concurrency level while preserving input order.
|
|
19
|
+
* If one worker rejects, the returned promise rejects immediately. Other
|
|
20
|
+
* in-flight workers may still finish their current item because promises are
|
|
21
|
+
* not cancellable.
|
|
22
|
+
*/
|
|
23
|
+
export const runWithConcurrency = async (items, concurrency, worker) => {
|
|
24
|
+
assertConcurrency(concurrency);
|
|
25
|
+
if (items.length === 0)
|
|
26
|
+
return [];
|
|
27
|
+
const results = new Array(items.length);
|
|
28
|
+
const workers = createWorkers(items, concurrency, worker, results);
|
|
29
|
+
await Promise.all(workers);
|
|
30
|
+
return results;
|
|
31
|
+
};
|