patron-oop 1.43.0 → 1.45.0
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/CHANGELOG.md +17 -0
- package/dist/patron.cjs +295 -275
- package/dist/patron.cjs.map +1 -1
- package/dist/patron.d.ts +181 -155
- package/dist/patron.js +283 -268
- package/dist/patron.js.map +1 -1
- package/dist/patron.min.js +1 -1
- package/dist/patron.min.mjs +1 -1
- package/dist/patron.min.mjs.map +1 -1
- package/dist/patron.mjs +283 -268
- package/dist/patron.mjs.map +1 -1
- package/package.json +1 -1
- package/src/Guest/Guest.test.ts +11 -6
- package/src/Guest/Guest.ts +7 -14
- package/src/Guest/GuestApplied.test.ts +13 -0
- package/src/Guest/GuestApplied.ts +16 -0
- package/src/Guest/GuestCast.test.ts +4 -5
- package/src/Guest/GuestCast.ts +3 -10
- package/src/Guest/GuestDisposable.test.ts +13 -17
- package/src/Guest/GuestDisposable.ts +3 -3
- package/src/Guest/GuestExecutorApplied.test.ts +27 -0
- package/src/Guest/GuestExecutorApplied.ts +23 -0
- package/src/Guest/GuestObject.test.ts +6 -6
- package/src/Guest/GuestObject.ts +3 -3
- package/src/Guest/GuestPool.test.ts +5 -22
- package/src/Guest/GuestPool.ts +7 -8
- package/src/Guest/GuestSync.test.ts +2 -2
- package/src/Patron/Patron.test.ts +4 -5
- package/src/Patron/Patron.ts +11 -3
- package/src/Patron/PatronOnce.sourceEmpty.test.ts +2 -2
- package/src/Patron/PatronOnce.test.ts +2 -2
- package/src/Patron/PatronOnce.ts +3 -9
- package/src/Patron/PatronPool.test.ts +2 -1
- package/src/Patron/PatronPool.ts +22 -27
- package/src/Private/PrivateClass.modules.test.ts +11 -8
- package/src/Private/PrivateClass.test.ts +7 -6
- package/src/Source/Source.test.ts +9 -5
- package/src/Source/Source.ts +46 -30
- package/src/Source/SourceActive.test.ts +13 -0
- package/src/Source/SourceActive.ts +41 -0
- package/src/Source/SourceAll._asArray.test.ts +22 -0
- package/src/Source/SourceAll._twoValuesAfter.test.ts +19 -0
- package/src/Source/SourceAll._twoValuesBefore.test.ts +19 -0
- package/src/Source/SourceAll._withPatron.test.ts +25 -0
- package/src/{Guest/GuestAwareAll.ts → Source/SourceAll.ts} +11 -11
- package/src/Source/SourceApplied.test.ts +14 -0
- package/src/Source/SourceApplied.ts +23 -0
- package/src/Source/SourceDynamic.ofSource.test.ts +12 -12
- package/src/Source/SourceDynamic.test.ts +9 -9
- package/src/Source/SourceDynamic.ts +7 -7
- package/src/Source/SourceExecutorApplied.test.ts +30 -0
- package/src/Source/SourceExecutorApplied.ts +22 -0
- package/src/Source/SourceMap.defered.test.ts +46 -0
- package/src/Source/SourceMap.fn.test.ts +27 -0
- package/src/Source/SourceMap.test.ts +32 -0
- package/src/Source/SourceMap.ts +48 -0
- package/src/Source/SourceOnce.notcalled.test.ts +13 -0
- package/src/Source/SourceOnce.test.ts +10 -0
- package/src/Source/SourceOnce.ts +31 -0
- package/src/Source/SourceRace.test.ts +46 -0
- package/src/Source/SourceRace.ts +30 -0
- package/src/Source/SourceSequence.defered.test.ts +53 -0
- package/src/Source/SourceSequence.test.ts +30 -0
- package/src/{Guest/GuestAwareSequence.ts → Source/SourceSequence.ts} +14 -19
- package/src/Source/SourceWithPool.empty.test.ts +14 -0
- package/src/Source/SourceWithPool.test.ts +10 -0
- package/src/Source/SourceWithPool.ts +58 -0
- package/src/index.ts +9 -7
- package/test-utils/debounce.ts +11 -0
- package/test-utils/id.ts +1 -0
- package/test-utils/wait.ts +6 -3
- package/src/Guest/GuestAware.test.ts +0 -13
- package/src/Guest/GuestAware.ts +0 -59
- package/src/Guest/GuestAwareActive.test.ts +0 -12
- package/src/Guest/GuestAwareActive.ts +0 -42
- package/src/Guest/GuestAwareAll._asArray.test.ts +0 -19
- package/src/Guest/GuestAwareAll._twoValuesAfter.test.ts +0 -16
- package/src/Guest/GuestAwareAll._twoValuesBefore.test.ts +0 -16
- package/src/Guest/GuestAwareAll._withPatron.test.ts +0 -22
- package/src/Guest/GuestAwareMap.defered.test.ts +0 -46
- package/src/Guest/GuestAwareMap.fn.test.ts +0 -27
- package/src/Guest/GuestAwareMap.test.ts +0 -29
- package/src/Guest/GuestAwareMap.ts +0 -48
- package/src/Guest/GuestAwareRace.test.ts +0 -46
- package/src/Guest/GuestAwareRace.ts +0 -33
- package/src/Guest/GuestAwareSequence.defered.test.ts +0 -58
- package/src/Guest/GuestAwareSequence.test.ts +0 -30
- package/src/Source/SourceEmpty.test.ts +0 -20
- package/src/Source/SourceEmpty.ts +0 -31
@@ -1,7 +1,7 @@
|
|
1
1
|
import { SourceDynamic } from "./SourceDynamic";
|
2
|
-
import { expect, test } from "vitest";
|
2
|
+
import { expect, test, vitest } from "vitest";
|
3
3
|
import { give, Guest } from "../Guest/Guest";
|
4
|
-
import {
|
4
|
+
import { Source } from "./Source";
|
5
5
|
|
6
6
|
test("SourceDynamic", () => {
|
7
7
|
let theValue = 1;
|
@@ -9,18 +9,18 @@ test("SourceDynamic", () => {
|
|
9
9
|
new Guest((value: number) => {
|
10
10
|
theValue = value;
|
11
11
|
}),
|
12
|
-
new
|
12
|
+
new Source((guest) => {
|
13
13
|
give(theValue, guest);
|
14
14
|
}),
|
15
15
|
);
|
16
16
|
|
17
|
-
|
18
|
-
|
19
|
-
|
17
|
+
const g1 = vitest.fn();
|
18
|
+
sourceDynamic.value(g1);
|
19
|
+
expect(g1).toBeCalledWith(1);
|
20
20
|
|
21
21
|
sourceDynamic.give(2);
|
22
22
|
|
23
|
-
|
24
|
-
|
25
|
-
|
23
|
+
const g2 = vitest.fn();
|
24
|
+
sourceDynamic.value(g2);
|
25
|
+
expect(g2).toBeCalledWith(2);
|
26
26
|
});
|
@@ -1,26 +1,26 @@
|
|
1
1
|
import { give, GuestType } from "../Guest/Guest";
|
2
|
-
import {
|
2
|
+
import { SourceType, value } from "./Source";
|
3
3
|
import { PatronPool } from "../Patron/PatronPool";
|
4
|
-
import {
|
4
|
+
import { SourceWithPoolType } from "./SourceWithPool";
|
5
5
|
|
6
6
|
/**
|
7
7
|
* @url https://kosukhin.github.io/patron.site/#/source-dynamic
|
8
8
|
*/
|
9
|
-
export class SourceDynamic<T = unknown> implements
|
9
|
+
export class SourceDynamic<T = unknown> implements SourceWithPoolType<T> {
|
10
10
|
public constructor(
|
11
11
|
private baseGuest: GuestType<T>,
|
12
|
-
private
|
12
|
+
private baseSource: SourceType<T>,
|
13
13
|
) {
|
14
14
|
if (baseGuest === undefined) {
|
15
15
|
throw new Error("SourceDynamic didnt receive baseGuest argument");
|
16
16
|
}
|
17
|
-
if (
|
18
|
-
throw new Error("SourceDynamic didnt receive
|
17
|
+
if (baseSource === undefined) {
|
18
|
+
throw new Error("SourceDynamic didnt receive baseSource argument");
|
19
19
|
}
|
20
20
|
}
|
21
21
|
|
22
22
|
public value(guest: GuestType<T>) {
|
23
|
-
value(this.
|
23
|
+
value(this.baseSource, guest);
|
24
24
|
return this;
|
25
25
|
}
|
26
26
|
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import { SourceExecutorApplied } from "../Source/SourceExecutorApplied";
|
2
|
+
import { SourceWithPool } from "../Source/SourceWithPool";
|
3
|
+
import { debounce } from "../../test-utils/debounce";
|
4
|
+
import { expect, test, vi } from "vitest";
|
5
|
+
import { Patron } from "../Patron/Patron";
|
6
|
+
|
7
|
+
test("SourceExecutorApplied.test", () => {
|
8
|
+
vi.useFakeTimers({ shouldAdvanceTime: true });
|
9
|
+
|
10
|
+
const source = new SourceWithPool<number>();
|
11
|
+
const sourceDebounced = new SourceExecutorApplied(
|
12
|
+
source,
|
13
|
+
debounce.bind(null, 100),
|
14
|
+
);
|
15
|
+
|
16
|
+
let counter = 0;
|
17
|
+
sourceDebounced.value(
|
18
|
+
new Patron((v) => {
|
19
|
+
counter += v;
|
20
|
+
}),
|
21
|
+
);
|
22
|
+
|
23
|
+
source.give(1);
|
24
|
+
source.give(1);
|
25
|
+
source.give(1);
|
26
|
+
|
27
|
+
vi.runOnlyPendingTimers();
|
28
|
+
|
29
|
+
expect(counter).toBe(1);
|
30
|
+
});
|
@@ -0,0 +1,22 @@
|
|
1
|
+
import {
|
2
|
+
SourceExecutorType,
|
3
|
+
SourceObjectType,
|
4
|
+
SourceType,
|
5
|
+
value,
|
6
|
+
} from "../Source/Source";
|
7
|
+
|
8
|
+
/**
|
9
|
+
* @url https://kosukhin.github.io/patron.site/#/source/source-executor-applied
|
10
|
+
*/
|
11
|
+
export class SourceExecutorApplied<T> implements SourceObjectType<T> {
|
12
|
+
public value: SourceExecutorType<T>;
|
13
|
+
|
14
|
+
public constructor(
|
15
|
+
source: SourceType<T>,
|
16
|
+
applier: (executor: SourceExecutorType<T>) => SourceExecutorType<T>,
|
17
|
+
) {
|
18
|
+
this.value = applier((g) => {
|
19
|
+
value(source, g);
|
20
|
+
});
|
21
|
+
}
|
22
|
+
}
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import { wait } from "../../test-utils/wait";
|
2
|
+
import { Private } from "../Private/Private";
|
3
|
+
import { afterEach, beforeEach, expect, test, vi } from "vitest";
|
4
|
+
import { SourceWithPool } from "./SourceWithPool";
|
5
|
+
import { give, GuestType } from "../Guest/Guest";
|
6
|
+
import { Source, SourceType, value } from "./Source";
|
7
|
+
import { SourceMap } from "./SourceMap";
|
8
|
+
import { GuestCast } from "../Guest/GuestCast";
|
9
|
+
|
10
|
+
beforeEach(() => {
|
11
|
+
vi.useFakeTimers({ shouldAdvanceTime: true });
|
12
|
+
});
|
13
|
+
|
14
|
+
afterEach(() => {
|
15
|
+
vi.runOnlyPendingTimers();
|
16
|
+
vi.useRealTimers();
|
17
|
+
});
|
18
|
+
|
19
|
+
function x2(baseNumber: SourceType<number>) {
|
20
|
+
return (guest: GuestType<number>) => {
|
21
|
+
value(
|
22
|
+
baseNumber,
|
23
|
+
new GuestCast(guest, (v) => {
|
24
|
+
give(v * 2, guest);
|
25
|
+
}),
|
26
|
+
);
|
27
|
+
return guest;
|
28
|
+
};
|
29
|
+
}
|
30
|
+
|
31
|
+
test("SourceMap.defered.test", async () => {
|
32
|
+
const sourceOf = (val: number) =>
|
33
|
+
new Source(async (guest) => {
|
34
|
+
await wait(5);
|
35
|
+
give(val, guest);
|
36
|
+
});
|
37
|
+
const source = new SourceWithPool([1, 2, 3, 9].map(sourceOf));
|
38
|
+
const guestMapped = new SourceMap(source, new Private(x2));
|
39
|
+
const callFn = vi.fn();
|
40
|
+
guestMapped.value((v) => {
|
41
|
+
callFn(v.join());
|
42
|
+
});
|
43
|
+
await wait(50);
|
44
|
+
expect(callFn).toBeCalled();
|
45
|
+
expect(callFn).toBeCalledWith("2,4,6,18");
|
46
|
+
});
|
@@ -0,0 +1,27 @@
|
|
1
|
+
import { Private } from "../Private/Private";
|
2
|
+
import { expect, test, vitest } from "vitest";
|
3
|
+
import { SourceWithPool } from "./SourceWithPool";
|
4
|
+
import { give, GuestType } from "../Guest/Guest";
|
5
|
+
import { SourceType, value } from "./Source";
|
6
|
+
import { SourceMap } from "./SourceMap";
|
7
|
+
import { GuestCast } from "../Guest/GuestCast";
|
8
|
+
|
9
|
+
function x2(baseNumber: SourceType<number>) {
|
10
|
+
return (guest: GuestType<number>) => {
|
11
|
+
value(
|
12
|
+
baseNumber,
|
13
|
+
new GuestCast(<GuestType>guest, (v) => {
|
14
|
+
give(v * 2, guest);
|
15
|
+
}),
|
16
|
+
);
|
17
|
+
return guest;
|
18
|
+
};
|
19
|
+
}
|
20
|
+
|
21
|
+
test("SourceMap.test", () => {
|
22
|
+
const source = new SourceWithPool([1, 2, 3, 9]);
|
23
|
+
const guestMapped = new SourceMap(source, new Private(x2));
|
24
|
+
const g = vitest.fn();
|
25
|
+
guestMapped.value(g);
|
26
|
+
expect(g).toBeCalledWith([2, 4, 6, 18]);
|
27
|
+
});
|
@@ -0,0 +1,32 @@
|
|
1
|
+
import { expect, test } from "vitest";
|
2
|
+
import { give, GuestType } from "../Guest/Guest";
|
3
|
+
import { SourceObjectType, SourceType, value } from "./Source";
|
4
|
+
import { SourceMap } from "./SourceMap";
|
5
|
+
import { GuestCast } from "../Guest/GuestCast";
|
6
|
+
import { SourceWithPool } from "./SourceWithPool";
|
7
|
+
import { PrivateClass } from "../Private/PrivateClass";
|
8
|
+
import { GuestSync } from "../Guest/GuestSync";
|
9
|
+
|
10
|
+
class X2 implements SourceObjectType<number> {
|
11
|
+
public constructor(private baseNumber: SourceType<number>) {}
|
12
|
+
|
13
|
+
public value(guest: GuestType<number>) {
|
14
|
+
value(
|
15
|
+
this.baseNumber,
|
16
|
+
new GuestCast(<GuestType>guest, (v) => {
|
17
|
+
give(v * 2, guest);
|
18
|
+
}),
|
19
|
+
);
|
20
|
+
return this;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
test("SourceMap.test", () => {
|
25
|
+
const source = new SourceWithPool([1, 2, 3, 9]);
|
26
|
+
const guestMapped = new SourceMap(source, new PrivateClass(X2));
|
27
|
+
const guest = new GuestSync([]);
|
28
|
+
|
29
|
+
guestMapped.value(guest);
|
30
|
+
|
31
|
+
expect(guest.value().join()).toBe("2,4,6,18");
|
32
|
+
});
|
@@ -0,0 +1,48 @@
|
|
1
|
+
import { PrivateType } from "../Private/Private";
|
2
|
+
import { give, GuestType } from "../Guest/Guest";
|
3
|
+
import {
|
4
|
+
Source,
|
5
|
+
SourceObjectType,
|
6
|
+
SourceType,
|
7
|
+
isSource,
|
8
|
+
value,
|
9
|
+
} from "./Source";
|
10
|
+
import { SourceAll } from "./SourceAll";
|
11
|
+
import { GuestCast } from "../Guest/GuestCast";
|
12
|
+
|
13
|
+
/**
|
14
|
+
* @url https://kosukhin.github.io/patron.site/#/guest/source-map
|
15
|
+
*/
|
16
|
+
export class SourceMap<T, TG> implements SourceObjectType<TG[]> {
|
17
|
+
public constructor(
|
18
|
+
private baseSource: SourceType<T[]>,
|
19
|
+
private targetSource: PrivateType<SourceType<TG>>,
|
20
|
+
) {
|
21
|
+
if (baseSource === undefined) {
|
22
|
+
throw new Error("SourceMap didnt receive baseSource argument");
|
23
|
+
}
|
24
|
+
if (targetSource === undefined) {
|
25
|
+
throw new Error("SourceMap didnt receive targetSource argument");
|
26
|
+
}
|
27
|
+
}
|
28
|
+
|
29
|
+
public value(guest: GuestType<TG[]>) {
|
30
|
+
const all = new SourceAll();
|
31
|
+
value(
|
32
|
+
this.baseSource,
|
33
|
+
new GuestCast(<GuestType>guest, (theValue) => {
|
34
|
+
theValue.forEach((val, index) => {
|
35
|
+
const valueSource = isSource(val)
|
36
|
+
? val
|
37
|
+
: new Source((innerGuest) => {
|
38
|
+
give(val, innerGuest);
|
39
|
+
});
|
40
|
+
const targetSource = this.targetSource.get(valueSource);
|
41
|
+
value(targetSource, all.guestKey(index.toString()));
|
42
|
+
});
|
43
|
+
}),
|
44
|
+
);
|
45
|
+
all.valueArray(<GuestType>guest);
|
46
|
+
return this;
|
47
|
+
}
|
48
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { expect, test, vi, vitest } from "vitest";
|
2
|
+
import { SourceOnce } from "./SourceOnce";
|
3
|
+
|
4
|
+
test("SourceOnce.notcalled.test", () => {
|
5
|
+
const source = new SourceOnce();
|
6
|
+
const guestNotCalled = vi.fn();
|
7
|
+
source.value(guestNotCalled);
|
8
|
+
expect(guestNotCalled).not.toHaveBeenCalled();
|
9
|
+
source.give(111);
|
10
|
+
const g = vitest.fn();
|
11
|
+
source.value(g);
|
12
|
+
expect(g).toBeCalledWith(111);
|
13
|
+
});
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { SourceOnce } from "./SourceOnce";
|
2
|
+
import { expect, test, vitest } from "vitest";
|
3
|
+
|
4
|
+
test("SourceOnce.test", () => {
|
5
|
+
const source = new SourceOnce(123);
|
6
|
+
source.give(321);
|
7
|
+
const g = vitest.fn();
|
8
|
+
source.value(g);
|
9
|
+
expect(g).toBeCalledWith(123);
|
10
|
+
});
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import { GuestType } from "../Guest/Guest";
|
2
|
+
import { PatronPool } from "../Patron/PatronPool";
|
3
|
+
import { value } from "./Source";
|
4
|
+
import { SourceWithPool, SourceWithPoolType } from "./SourceWithPool";
|
5
|
+
|
6
|
+
/**
|
7
|
+
* @url https://kosukhin.github.io/patron.site/#/source/source-once
|
8
|
+
*/
|
9
|
+
export class SourceOnce<T> implements SourceWithPoolType<T> {
|
10
|
+
private source: SourceWithPool<T>;
|
11
|
+
|
12
|
+
public constructor(initialValue?: T) {
|
13
|
+
this.source = new SourceWithPool(initialValue);
|
14
|
+
}
|
15
|
+
|
16
|
+
public value(guest: GuestType<T>) {
|
17
|
+
value(this.source, guest);
|
18
|
+
return this;
|
19
|
+
}
|
20
|
+
|
21
|
+
public give(value: T): this {
|
22
|
+
if (!this.source.filled()) {
|
23
|
+
this.source.give(value);
|
24
|
+
}
|
25
|
+
return this;
|
26
|
+
}
|
27
|
+
|
28
|
+
public pool(): PatronPool<T> {
|
29
|
+
return this.source.pool();
|
30
|
+
}
|
31
|
+
}
|
@@ -0,0 +1,46 @@
|
|
1
|
+
import { SourceWithPool } from "../Source/SourceWithPool";
|
2
|
+
import { SourceRace } from "./SourceRace";
|
3
|
+
import { afterEach, beforeEach, expect, test, vi, vitest } from "vitest";
|
4
|
+
|
5
|
+
beforeEach(() => {
|
6
|
+
vi.useFakeTimers();
|
7
|
+
});
|
8
|
+
|
9
|
+
afterEach(() => {
|
10
|
+
vi.useRealTimers();
|
11
|
+
});
|
12
|
+
|
13
|
+
test("SourceRace.test", async () => {
|
14
|
+
const sBuild = (result: number, delay: number) => {
|
15
|
+
const s = new SourceWithPool();
|
16
|
+
|
17
|
+
setTimeout(() => {
|
18
|
+
s.give(result);
|
19
|
+
}, delay);
|
20
|
+
|
21
|
+
return s;
|
22
|
+
};
|
23
|
+
|
24
|
+
const s2 = sBuild(2, 100);
|
25
|
+
const s1 = sBuild(1, 200);
|
26
|
+
|
27
|
+
const sAny = new SourceRace([s1, s2]);
|
28
|
+
|
29
|
+
await vi.advanceTimersByTime(201);
|
30
|
+
|
31
|
+
const g1 = vitest.fn();
|
32
|
+
sAny.value(g1);
|
33
|
+
expect(g1).toBeCalledWith(1);
|
34
|
+
|
35
|
+
setTimeout(() => {
|
36
|
+
s1.give(3);
|
37
|
+
s2.give(4);
|
38
|
+
}, 300);
|
39
|
+
|
40
|
+
await vi.advanceTimersByTime(301);
|
41
|
+
|
42
|
+
const g2 = vitest.fn();
|
43
|
+
sAny.value(g2);
|
44
|
+
// ignores second value
|
45
|
+
expect(g2).toBeCalledWith(3);
|
46
|
+
});
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import { give, GuestType } from "../Guest/Guest";
|
2
|
+
import { SourceObjectType, SourceType, value } from "./Source";
|
3
|
+
import { GuestCast } from "../Guest/GuestCast";
|
4
|
+
|
5
|
+
/**
|
6
|
+
* @url https://kosukhin.github.io/patron.site/#/guest/source-race
|
7
|
+
*/
|
8
|
+
export class SourceRace<T> implements SourceObjectType<T> {
|
9
|
+
public constructor(private sources: SourceType<T>[]) {
|
10
|
+
if (sources === undefined) {
|
11
|
+
throw new Error("SourceRace didnt receive sources argument");
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
public value(guest: GuestType<T>): this {
|
16
|
+
let connectedWithSource: SourceType | null = null;
|
17
|
+
this.sources.forEach((source) => {
|
18
|
+
value(
|
19
|
+
source,
|
20
|
+
new GuestCast(<GuestType>guest, (value) => {
|
21
|
+
if (!connectedWithSource || connectedWithSource === source) {
|
22
|
+
give(value as T, guest);
|
23
|
+
connectedWithSource = source;
|
24
|
+
}
|
25
|
+
}),
|
26
|
+
);
|
27
|
+
});
|
28
|
+
return this;
|
29
|
+
}
|
30
|
+
}
|
@@ -0,0 +1,53 @@
|
|
1
|
+
import { SourceSequence } from "./SourceSequence";
|
2
|
+
import { give } from "../Guest/Guest";
|
3
|
+
import { Source, SourceObjectType, SourceType, value } from "./Source";
|
4
|
+
import { GuestCast } from "../Guest/GuestCast";
|
5
|
+
import { GuestType } from "../Guest/Guest";
|
6
|
+
import { afterEach, beforeEach, expect, test, vi } from "vitest";
|
7
|
+
import { SourceWithPool } from "./SourceWithPool";
|
8
|
+
import { PrivateClass } from "../Private/PrivateClass";
|
9
|
+
import { wait } from "../../test-utils/wait";
|
10
|
+
|
11
|
+
beforeEach(() => {
|
12
|
+
vi.useFakeTimers({ shouldAdvanceTime: true });
|
13
|
+
});
|
14
|
+
|
15
|
+
afterEach(() => {
|
16
|
+
vi.runOnlyPendingTimers();
|
17
|
+
vi.useRealTimers();
|
18
|
+
});
|
19
|
+
|
20
|
+
class X2 implements SourceObjectType<number> {
|
21
|
+
public constructor(private baseNumber: SourceType<number>) {}
|
22
|
+
|
23
|
+
public value(guest: GuestType<number>) {
|
24
|
+
value(
|
25
|
+
this.baseNumber,
|
26
|
+
new GuestCast(<GuestType>guest, (v) => {
|
27
|
+
give(v * 2, guest);
|
28
|
+
}),
|
29
|
+
);
|
30
|
+
return this;
|
31
|
+
}
|
32
|
+
}
|
33
|
+
|
34
|
+
test("SourceSequence.defered.test", async () => {
|
35
|
+
const sourceOf = (val: number) =>
|
36
|
+
new Source((guest) => {
|
37
|
+
setTimeout(() => {
|
38
|
+
give(val, guest);
|
39
|
+
}, 10);
|
40
|
+
});
|
41
|
+
const source = new SourceWithPool([1, 2, 3, 9].map(sourceOf));
|
42
|
+
|
43
|
+
const sequence = new SourceSequence(source, new PrivateClass(X2));
|
44
|
+
|
45
|
+
const callFn = vi.fn();
|
46
|
+
sequence.value((v) => {
|
47
|
+
callFn(v.join());
|
48
|
+
});
|
49
|
+
|
50
|
+
await wait(51);
|
51
|
+
expect(callFn).toBeCalled();
|
52
|
+
expect(callFn).toBeCalledWith("2,4,6,18");
|
53
|
+
});
|
@@ -0,0 +1,30 @@
|
|
1
|
+
import { SourceSequence } from "./SourceSequence";
|
2
|
+
import { give } from "../Guest/Guest";
|
3
|
+
import { SourceObjectType, SourceType, value } from "./Source";
|
4
|
+
import { GuestCast } from "../Guest/GuestCast";
|
5
|
+
import { GuestType } from "../Guest/Guest";
|
6
|
+
import { expect, test, vitest } from "vitest";
|
7
|
+
import { SourceWithPool } from "./SourceWithPool";
|
8
|
+
import { PrivateClass } from "../Private/PrivateClass";
|
9
|
+
|
10
|
+
class X2 implements SourceObjectType<number> {
|
11
|
+
public constructor(private baseNumber: SourceType<number>) {}
|
12
|
+
|
13
|
+
public value(guest: GuestType<number>) {
|
14
|
+
value(
|
15
|
+
this.baseNumber,
|
16
|
+
new GuestCast(<GuestType>guest, (v) => {
|
17
|
+
give(v * 2, guest);
|
18
|
+
}),
|
19
|
+
);
|
20
|
+
return this;
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
test("SourceSequence.test", () => {
|
25
|
+
const source = new SourceWithPool([1, 2, 3, 9]);
|
26
|
+
const guestMapped = new SourceSequence(source, new PrivateClass(X2));
|
27
|
+
const g = vitest.fn();
|
28
|
+
guestMapped.value(g);
|
29
|
+
expect(g).toBeCalledWith([2, 4, 6, 18]);
|
30
|
+
});
|
@@ -1,35 +1,30 @@
|
|
1
|
+
import { SourceWithPool } from "../Source/SourceWithPool";
|
2
|
+
import { give, GuestType } from "../Guest/Guest";
|
3
|
+
import { GuestCast } from "../Guest/GuestCast";
|
1
4
|
import { PatronOnce } from "../Patron/PatronOnce";
|
2
5
|
import { PrivateType } from "../Private/Private";
|
3
|
-
import {
|
4
|
-
import {
|
5
|
-
import {
|
6
|
-
GuestAwareObjectType,
|
7
|
-
GuestAwareType,
|
8
|
-
isGuestAware,
|
9
|
-
value,
|
10
|
-
} from "./GuestAware";
|
11
|
-
import { GuestAwareAll } from "./GuestAwareAll";
|
12
|
-
import { GuestCast } from "./GuestCast";
|
6
|
+
import { isSource, SourceObjectType, SourceType, value } from "./Source";
|
7
|
+
import { SourceAll } from "./SourceAll";
|
13
8
|
|
14
9
|
/**
|
15
|
-
* @url https://kosukhin.github.io/patron.site/#/guest/
|
10
|
+
* @url https://kosukhin.github.io/patron.site/#/guest/source-sequence
|
16
11
|
*/
|
17
|
-
export class
|
12
|
+
export class SourceSequence<T, TG> implements SourceObjectType<TG[]> {
|
18
13
|
public constructor(
|
19
|
-
private baseSource:
|
20
|
-
private targetSource: PrivateType<
|
14
|
+
private baseSource: SourceType<T[]>,
|
15
|
+
private targetSource: PrivateType<SourceType<TG>>,
|
21
16
|
) {
|
22
17
|
if (baseSource === undefined) {
|
23
|
-
throw new Error("
|
18
|
+
throw new Error("SourceSequence didnt receive baseSource argument");
|
24
19
|
}
|
25
20
|
if (targetSource === undefined) {
|
26
|
-
throw new Error("
|
21
|
+
throw new Error("SourceSequence didnt receive targetSource argument");
|
27
22
|
}
|
28
23
|
}
|
29
24
|
|
30
25
|
public value(guest: GuestType<TG[]>) {
|
31
|
-
const all = new
|
32
|
-
const sequenceSource = new
|
26
|
+
const all = new SourceAll<TG[]>();
|
27
|
+
const sequenceSource = new SourceWithPool();
|
33
28
|
const targetSource = this.targetSource.get(sequenceSource);
|
34
29
|
|
35
30
|
value(
|
@@ -49,7 +44,7 @@ export class GuestAwareSequence<T, TG> implements GuestAwareObjectType<TG[]> {
|
|
49
44
|
function handle() {
|
50
45
|
sequenceSource.give(null);
|
51
46
|
const nextValue = theValue[index];
|
52
|
-
if (
|
47
|
+
if (isSource(nextValue)) {
|
53
48
|
value(
|
54
49
|
nextValue,
|
55
50
|
new PatronOnce((theNextValue) => {
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { expect, test, vitest } from "vitest";
|
2
|
+
import { SourceWithPool } from "./SourceWithPool";
|
3
|
+
import { Patron } from "../Patron/Patron";
|
4
|
+
|
5
|
+
test("SourceChangeable.test", () => {
|
6
|
+
const source = new SourceWithPool();
|
7
|
+
const guest = vitest.fn();
|
8
|
+
|
9
|
+
source.value(new Patron(guest));
|
10
|
+
source.give(42);
|
11
|
+
|
12
|
+
expect(guest).toBeCalled();
|
13
|
+
expect(guest).toBeCalledWith(42);
|
14
|
+
});
|
@@ -0,0 +1,10 @@
|
|
1
|
+
import { expect, test, vitest } from "vitest";
|
2
|
+
import { SourceWithPool } from "./SourceWithPool";
|
3
|
+
|
4
|
+
test("SourceChangeable.test", () => {
|
5
|
+
const source = new SourceWithPool(42);
|
6
|
+
|
7
|
+
const g = vitest.fn();
|
8
|
+
source.value(g);
|
9
|
+
expect(g).toBeCalledWith(42);
|
10
|
+
});
|
@@ -0,0 +1,58 @@
|
|
1
|
+
import { Guest, GuestObjectType, GuestType } from "../Guest/Guest";
|
2
|
+
import { SourceObjectType } from "./Source";
|
3
|
+
import { PatronPool } from "../Patron/PatronPool";
|
4
|
+
import { isPatron } from "../Patron/Patron";
|
5
|
+
|
6
|
+
export interface PoolAwareType<T = any> {
|
7
|
+
pool(): PatronPool<T>;
|
8
|
+
}
|
9
|
+
|
10
|
+
/**
|
11
|
+
* @url https://kosukhin.github.io/patron.site/#/source-with-pool
|
12
|
+
*/
|
13
|
+
export type SourceWithPoolType<T = any> = SourceObjectType<T> &
|
14
|
+
GuestObjectType<T> &
|
15
|
+
PoolAwareType<T>;
|
16
|
+
|
17
|
+
export class SourceWithPool<T> implements SourceWithPoolType<T> {
|
18
|
+
private thePool = new PatronPool(this);
|
19
|
+
private theEmptyPool = new PatronPool(this);
|
20
|
+
private isEmpty: boolean;
|
21
|
+
|
22
|
+
public constructor(private sourceDocument?: T) {
|
23
|
+
this.isEmpty = sourceDocument === undefined;
|
24
|
+
}
|
25
|
+
|
26
|
+
public pool() {
|
27
|
+
return this.thePool;
|
28
|
+
}
|
29
|
+
|
30
|
+
public give(value: T): this {
|
31
|
+
this.isEmpty = false;
|
32
|
+
this.sourceDocument = value;
|
33
|
+
this.thePool.give(this.sourceDocument);
|
34
|
+
this.theEmptyPool.give(this.sourceDocument);
|
35
|
+
return this;
|
36
|
+
}
|
37
|
+
|
38
|
+
public value(guest: GuestType<T>): this {
|
39
|
+
if (this.isEmpty) {
|
40
|
+
if (isPatron(guest)) {
|
41
|
+
this.theEmptyPool.add(guest);
|
42
|
+
}
|
43
|
+
return this;
|
44
|
+
}
|
45
|
+
|
46
|
+
if (typeof guest === "function") {
|
47
|
+
this.thePool.distribute(this.sourceDocument, new Guest(guest));
|
48
|
+
} else {
|
49
|
+
this.thePool.distribute(this.sourceDocument, guest);
|
50
|
+
}
|
51
|
+
|
52
|
+
return this;
|
53
|
+
}
|
54
|
+
|
55
|
+
public filled() {
|
56
|
+
return !this.isEmpty;
|
57
|
+
}
|
58
|
+
}
|
package/src/index.ts
CHANGED
@@ -1,20 +1,22 @@
|
|
1
|
-
export * from "./Guest/GuestAware";
|
2
|
-
export * from "./Guest/GuestAwareSequence";
|
3
|
-
export * from "./Guest/GuestAwareMap";
|
4
|
-
export * from "./Guest/GuestAwareRace";
|
5
|
-
export * from "./Guest/GuestAwareActive";
|
6
1
|
export * from "./Guest/Guest";
|
7
2
|
export * from "./Guest/GuestCast";
|
8
|
-
export * from "./Guest/GuestAwareAll";
|
9
3
|
export * from "./Guest/GuestPool";
|
10
4
|
export * from "./Guest/GuestSync";
|
11
5
|
export * from "./Guest/GuestObject";
|
12
6
|
export * from "./Guest/GuestDisposable";
|
7
|
+
export * from "./Guest/GuestApplied";
|
13
8
|
export * from "./Patron/Patron";
|
14
9
|
export * from "./Patron/PatronOnce";
|
15
10
|
export * from "./Patron/PatronPool";
|
11
|
+
export * from "./Source/SourceAll";
|
16
12
|
export * from "./Source/Source";
|
13
|
+
export * from "./Source/SourceSequence";
|
14
|
+
export * from "./Source/SourceMap";
|
15
|
+
export * from "./Source/SourceRace";
|
16
|
+
export * from "./Source/SourceActive";
|
17
|
+
export * from "./Source/SourceWithPool";
|
17
18
|
export * from "./Source/SourceDynamic";
|
18
|
-
export * from "./Source/
|
19
|
+
export * from "./Source/SourceApplied";
|
20
|
+
export * from "./Source/SourceExecutorApplied";
|
19
21
|
export * from "./Private/PrivateClass";
|
20
22
|
export * from "./Private/Private";
|