patron-oop 1.45.0 → 1.46.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.
Files changed (140) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/patron.cjs +106 -35
  3. package/dist/patron.cjs.map +1 -1
  4. package/dist/patron.d.ts +40 -1
  5. package/dist/patron.js +103 -36
  6. package/dist/patron.js.map +1 -1
  7. package/dist/patron.min.js +1 -1
  8. package/dist/patron.min.mjs +1 -1
  9. package/dist/patron.min.mjs.map +1 -1
  10. package/dist/patron.mjs +103 -36
  11. package/dist/patron.mjs.map +1 -1
  12. package/docs/README.md +3 -0
  13. package/docs/assets/css/base.css +42 -0
  14. package/docs/assets/favicon/android-icon-144x144.png +0 -0
  15. package/docs/assets/favicon/android-icon-192x192.png +0 -0
  16. package/docs/assets/favicon/android-icon-36x36.png +0 -0
  17. package/docs/assets/favicon/android-icon-48x48.png +0 -0
  18. package/docs/assets/favicon/android-icon-72x72.png +0 -0
  19. package/docs/assets/favicon/android-icon-96x96.png +0 -0
  20. package/docs/assets/favicon/apple-icon-114x114.png +0 -0
  21. package/docs/assets/favicon/apple-icon-120x120.png +0 -0
  22. package/docs/assets/favicon/apple-icon-144x144.png +0 -0
  23. package/docs/assets/favicon/apple-icon-152x152.png +0 -0
  24. package/docs/assets/favicon/apple-icon-180x180.png +0 -0
  25. package/docs/assets/favicon/apple-icon-57x57.png +0 -0
  26. package/docs/assets/favicon/apple-icon-60x60.png +0 -0
  27. package/docs/assets/favicon/apple-icon-72x72.png +0 -0
  28. package/docs/assets/favicon/apple-icon-76x76.png +0 -0
  29. package/docs/assets/favicon/apple-icon-precomposed.png +0 -0
  30. package/docs/assets/favicon/apple-icon.png +0 -0
  31. package/docs/assets/favicon/browserconfig.xml +2 -0
  32. package/docs/assets/favicon/favicon-16x16.png +0 -0
  33. package/docs/assets/favicon/favicon-32x32.png +0 -0
  34. package/docs/assets/favicon/favicon-96x96.png +0 -0
  35. package/docs/assets/favicon/favicon.ico +0 -0
  36. package/docs/assets/favicon/manifest.json +41 -0
  37. package/docs/assets/favicon/ms-icon-144x144.png +0 -0
  38. package/docs/assets/favicon/ms-icon-150x150.png +0 -0
  39. package/docs/assets/favicon/ms-icon-310x310.png +0 -0
  40. package/docs/assets/favicon/ms-icon-70x70.png +0 -0
  41. package/docs/assets/img/404.jpg +0 -0
  42. package/docs/assets/img/angular_16.jpg +0 -0
  43. package/docs/assets/img/angular_32.jpg +0 -0
  44. package/docs/assets/img/eo_16.jpg +0 -0
  45. package/docs/assets/img/eo_big.png +0 -0
  46. package/docs/assets/img/github_16.jpg +0 -0
  47. package/docs/assets/img/logo.jpg +0 -0
  48. package/docs/assets/img/philosofy/observable.jpg +0 -0
  49. package/docs/assets/img/philosofy/responsible.jpg +0 -0
  50. package/docs/assets/img/philosofy/result.jpg +0 -0
  51. package/docs/assets/img/philosofy/tell.jpg +0 -0
  52. package/docs/assets/img/react_16.jpg +0 -0
  53. package/docs/assets/img/react_32.jpg +0 -0
  54. package/docs/assets/img/vue_16.jpg +0 -0
  55. package/docs/assets/img/vue_32.jpg +0 -0
  56. package/docs/assets/js/components/linkDynamic.mjs +11 -0
  57. package/docs/assets/js/components/linkReloadable.mjs +13 -0
  58. package/docs/assets/js/entrypoints/compatibility.mjs +31 -0
  59. package/docs/assets/js/entrypoints/components.mjs +2 -0
  60. package/docs/assets/js/entrypoints/examples.mjs +25 -0
  61. package/docs/assets/js/entrypoints/factory.mjs +20 -0
  62. package/docs/assets/js/entrypoints/guest.mjs +61 -0
  63. package/docs/assets/js/entrypoints/index.mjs +110 -0
  64. package/docs/assets/js/entrypoints/integrations.mjs +36 -0
  65. package/docs/assets/js/entrypoints/patron.mjs +46 -0
  66. package/docs/assets/js/entrypoints/source.mjs +76 -0
  67. package/docs/assets/js/entrypoints/terminology.mjs +51 -0
  68. package/docs/assets/js/entrypoints/utils.mjs +61 -0
  69. package/docs/assets/js/lib/StyleFetched.mjs +14 -0
  70. package/docs/assets/js/routing.mjs +110 -0
  71. package/docs/assets/schemes/dip.html +28 -0
  72. package/docs/favicon.ico +0 -0
  73. package/docs/index-dev.html +346 -0
  74. package/docs/index.html +346 -0
  75. package/docs/manifest.json +41 -0
  76. package/docs/pages/404.html +9 -0
  77. package/docs/pages/common/layout.html +17 -0
  78. package/docs/pages/compatibility/dip.html +82 -0
  79. package/docs/pages/compatibility/elegant-objects.html +373 -0
  80. package/docs/pages/compatibility/layout.html +17 -0
  81. package/docs/pages/examples/errors.html +167 -0
  82. package/docs/pages/examples/index.html +10 -0
  83. package/docs/pages/examples.html +41 -0
  84. package/docs/pages/factory/index.html +18 -0
  85. package/docs/pages/factory.html +36 -0
  86. package/docs/pages/guest/guest-applied.html +51 -0
  87. package/docs/pages/guest/guest-cast.html +219 -0
  88. package/docs/pages/guest/guest-disposable.html +147 -0
  89. package/docs/pages/guest/guest-executor-applied.html +65 -0
  90. package/docs/pages/guest/guest-object.html +101 -0
  91. package/docs/pages/guest/guest-pool.html +107 -0
  92. package/docs/pages/guest/guest-sync.html +66 -0
  93. package/docs/pages/guest/index.html +115 -0
  94. package/docs/pages/guest.html +59 -0
  95. package/docs/pages/index.html +72 -0
  96. package/docs/pages/integrations/angular.html +5 -0
  97. package/docs/pages/integrations/layout.html +17 -0
  98. package/docs/pages/integrations/react.html +7 -0
  99. package/docs/pages/integrations/vue.html +102 -0
  100. package/docs/pages/patron/index.html +140 -0
  101. package/docs/pages/patron/patron-applied.html +66 -0
  102. package/docs/pages/patron/patron-executor-applied.html +94 -0
  103. package/docs/pages/patron/patron-once.html +110 -0
  104. package/docs/pages/patron/patron-pool.html +99 -0
  105. package/docs/pages/patron.html +50 -0
  106. package/docs/pages/philosofy.html +210 -0
  107. package/docs/pages/source/index.html +167 -0
  108. package/docs/pages/source/source-active.html +113 -0
  109. package/docs/pages/source/source-all.html +129 -0
  110. package/docs/pages/source/source-applied.html +73 -0
  111. package/docs/pages/source/source-dynamic.html +93 -0
  112. package/docs/pages/source/source-executor-applied.html +64 -0
  113. package/docs/pages/source/source-map.html +192 -0
  114. package/docs/pages/source/source-once.html +73 -0
  115. package/docs/pages/source/source-race.html +171 -0
  116. package/docs/pages/source/source-sequence.html +160 -0
  117. package/docs/pages/source/source-with-pool.html +102 -0
  118. package/docs/pages/source/source.html +167 -0
  119. package/docs/pages/source.html +68 -0
  120. package/docs/pages/terminology/guest.html +14 -0
  121. package/docs/pages/terminology/index.html +6 -0
  122. package/docs/pages/terminology/introduction.html +25 -0
  123. package/docs/pages/terminology/patron.html +10 -0
  124. package/docs/pages/terminology/source.html +55 -0
  125. package/docs/pages/terminology/visitor.html +19 -0
  126. package/docs/pages/terminology.html +53 -0
  127. package/docs/pages/utils/give.html +47 -0
  128. package/docs/pages/utils/index.html +24 -0
  129. package/docs/pages/utils/is-guest-aware.html +22 -0
  130. package/docs/pages/utils/is-guest.html +21 -0
  131. package/docs/pages/utils/is-patron-in-pools.html +53 -0
  132. package/docs/pages/utils/private.html +44 -0
  133. package/docs/pages/utils/remove-patron-from-pools.html +57 -0
  134. package/docs/pages/utils/value.html +47 -0
  135. package/docs/pages/utils.html +61 -0
  136. package/eslint.config.mjs +6 -0
  137. package/package.json +1 -1
  138. package/src/Patron/PatronApplied.ts +22 -0
  139. package/src/Patron/PatronExecutorApplied.ts +25 -0
  140. package/src/index.ts +4 -0
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "App",
3
+ "icons": [
4
+ {
5
+ "src": ".\/assets\/favicon\/android-icon-36x36.png",
6
+ "sizes": "36x36",
7
+ "type": "image\/png",
8
+ "density": "0.75"
9
+ },
10
+ {
11
+ "src": ".\/assets\/favicon\/android-icon-48x48.png",
12
+ "sizes": "48x48",
13
+ "type": "image\/png",
14
+ "density": "1.0"
15
+ },
16
+ {
17
+ "src": ".\/assets\/favicon\/android-icon-72x72.png",
18
+ "sizes": "72x72",
19
+ "type": "image\/png",
20
+ "density": "1.5"
21
+ },
22
+ {
23
+ "src": ".\/assets\/favicon\/android-icon-96x96.png",
24
+ "sizes": "96x96",
25
+ "type": "image\/png",
26
+ "density": "2.0"
27
+ },
28
+ {
29
+ "src": ".\/assets\/favicon\/android-icon-144x144.png",
30
+ "sizes": "144x144",
31
+ "type": "image\/png",
32
+ "density": "3.0"
33
+ },
34
+ {
35
+ "src": ".\/assets\/favicon\/android-icon-192x192.png",
36
+ "sizes": "192x192",
37
+ "type": "image\/png",
38
+ "density": "4.0"
39
+ }
40
+ ]
41
+ }
@@ -0,0 +1,9 @@
1
+ <div class="text-center">
2
+ <img class="mb-5 inline" src="./assets/img/404.jpg" width="200" height="200" />
3
+ <h1 class="pb-3 text-xl font-semibold text-gray-600">
4
+ Страница не найдена
5
+ </h1>
6
+ <p>
7
+ Попробуйте другой раздел или вернитесь на главную
8
+ </p>
9
+ </div>
@@ -0,0 +1,17 @@
1
+ <div class="common-menu"></div>
2
+ <div class="w-full sm:w-2/3 mt-4 sm:mt-0 mx-auto">
3
+ <div class="common-loader">
4
+ <div class="w-full flex justify-center">
5
+ <div
6
+ class="inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-current border-e-transparent align-[-0.125em] text-indigo-500 motion-reduce:animate-[spin_1.5s_linear_infinite]"
7
+ role="status"
8
+ >
9
+ <span
10
+ class="!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]"
11
+ >Loading...</span
12
+ >
13
+ </div>
14
+ </div>
15
+ </div>
16
+ <div class="common-page-area"></div>
17
+ </div>
@@ -0,0 +1,82 @@
1
+ <h1 class="pb-3 text-xl font-semibold text-gray-600">
2
+ Dependency Inversion Principal
3
+ </h1>
4
+
5
+ <p class="text-gray-600 text-lg mb-4">
6
+ <b>DIP</b> - принцип инверсии зависимостей, описанный Робертом Мартином.
7
+ Принцип говорит о том, что архитектор системы может изменить направление
8
+ зависимости от процедурного - когда большее зависит от меньшего на
9
+ противополложное когда меньшее зависит от большего. Большее - это higher
10
+ policy (бизнес логика) и от потребностей бизнес логики зависят плагины
11
+ конкретных систем, например плагин работы с БД, обеспечивающий нашу бизнес
12
+ логику данными из БД.
13
+ </p>
14
+
15
+ <p class="text-gray-600 text-lg mb-4">
16
+ Библиотека Patron - это реализация DIP принципа. Ваша бизнес логика может
17
+ зависеть от интерфейсов
18
+ <link-reloadable
19
+ target-blank
20
+ href="https://github.com/kosukhin/patron/blob/main/src/Source/Source.ts#L9"
21
+ >
22
+ SourceType
23
+ </link-reloadable>
24
+ или
25
+ <link-reloadable
26
+ target-blank
27
+ href="https://github.com/kosukhin/patron/blob/main/src/Guest/Guest.ts#L17"
28
+ >
29
+ GuestType
30
+ </link-reloadable>
31
+ или
32
+ <link-reloadable
33
+ target-blank
34
+ href="https://github.com/kosukhin/patron/blob/main/src/Source/SourceActive.ts#L9"
35
+ >
36
+ ActionType
37
+ </link-reloadable>
38
+ . Эти общие интерфейсы позволяют либо получить данные(SourceType) либо
39
+ принять того кому данные нужно передать(GuestType) либо принять объект который
40
+ умеет делать действия(ActionType)
41
+ </p>
42
+
43
+ <p class="text-gray-600 text-lg mb-0 font-bold">
44
+ Схема 1. Пример приложения с DIP + Patron
45
+ </p>
46
+
47
+ <iframe
48
+ src="./assets/schemes/dip.html"
49
+ border="0"
50
+ width="100%"
51
+ height="500"
52
+ ></iframe>
53
+
54
+ <p>&nbsp;</p>
55
+ <p class="text-gray-600 text-lg mb-4">
56
+ Как видно из схемы 1 все классы зависят только от интерфейсов из библиотеки
57
+ Patron, только дополняя параметры дженериков нужными типами.
58
+ </p>
59
+
60
+ <p class="text-gray-600 text-lg mb-4">
61
+ Прикладной код может выглядеть следующим образом, как показано в примере 1.
62
+ </p>
63
+
64
+ <p class="text-gray-600 text-lg mb-0 font-bold">Пример 1.</p>
65
+ <pre
66
+ class="mb-4"
67
+ ><code class="language-js">// Условный код, для демонстрации композиции классов схемы 1
68
+ const credentials = new CredentialsFromPostRequest(request);
69
+
70
+ const user = new UserStatus(
71
+ new SQLUserOfCredentials(credentials)
72
+ );
73
+
74
+ const card = new UserCard();
75
+ user.value(card);
76
+ </code></pre>
77
+
78
+ <p class="text-gray-600 text-lg mb-4">
79
+ Выгода использования Patron - хорошо видна, каждый класс не зависит ни от чего
80
+ кроме библиотеки Patron и тех библиотек плагином которых является, а в случае
81
+ класса бизнес - логики зависимость будет только от Patron.
82
+ </p>
@@ -0,0 +1,373 @@
1
+ <h1 class="pb-3 text-xl font-semibold text-gray-600">Elegant Objects</h1>
2
+
3
+ <img
4
+ src="./assets/img/eo_big.png"
5
+ width="150"
6
+ height="170"
7
+ class="float-left m-3"
8
+ />
9
+
10
+ <p class="text-gray-600 text-lg mb-4">
11
+ Работы по библиотеке Patron вдохновлены двумя книгами:
12
+ <a
13
+ class="inline-block whitespace-nowrap rounded-[0.27rem] bg-primary-100 px-[0.65em] pb-[0.25em] pt-[0.35em] text-center align-baseline text-[0.75em] font-bold leading-none text-white bg-slate-900"
14
+ href="https://www.elegantobjects.org/"
15
+ target="_blank"
16
+ >
17
+ Elegant Objects
18
+ </a>
19
+ и
20
+ <a
21
+ class="inline-block whitespace-nowrap rounded-[0.27rem] bg-primary-100 px-[0.65em] pb-[0.25em] pt-[0.35em] text-center align-baseline text-[0.75em] font-bold leading-none text-white bg-slate-900"
22
+ href="https://www.amazon.com/Object-Thinking-Developer-Reference-David/dp/0735619654"
23
+ target="_blank"
24
+ >
25
+ Object Thinking
26
+ </a>
27
+ </p>
28
+
29
+ <div class="clear-both"></div>
30
+
31
+ <p class="text-gray-600 text-lg mb-4">
32
+ В этом разделе сделаем пример кода по расчету простой арифметической формулы с
33
+ возможностью изменять переменные и одна из переменных будет таймером.
34
+ </p>
35
+
36
+ <p>&nbsp;</p>
37
+
38
+ <p class="text-gray-600 text-lg mb-0 font-bold">
39
+ Результат 1. Вычисление на лету
40
+ </p>
41
+ <div class="example mb-4">
42
+ <span class="guest-result">
43
+ (
44
+ <input
45
+ type="number"
46
+ class="input-1"
47
+ style="
48
+ width: 60px;
49
+ background: rgba(255, 255, 255, 0.3);
50
+ border: solid 1px #eee;
51
+ color: #000;
52
+ "
53
+ />
54
+ +
55
+ <span class="eo-counter">?</span>
56
+ ) *
57
+ <input
58
+ type="number"
59
+ class="input-2"
60
+ style="
61
+ width: 60px;
62
+ background: rgba(255, 255, 255, 0.3);
63
+ border: solid 1px #eee;
64
+ color: #000;
65
+ "
66
+ />
67
+ = <span class="eo-result">??</span>
68
+ </span>
69
+ <div class="mt-4">
70
+ <button
71
+ onclick="window.numberTimer.stop()"
72
+ class="stop inline-flex gap-1 items-center bg-gray-100 border-0 py-1 px-3 focus:outline-none hover:bg-gray-200 rounded text-black mt-4 md:mt-0"
73
+ >
74
+ Остановить
75
+ </button>
76
+ <button
77
+ onclick="window.numberTimer.start()"
78
+ class="begin inline-flex gap-1 items-center bg-gray-100 border-0 py-1 px-3 focus:outline-none hover:bg-gray-200 rounded text-black mt-4 md:mt-0"
79
+ >
80
+ Запустить
81
+ </button>
82
+ <button
83
+ onclick="window.numberTimer.reset()"
84
+ class="inline-flex gap-1 items-center bg-gray-100 border-0 py-1 px-3 focus:outline-none hover:bg-gray-200 rounded text-black mt-4 md:mt-0"
85
+ >
86
+ Сбросить
87
+ </button>
88
+ </div>
89
+ </div>
90
+
91
+ <script type="module">
92
+ import {
93
+ Guest,
94
+ Source,
95
+ Patron,
96
+ SourceAll,
97
+ GuestCast,
98
+ GuestDisposable,
99
+ } from "patron-oop";
100
+ import { Text, Input } from "patron-components";
101
+
102
+ class NumberFromTimer {
103
+ timerHead = null;
104
+
105
+ constructor() {
106
+ this.source = new Source(1);
107
+ this.isStoppedSource = new Source(false);
108
+ }
109
+
110
+ number(guest) {
111
+ this.source.value(guest);
112
+ }
113
+
114
+ start() {
115
+ this.isStoppedSource.give(false);
116
+ if (this.timerHead) {
117
+ return;
118
+ }
119
+ const repeat = () => {
120
+ this.source.value((value) => {
121
+ this.timerHead = setTimeout(() => {
122
+ this.source.give(value + 1);
123
+ repeat();
124
+ if (!this.source.pool().size()) {
125
+ this.stop();
126
+ }
127
+ }, 1000);
128
+ });
129
+ };
130
+ repeat();
131
+ }
132
+
133
+ stop() {
134
+ this.isStoppedSource.give(true);
135
+ clearTimeout(this.timerHead);
136
+ this.timerHead = null;
137
+ }
138
+
139
+ reset() {
140
+ this.stop();
141
+ this.source.give(1);
142
+ this.start();
143
+ }
144
+
145
+ isStopped(guest) {
146
+ this.isStoppedSource.value(guest);
147
+ }
148
+ }
149
+
150
+ class NumberFromInput {
151
+ constructor(selector) {
152
+ this.source = new Source(1);
153
+ this.input = new Input(this.source, selector);
154
+ }
155
+
156
+ number(guest) {
157
+ this.source.value(
158
+ new GuestCast(guest, (value) => {
159
+ guest.give(+value);
160
+ })
161
+ );
162
+ }
163
+ }
164
+
165
+ class Addition {
166
+ constructor(num1, num2) {
167
+ this.num1 = num1;
168
+ this.num2 = num2;
169
+ }
170
+
171
+ number(guest) {
172
+ const all = new SourceAll();
173
+ this.num1.number(new GuestCast(guest, all.guestKey("n1")));
174
+ this.num2.number(new GuestCast(guest, all.guestKey("n2")));
175
+ all.value(
176
+ new GuestCast(guest, ({ n1, n2 }) => {
177
+ guest.give(n1 + n2);
178
+ })
179
+ );
180
+ }
181
+ }
182
+
183
+ class Multiplication {
184
+ constructor(num1, num2) {
185
+ this.num1 = num1;
186
+ this.num2 = num2;
187
+ }
188
+
189
+ number(guest) {
190
+ const all = new SourceAll();
191
+ this.num1.number(new GuestCast(guest, all.guestKey("n1")));
192
+ this.num2.number(new GuestCast(guest, all.guestKey("n2")));
193
+ all.value(
194
+ new GuestCast(guest, ({ n1, n2 }) => {
195
+ guest.give(n1 * n2);
196
+ })
197
+ );
198
+ }
199
+ }
200
+
201
+ const disposeIfNoSelector = (selector) => () =>
202
+ !document.querySelector(selector);
203
+
204
+ window.numberTimer = new NumberFromTimer();
205
+ const numberInput1 = new NumberFromInput(".input-1");
206
+ const numberInput2 = new NumberFromInput(".input-2");
207
+ const result = new Multiplication(
208
+ new Addition(numberInput1, numberTimer),
209
+ numberInput2
210
+ );
211
+ numberTimer.start();
212
+ numberTimer.number(
213
+ new Patron(
214
+ new GuestDisposable(
215
+ new Text(".eo-counter"),
216
+ disposeIfNoSelector(".eo-counter")
217
+ )
218
+ )
219
+ );
220
+ numberTimer.isStopped(
221
+ new Patron((isStopped) => {
222
+ document
223
+ .querySelector(".stop")
224
+ .classList[isStopped ? "add" : "remove"]("opacity-20");
225
+ document
226
+ .querySelector(".begin")
227
+ .classList[!isStopped ? "add" : "remove"]("opacity-20");
228
+ })
229
+ );
230
+ result.number(
231
+ new Patron(
232
+ new GuestDisposable(
233
+ new Text(".eo-result"),
234
+ disposeIfNoSelector(".eo-result")
235
+ )
236
+ )
237
+ );
238
+ </script>
239
+
240
+ <p class="text-gray-600 text-lg mb-0 font-bold">Листинг 1.</p>
241
+ <pre class="mb-4"><code class="language-js">import {
242
+ Guest,
243
+ Source,
244
+ Patron,
245
+ SourceAll,
246
+ GuestCast,
247
+ GuestDisposable,
248
+ } from "patron-oop";
249
+ import { Text, Input } from "patron-components";
250
+
251
+ // Переместил клиентский код наверх,
252
+ // чтобы не крутить до самой интересной части.
253
+ window.numberTimer = new NumberFromTimer();
254
+ const numberInput1 = new NumberFromInput(".input-1");
255
+ const numberInput2 = new NumberFromInput(".input-2");
256
+ const result = new Multiplication(
257
+ new Addition(numberInput1, numberTimer),
258
+ numberInput2
259
+ );
260
+ numberTimer.start();
261
+ numberTimer.number(
262
+ new Patron(
263
+ new GuestDisposable(
264
+ new Text(".eo-counter"),
265
+ disposeIfNoSelector(".eo-counter")
266
+ )
267
+ )
268
+ );
269
+ result.number(
270
+ new Patron(
271
+ new GuestDisposable(
272
+ new Text(".eo-result"),
273
+ disposeIfNoSelector(".eo-result")
274
+ )
275
+ )
276
+ );
277
+
278
+ class NumberFromTimer {
279
+ timerHead = null;
280
+
281
+ constructor() {
282
+ this.source = new Source(1);
283
+ }
284
+
285
+ number(guest) {
286
+ this.source.value(guest);
287
+ }
288
+
289
+ start() {
290
+ if (this.timerHead) {
291
+ return;
292
+ }
293
+ const repeat = () => {
294
+ this.source.value((value) => {
295
+ this.timerHead = setTimeout(() => {
296
+ this.source.give(value + 1);
297
+ repeat();
298
+ if (!this.source.pool().size()) {
299
+ this.stop();
300
+ }
301
+ }, 1000);
302
+ });
303
+ };
304
+ repeat();
305
+ }
306
+
307
+ stop() {
308
+ clearTimeout(this.timerHead);
309
+ this.timerHead = null;
310
+ }
311
+
312
+ reset() {
313
+ this.stop();
314
+ this.source.give(1);
315
+ this.start();
316
+ }
317
+ }
318
+
319
+ class NumberFromInput {
320
+ constructor(selector) {
321
+ this.source = new Source(1);
322
+ this.input = new Input(this.source, selector);
323
+ }
324
+
325
+ number(guest) {
326
+ this.source.value(
327
+ new GuestCast(guest, (value) => {
328
+ guest.give(+value);
329
+ })
330
+ );
331
+ }
332
+ }
333
+
334
+ class Addition {
335
+ constructor(num1, num2) {
336
+ this.num1 = num1;
337
+ this.num2 = num2;
338
+ }
339
+
340
+ number(guest) {
341
+ const all = new SourceAll();
342
+ this.num1.number(new GuestCast(guest, all.guestKey("n1")));
343
+ this.num2.number(new GuestCast(guest, all.guestKey("n2")));
344
+ all.value(
345
+ new GuestCast(guest, ({ n1, n2 }) => {
346
+ guest.give(n1 + n2);
347
+ })
348
+ );
349
+ }
350
+ }
351
+
352
+ class Multiplication {
353
+ constructor(num1, num2) {
354
+ this.num1 = num1;
355
+ this.num2 = num2;
356
+ }
357
+
358
+ number(guest) {
359
+ const all = new SourceAll();
360
+ this.num1.number(new GuestCast(guest, all.guestKey("n1")));
361
+ this.num2.number(new GuestCast(guest, all.guestKey("n2")));
362
+ all.value(
363
+ new GuestCast(guest, ({ n1, n2 }) => {
364
+ guest.give(n1 * n2);
365
+ })
366
+ );
367
+ }
368
+ }
369
+
370
+ const disposeIfNoSelector = (selector) => () =>
371
+ !document.querySelector(selector);
372
+
373
+ </code></pre>
@@ -0,0 +1,17 @@
1
+ <div class="compatibility-menu"></div>
2
+ <div class="w-full sm:w-2/3 mt-4 sm:mt-0 mx-auto">
3
+ <div class="compatibility-loader">
4
+ <div class="w-full flex justify-center">
5
+ <div
6
+ class="inline-block h-8 w-8 animate-spin rounded-full border-4 border-solid border-current border-e-transparent align-[-0.125em] text-indigo-500 motion-reduce:animate-[spin_1.5s_linear_infinite]"
7
+ role="status"
8
+ >
9
+ <span
10
+ class="!absolute !-m-px !h-px !w-px !overflow-hidden !whitespace-nowrap !border-0 !p-0 ![clip:rect(0,0,0,0)]"
11
+ >Loading...</span
12
+ >
13
+ </div>
14
+ </div>
15
+ </div>
16
+ <div class="compatibility-page-area"></div>
17
+ </div>