silentium-components 0.0.26 → 0.0.28
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 +34 -0
- package/dist/silentium-components.cjs +570 -342
- package/dist/silentium-components.cjs.map +1 -1
- package/dist/silentium-components.d.ts +169 -30
- package/dist/silentium-components.js +546 -319
- package/dist/silentium-components.js.map +1 -1
- package/dist/silentium-components.min.js +1 -1
- package/dist/silentium-components.min.mjs +1 -1
- package/dist/silentium-components.min.mjs.map +1 -1
- package/dist/silentium-components.mjs +546 -319
- package/dist/silentium-components.mjs.map +1 -1
- package/package.json +2 -2
- package/src/behaviors/Branch._main.test.ts +22 -0
- package/src/behaviors/Branch.branchesDontAffectResult.test.ts +11 -11
- package/src/behaviors/Branch.dontRespondAfterRespond.test.ts +15 -17
- package/src/behaviors/Branch.ts +28 -21
- package/src/behaviors/{Deadline.test.ts → Deadline._main.test.ts} +5 -5
- package/src/behaviors/Deadline._value.test.ts +6 -6
- package/src/behaviors/Deadline.ts +45 -41
- package/src/behaviors/Deferred.test.ts +14 -14
- package/src/behaviors/Deferred.ts +21 -15
- package/src/behaviors/Dirty.test.ts +8 -8
- package/src/behaviors/Dirty.ts +43 -35
- package/src/behaviors/Loading.test.ts +8 -8
- package/src/behaviors/Loading.ts +24 -14
- package/src/behaviors/Lock.test.ts +14 -14
- package/src/behaviors/Lock.ts +21 -14
- package/src/behaviors/Memo.test.ts +16 -14
- package/src/behaviors/Memo.ts +20 -12
- package/src/behaviors/OnlyChanged.test.ts +7 -7
- package/src/behaviors/OnlyChanged.ts +22 -15
- package/src/behaviors/Path._main.test.ts +14 -0
- package/src/behaviors/Path.index.test.ts +4 -4
- package/src/behaviors/Path.nested.test.ts +4 -4
- package/src/behaviors/Path.ts +27 -22
- package/src/behaviors/Shot._main.test.ts +29 -0
- package/src/behaviors/Shot._onlyChanged.test.ts +15 -13
- package/src/behaviors/Shot.ts +24 -15
- package/src/behaviors/Sync.test.ts +10 -0
- package/src/behaviors/Sync.ts +38 -15
- package/src/behaviors/Tick.test.ts +8 -8
- package/src/behaviors/Tick.ts +20 -12
- package/src/boolean/And.test.ts +12 -12
- package/src/boolean/And.ts +18 -14
- package/src/boolean/Bool.ts +11 -2
- package/src/boolean/Not.test.ts +6 -6
- package/src/boolean/Not.ts +15 -10
- package/src/boolean/Or.test.ts +12 -12
- package/src/boolean/Or.ts +18 -14
- package/src/boolean/index.ts +1 -0
- package/src/formats/FromJson.test.ts +11 -0
- package/src/formats/FromJson.ts +22 -15
- package/src/formats/ToJson.test.ts +11 -0
- package/src/formats/ToJson.ts +23 -16
- package/src/lists/First.test.ts +4 -4
- package/src/lists/First.ts +11 -6
- package/src/navigation/Router.test.ts +13 -13
- package/src/navigation/Router.ts +36 -29
- package/src/strings/Concatenated.test.ts +6 -6
- package/src/strings/Concatenated.ts +18 -14
- package/src/structures/HashTable.test.ts +7 -7
- package/src/structures/HashTable.ts +17 -11
- package/src/structures/Record._main.test.ts +28 -0
- package/src/structures/Record.concatenated.test.ts +17 -15
- package/src/structures/Record.nested.test.ts +10 -10
- package/src/structures/RecordOf.ts +29 -0
- package/src/structures/index.ts +1 -1
- package/src/system/RegexpMatch._group.test.ts +9 -6
- package/src/system/RegexpMatch._main.test.ts +16 -0
- package/src/system/RegexpMatch.ts +20 -17
- package/src/system/RegexpMatched.test.ts +6 -6
- package/src/system/RegexpMatched.ts +19 -16
- package/src/system/RegexpReplaced.test.ts +10 -6
- package/src/system/RegexpReplaced.ts +25 -18
- package/src/system/Set.test.ts +6 -6
- package/src/system/Set.ts +20 -17
- package/src/behaviors/Branch.test.ts +0 -22
- package/src/behaviors/Path.test.ts +0 -14
- package/src/behaviors/Shot.test.ts +0 -29
- package/src/structures/Record.test.ts +0 -28
- package/src/structures/Record.ts +0 -22
- package/src/system/RegexpMatch.test.ts +0 -13
package/src/behaviors/Sync.ts
CHANGED
|
@@ -1,19 +1,42 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { From, isFilled, TheInformation, TheOwner } from "silentium";
|
|
2
2
|
|
|
3
|
-
export
|
|
4
|
-
|
|
3
|
+
export class Sync<T> extends TheInformation<T> {
|
|
4
|
+
private theValue: T | undefined;
|
|
5
|
+
private isInit = false;
|
|
5
6
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
}
|
|
7
|
+
public constructor(private baseSrc: TheInformation<T>) {
|
|
8
|
+
super(baseSrc);
|
|
9
|
+
}
|
|
9
10
|
|
|
10
|
-
|
|
11
|
-
value()
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
11
|
+
public value(o: TheOwner<T>): this {
|
|
12
|
+
this.baseSrc.value(o);
|
|
13
|
+
return this;
|
|
14
|
+
}
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
16
|
+
public valueExisted() {
|
|
17
|
+
this.initOwner();
|
|
18
|
+
return isFilled(this.theValue);
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
public valueSync(): T {
|
|
22
|
+
this.initOwner();
|
|
23
|
+
|
|
24
|
+
if (!isFilled(this.theValue)) {
|
|
25
|
+
throw new Error("no value in sync");
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
return this.theValue;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
public initOwner() {
|
|
32
|
+
if (!this.isInit) {
|
|
33
|
+
this.isInit = true;
|
|
34
|
+
this.value(
|
|
35
|
+
new From((v) => {
|
|
36
|
+
this.theValue = v;
|
|
37
|
+
}),
|
|
38
|
+
);
|
|
39
|
+
}
|
|
40
|
+
return this;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Any, From, Late, Shared } from "silentium";
|
|
2
2
|
import { afterEach, beforeEach, expect, test, vi } from "vitest";
|
|
3
|
-
import {
|
|
3
|
+
import { Tick } from "../behaviors/Tick";
|
|
4
4
|
|
|
5
5
|
beforeEach(() => {
|
|
6
6
|
vi.useFakeTimers({ shouldAdvanceTime: true });
|
|
@@ -12,15 +12,15 @@ afterEach(() => {
|
|
|
12
12
|
});
|
|
13
13
|
|
|
14
14
|
test("Tick.test", async () => {
|
|
15
|
-
const
|
|
16
|
-
const
|
|
17
|
-
const
|
|
15
|
+
const s1 = new Late<number>(1);
|
|
16
|
+
const s2 = new Late<number>(2);
|
|
17
|
+
const tickSrc = new Shared(new Tick(new Any(s1, s2)), true);
|
|
18
18
|
|
|
19
19
|
const g = vi.fn();
|
|
20
|
-
tickSrc(g);
|
|
20
|
+
tickSrc.value(new From(g));
|
|
21
21
|
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
s1.owner().give(3);
|
|
23
|
+
s2.owner().give(4);
|
|
24
24
|
|
|
25
25
|
await vi.advanceTimersByTimeAsync(10);
|
|
26
26
|
vi.runAllTicks();
|
package/src/behaviors/Tick.ts
CHANGED
|
@@ -1,11 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { From, TheInformation, TheOwner } from "silentium";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Accumulates the last value of the source and returns one result once per tick
|
|
5
5
|
* https://silentium-lab.github.io/silentium-components/#/behaviors/tick
|
|
6
6
|
*/
|
|
7
|
-
export
|
|
8
|
-
|
|
7
|
+
export class Tick<T> extends TheInformation<T> {
|
|
8
|
+
public constructor(private baseSrc: TheInformation<T>) {
|
|
9
|
+
super(baseSrc);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
public value(o: TheOwner<T>): this {
|
|
9
13
|
let microtaskScheduled = false;
|
|
10
14
|
let lastValue: T | null = null;
|
|
11
15
|
|
|
@@ -14,17 +18,21 @@ export const tick = <T>(baseSrc: InformationType<T>): InformationType<T> => {
|
|
|
14
18
|
queueMicrotask(() => {
|
|
15
19
|
microtaskScheduled = false;
|
|
16
20
|
if (lastValue !== null) {
|
|
17
|
-
o(lastValue);
|
|
21
|
+
o.give(lastValue);
|
|
18
22
|
lastValue = null;
|
|
19
23
|
}
|
|
20
24
|
});
|
|
21
25
|
};
|
|
22
26
|
|
|
23
|
-
baseSrc(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
27
|
+
this.baseSrc.value(
|
|
28
|
+
new From((v) => {
|
|
29
|
+
lastValue = v;
|
|
30
|
+
if (!microtaskScheduled) {
|
|
31
|
+
scheduleMicrotask();
|
|
32
|
+
}
|
|
33
|
+
}),
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
return this;
|
|
37
|
+
}
|
|
38
|
+
}
|
package/src/boolean/And.test.ts
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { From, Late } from "silentium";
|
|
2
2
|
import { expect, test, vi } from "vitest";
|
|
3
|
-
import {
|
|
3
|
+
import { And } from "../boolean/And";
|
|
4
4
|
|
|
5
5
|
test("And.test", () => {
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const result =
|
|
6
|
+
const one = new Late<boolean>(false);
|
|
7
|
+
const two = new Late<boolean>(false);
|
|
8
|
+
const result = new And(one, two);
|
|
9
9
|
const g = vi.fn();
|
|
10
|
-
result(g);
|
|
10
|
+
result.value(new From(g));
|
|
11
11
|
expect(g).toHaveBeenLastCalledWith(false);
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
one.owner().give(true);
|
|
14
|
+
two.owner().give(false);
|
|
15
15
|
expect(g).toHaveBeenLastCalledWith(false);
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
one.owner().give(false);
|
|
18
|
+
two.owner().give(true);
|
|
19
19
|
expect(g).toHaveBeenLastCalledWith(false);
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
one.owner().give(true);
|
|
22
|
+
two.owner().give(true);
|
|
23
23
|
expect(g).toHaveBeenLastCalledWith(true);
|
|
24
24
|
});
|
package/src/boolean/And.ts
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { All, From, TheInformation, TheOwner } from "silentium";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* https://silentium-lab.github.io/silentium-components/#/boolean/and
|
|
5
5
|
*/
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
6
|
+
export class And extends TheInformation<boolean> {
|
|
7
|
+
public constructor(
|
|
8
|
+
private oneSrc: TheInformation<boolean>,
|
|
9
|
+
private twoSrc: TheInformation<boolean>,
|
|
10
|
+
) {
|
|
11
|
+
super(oneSrc, twoSrc);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public value(o: TheOwner<boolean>): this {
|
|
15
|
+
new All(this.oneSrc, this.twoSrc).value(
|
|
16
|
+
new From(([one, two]) => {
|
|
17
|
+
o.give(one && two);
|
|
18
|
+
}),
|
|
19
|
+
);
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
}
|
package/src/boolean/Bool.ts
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Applied, TheInformation, TheOwner } from "silentium";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Convert any source to boolean source
|
|
5
5
|
* https://silentium-lab.github.io/silentium-components/#/boolean/bool
|
|
6
6
|
*/
|
|
7
|
-
export
|
|
7
|
+
export class Bool extends TheInformation<boolean> {
|
|
8
|
+
public constructor(private baseSrc: TheInformation) {
|
|
9
|
+
super(baseSrc);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
public value(o: TheOwner<boolean>): this {
|
|
13
|
+
new Applied(this.baseSrc, Boolean).value(o);
|
|
14
|
+
return this;
|
|
15
|
+
}
|
|
16
|
+
}
|
package/src/boolean/Not.test.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { From, Late } from "silentium";
|
|
2
2
|
import { expect, test, vi } from "vitest";
|
|
3
|
-
import {
|
|
3
|
+
import { Not } from "../boolean/Not";
|
|
4
4
|
|
|
5
5
|
test("Not.test", () => {
|
|
6
|
-
const
|
|
7
|
-
const result =
|
|
6
|
+
const one = new Late<boolean>(false);
|
|
7
|
+
const result = new Not(one);
|
|
8
8
|
const g = vi.fn();
|
|
9
|
-
result(g);
|
|
9
|
+
result.value(new From(g));
|
|
10
10
|
expect(g).toHaveBeenLastCalledWith(true);
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
one.owner().give(true);
|
|
13
13
|
expect(g).toHaveBeenLastCalledWith(false);
|
|
14
14
|
});
|
package/src/boolean/Not.ts
CHANGED
|
@@ -1,14 +1,19 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { From, TheInformation, TheOwner } from "silentium";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* https://silentium-lab.github.io/silentium-components/#/boolean/not
|
|
5
5
|
*/
|
|
6
|
-
export
|
|
7
|
-
baseSrc:
|
|
8
|
-
)
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
export class Not extends TheInformation<boolean> {
|
|
7
|
+
public constructor(private baseSrc: TheInformation<boolean>) {
|
|
8
|
+
super(baseSrc);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
public value(o: TheOwner<boolean>): this {
|
|
12
|
+
this.baseSrc.value(
|
|
13
|
+
new From((v) => {
|
|
14
|
+
o.give(!v);
|
|
15
|
+
}),
|
|
16
|
+
);
|
|
17
|
+
return this;
|
|
18
|
+
}
|
|
19
|
+
}
|
package/src/boolean/Or.test.ts
CHANGED
|
@@ -1,24 +1,24 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { From, Late } from "silentium";
|
|
2
2
|
import { expect, test, vi } from "vitest";
|
|
3
|
-
import {
|
|
3
|
+
import { Or } from "../boolean/Or";
|
|
4
4
|
|
|
5
5
|
test("Or.test", () => {
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const result =
|
|
6
|
+
const one = new Late<boolean>(false);
|
|
7
|
+
const two = new Late<boolean>(false);
|
|
8
|
+
const result = new Or(one, two);
|
|
9
9
|
const g = vi.fn();
|
|
10
|
-
result(g);
|
|
10
|
+
result.value(new From(g));
|
|
11
11
|
expect(g).toHaveBeenLastCalledWith(false);
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
one.owner().give(true);
|
|
14
|
+
two.owner().give(false);
|
|
15
15
|
expect(g).toHaveBeenLastCalledWith(true);
|
|
16
16
|
|
|
17
|
-
|
|
18
|
-
|
|
17
|
+
one.owner().give(false);
|
|
18
|
+
two.owner().give(true);
|
|
19
19
|
expect(g).toHaveBeenLastCalledWith(true);
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
one.owner().give(true);
|
|
22
|
+
two.owner().give(true);
|
|
23
23
|
expect(g).toHaveBeenLastCalledWith(true);
|
|
24
24
|
});
|
package/src/boolean/Or.ts
CHANGED
|
@@ -1,18 +1,22 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { All, From, TheInformation, TheOwner } from "silentium";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* https://silentium-lab.github.io/silentium-components/#/boolean/or
|
|
5
5
|
*/
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
}
|
|
6
|
+
export class Or extends TheInformation<boolean> {
|
|
7
|
+
public constructor(
|
|
8
|
+
private oneSrc: TheInformation<boolean>,
|
|
9
|
+
private twoSrc: TheInformation<boolean>,
|
|
10
|
+
) {
|
|
11
|
+
super(oneSrc, twoSrc);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public value(o: TheOwner<boolean>): this {
|
|
15
|
+
new All(this.oneSrc, this.twoSrc).value(
|
|
16
|
+
new From(([one, two]) => {
|
|
17
|
+
o.give(one || two);
|
|
18
|
+
}),
|
|
19
|
+
);
|
|
20
|
+
return this;
|
|
21
|
+
}
|
|
22
|
+
}
|
package/src/boolean/index.ts
CHANGED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Late } from "silentium";
|
|
2
|
+
import { expect, test } from "vitest";
|
|
3
|
+
import { Sync } from "../behaviors/Sync";
|
|
4
|
+
import { FromJson } from "../formats/FromJson";
|
|
5
|
+
|
|
6
|
+
test("FromJson.test", () => {
|
|
7
|
+
const one = new Late('{"hello": "world"}');
|
|
8
|
+
const objectSync = new Sync(new FromJson<{ hello: string }>(one));
|
|
9
|
+
|
|
10
|
+
expect(objectSync.valueSync().hello).toBe("world");
|
|
11
|
+
});
|
package/src/formats/FromJson.ts
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { From, TheInformation, TheOwner } from "silentium";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Represents object from json
|
|
5
5
|
*/
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
jsonSrc
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
6
|
+
export class FromJson<T> extends TheInformation<T> {
|
|
7
|
+
public constructor(
|
|
8
|
+
private jsonSrc: TheInformation<string>,
|
|
9
|
+
private errorOwner?: TheOwner,
|
|
10
|
+
) {
|
|
11
|
+
super(jsonSrc);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public value(o: TheOwner<T>): this {
|
|
15
|
+
this.jsonSrc.value(
|
|
16
|
+
new From((json) => {
|
|
17
|
+
try {
|
|
18
|
+
o.give(JSON.parse(json));
|
|
19
|
+
} catch (error) {
|
|
20
|
+
this.errorOwner?.give(new Error(`Failed to parse JSON: ${error}`));
|
|
21
|
+
}
|
|
22
|
+
}),
|
|
23
|
+
);
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Late } from "silentium";
|
|
2
|
+
import { expect, test } from "vitest";
|
|
3
|
+
import { Sync } from "../behaviors/Sync";
|
|
4
|
+
import { ToJson } from "../formats/ToJson";
|
|
5
|
+
|
|
6
|
+
test("FromJson.test", () => {
|
|
7
|
+
const one = new Late({ hello: "world" });
|
|
8
|
+
const objectSync = new Sync(new ToJson(one));
|
|
9
|
+
|
|
10
|
+
expect(objectSync.valueSync()).toBe('{"hello":"world"}');
|
|
11
|
+
});
|
package/src/formats/ToJson.ts
CHANGED
|
@@ -1,19 +1,26 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { From, TheInformation, TheOwner } from "silentium";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
|
-
*
|
|
4
|
+
* Represents json from object
|
|
5
5
|
*/
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
dataSrc
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
}
|
|
6
|
+
export class ToJson extends TheInformation<string> {
|
|
7
|
+
public constructor(
|
|
8
|
+
private dataSrc: TheInformation,
|
|
9
|
+
private errorOwner?: TheOwner,
|
|
10
|
+
) {
|
|
11
|
+
super(dataSrc);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
public value(o: TheOwner<string>): this {
|
|
15
|
+
this.dataSrc.value(
|
|
16
|
+
new From((data: unknown) => {
|
|
17
|
+
try {
|
|
18
|
+
o.give(JSON.stringify(data));
|
|
19
|
+
} catch {
|
|
20
|
+
this.errorOwner?.give(new Error("Failed to convert to JSON"));
|
|
21
|
+
}
|
|
22
|
+
}),
|
|
23
|
+
);
|
|
24
|
+
return this;
|
|
25
|
+
}
|
|
26
|
+
}
|
package/src/lists/First.test.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { From, Of } from "silentium";
|
|
2
2
|
import { expect, test, vi } from "vitest";
|
|
3
|
-
import {
|
|
3
|
+
import { First } from "./First";
|
|
4
4
|
|
|
5
5
|
test("first", () => {
|
|
6
|
-
const f =
|
|
6
|
+
const f = new First(new Of([1, 2, 3]));
|
|
7
7
|
const g = vi.fn();
|
|
8
|
-
f(g);
|
|
8
|
+
f.value(new From(g));
|
|
9
9
|
expect(g).toHaveBeenCalledWith(1);
|
|
10
10
|
});
|
package/src/lists/First.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Applied, TheInformation, TheOwner } from "silentium";
|
|
2
2
|
|
|
3
3
|
/**
|
|
4
4
|
* Represents the first element of an array.
|
|
5
5
|
*/
|
|
6
|
-
export
|
|
7
|
-
baseSrc:
|
|
8
|
-
)
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
export class First<T extends Array<unknown>> extends TheInformation<T[0]> {
|
|
7
|
+
public constructor(private baseSrc: TheInformation<T>) {
|
|
8
|
+
super(baseSrc);
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
public value(o: TheOwner<T[0]>): this {
|
|
12
|
+
new Applied(this.baseSrc, (a) => a[0]).value(o);
|
|
13
|
+
return this;
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { Applied, From, Late, Of, Shared } from "silentium";
|
|
2
2
|
import { expect, test, vi } from "vitest";
|
|
3
|
-
import {
|
|
3
|
+
import { Router } from "../navigation/Router";
|
|
4
4
|
|
|
5
5
|
const drop = (dropPart: string) => (value: string) => {
|
|
6
6
|
return value.replace(dropPart, "");
|
|
7
7
|
};
|
|
8
8
|
|
|
9
9
|
test("Router.test", () => {
|
|
10
|
-
const
|
|
11
|
-
const
|
|
10
|
+
const urlSrc = new Late<string>("http://domain.com/");
|
|
11
|
+
const urlPathSrc = new Shared(new Applied(urlSrc, drop("http://domain.com")));
|
|
12
12
|
const g = vi.fn();
|
|
13
|
-
urlPathSrc(g);
|
|
13
|
+
urlPathSrc.value(new From(g));
|
|
14
14
|
|
|
15
|
-
const routerSrc =
|
|
15
|
+
const routerSrc = new Router(
|
|
16
16
|
urlPathSrc,
|
|
17
|
-
|
|
17
|
+
new Of([
|
|
18
18
|
{
|
|
19
19
|
pattern: "^/$",
|
|
20
|
-
template:
|
|
20
|
+
template: new Of("page/home.html"),
|
|
21
21
|
},
|
|
22
22
|
{
|
|
23
23
|
pattern: "/some/contacts",
|
|
24
24
|
template: "page/contacts.html",
|
|
25
25
|
},
|
|
26
26
|
]),
|
|
27
|
-
|
|
27
|
+
new Of<string>("page/404.html"),
|
|
28
28
|
);
|
|
29
29
|
const g2 = vi.fn();
|
|
30
|
-
routerSrc(g2);
|
|
30
|
+
routerSrc.value(new From(g2));
|
|
31
31
|
|
|
32
32
|
expect(g2).toHaveBeenLastCalledWith("page/home.html");
|
|
33
33
|
|
|
34
|
-
|
|
34
|
+
urlSrc.owner().give("http://domain.com/some/contacts");
|
|
35
35
|
|
|
36
36
|
expect(g).toHaveBeenLastCalledWith("/some/contacts");
|
|
37
37
|
expect(g2).toHaveBeenLastCalledWith("page/contacts.html");
|
|
38
38
|
|
|
39
|
-
|
|
39
|
+
urlSrc.owner().give("http://domain.com/some/unknown/");
|
|
40
40
|
|
|
41
41
|
expect(g2).toHaveBeenLastCalledWith("page/404.html");
|
|
42
42
|
|
|
43
|
-
|
|
43
|
+
urlSrc.owner().give("http://domain.com/");
|
|
44
44
|
|
|
45
45
|
expect(g2).toHaveBeenLastCalledWith("page/home.html");
|
|
46
46
|
});
|
package/src/navigation/Router.ts
CHANGED
|
@@ -1,39 +1,46 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
1
|
+
import { Any, Chain, From, Of, TheInformation, TheOwner } from "silentium";
|
|
2
|
+
import { Branch } from "../behaviors";
|
|
3
|
+
import { RegexpMatched } from "../system";
|
|
4
4
|
|
|
5
5
|
export interface Route<T> {
|
|
6
6
|
pattern: string;
|
|
7
7
|
patternFlags?: string;
|
|
8
|
-
template: T |
|
|
8
|
+
template: T | TheInformation<T>;
|
|
9
9
|
}
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* Router component what will return template if url matches pattern
|
|
13
13
|
* https://silentium-lab.github.io/silentium-components/#/navigation/router
|
|
14
14
|
*/
|
|
15
|
-
export
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
15
|
+
export class Router<T = "string"> extends TheInformation<T> {
|
|
16
|
+
public constructor(
|
|
17
|
+
private urlSrc: TheInformation<string>,
|
|
18
|
+
private routesSrc: TheInformation<Route<T>[]>,
|
|
19
|
+
private defaultSrc: TheInformation<T>,
|
|
20
|
+
) {
|
|
21
|
+
super(urlSrc, routesSrc, defaultSrc);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
public value(o: TheOwner<T>): this {
|
|
25
|
+
this.routesSrc.value(
|
|
26
|
+
new From((routes) => {
|
|
27
|
+
new Any(
|
|
28
|
+
new Chain(this.urlSrc, this.defaultSrc),
|
|
29
|
+
...routes.map((r) => {
|
|
30
|
+
return new Branch(
|
|
31
|
+
new RegexpMatched(
|
|
32
|
+
new Of(r.pattern),
|
|
33
|
+
this.urlSrc,
|
|
34
|
+
r.patternFlags ? new Of(r.patternFlags) : undefined,
|
|
35
|
+
),
|
|
36
|
+
(r.template instanceof TheInformation
|
|
37
|
+
? r.template
|
|
38
|
+
: new Of(r.template)) as TheInformation,
|
|
39
|
+
);
|
|
40
|
+
}),
|
|
41
|
+
).value(o as TheOwner);
|
|
42
|
+
}),
|
|
43
|
+
);
|
|
44
|
+
return this;
|
|
45
|
+
}
|
|
46
|
+
}
|