ctrl-fx 0.1.0 → 0.1.2

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 (152) hide show
  1. package/README.md +13 -0
  2. package/dist/chunk-BDTTV33M.js +4050 -0
  3. package/dist/chunk-EKBLRHWK.js +916 -0
  4. package/dist/chunk-OSIRHKDB.js +1812 -0
  5. package/dist/chunk-PKBMQBKP.js +7 -0
  6. package/dist/chunk-XICUXW4T.js +252 -0
  7. package/dist/db/index.d.ts +218 -16
  8. package/dist/db/index.js +53 -19
  9. package/dist/dom/index.d.ts +2 -248
  10. package/dist/dom/index.js +30 -266
  11. package/dist/effects.d.ts +2 -580
  12. package/dist/effects.js +111 -1556
  13. package/dist/index-DeEjNrg-.d.ts +1399 -0
  14. package/dist/index.d.ts +2 -41
  15. package/dist/index.js +18 -78
  16. package/dist/router.d.ts +11 -12
  17. package/dist/router.js +57 -68
  18. package/dist/testing.d.ts +67 -60
  19. package/dist/testing.js +46 -158
  20. package/dist/webcomponent.d.ts +7 -4
  21. package/dist/webcomponent.js +48 -40
  22. package/package.json +4 -3
  23. package/dist/clipboard.d.ts +0 -7
  24. package/dist/clipboard.d.ts.map +0 -1
  25. package/dist/clipboard.js +0 -3
  26. package/dist/db/effects.d.ts +0 -78
  27. package/dist/db/effects.d.ts.map +0 -1
  28. package/dist/db/effects.js +0 -98
  29. package/dist/db/errors.d.ts +0 -21
  30. package/dist/db/errors.d.ts.map +0 -1
  31. package/dist/db/errors.js +0 -13
  32. package/dist/db/index.d.ts.map +0 -1
  33. package/dist/db/keypath.d.ts +0 -40
  34. package/dist/db/keypath.d.ts.map +0 -1
  35. package/dist/db/keypath.js +0 -20
  36. package/dist/db/setup.d.ts +0 -83
  37. package/dist/db/setup.d.ts.map +0 -1
  38. package/dist/db/setup.js +0 -100
  39. package/dist/db/testdb.d.ts +0 -19
  40. package/dist/db/testdb.d.ts.map +0 -1
  41. package/dist/db/testdb.js +0 -34
  42. package/dist/dom/attrs.d.ts +0 -67
  43. package/dist/dom/attrs.d.ts.map +0 -1
  44. package/dist/dom/attrs.js +0 -154
  45. package/dist/dom/components.d.ts +0 -43
  46. package/dist/dom/components.d.ts.map +0 -1
  47. package/dist/dom/components.js +0 -86
  48. package/dist/dom/elems.d.ts +0 -121
  49. package/dist/dom/elems.d.ts.map +0 -1
  50. package/dist/dom/elems.js +0 -52
  51. package/dist/dom/events.d.ts +0 -232
  52. package/dist/dom/events.d.ts.map +0 -1
  53. package/dist/dom/events.js +0 -289
  54. package/dist/dom/index.d.ts.map +0 -1
  55. package/dist/dom/nodeid.d.ts +0 -9
  56. package/dist/dom/nodeid.d.ts.map +0 -1
  57. package/dist/dom/nodeid.js +0 -27
  58. package/dist/dom/svg.d.ts +0 -23
  59. package/dist/dom/svg.d.ts.map +0 -1
  60. package/dist/dom/svg.js +0 -1
  61. package/dist/dom/views.d.ts +0 -60
  62. package/dist/dom/views.d.ts.map +0 -1
  63. package/dist/dom/views.js +0 -154
  64. package/dist/effects.d.ts.map +0 -1
  65. package/dist/index.d.ts.map +0 -1
  66. package/dist/internal/clipboard.d.ts +0 -5
  67. package/dist/internal/clipboard.d.ts.map +0 -1
  68. package/dist/internal/clipboard.js +0 -33
  69. package/dist/internal/cmpmgr.d.ts +0 -46
  70. package/dist/internal/cmpmgr.d.ts.map +0 -1
  71. package/dist/internal/cmpmgr.js +0 -561
  72. package/dist/internal/dbmgr.d.ts +0 -11
  73. package/dist/internal/dbmgr.d.ts.map +0 -1
  74. package/dist/internal/dbmgr.js +0 -200
  75. package/dist/internal/dominterpreter.d.ts +0 -5
  76. package/dist/internal/dominterpreter.d.ts.map +0 -1
  77. package/dist/internal/dominterpreter.js +0 -337
  78. package/dist/internal/eventmgr.d.ts +0 -41
  79. package/dist/internal/eventmgr.d.ts.map +0 -1
  80. package/dist/internal/eventmgr.js +0 -696
  81. package/dist/internal/index.d.ts +0 -19
  82. package/dist/internal/index.d.ts.map +0 -1
  83. package/dist/internal/index.js +0 -38
  84. package/dist/internal/interpreter.d.ts +0 -10
  85. package/dist/internal/interpreter.d.ts.map +0 -1
  86. package/dist/internal/interpreter.js +0 -1
  87. package/dist/internal/locutils.d.ts +0 -4
  88. package/dist/internal/locutils.d.ts.map +0 -1
  89. package/dist/internal/locutils.js +0 -22
  90. package/dist/internal/net.d.ts +0 -4
  91. package/dist/internal/net.d.ts.map +0 -1
  92. package/dist/internal/net.js +0 -64
  93. package/dist/internal/realdom.d.ts +0 -249
  94. package/dist/internal/realdom.d.ts.map +0 -1
  95. package/dist/internal/realdom.js +0 -1
  96. package/dist/internal/styleregistry.d.ts +0 -6
  97. package/dist/internal/styleregistry.d.ts.map +0 -1
  98. package/dist/internal/styleregistry.js +0 -18
  99. package/dist/internal/taskreg.d.ts +0 -9
  100. package/dist/internal/taskreg.d.ts.map +0 -1
  101. package/dist/internal/taskreg.js +0 -28
  102. package/dist/internal/testing.d.ts +0 -12
  103. package/dist/internal/testing.d.ts.map +0 -1
  104. package/dist/internal/testing.js +0 -974
  105. package/dist/internal/testinginterpreter.d.ts +0 -10
  106. package/dist/internal/testinginterpreter.d.ts.map +0 -1
  107. package/dist/internal/testinginterpreter.js +0 -646
  108. package/dist/internal/vdom.d.ts +0 -93
  109. package/dist/internal/vdom.d.ts.map +0 -1
  110. package/dist/internal/vdom.js +0 -470
  111. package/dist/json/index.d.ts +0 -5
  112. package/dist/json/index.d.ts.map +0 -1
  113. package/dist/json/index.js +0 -2
  114. package/dist/json/validation.d.ts +0 -28
  115. package/dist/json/validation.d.ts.map +0 -1
  116. package/dist/json/validation.js +0 -8
  117. package/dist/net/fragment.d.ts +0 -10
  118. package/dist/net/fragment.d.ts.map +0 -1
  119. package/dist/net/fragment.js +0 -27
  120. package/dist/net/index.d.ts +0 -42
  121. package/dist/net/index.d.ts.map +0 -1
  122. package/dist/net/index.js +0 -60
  123. package/dist/net/location.d.ts +0 -21
  124. package/dist/net/location.d.ts.map +0 -1
  125. package/dist/net/location.js +0 -41
  126. package/dist/net/path.d.ts +0 -12
  127. package/dist/net/path.d.ts.map +0 -1
  128. package/dist/net/path.js +0 -29
  129. package/dist/net/queryparam.d.ts +0 -10
  130. package/dist/net/queryparam.d.ts.map +0 -1
  131. package/dist/net/queryparam.js +0 -34
  132. package/dist/router.d.ts.map +0 -1
  133. package/dist/scroll.d.ts +0 -7
  134. package/dist/scroll.d.ts.map +0 -1
  135. package/dist/scroll.js +0 -3
  136. package/dist/testing.d.ts.map +0 -1
  137. package/dist/utils/apply.d.ts +0 -9
  138. package/dist/utils/apply.d.ts.map +0 -1
  139. package/dist/utils/apply.js +0 -10
  140. package/dist/utils/index.d.ts +0 -22
  141. package/dist/utils/index.d.ts.map +0 -1
  142. package/dist/utils/index.js +0 -138
  143. package/dist/utils/lens.d.ts +0 -18
  144. package/dist/utils/lens.d.ts.map +0 -1
  145. package/dist/utils/lens.js +0 -27
  146. package/dist/utils/match.d.ts +0 -17
  147. package/dist/utils/match.d.ts.map +0 -1
  148. package/dist/utils/match.js +0 -28
  149. package/dist/utils/result.d.ts +0 -47
  150. package/dist/utils/result.d.ts.map +0 -1
  151. package/dist/utils/result.js +0 -97
  152. package/dist/webcomponent.d.ts.map +0 -1
@@ -1,974 +0,0 @@
1
- import { pure } from '../effects';
2
- import { newTestData, } from '../testing';
3
- import {} from '../utils';
4
- import { exhaustivenessCheck } from '../utils';
5
- import { ComponentManager } from './cmpmgr';
6
- import { noopStyleRegistry } from './styleregistry';
7
- import { makeTestingInterpreter } from './testinginterpreter';
8
- class Node {
9
- constructor() {
10
- Object.defineProperty(this, "previousSibling", {
11
- enumerable: true,
12
- configurable: true,
13
- writable: true,
14
- value: null
15
- });
16
- Object.defineProperty(this, "nextSibling", {
17
- enumerable: true,
18
- configurable: true,
19
- writable: true,
20
- value: null
21
- });
22
- Object.defineProperty(this, "parentNode", {
23
- enumerable: true,
24
- configurable: true,
25
- writable: true,
26
- value: null
27
- });
28
- }
29
- remove() {
30
- if (this.previousSibling) {
31
- this.previousSibling.nextSibling = this.nextSibling;
32
- }
33
- else {
34
- if (this.parentNode) {
35
- this.parentNode.firstChild = this.nextSibling;
36
- }
37
- }
38
- if (this.nextSibling) {
39
- this.nextSibling.previousSibling = this.previousSibling;
40
- }
41
- this.parentNode = null;
42
- }
43
- insertBefore(node) {
44
- const newNode = typeof node === 'string' ? new TextNode(node) : node;
45
- if (this.previousSibling) {
46
- this.previousSibling.nextSibling = newNode;
47
- newNode.previousSibling = this.previousSibling;
48
- }
49
- else {
50
- if (this.parentNode) {
51
- this.parentNode.firstChild = newNode;
52
- }
53
- }
54
- newNode.nextSibling = this;
55
- newNode.parentNode = this.parentNode;
56
- this.previousSibling = newNode;
57
- return newNode;
58
- }
59
- insertAfter(node) {
60
- const newNode = typeof node === 'string' ? new TextNode(node) : node;
61
- if (this.nextSibling) {
62
- this.nextSibling.previousSibling = newNode;
63
- newNode.nextSibling = this.nextSibling;
64
- }
65
- newNode.previousSibling = this;
66
- newNode.parentNode = this.parentNode;
67
- this.nextSibling = newNode;
68
- return newNode;
69
- }
70
- before(...nodes) {
71
- // eslint-disable-next-line @typescript-eslint/no-this-alias
72
- let current = this;
73
- for (let i = nodes.length - 1; i >= 0; i--) {
74
- current = current.insertBefore(nodes[i]);
75
- }
76
- }
77
- after(...nodes) {
78
- // eslint-disable-next-line @typescript-eslint/no-this-alias
79
- let current = this;
80
- for (let i = 0; i < nodes.length; i++) {
81
- current = current.insertAfter(nodes[i]);
82
- }
83
- }
84
- }
85
- class TextNode extends Node {
86
- constructor(nodeValue) {
87
- super();
88
- Object.defineProperty(this, "nodeValue", {
89
- enumerable: true,
90
- configurable: true,
91
- writable: true,
92
- value: void 0
93
- });
94
- this.nodeValue = nodeValue;
95
- }
96
- }
97
- class ElementNode extends Node {
98
- scrollTo(options) {
99
- if (options.top !== undefined)
100
- this.scrollTop = options.top;
101
- if (options.left !== undefined)
102
- this.scrollLeft = options.left;
103
- }
104
- constructor(tagName) {
105
- super();
106
- Object.defineProperty(this, "tagName", {
107
- enumerable: true,
108
- configurable: true,
109
- writable: true,
110
- value: void 0
111
- });
112
- Object.defineProperty(this, "attributes", {
113
- enumerable: true,
114
- configurable: true,
115
- writable: true,
116
- value: {}
117
- });
118
- Object.defineProperty(this, "firstChild", {
119
- enumerable: true,
120
- configurable: true,
121
- writable: true,
122
- value: null
123
- });
124
- Object.defineProperty(this, "scrollTop", {
125
- enumerable: true,
126
- configurable: true,
127
- writable: true,
128
- value: 0
129
- });
130
- Object.defineProperty(this, "scrollLeft", {
131
- enumerable: true,
132
- configurable: true,
133
- writable: true,
134
- value: 0
135
- });
136
- Object.defineProperty(this, "eventListeners", {
137
- enumerable: true,
138
- configurable: true,
139
- writable: true,
140
- value: []
141
- });
142
- this.tagName = tagName;
143
- }
144
- removeAttribute(name) {
145
- delete this.attributes[name];
146
- }
147
- setAttribute(name, value) {
148
- this.attributes[name] = value;
149
- }
150
- lastChild() {
151
- let child = this.firstChild;
152
- while (child && child.nextSibling) {
153
- child = child.nextSibling;
154
- }
155
- return child;
156
- }
157
- append(...nodes) {
158
- if (nodes.length === 0) {
159
- return;
160
- }
161
- let last = this.lastChild();
162
- if (!last) {
163
- this.firstChild = nodes[0];
164
- this.firstChild.parentNode = this;
165
- nodes = nodes.slice(1);
166
- last = this.firstChild;
167
- }
168
- last.after(...nodes);
169
- }
170
- prepend(...nodes) {
171
- if (this.firstChild) {
172
- this.firstChild.before(...nodes);
173
- }
174
- else {
175
- this.append(...nodes);
176
- }
177
- }
178
- addEventListener(type, listener, options) {
179
- this.eventListeners.push({
180
- type,
181
- listener,
182
- options,
183
- });
184
- }
185
- removeEventListener(type, listener, useCapture) {
186
- this.eventListeners = this.eventListeners.filter(el => {
187
- return !(el.type === type &&
188
- el.listener === listener &&
189
- (useCapture ? el.options.capture : !el.options.capture));
190
- });
191
- }
192
- matchesSelector(selector) {
193
- const parts = parseSelector(selector);
194
- return matchesSelectorSequence(this, parts);
195
- }
196
- traverseAndCollect(selector, result) {
197
- if (this.matchesSelector(selector)) {
198
- result.push(this);
199
- }
200
- let child = this.firstChild;
201
- while (child) {
202
- if (child instanceof ElementNode) {
203
- child.traverseAndCollect(selector, result);
204
- }
205
- child = child.nextSibling;
206
- }
207
- }
208
- querySelector(selector) {
209
- const results = this.querySelectorAll(selector);
210
- return results.length > 0 ? results[0] : null;
211
- }
212
- querySelectorAll(selector) {
213
- const result = [];
214
- this.traverseAndCollect(selector, result);
215
- return result;
216
- }
217
- }
218
- class EventTarget {
219
- constructor(tagName) {
220
- Object.defineProperty(this, "tagName", {
221
- enumerable: true,
222
- configurable: true,
223
- writable: true,
224
- value: void 0
225
- });
226
- this.tagName = tagName;
227
- }
228
- }
229
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
230
- class HTMLInputELementTarget extends EventTarget {
231
- constructor(value) {
232
- super('INPUT');
233
- Object.defineProperty(this, "value", {
234
- enumerable: true,
235
- configurable: true,
236
- writable: true,
237
- value: void 0
238
- });
239
- Object.defineProperty(this, "selectionStart", {
240
- enumerable: true,
241
- configurable: true,
242
- writable: true,
243
- value: null
244
- });
245
- Object.defineProperty(this, "selectionEnd", {
246
- enumerable: true,
247
- configurable: true,
248
- writable: true,
249
- value: null
250
- });
251
- this.value = value;
252
- }
253
- }
254
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
255
- class HTMLTextareaElementTarget extends EventTarget {
256
- constructor(value) {
257
- super('TEXTAREA');
258
- Object.defineProperty(this, "value", {
259
- enumerable: true,
260
- configurable: true,
261
- writable: true,
262
- value: void 0
263
- });
264
- Object.defineProperty(this, "selectionStart", {
265
- enumerable: true,
266
- configurable: true,
267
- writable: true,
268
- value: 0
269
- });
270
- Object.defineProperty(this, "selectionEnd", {
271
- enumerable: true,
272
- configurable: true,
273
- writable: true,
274
- value: 0
275
- });
276
- this.value = value;
277
- }
278
- }
279
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
280
- class HTMLDivElementTarget extends EventTarget {
281
- constructor() {
282
- super('DIV');
283
- Object.defineProperty(this, "innerText", {
284
- enumerable: true,
285
- configurable: true,
286
- writable: true,
287
- value: ''
288
- });
289
- }
290
- }
291
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
292
- class HTMLOtherTarget extends EventTarget {
293
- constructor() {
294
- super('OTHER');
295
- }
296
- }
297
- class Event {
298
- constructor(type, target, eventPhase) {
299
- Object.defineProperty(this, "type", {
300
- enumerable: true,
301
- configurable: true,
302
- writable: true,
303
- value: void 0
304
- });
305
- Object.defineProperty(this, "eventPhase", {
306
- enumerable: true,
307
- configurable: true,
308
- writable: true,
309
- value: void 0
310
- });
311
- Object.defineProperty(this, "defaultPrevented", {
312
- enumerable: true,
313
- configurable: true,
314
- writable: true,
315
- value: false
316
- });
317
- Object.defineProperty(this, "propagationStopped", {
318
- enumerable: true,
319
- configurable: true,
320
- writable: true,
321
- value: false
322
- });
323
- Object.defineProperty(this, "target", {
324
- enumerable: true,
325
- configurable: true,
326
- writable: true,
327
- value: void 0
328
- });
329
- this.type = type;
330
- this.target = target;
331
- this.eventPhase = eventPhase;
332
- }
333
- preventDefault() {
334
- this.defaultPrevented = true;
335
- }
336
- stopImmediatePropagation() {
337
- this.propagationStopped = true;
338
- }
339
- }
340
- class Touch {
341
- constructor(clientX, clientY, pageX, pageY) {
342
- Object.defineProperty(this, "clientX", {
343
- enumerable: true,
344
- configurable: true,
345
- writable: true,
346
- value: void 0
347
- });
348
- Object.defineProperty(this, "clientY", {
349
- enumerable: true,
350
- configurable: true,
351
- writable: true,
352
- value: void 0
353
- });
354
- Object.defineProperty(this, "pageX", {
355
- enumerable: true,
356
- configurable: true,
357
- writable: true,
358
- value: void 0
359
- });
360
- Object.defineProperty(this, "pageY", {
361
- enumerable: true,
362
- configurable: true,
363
- writable: true,
364
- value: void 0
365
- });
366
- this.clientX = clientX;
367
- this.clientY = clientY;
368
- this.pageX = pageX;
369
- this.pageY = pageY;
370
- }
371
- }
372
- class TouchList {
373
- constructor(items) {
374
- Object.defineProperty(this, "length", {
375
- enumerable: true,
376
- configurable: true,
377
- writable: true,
378
- value: void 0
379
- });
380
- this.length = items.length;
381
- for (let i = 0; i < items.length; i++) {
382
- this[i] = items[i];
383
- }
384
- }
385
- item(index) {
386
- return this[index] ?? null;
387
- }
388
- }
389
- class TouchEvent extends Event {
390
- constructor(type, target, eventPhase) {
391
- super(type, target, eventPhase);
392
- }
393
- }
394
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
395
- class TouchStartEvent extends TouchEvent {
396
- constructor(eventPhase, touches, target) {
397
- super('touchstart', target, eventPhase);
398
- Object.defineProperty(this, "touches", {
399
- enumerable: true,
400
- configurable: true,
401
- writable: true,
402
- value: void 0
403
- });
404
- this.touches = touches;
405
- this.eventPhase = eventPhase;
406
- }
407
- }
408
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
409
- class TouchMoveEvent extends TouchEvent {
410
- constructor(eventPhase, touches, target) {
411
- super('touchmove', target, eventPhase);
412
- Object.defineProperty(this, "touches", {
413
- enumerable: true,
414
- configurable: true,
415
- writable: true,
416
- value: void 0
417
- });
418
- this.touches = touches;
419
- this.eventPhase = eventPhase;
420
- }
421
- }
422
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
423
- class TouchEndEvent extends TouchEvent {
424
- constructor(eventPhase, touches, target) {
425
- super('touchend', target, eventPhase);
426
- Object.defineProperty(this, "touches", {
427
- enumerable: true,
428
- configurable: true,
429
- writable: true,
430
- value: void 0
431
- });
432
- this.touches = touches;
433
- this.eventPhase = eventPhase;
434
- }
435
- }
436
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
437
- class TouchCancelEvent extends TouchEvent {
438
- constructor(eventPhase, touches, target) {
439
- super('touchcancel', target, eventPhase);
440
- Object.defineProperty(this, "touches", {
441
- enumerable: true,
442
- configurable: true,
443
- writable: true,
444
- value: void 0
445
- });
446
- this.touches = touches;
447
- this.eventPhase = eventPhase;
448
- }
449
- }
450
- class KeyEvent extends Event {
451
- constructor(type, key, code, target, eventPhase) {
452
- super(type, target, eventPhase);
453
- Object.defineProperty(this, "key", {
454
- enumerable: true,
455
- configurable: true,
456
- writable: true,
457
- value: void 0
458
- });
459
- Object.defineProperty(this, "code", {
460
- enumerable: true,
461
- configurable: true,
462
- writable: true,
463
- value: void 0
464
- });
465
- this.key = key;
466
- this.code = code;
467
- this.target = target;
468
- }
469
- }
470
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
471
- class KeyUpEvent extends KeyEvent {
472
- constructor(key, code, target, eventPhase) {
473
- super('keyup', key, code, target, eventPhase);
474
- }
475
- }
476
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
477
- class KeyDownEvent extends KeyEvent {
478
- constructor(key, code, target, eventPhase) {
479
- super('keydown', key, code, target, eventPhase);
480
- }
481
- }
482
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
483
- class KeyPressEvent extends KeyEvent {
484
- constructor(key, code, target, eventPhase) {
485
- super('keypress', key, code, target, eventPhase);
486
- }
487
- }
488
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
489
- class OtherEvent extends Event {
490
- constructor(target, eventPhase) {
491
- super('other', target, eventPhase);
492
- }
493
- }
494
- class Document {
495
- constructor() {
496
- Object.defineProperty(this, "head", {
497
- enumerable: true,
498
- configurable: true,
499
- writable: true,
500
- value: this.createElement('head')
501
- });
502
- Object.defineProperty(this, "body", {
503
- enumerable: true,
504
- configurable: true,
505
- writable: true,
506
- value: this.createElement('body')
507
- });
508
- Object.defineProperty(this, "visibilityState", {
509
- enumerable: true,
510
- configurable: true,
511
- writable: true,
512
- value: 'visible'
513
- });
514
- Object.defineProperty(this, "documentEventListeners", {
515
- enumerable: true,
516
- configurable: true,
517
- writable: true,
518
- value: []
519
- });
520
- }
521
- createTextNode(text) {
522
- return new TextNode(text);
523
- }
524
- getElementById(id) {
525
- return this.body.querySelector('#' + id);
526
- }
527
- querySelector(selector) {
528
- return this.body.querySelector(selector);
529
- }
530
- createElement(tag) {
531
- return new ElementNode(tag);
532
- }
533
- addEventListener(type,
534
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
535
- listener, options) {
536
- this.documentEventListeners.push({ type, listener, options });
537
- }
538
- removeEventListener(type,
539
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
540
- listener, useCapture) {
541
- this.documentEventListeners = this.documentEventListeners.filter(el => !(el.type === type &&
542
- el.listener === listener &&
543
- (useCapture ? el.options.capture : !el.options.capture)));
544
- }
545
- }
546
- class Window {
547
- constructor() {
548
- Object.defineProperty(this, "document", {
549
- enumerable: true,
550
- configurable: true,
551
- writable: true,
552
- value: new Document()
553
- });
554
- Object.defineProperty(this, "innerWidth", {
555
- enumerable: true,
556
- configurable: true,
557
- writable: true,
558
- value: 1024
559
- });
560
- Object.defineProperty(this, "innerHeight", {
561
- enumerable: true,
562
- configurable: true,
563
- writable: true,
564
- value: 768
565
- });
566
- Object.defineProperty(this, "location", {
567
- enumerable: true,
568
- configurable: true,
569
- writable: true,
570
- value: {
571
- protocol: 'http',
572
- hostname: 'localhost',
573
- port: '8080',
574
- pathname: '/',
575
- search: '',
576
- hash: '',
577
- }
578
- });
579
- Object.defineProperty(this, "eventListeners", {
580
- enumerable: true,
581
- configurable: true,
582
- writable: true,
583
- value: []
584
- });
585
- }
586
- addEventListener(type, listener, options) {
587
- this.eventListeners.push({
588
- type,
589
- listener,
590
- options,
591
- });
592
- }
593
- removeEventListener(type, listener, useCapture) {
594
- this.eventListeners = this.eventListeners.filter(el => {
595
- return !(el.type === type &&
596
- el.listener === listener &&
597
- (useCapture ? el.options.capture : !el.options.capture));
598
- });
599
- }
600
- }
601
- function serializeElement(elem) {
602
- const attrs = Object.entries(elem.attributes).map(([name, value]) => ({ name, value }));
603
- const childNodes = [];
604
- let child = elem.firstChild;
605
- while (child) {
606
- if (child instanceof TextNode) {
607
- childNodes.push(child.nodeValue);
608
- }
609
- else if (child instanceof ElementNode) {
610
- childNodes.push(serializeElement(child));
611
- }
612
- child = child.nextSibling;
613
- }
614
- return { tag: elem.tagName, attrs, childNodes };
615
- }
616
- function serializeDom(doc) {
617
- return {
618
- head: serializeElement(doc.head),
619
- body: serializeElement(doc.body),
620
- };
621
- }
622
- function dispatchClick(element) {
623
- const syntheticEvent = {
624
- type: 'click',
625
- target: null,
626
- eventPhase: 2,
627
- defaultPrevented: false,
628
- propagationStopped: false,
629
- preventDefault() {
630
- this.defaultPrevented = true;
631
- },
632
- stopImmediatePropagation() {
633
- this.propagationStopped = true;
634
- },
635
- };
636
- for (const entry of element.eventListeners) {
637
- if (entry.type === 'click') {
638
- entry.listener(syntheticEvent);
639
- if (syntheticEvent.propagationStopped) {
640
- break;
641
- }
642
- }
643
- }
644
- }
645
- function dispatchSubmit(element) {
646
- const syntheticEvent = {
647
- type: 'submit',
648
- target: null,
649
- eventPhase: 2,
650
- defaultPrevented: false,
651
- propagationStopped: false,
652
- preventDefault() {
653
- this.defaultPrevented = true;
654
- },
655
- stopImmediatePropagation() {
656
- this.propagationStopped = true;
657
- },
658
- };
659
- for (const entry of element.eventListeners) {
660
- if (entry.type === 'submit') {
661
- entry.listener(syntheticEvent);
662
- if (syntheticEvent.propagationStopped) {
663
- break;
664
- }
665
- }
666
- }
667
- }
668
- function dispatchCustomEvent(element, eventName, detail) {
669
- const syntheticEvent = {
670
- type: eventName,
671
- detail,
672
- target: null,
673
- eventPhase: 2,
674
- defaultPrevented: false,
675
- propagationStopped: false,
676
- preventDefault() {
677
- this.defaultPrevented = true;
678
- },
679
- stopImmediatePropagation() {
680
- this.propagationStopped = true;
681
- },
682
- };
683
- for (const entry of element.eventListeners) {
684
- if (entry.type === eventName) {
685
- entry.listener(syntheticEvent);
686
- if (syntheticEvent.propagationStopped) {
687
- break;
688
- }
689
- }
690
- }
691
- }
692
- function dispatchTextInput(element, value) {
693
- const syntheticEvent = {
694
- type: 'input',
695
- target: { tagName: 'INPUT', value, selectionStart: value.length, selectionEnd: value.length },
696
- eventPhase: 2,
697
- defaultPrevented: false,
698
- propagationStopped: false,
699
- preventDefault() {
700
- this.defaultPrevented = true;
701
- },
702
- stopImmediatePropagation() {
703
- this.propagationStopped = true;
704
- },
705
- };
706
- for (const entry of element.eventListeners) {
707
- if (entry.type === 'input') {
708
- entry.listener(syntheticEvent);
709
- if (syntheticEvent.propagationStopped) {
710
- break;
711
- }
712
- }
713
- }
714
- }
715
- function querySelectorAllInApp(window, selector) {
716
- const appRoot = window.document.getElementById('app');
717
- if (!appRoot)
718
- return [];
719
- const results = [];
720
- let child = appRoot.firstChild;
721
- while (child) {
722
- if (child instanceof ElementNode) {
723
- results.push(...child.querySelectorAll(selector));
724
- }
725
- child = child.nextSibling;
726
- }
727
- return results;
728
- }
729
- function makeWindow() {
730
- const win = new Window();
731
- const root = win.document.createElement('div');
732
- root.setAttribute('id', 'app');
733
- win.document.body.append(root);
734
- return win;
735
- }
736
- class TestableComponentImpl {
737
- constructor(component, state, config, data, dom, window) {
738
- Object.defineProperty(this, "config", {
739
- enumerable: true,
740
- configurable: true,
741
- writable: true,
742
- value: void 0
743
- });
744
- Object.defineProperty(this, "data", {
745
- enumerable: true,
746
- configurable: true,
747
- writable: true,
748
- value: void 0
749
- });
750
- Object.defineProperty(this, "dom", {
751
- enumerable: true,
752
- configurable: true,
753
- writable: true,
754
- value: void 0
755
- });
756
- Object.defineProperty(this, "_component", {
757
- enumerable: true,
758
- configurable: true,
759
- writable: true,
760
- value: void 0
761
- });
762
- Object.defineProperty(this, "state", {
763
- enumerable: true,
764
- configurable: true,
765
- writable: true,
766
- value: void 0
767
- });
768
- Object.defineProperty(this, "_window", {
769
- enumerable: true,
770
- configurable: true,
771
- writable: true,
772
- value: void 0
773
- });
774
- this._component = component;
775
- this.state = state;
776
- this.config = config;
777
- this.data = data;
778
- this.dom = dom;
779
- this._window = window;
780
- }
781
- withConfig(config) {
782
- return new TestableComponentImpl(this._component, this.state, config, this.data, this.dom, this._window);
783
- }
784
- withData(data) {
785
- return new TestableComponentImpl(this._component, this.state, this.config, data, this.dom, this._window);
786
- }
787
- run(...interactions) {
788
- const win = makeWindow();
789
- const { interpreter, getData, advanceTime, fireBroadcast } = makeTestingInterpreter(this.data, win, this.config);
790
- const currentState = this.state;
791
- const wrappedComponent = {
792
- ...this._component,
793
- initialState: (_params) => pure(currentState),
794
- };
795
- const appNode = win.document.getElementById('app');
796
- const mgr = new ComponentManager(wrappedComponent, appNode, win, interpreter, noopStyleRegistry());
797
- for (const interaction of interactions) {
798
- if ('_type' in interaction) {
799
- switch (interaction._type) {
800
- case 'AdvanceTime':
801
- advanceTime(interaction.milliseconds);
802
- break;
803
- case 'ReceiveBroadcast':
804
- fireBroadcast(interaction.channel, interaction.message);
805
- break;
806
- case 'FireCustomEvent': {
807
- const qs = interaction.selector;
808
- const cssSelector = qs.selector;
809
- const results = win.document.body.querySelectorAll(cssSelector);
810
- results.forEach(el => dispatchCustomEvent(el, interaction.eventName, interaction.detail));
811
- break;
812
- }
813
- case 'Submit': {
814
- const qs = interaction.selector;
815
- const cssSelector = qs.selector;
816
- const results = win.document.body.querySelectorAll(cssSelector);
817
- results.forEach(el => dispatchSubmit(el));
818
- break;
819
- }
820
- case 'TextInput': {
821
- const qs = interaction.selector;
822
- const cssSelector = qs.selector;
823
- const results = win.document.body.querySelectorAll(cssSelector);
824
- results.forEach(el => dispatchTextInput(el, interaction.value));
825
- break;
826
- }
827
- default:
828
- exhaustivenessCheck(interaction);
829
- }
830
- }
831
- else {
832
- switch (interaction.type) {
833
- case 'Click': {
834
- const qs = interaction.selector;
835
- const cssSelector = qs.selector;
836
- const results = win.document.body.querySelectorAll(cssSelector);
837
- switch (qs._type) {
838
- case 'ExactlyOne':
839
- if (results.length !== 1)
840
- throw new Error(`Expected exactly one element matching '${cssSelector}', found ${results.length}`);
841
- break;
842
- case 'OneOrMore':
843
- if (results.length === 0)
844
- throw new Error(`Expected at least one element matching '${cssSelector}', found 0`);
845
- break;
846
- case 'ZeroOrOne':
847
- if (results.length > 1)
848
- throw new Error(`Expected zero or one element matching '${cssSelector}', found ${results.length}`);
849
- break;
850
- case 'ZeroOrMore':
851
- break;
852
- default:
853
- exhaustivenessCheck(qs);
854
- }
855
- results.forEach(el => dispatchClick(el));
856
- break;
857
- }
858
- default:
859
- exhaustivenessCheck(interaction.type);
860
- }
861
- }
862
- }
863
- const stateAfter = mgr.getRootState();
864
- const newState = stateAfter._type === 'Ready' ? stateAfter.value : currentState;
865
- return new TestableComponentImpl(this._component, newState, this.config, getData(), serializeDom(win.document), win);
866
- }
867
- find(selector) {
868
- return querySelectorAllInApp(this._window, selector).map(serializeElement);
869
- }
870
- findOne(selector) {
871
- const results = querySelectorAllInApp(this._window, selector);
872
- if (results.length !== 1)
873
- throw new Error(`findOne('${selector}'): expected 1 element, found ${results.length}`);
874
- return serializeElement(results[0]);
875
- }
876
- findOneOrMore(selector) {
877
- const results = querySelectorAllInApp(this._window, selector);
878
- if (results.length === 0)
879
- throw new Error(`findOneOrMore('${selector}'): expected at least 1 element, found 0`);
880
- return results.map(serializeElement);
881
- }
882
- findMaybeOne(selector) {
883
- const results = querySelectorAllInApp(this._window, selector);
884
- if (results.length > 1)
885
- throw new Error(`findMaybeOne('${selector}'): expected 0 or 1 elements, found ${results.length}`);
886
- return results.length === 0 ? undefined : serializeElement(results[0]);
887
- }
888
- }
889
- // eslint-disable-next-line @typescript-eslint/no-empty-object-type
890
- export function testableComponent(component, config, data) {
891
- const initialData = data || newTestData();
892
- const win = makeWindow();
893
- const { interpreter, getData } = makeTestingInterpreter(initialData, win, config);
894
- const appNode = win.document.getElementById('app');
895
- const mgr = new ComponentManager(component, appNode, win, interpreter, noopStyleRegistry());
896
- const stateAfter = mgr.getRootState();
897
- const currentState = stateAfter._type === 'Ready'
898
- ? stateAfter.value
899
- : undefined;
900
- return new TestableComponentImpl(component, currentState, config, getData(), serializeDom(win.document), win);
901
- }
902
- function parseSelector(selector) {
903
- const parts = selector.trim().split(/\s+/);
904
- return parts.map(parsePart);
905
- }
906
- function parsePart(part) {
907
- const attrs = {};
908
- const classes = [];
909
- let tag = undefined;
910
- // Handle #id
911
- if (part.startsWith('#')) {
912
- attrs['id'] = part.substring(1);
913
- return { tag, classes, attrs };
914
- }
915
- // Handle .class
916
- if (part.startsWith('.')) {
917
- classes.push(part.substring(1));
918
- return { tag, classes, attrs };
919
- }
920
- // Handle tag.class[attr=value]
921
- const attrRegex = /\[([^\]=]+)=([^\]]+)\]/g;
922
- let match;
923
- while ((match = attrRegex.exec(part)) !== null) {
924
- attrs[match[1]] = match[2];
925
- }
926
- const withoutAttrs = part.replace(attrRegex, '').trim();
927
- const dotParts = withoutAttrs.split('.');
928
- tag = dotParts[0] || undefined;
929
- classes.push(...dotParts.slice(1));
930
- return { tag, classes, attrs };
931
- }
932
- function matchesPart(element, part) {
933
- if (part.tag && element.tagName.toLowerCase() !== part.tag.toLowerCase()) {
934
- return false;
935
- }
936
- for (const cls of part.classes) {
937
- const elementClasses = (element.attributes['class'] || '').split(/\s+/);
938
- if (!elementClasses.includes(cls)) {
939
- return false;
940
- }
941
- }
942
- for (const [attr, value] of Object.entries(part.attrs)) {
943
- if (element.attributes[attr] !== value) {
944
- return false;
945
- }
946
- }
947
- return true;
948
- }
949
- function matchesSelectorSequence(element, parts) {
950
- if (parts.length === 0)
951
- return true;
952
- // The rightmost part must match the element itself, not just any ancestor
953
- if (!matchesPart(element, parts[parts.length - 1])) {
954
- return false;
955
- }
956
- if (parts.length === 1)
957
- return true;
958
- // Each remaining part (right to left) must be matched by some ancestor
959
- let ancestor = element.parentNode;
960
- for (let i = parts.length - 2; i >= 0; i--) {
961
- let found = false;
962
- while (ancestor) {
963
- if (matchesPart(ancestor, parts[i])) {
964
- found = true;
965
- ancestor = ancestor.parentNode;
966
- break;
967
- }
968
- ancestor = ancestor.parentNode;
969
- }
970
- if (!found)
971
- return false;
972
- }
973
- return true;
974
- }