patron-oop 1.3.0 → 1.5.0
Sign up to get free protection for your applications and to get access to all the features.
- package/CHANGELOG.md +18 -0
- package/README.md +60 -0
- package/dist/patron.d.ts +59 -83
- package/dist/patron.js +128 -127
- package/dist/patron.js.map +1 -1
- package/dist/patron.min.js +1 -1
- package/dist/patron.mjs +126 -118
- package/dist/patron.mjs.map +1 -1
- package/package.json +1 -1
- package/src/Guest/Guest.ts +45 -0
- package/src/Guest/GuestAware.test.ts +15 -0
- package/src/{GuestAware.ts → Guest/GuestAware.ts} +5 -2
- package/src/Guest/GuestCallback.test.ts +13 -0
- package/src/Guest/GuestCallback.ts +21 -0
- package/src/Guest/GuestCast.test.ts +31 -0
- package/src/{GuestCast.ts → Guest/GuestCast.ts} +1 -1
- package/src/Guest/GuestChain.test.ts +72 -0
- package/src/{Chain.ts → Guest/GuestChain.ts} +15 -11
- package/src/Guest/GuestInTheMiddle.test.ts +71 -0
- package/src/{GuestInTheMiddle.ts → Guest/GuestInTheMiddle.ts} +1 -1
- package/src/{GuestPool.test.ts → Guest/GuestPool.test.ts} +7 -7
- package/src/{GuestPool.ts → Guest/GuestPool.ts} +3 -3
- package/src/Guest/GuestSync.test.ts +13 -0
- package/src/{GuestSync.ts → Guest/GuestSync.ts} +5 -1
- package/src/Patron/Patron.ts +18 -0
- package/src/{Patron.test.ts → Patron/PatronOfGuest.test.ts} +6 -6
- package/src/{Patron.ts → Patron/PatronOfGuest.ts} +2 -2
- package/src/{PatronOnce.test.ts → Patron/PatronOnce.test.ts} +4 -4
- package/src/{PatronOnce.ts → Patron/PatronOnce.ts} +3 -3
- package/src/{PatronPool.test.ts → Patron/PatronPool.test.ts} +6 -6
- package/src/{PatronPool.ts → Patron/PatronPool.ts} +7 -2
- package/src/Source/Source.ts +12 -0
- package/src/Source/SourceOfValue.test.ts +13 -0
- package/src/{Source.ts → Source/SourceOfValue.ts} +6 -4
- package/src/Source/SourcesApplied.test.ts +14 -0
- package/src/Source/SourcesApplied.ts +40 -0
- package/src/index.ts +9 -16
- package/src/Cache.test.ts +0 -20
- package/src/Cache.ts +0 -31
- package/src/CacheType.ts +0 -4
- package/src/Chain.test.ts +0 -72
- package/src/ChainType.ts +0 -7
- package/src/Factory.test.ts +0 -16
- package/src/Factory.ts +0 -21
- package/src/FactoryDynamic.ts +0 -11
- package/src/FactoryType.ts +0 -3
- package/src/FactoryWithFactories.ts +0 -25
- package/src/Guest.test.ts +0 -13
- package/src/Guest.ts +0 -11
- package/src/GuestAwareType.ts +0 -5
- package/src/GuestExecutorType.ts +0 -3
- package/src/GuestInTheMiddle.test.ts +0 -71
- package/src/GuestSync.test.ts +0 -11
- package/src/GuestType.ts +0 -10
- package/src/GuestValueType.ts +0 -5
- package/src/PoolType.ts +0 -7
- package/src/Source.test.ts +0 -13
- package/src/SourceType.ts +0 -4
@@ -0,0 +1,15 @@
|
|
1
|
+
import { expect, test } from "vitest";
|
2
|
+
import { GuestAware } from "./GuestAware";
|
3
|
+
import { GuestCallback } from "./GuestCallback";
|
4
|
+
|
5
|
+
test("guest aware", () => {
|
6
|
+
const awared = new GuestAware((guest) => {
|
7
|
+
guest.receive(111);
|
8
|
+
});
|
9
|
+
|
10
|
+
awared.receiving(
|
11
|
+
new GuestCallback((value) => {
|
12
|
+
expect(value).toBe(111);
|
13
|
+
}),
|
14
|
+
);
|
15
|
+
});
|
@@ -1,5 +1,8 @@
|
|
1
|
-
import { GuestType } from "./
|
2
|
-
|
1
|
+
import { GuestType } from "./GuestCallback";
|
2
|
+
|
3
|
+
export interface GuestAwareType<T = unknown> {
|
4
|
+
receiving(guest: GuestType<T>): unknown;
|
5
|
+
}
|
3
6
|
|
4
7
|
export class GuestAware<T = unknown> implements GuestAwareType<T> {
|
5
8
|
public constructor(private guestReceiver: (guest: GuestType<T>) => void) {}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { expect, test } from "vitest";
|
2
|
+
import { GuestCallback } from "./GuestCallback";
|
3
|
+
import { SourceOfValue } from "../Source/SourceOfValue";
|
4
|
+
|
5
|
+
test("guest dynamic", () => {
|
6
|
+
const one = new SourceOfValue(1);
|
7
|
+
|
8
|
+
one.receiving(
|
9
|
+
new GuestCallback((value) => {
|
10
|
+
expect(value).toBe(1);
|
11
|
+
}),
|
12
|
+
);
|
13
|
+
});
|
@@ -0,0 +1,21 @@
|
|
1
|
+
type GuestIntroduction = "guest" | "patron";
|
2
|
+
|
3
|
+
export interface ReceiveOptions {
|
4
|
+
data?: unknown;
|
5
|
+
}
|
6
|
+
|
7
|
+
export type GuestExecutorType<T> = (value: T, options?: ReceiveOptions) => void;
|
8
|
+
|
9
|
+
export interface GuestType<T = unknown> {
|
10
|
+
receive(value: T, options?: ReceiveOptions): this;
|
11
|
+
introduction?(): GuestIntroduction;
|
12
|
+
}
|
13
|
+
|
14
|
+
export class GuestCallback<T> implements GuestType<T> {
|
15
|
+
public constructor(private receiver: GuestExecutorType<T>) {}
|
16
|
+
|
17
|
+
public receive(value: T, options?: ReceiveOptions) {
|
18
|
+
this.receiver(value, options);
|
19
|
+
return this;
|
20
|
+
}
|
21
|
+
}
|
@@ -0,0 +1,31 @@
|
|
1
|
+
import { expect, test } from "vitest";
|
2
|
+
import { SourceOfValue } from "../Source/SourceOfValue";
|
3
|
+
import { PatronOfGuest } from "../Patron/PatronOfGuest";
|
4
|
+
import { GuestCallback } from "./GuestCallback";
|
5
|
+
import { GuestCast } from "./GuestCast";
|
6
|
+
|
7
|
+
test("chain guest returns 2 values after result guest", () => {
|
8
|
+
const source = new SourceOfValue(1);
|
9
|
+
let acc = 0;
|
10
|
+
const mainGuest = new PatronOfGuest(
|
11
|
+
new GuestCallback((value: number) => {
|
12
|
+
acc += value;
|
13
|
+
}),
|
14
|
+
);
|
15
|
+
// Становится патроном тоже, тк наследует это сойство от mainGuest
|
16
|
+
const secondGuest = new GuestCast(
|
17
|
+
mainGuest,
|
18
|
+
new GuestCallback((value: number) => {
|
19
|
+
acc += value;
|
20
|
+
}),
|
21
|
+
);
|
22
|
+
|
23
|
+
source.receiving(mainGuest);
|
24
|
+
source.receiving(secondGuest);
|
25
|
+
|
26
|
+
source.receive(2);
|
27
|
+
|
28
|
+
setTimeout(() => {
|
29
|
+
expect(acc).toBe(6);
|
30
|
+
});
|
31
|
+
});
|
@@ -0,0 +1,72 @@
|
|
1
|
+
import { expect, test } from "vitest";
|
2
|
+
import { GuestChain } from "./GuestChain";
|
3
|
+
import { GuestCallback } from "./GuestCallback";
|
4
|
+
import { SourceOfValue } from "../Source/SourceOfValue";
|
5
|
+
import { PatronOfGuest } from "../Patron/PatronOfGuest";
|
6
|
+
|
7
|
+
test("chain guest returns 2 values after result guest", () => {
|
8
|
+
const one = new SourceOfValue(1);
|
9
|
+
const two = new SourceOfValue(2);
|
10
|
+
const chain = new GuestChain<{ one: number; two: number }>();
|
11
|
+
|
12
|
+
chain.result(
|
13
|
+
new GuestCallback((value) => {
|
14
|
+
expect(Object.values(value).join()).toBe("1,2");
|
15
|
+
}),
|
16
|
+
);
|
17
|
+
|
18
|
+
one.receiving(chain.receiveKey("one"));
|
19
|
+
two.receiving(chain.receiveKey("two"));
|
20
|
+
});
|
21
|
+
|
22
|
+
test("chain guest returns 2 values before result guest", () => {
|
23
|
+
const one = new SourceOfValue(1);
|
24
|
+
const two = new SourceOfValue(2);
|
25
|
+
const chain = new GuestChain<{ one: number; two: number }>();
|
26
|
+
|
27
|
+
one.receiving(chain.receiveKey("one"));
|
28
|
+
two.receiving(chain.receiveKey("two"));
|
29
|
+
|
30
|
+
chain.result(
|
31
|
+
new GuestCallback((value) => {
|
32
|
+
expect(Object.values(value).join()).toBe("1,2");
|
33
|
+
}),
|
34
|
+
);
|
35
|
+
});
|
36
|
+
|
37
|
+
test("chain with patron", () => {
|
38
|
+
const one = new SourceOfValue(1);
|
39
|
+
const two = new SourceOfValue(2);
|
40
|
+
const chain = new GuestChain<{ one: number; two: number }>();
|
41
|
+
|
42
|
+
one.receiving(new PatronOfGuest(chain.receiveKey("one")));
|
43
|
+
two.receiving(new PatronOfGuest(chain.receiveKey("two")));
|
44
|
+
|
45
|
+
one.receive(3);
|
46
|
+
one.receive(4);
|
47
|
+
|
48
|
+
chain.result(
|
49
|
+
new PatronOfGuest(
|
50
|
+
new GuestCallback((value: Record<string, unknown>) => {
|
51
|
+
expect(Object.values(value).length).toBe(2);
|
52
|
+
}),
|
53
|
+
),
|
54
|
+
);
|
55
|
+
});
|
56
|
+
|
57
|
+
test("chain as array", () => {
|
58
|
+
const one = new SourceOfValue(1);
|
59
|
+
const two = new SourceOfValue(2);
|
60
|
+
const chain = new GuestChain<[number, number]>();
|
61
|
+
|
62
|
+
one.receiving(new PatronOfGuest(chain.receiveKey("0")));
|
63
|
+
two.receiving(new PatronOfGuest(chain.receiveKey("1")));
|
64
|
+
|
65
|
+
chain.resultArray(
|
66
|
+
new PatronOfGuest(
|
67
|
+
new GuestCallback((value) => {
|
68
|
+
expect(JSON.stringify(value)).toBe("[1, 2]");
|
69
|
+
}),
|
70
|
+
),
|
71
|
+
);
|
72
|
+
});
|
@@ -1,12 +1,16 @@
|
|
1
|
-
import {
|
2
|
-
import { Guest } from "./Guest";
|
1
|
+
import { GuestCallback, GuestType } from "./GuestCallback";
|
3
2
|
import { GuestPool } from "./GuestPool";
|
4
|
-
import { ChainType } from "./ChainType";
|
5
3
|
import { GuestInTheMiddle } from "./GuestInTheMiddle";
|
6
|
-
import {
|
4
|
+
import { SourceOfValue } from "../Source/SourceOfValue";
|
7
5
|
|
8
|
-
export
|
9
|
-
|
6
|
+
export interface ChainType<T = unknown> {
|
7
|
+
result(guest: GuestType<T>): this;
|
8
|
+
resultArray(guest: GuestType<T>): this;
|
9
|
+
receiveKey<R>(key: string): GuestType<R>;
|
10
|
+
}
|
11
|
+
|
12
|
+
export class GuestChain<T> implements ChainType<T> {
|
13
|
+
private theChain: SourceOfValue<Record<string, unknown>>;
|
10
14
|
|
11
15
|
private keysKnown = new Set();
|
12
16
|
|
@@ -15,7 +19,7 @@ export class Chain<T> implements ChainType<T> {
|
|
15
19
|
private filledChainPool = new GuestPool(this);
|
16
20
|
|
17
21
|
public constructor() {
|
18
|
-
this.theChain = new
|
22
|
+
this.theChain = new SourceOfValue<Record<string, unknown>>({});
|
19
23
|
}
|
20
24
|
|
21
25
|
public resultArray(guest: GuestType<T>) {
|
@@ -26,7 +30,7 @@ export class Chain<T> implements ChainType<T> {
|
|
26
30
|
);
|
27
31
|
if (this.isChainFilled()) {
|
28
32
|
this.theChain.receiving(
|
29
|
-
new
|
33
|
+
new GuestCallback((chain: Record<string, unknown>) => {
|
30
34
|
this.filledChainPool.receive(Object.values(chain));
|
31
35
|
}),
|
32
36
|
);
|
@@ -39,7 +43,7 @@ export class Chain<T> implements ChainType<T> {
|
|
39
43
|
if (this.isChainFilled()) {
|
40
44
|
this.filledChainPool.add(guest);
|
41
45
|
this.theChain.receiving(
|
42
|
-
new
|
46
|
+
new GuestCallback((chain) => {
|
43
47
|
this.filledChainPool.receive(chain);
|
44
48
|
}),
|
45
49
|
);
|
@@ -51,11 +55,11 @@ export class Chain<T> implements ChainType<T> {
|
|
51
55
|
|
52
56
|
public receiveKey<R>(key: string): GuestType<R> {
|
53
57
|
this.keysKnown.add(key);
|
54
|
-
return new
|
58
|
+
return new GuestCallback((value) => {
|
55
59
|
// Обернул в очередь чтобы можно было синхронно наполнить очередь известных ключей
|
56
60
|
queueMicrotask(() => {
|
57
61
|
this.theChain.receiving(
|
58
|
-
new
|
62
|
+
new GuestCallback((chain: Record<string, unknown>) => {
|
59
63
|
this.keysFilled.add(key);
|
60
64
|
const lastChain = {
|
61
65
|
...chain,
|
@@ -0,0 +1,71 @@
|
|
1
|
+
import { expect, test } from "vitest";
|
2
|
+
import { GuestCallback } from "./GuestCallback";
|
3
|
+
import { GuestInTheMiddle } from "./GuestInTheMiddle";
|
4
|
+
import { GuestChain } from "./GuestChain";
|
5
|
+
import { SourceOfValue } from "../Source/SourceOfValue";
|
6
|
+
import { PatronOfGuest } from "../Patron/PatronOfGuest";
|
7
|
+
|
8
|
+
test("test guest in the middle", () => {
|
9
|
+
const one = new SourceOfValue(1);
|
10
|
+
|
11
|
+
let accumValue = 0;
|
12
|
+
const guest = new GuestCallback((value: number) => {
|
13
|
+
accumValue += value;
|
14
|
+
});
|
15
|
+
one.receiving(
|
16
|
+
new GuestInTheMiddle(guest, (value: number) => {
|
17
|
+
guest.receive(value + 3);
|
18
|
+
}),
|
19
|
+
);
|
20
|
+
|
21
|
+
expect(accumValue).toBe(4);
|
22
|
+
});
|
23
|
+
|
24
|
+
test("test patron in the middle", () => {
|
25
|
+
const one = new SourceOfValue(1);
|
26
|
+
|
27
|
+
let accumValue = 0;
|
28
|
+
const guest = new PatronOfGuest(
|
29
|
+
new GuestCallback((value: number) => {
|
30
|
+
accumValue += value;
|
31
|
+
}),
|
32
|
+
);
|
33
|
+
one.receiving(
|
34
|
+
new GuestInTheMiddle(guest, (value: number) => {
|
35
|
+
guest.receive(value + 3);
|
36
|
+
}),
|
37
|
+
);
|
38
|
+
one.receive(3);
|
39
|
+
|
40
|
+
setTimeout(() => {
|
41
|
+
one.receive(3);
|
42
|
+
});
|
43
|
+
|
44
|
+
setTimeout(() => {
|
45
|
+
expect(accumValue).toBe(16);
|
46
|
+
});
|
47
|
+
});
|
48
|
+
|
49
|
+
test("test chain in the middle", () => {
|
50
|
+
const one = new SourceOfValue(1);
|
51
|
+
const two = new SourceOfValue(2);
|
52
|
+
const chain = new GuestChain<{ one: number; two: number }>();
|
53
|
+
|
54
|
+
one.receiving(new PatronOfGuest(chain.receiveKey("one")));
|
55
|
+
two.receiving(new PatronOfGuest(chain.receiveKey("two")));
|
56
|
+
|
57
|
+
one.receive(3);
|
58
|
+
one.receive(4);
|
59
|
+
|
60
|
+
const guest = new PatronOfGuest(
|
61
|
+
new GuestCallback((value: { one: number; two: number; three: number }) => {
|
62
|
+
expect(Object.values(value).length).toBe(3);
|
63
|
+
}),
|
64
|
+
);
|
65
|
+
|
66
|
+
chain.result(
|
67
|
+
new GuestInTheMiddle(guest, (value) => {
|
68
|
+
guest.receive({ ...value, three: 99 });
|
69
|
+
}),
|
70
|
+
);
|
71
|
+
});
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { expect, test } from "vitest";
|
2
|
-
import {
|
3
|
-
import { Patron } from "./Patron";
|
2
|
+
import { GuestCallback } from "./GuestCallback";
|
4
3
|
import { GuestPool } from "./GuestPool";
|
4
|
+
import { PatronOfGuest } from "../Patron/PatronOfGuest";
|
5
5
|
|
6
6
|
test("patron pool with guests", () => {
|
7
7
|
const pool = new GuestPool(null);
|
@@ -9,23 +9,23 @@ test("patron pool with guests", () => {
|
|
9
9
|
|
10
10
|
// 2 + 2
|
11
11
|
pool.add(
|
12
|
-
new
|
13
|
-
new
|
12
|
+
new PatronOfGuest(
|
13
|
+
new GuestCallback<number>((value) => {
|
14
14
|
receivedCount += value;
|
15
15
|
}),
|
16
16
|
),
|
17
17
|
);
|
18
18
|
// 2 + 2
|
19
19
|
pool.add(
|
20
|
-
new
|
21
|
-
new
|
20
|
+
new PatronOfGuest(
|
21
|
+
new GuestCallback<number>((value) => {
|
22
22
|
receivedCount += value;
|
23
23
|
}),
|
24
24
|
),
|
25
25
|
);
|
26
26
|
// 2
|
27
27
|
pool.add(
|
28
|
-
new
|
28
|
+
new GuestCallback<number>((value) => {
|
29
29
|
receivedCount += value;
|
30
30
|
}),
|
31
31
|
);
|
@@ -1,6 +1,6 @@
|
|
1
|
-
import { PatronPool } from "
|
2
|
-
import { PoolType } from "
|
3
|
-
import { GuestType, ReceiveOptions } from "./
|
1
|
+
import { PatronPool } from "../Patron/PatronPool";
|
2
|
+
import { PoolType } from "../Patron/PatronPool";
|
3
|
+
import { GuestType, ReceiveOptions } from "./GuestCallback";
|
4
4
|
|
5
5
|
export class GuestPool<T> implements GuestType<T>, PoolType<T> {
|
6
6
|
private guests = new Set<GuestType<T>>();
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { expect, test } from "vitest";
|
2
|
+
import { GuestSync } from "./GuestSync";
|
3
|
+
import { SourceOfValue } from "../Source/SourceOfValue";
|
4
|
+
import { GuestCallback } from "./GuestCallback";
|
5
|
+
|
6
|
+
test("guest sync", () => {
|
7
|
+
const source = new SourceOfValue(123);
|
8
|
+
const syncGuest = new GuestSync(new GuestCallback(() => {}));
|
9
|
+
syncGuest.receive(222);
|
10
|
+
expect(syncGuest.value()).toBe(222);
|
11
|
+
source.receiving(syncGuest);
|
12
|
+
expect(syncGuest.value()).toBe(123);
|
13
|
+
});
|
@@ -1,4 +1,8 @@
|
|
1
|
-
import {
|
1
|
+
import { GuestType } from "./GuestCallback";
|
2
|
+
|
3
|
+
export interface GuestValueType<T = unknown> extends GuestType<T> {
|
4
|
+
value(): T;
|
5
|
+
}
|
2
6
|
|
3
7
|
export class GuestSync<T> implements GuestValueType<T> {
|
4
8
|
public constructor(private theValue: T) {}
|
@@ -0,0 +1,18 @@
|
|
1
|
+
import { PatronOfGuest } from "./PatronOfGuest";
|
2
|
+
import { GuestType } from "../Guest/GuestCallback";
|
3
|
+
import { PatronOnce } from "./PatronOnce";
|
4
|
+
import { PatronPool } from "./PatronPool";
|
5
|
+
|
6
|
+
export class Patron {
|
7
|
+
public ofGuest<P>(willBePatron: GuestType<P>) {
|
8
|
+
return new PatronOfGuest(willBePatron);
|
9
|
+
}
|
10
|
+
|
11
|
+
public once<P>(baseGuest: GuestType<P>) {
|
12
|
+
return new PatronOnce(baseGuest);
|
13
|
+
}
|
14
|
+
|
15
|
+
public pool(initiator: unknown) {
|
16
|
+
return new PatronPool(initiator);
|
17
|
+
}
|
18
|
+
}
|
@@ -1,13 +1,13 @@
|
|
1
1
|
import { expect, test } from "vitest";
|
2
|
-
import {
|
3
|
-
import {
|
4
|
-
import {
|
2
|
+
import { PatronOfGuest } from "./PatronOfGuest";
|
3
|
+
import { SourceOfValue } from "../Source/SourceOfValue";
|
4
|
+
import { GuestCallback } from "../Guest/GuestCallback";
|
5
5
|
|
6
6
|
test("patron always guest", () => {
|
7
|
-
const one = new
|
7
|
+
const one = new SourceOfValue(1);
|
8
8
|
let patronCalledTimes = 0;
|
9
|
-
const patron = new
|
10
|
-
new
|
9
|
+
const patron = new PatronOfGuest(
|
10
|
+
new GuestCallback(() => {
|
11
11
|
patronCalledTimes += 1;
|
12
12
|
}),
|
13
13
|
);
|
@@ -1,9 +1,9 @@
|
|
1
|
-
import { GuestType, ReceiveOptions } from "
|
1
|
+
import { GuestType, ReceiveOptions } from "../Guest/GuestCallback";
|
2
2
|
|
3
3
|
/**
|
4
4
|
* Патрон - это постоянный посетитель
|
5
5
|
*/
|
6
|
-
export class
|
6
|
+
export class PatronOfGuest<T> implements GuestType<T> {
|
7
7
|
public constructor(private willBePatron: GuestType<T>) {}
|
8
8
|
|
9
9
|
public introduction() {
|
@@ -1,13 +1,13 @@
|
|
1
1
|
import { expect, test } from "vitest";
|
2
|
-
import { Source } from "./Source";
|
3
2
|
import { PatronOnce } from "./PatronOnce";
|
4
|
-
import {
|
3
|
+
import { GuestCallback } from "../Guest/GuestCallback";
|
4
|
+
import { SourceOfValue } from "../Source/SourceOfValue";
|
5
5
|
|
6
6
|
test("patron once", () => {
|
7
|
-
const source = new
|
7
|
+
const source = new SourceOfValue(42);
|
8
8
|
let calls = 0;
|
9
9
|
const patron = new PatronOnce(
|
10
|
-
new
|
10
|
+
new GuestCallback(() => {
|
11
11
|
calls += 1;
|
12
12
|
}),
|
13
13
|
);
|
@@ -1,5 +1,5 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
1
|
+
import { PoolType } from "./PatronPool";
|
2
|
+
import { GuestType, ReceiveOptions } from "../Guest/GuestCallback";
|
3
3
|
|
4
4
|
type PoolAware = {
|
5
5
|
pool?: PoolType;
|
@@ -20,7 +20,7 @@ export class PatronOnce<T> implements GuestType<T> {
|
|
20
20
|
}
|
21
21
|
|
22
22
|
const data = options?.data as PoolAware;
|
23
|
-
|
23
|
+
|
24
24
|
if (data?.pool) {
|
25
25
|
data.pool.remove(this);
|
26
26
|
}
|
@@ -1,22 +1,22 @@
|
|
1
1
|
import { expect, test } from "vitest";
|
2
|
-
import { Guest } from "./Guest";
|
3
2
|
import { PatronPool } from "./PatronPool";
|
4
|
-
import {
|
3
|
+
import { PatronOfGuest } from "./PatronOfGuest";
|
4
|
+
import { GuestCallback } from "../Guest/GuestCallback";
|
5
5
|
|
6
6
|
test("patron pool", () => {
|
7
7
|
const pool = new PatronPool(null);
|
8
8
|
let receivedCount = 0;
|
9
9
|
|
10
10
|
pool.add(
|
11
|
-
new
|
12
|
-
new
|
11
|
+
new PatronOfGuest(
|
12
|
+
new GuestCallback<number>((value) => {
|
13
13
|
receivedCount += value;
|
14
14
|
}),
|
15
15
|
),
|
16
16
|
);
|
17
17
|
pool.add(
|
18
|
-
new
|
19
|
-
new
|
18
|
+
new PatronOfGuest(
|
19
|
+
new GuestCallback<number>((value) => {
|
20
20
|
receivedCount += value;
|
21
21
|
expect(receivedCount).toBe(4);
|
22
22
|
}),
|
@@ -1,5 +1,4 @@
|
|
1
|
-
import {
|
2
|
-
import { GuestType, ReceiveOptions } from "./GuestType";
|
1
|
+
import { GuestType, ReceiveOptions } from "../Guest/GuestCallback";
|
3
2
|
|
4
3
|
const poolSets = new Map<PoolType, Set<GuestType>>();
|
5
4
|
|
@@ -12,6 +11,12 @@ export const removePatronFromPools = (patron: GuestType) => {
|
|
12
11
|
});
|
13
12
|
};
|
14
13
|
|
14
|
+
export interface PoolType<T = unknown> extends GuestType<T> {
|
15
|
+
add(guest: GuestType<T>): this;
|
16
|
+
distribute(receiving: T, possiblePatron: GuestType<T>): this;
|
17
|
+
remove(patron: GuestType<T>): this;
|
18
|
+
}
|
19
|
+
|
15
20
|
export class PatronPool<T> implements PoolType<T> {
|
16
21
|
private patrons = new Set<GuestType<T>>();
|
17
22
|
|
@@ -0,0 +1,12 @@
|
|
1
|
+
import { SourceOfValue } from "./SourceOfValue";
|
2
|
+
import { sourcesApplied } from "./SourcesApplied";
|
3
|
+
|
4
|
+
export class Source {
|
5
|
+
public ofValue<P>(sourceDocument: P) {
|
6
|
+
return new SourceOfValue(sourceDocument);
|
7
|
+
}
|
8
|
+
|
9
|
+
public applySources<P>(target: P, methodsSources: Record<string, unknown[]>) {
|
10
|
+
return sourcesApplied(target, methodsSources);
|
11
|
+
}
|
12
|
+
}
|
@@ -0,0 +1,13 @@
|
|
1
|
+
import { expect, test } from "vitest";
|
2
|
+
import { SourceOfValue } from "./SourceOfValue";
|
3
|
+
import { GuestCallback } from "../Guest/GuestCallback";
|
4
|
+
|
5
|
+
test("source", () => {
|
6
|
+
const source = new SourceOfValue(42);
|
7
|
+
|
8
|
+
source.receiving(
|
9
|
+
new GuestCallback((value) => {
|
10
|
+
expect(value).toBe(42);
|
11
|
+
}),
|
12
|
+
);
|
13
|
+
});
|
@@ -1,8 +1,10 @@
|
|
1
|
-
import {
|
2
|
-
import {
|
3
|
-
import {
|
1
|
+
import { GuestAwareType } from "../Guest/GuestAware";
|
2
|
+
import { GuestType } from "../Guest/GuestCallback";
|
3
|
+
import { PatronPool } from "../Patron/PatronPool";
|
4
4
|
|
5
|
-
export
|
5
|
+
export type SourceType<T = unknown> = GuestAwareType<T> & GuestType<T>;
|
6
|
+
|
7
|
+
export class SourceOfValue<T> implements SourceType<T> {
|
6
8
|
private pool = new PatronPool(this);
|
7
9
|
|
8
10
|
public constructor(private sourceDocument: T) {}
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { expect, test } from "vitest";
|
2
|
+
import { sourcesApplied } from "./SourcesApplied";
|
3
|
+
|
4
|
+
test("sources applied", () => {
|
5
|
+
const target = {
|
6
|
+
one(data: { one: string }, after: string) {
|
7
|
+
return data.one + " " + after;
|
8
|
+
},
|
9
|
+
};
|
10
|
+
const targetApplied = sourcesApplied(target, {
|
11
|
+
one: [{ one: "hello world" }, "after"],
|
12
|
+
});
|
13
|
+
expect(targetApplied.one()).toBe("hello world after");
|
14
|
+
});
|
@@ -0,0 +1,40 @@
|
|
1
|
+
type TupleSplit<
|
2
|
+
T,
|
3
|
+
N extends number,
|
4
|
+
O extends readonly any[] = readonly [],
|
5
|
+
> = O["length"] extends N
|
6
|
+
? [O, T]
|
7
|
+
: T extends readonly [infer F, ...infer R]
|
8
|
+
? TupleSplit<readonly [...R], N, readonly [...O, F]>
|
9
|
+
: [O, T];
|
10
|
+
|
11
|
+
type SkipFirst<T extends readonly any[], N extends number> = TupleSplit<
|
12
|
+
T,
|
13
|
+
N
|
14
|
+
>[1];
|
15
|
+
|
16
|
+
export const sourcesApplied = <T>(
|
17
|
+
target: T,
|
18
|
+
methodsSources: Record<string, unknown[]>,
|
19
|
+
) => {
|
20
|
+
return Object.fromEntries(
|
21
|
+
Object.entries(target as object).map(([key, value]) => {
|
22
|
+
if (value instanceof Function && methodsSources[key]) {
|
23
|
+
const methodArgs = methodsSources[key];
|
24
|
+
return [
|
25
|
+
key,
|
26
|
+
new Proxy(value, {
|
27
|
+
apply(target: Function, thisArg: any, argArray: any[]): any {
|
28
|
+
return target.apply(thisArg, [
|
29
|
+
...methodsSources[key],
|
30
|
+
...argArray,
|
31
|
+
]);
|
32
|
+
},
|
33
|
+
}) as (...args: Parameters<typeof value>) => ReturnType<typeof value>,
|
34
|
+
];
|
35
|
+
}
|
36
|
+
|
37
|
+
return [key, value];
|
38
|
+
}),
|
39
|
+
);
|
40
|
+
};
|
package/src/index.ts
CHANGED
@@ -1,16 +1,9 @@
|
|
1
|
-
export * from "./
|
2
|
-
export * from "./
|
3
|
-
export * from "./
|
4
|
-
export * from "./
|
5
|
-
export * from "./
|
6
|
-
|
7
|
-
export * from "./Guest";
|
8
|
-
export * from "./
|
9
|
-
export * from "./
|
10
|
-
export * from "./GuestInTheMiddle";
|
11
|
-
export * from "./GuestPool";
|
12
|
-
export * from "./GuestSync";
|
13
|
-
export * from "./Patron";
|
14
|
-
export * from "./PatronOnce";
|
15
|
-
export * from "./PatronPool";
|
16
|
-
export * from "./Source";
|
1
|
+
export * from "./Guest/GuestCallback";
|
2
|
+
export * from "./Guest/GuestChain";
|
3
|
+
export * from "./Guest/GuestSync";
|
4
|
+
export * from "./Patron/PatronPool";
|
5
|
+
export * from "./Source/SourceOfValue";
|
6
|
+
|
7
|
+
export * from "./Guest/Guest";
|
8
|
+
export * from "./Patron/Patron";
|
9
|
+
export * from "./Source/Source";
|