silentium-components 0.0.78 → 0.0.80

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.
@@ -0,0 +1,61 @@
1
+ import { Late, Transport } from "silentium";
2
+ import { Task } from "../behaviors/Task";
3
+ import { afterEach, beforeEach, expect, test, vi } from "vitest";
4
+
5
+ beforeEach(() => {
6
+ vi.useFakeTimers({ shouldAdvanceTime: true });
7
+ });
8
+
9
+ afterEach(() => {
10
+ vi.runOnlyPendingTimers();
11
+ vi.useRealTimers();
12
+ });
13
+
14
+ test("Task delays emission", () => {
15
+ const $trigger = Late<string>();
16
+ const delayed = Task($trigger, 100);
17
+ const data: string[] = [];
18
+ delayed.event(
19
+ Transport((v) => {
20
+ data.push(v);
21
+ }),
22
+ );
23
+
24
+ $trigger.use("first");
25
+
26
+ // Before delay, no emission
27
+ expect(data).toStrictEqual([]);
28
+
29
+ // Advance time to trigger emission
30
+ vi.advanceTimersByTime(100);
31
+
32
+ expect(data).toStrictEqual(["first"]);
33
+ });
34
+
35
+ test("Task emits only last value when multiple before delay", () => {
36
+ const $trigger = Late<string>();
37
+ const delayed = Task($trigger, 100);
38
+ const data: string[] = [];
39
+ delayed.event(
40
+ Transport((v) => {
41
+ data.push(v);
42
+ }),
43
+ );
44
+
45
+ $trigger.use("first");
46
+ $trigger.use("second");
47
+ $trigger.use("third");
48
+
49
+ // Before delay, no emission
50
+ expect(data).toStrictEqual([]);
51
+
52
+ // Advance time partially
53
+ vi.advanceTimersByTime(50);
54
+ expect(data).toStrictEqual([]);
55
+
56
+ // Advance to full delay
57
+ vi.advanceTimersByTime(50);
58
+
59
+ // Only last value should be emitted
60
+ expect(data).toStrictEqual(["third"]);
61
+ });
@@ -0,0 +1,98 @@
1
+ import {
2
+ Applied,
3
+ Late,
4
+ Of,
5
+ Shared,
6
+ Transport,
7
+ Event,
8
+ TransportEvent,
9
+ } from "silentium";
10
+ import { Router } from "../navigation/Router";
11
+ import { expect, test, vi } from "vitest";
12
+
13
+ const drop = (dropPart: string) => (value: string) => {
14
+ return value.replace(dropPart, "");
15
+ };
16
+
17
+ test("Router destroys previous route events when switching routes", () => {
18
+ const $url = Late<string>("http://domain.com/");
19
+ const $urlPath = Shared(Applied($url, drop("http://domain.com")));
20
+ const g = vi.fn();
21
+ $urlPath.event(Transport(g));
22
+
23
+ // Create mock destroyable events for routes
24
+ const firstRouteDestroy = vi.fn();
25
+ const secondRouteDestroy = vi.fn();
26
+ const defaultDestroy = vi.fn();
27
+
28
+ const firstRouteEvent = TransportEvent(() =>
29
+ Event<string>((transport) => {
30
+ transport.use("first-route-response");
31
+ return firstRouteDestroy;
32
+ }),
33
+ );
34
+
35
+ const secondRouteEvent = TransportEvent(() =>
36
+ Event<string>((transport) => {
37
+ transport.use("second-route-response");
38
+ return secondRouteDestroy;
39
+ }),
40
+ );
41
+
42
+ const defaultEvent = TransportEvent(() =>
43
+ Event<string>((transport) => {
44
+ transport.use("default-response");
45
+ return defaultDestroy;
46
+ }),
47
+ );
48
+
49
+ const $router = Router(
50
+ $urlPath,
51
+ Of([
52
+ {
53
+ pattern: "^/first$",
54
+ event: firstRouteEvent,
55
+ },
56
+ {
57
+ pattern: "^/second$",
58
+ event: secondRouteEvent,
59
+ },
60
+ ]),
61
+ defaultEvent,
62
+ );
63
+
64
+ const g2 = vi.fn();
65
+ $router.event(Transport(g2));
66
+
67
+ // Initially no route matches, should use default
68
+ expect(g2).toHaveBeenLastCalledWith("default-response");
69
+ expect(defaultDestroy).not.toHaveBeenCalled();
70
+
71
+ // Change to first route
72
+ $url.use("http://domain.com/first");
73
+
74
+ expect(g2).toHaveBeenLastCalledWith("first-route-response");
75
+ expect(defaultDestroy).toHaveBeenCalledTimes(1); // Default should be destroyed
76
+ expect(firstRouteDestroy).not.toHaveBeenCalled();
77
+
78
+ // Change to second route
79
+ $url.use("http://domain.com/second");
80
+
81
+ expect(g2).toHaveBeenLastCalledWith("second-route-response");
82
+ expect(firstRouteDestroy).toHaveBeenCalledTimes(1); // First route should be destroyed
83
+ expect(secondRouteDestroy).not.toHaveBeenCalled();
84
+
85
+ // Change back to no match (default)
86
+ $url.use("http://domain.com/nomatch");
87
+
88
+ expect(g2).toHaveBeenLastCalledWith("default-response");
89
+ expect(secondRouteDestroy).toHaveBeenCalledTimes(1); // Second route should be destroyed
90
+ expect(defaultDestroy).toHaveBeenCalledTimes(1); // Still only once, as it was destroyed before
91
+
92
+ // Change back to first route
93
+ $url.use("http://domain.com/first");
94
+
95
+ expect(g2).toHaveBeenLastCalledWith("first-route-response");
96
+ expect(defaultDestroy).toHaveBeenCalledTimes(2); // Default destroyed again
97
+ expect(firstRouteDestroy).toHaveBeenCalledTimes(1); // Still only once
98
+ });
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  All,
3
3
  DestroyableType,
4
+ DestroyContainer,
4
5
  Event,
5
6
  EventType,
6
- isDestroyable,
7
7
  Of,
8
8
  Transport,
9
9
  TransportType,
@@ -26,15 +26,9 @@ export function Router<T = "string">(
26
26
  $default: TransportType<void, EventType<T>>,
27
27
  ): EventType<T> & DestroyableType {
28
28
  return Event<T>((transport) => {
29
- const destroyableList: DestroyableType[] = [];
30
- const checkDestroyable = (instance: unknown) => {
31
- if (isDestroyable(instance)) {
32
- destroyableList.push(instance);
33
- }
34
- };
29
+ const dc = DestroyContainer();
35
30
  const destructor = () => {
36
- destroyableList.forEach((d) => d.destroy());
37
- destroyableList.length = 0;
31
+ dc.destroy();
38
32
  };
39
33
  All($routes, $url).event(
40
34
  Transport(([routes, url]) => {
@@ -54,13 +48,13 @@ export function Router<T = "string">(
54
48
 
55
49
  if (index === -1) {
56
50
  const instance = $default.use();
57
- checkDestroyable(instance);
51
+ dc.add(instance);
58
52
  instance.event(transport);
59
53
  }
60
54
 
61
55
  if (index > -1) {
62
56
  const instance = routes[index].event.use();
63
- checkDestroyable(instance);
57
+ dc.add(instance);
64
58
  instance.event(transport);
65
59
  }
66
60
  }),