@motifx/core 1.0.1

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/dist/index.cjs ADDED
@@ -0,0 +1,1517 @@
1
+ 'use strict';
2
+
3
+ var internal = require('./chunks/core-DfzGo_Ti.cjs');
4
+ var devtools = require('./chunks/core-DXGu4dNE.cjs');
5
+
6
+ class NameValuePair {
7
+ Key;
8
+ value;
9
+ }
10
+
11
+ class List {
12
+ ItemAdded;
13
+ ItemAddedBefore;
14
+ ItemSplice;
15
+ __list = [];
16
+ _map = new Set();
17
+ Dispose() {
18
+ this.__list = [];
19
+ }
20
+ Add(item) {
21
+ this._map.add(item);
22
+ var i = this.__list.push(item) - 1;
23
+ if (this.ItemAdded != undefined) {
24
+ this.ItemAdded(item);
25
+ }
26
+ return i;
27
+ }
28
+ AddBefore(item) {
29
+ this._map.add(item);
30
+ var i = this.__list.unshift(item) - 1;
31
+ if (this.ItemAddedBefore != undefined) {
32
+ this.ItemAddedBefore(item);
33
+ }
34
+ return i;
35
+ }
36
+ Insert(start, item) {
37
+ this._map.add(item);
38
+ var i = this.__list.splice(start, 0, item);
39
+ if (this.ItemSplice != undefined) {
40
+ this.ItemSplice(start, item);
41
+ }
42
+ return i;
43
+ }
44
+ get items() {
45
+ return this.__list;
46
+ }
47
+ clear() {
48
+ this._map.clear();
49
+ this.__list.splice(0);
50
+ this.__list = [];
51
+ return this.__list;
52
+ }
53
+ ;
54
+ get count() {
55
+ return this.__list.length;
56
+ }
57
+ ;
58
+ remove(item) {
59
+ this._map.delete(item);
60
+ this.__list.splice(this.__list.indexOf(item), 1);
61
+ item = null;
62
+ return [];
63
+ }
64
+ ;
65
+ indexOf(item) {
66
+ return this.__list.indexOf(item);
67
+ }
68
+ FindFromKey(key, value) {
69
+ return this.__list.filter(i => { return i[key] === value; });
70
+ }
71
+ removeIndex(index) {
72
+ var deleted = this.__list.splice(index, 1);
73
+ deleted.forEach(t => {
74
+ this._map.delete(t);
75
+ });
76
+ return deleted;
77
+ }
78
+ ;
79
+ has(item) {
80
+ return this._map.has(item);
81
+ }
82
+ item(index) {
83
+ return this.__list[index];
84
+ }
85
+ forEach(callbackfn) {
86
+ this.__list?.forEach(callbackfn);
87
+ }
88
+ ReverseClone() {
89
+ return this.__list.reverse();
90
+ }
91
+ filter(callbackfn) {
92
+ return this.__list.filter(callbackfn);
93
+ }
94
+ }
95
+
96
+ class Dictionary {
97
+ __values = new List();
98
+ Add(Key, Value) {
99
+ var item = new NameValuePair();
100
+ item.Key = Key;
101
+ item.value = Value;
102
+ var n = this.__values.Add(item);
103
+ if (this.OnItemAdded != null) {
104
+ this.OnItemAdded(item.Key, item.value);
105
+ }
106
+ return n;
107
+ }
108
+ has(key) {
109
+ return this.filter(t => t.Key == key)[0] ? true : false;
110
+ }
111
+ item(key) {
112
+ return this.filter(t => t.Key == key)[0];
113
+ }
114
+ OnItemAdded;
115
+ removeIndex(index) {
116
+ var i = this.__values.removeIndex(index - 1);
117
+ return i;
118
+ }
119
+ ;
120
+ remove(Key) {
121
+ var item = this.__values.filter(x => x.Key == Key);
122
+ item.forEach((v) => {
123
+ this.__values.remove(v);
124
+ });
125
+ }
126
+ ;
127
+ clear() {
128
+ this.__values.clear();
129
+ }
130
+ ;
131
+ forEach(callback) {
132
+ this.__values.forEach(callback);
133
+ }
134
+ get values() {
135
+ return this.__values;
136
+ }
137
+ filter(callbackfn) {
138
+ return this.__values.items.filter(callbackfn);
139
+ }
140
+ find(predicate, thisArg) {
141
+ return this.__values.items.find(predicate);
142
+ }
143
+ }
144
+
145
+ function toGetter(value) {
146
+ return typeof value === 'function' ? value : () => value;
147
+ }
148
+ function read(value) {
149
+ return typeof value === 'function' ? value() : value;
150
+ }
151
+
152
+ function compareKeys(a, b) {
153
+ return a > b ? 1 : a < b ? -1 : 0;
154
+ }
155
+ class Query {
156
+ source;
157
+ constructor(source) {
158
+ this.source = Array.isArray(source) ? source : Array.from(source);
159
+ }
160
+ static from(source) {
161
+ return new Query(source);
162
+ }
163
+ where(predicate) {
164
+ return new Query(this.source.filter(predicate));
165
+ }
166
+ select(selector) {
167
+ return new Query(this.source.map(selector));
168
+ }
169
+ orderBy(keySelector) {
170
+ return new Query([...this.source].sort((a, b) => compareKeys(keySelector(a), keySelector(b))));
171
+ }
172
+ orderByDescending(keySelector) {
173
+ return new Query([...this.source].sort((a, b) => compareKeys(keySelector(b), keySelector(a))));
174
+ }
175
+ distinctBy(keySelector) {
176
+ const seen = new Set();
177
+ return new Query(this.source.filter(item => {
178
+ const key = keySelector(item);
179
+ if (seen.has(key))
180
+ return false;
181
+ seen.add(key);
182
+ return true;
183
+ }));
184
+ }
185
+ groupBy(keySelector) {
186
+ const map = new Map();
187
+ for (const item of this.source) {
188
+ const key = keySelector(item);
189
+ const group = map.get(key);
190
+ if (group) {
191
+ group.push(item);
192
+ }
193
+ else {
194
+ map.set(key, [item]);
195
+ }
196
+ }
197
+ return new Query(Array.from(map, ([key, items]) => ({ key, items })));
198
+ }
199
+ first() {
200
+ if (this.source.length === 0) {
201
+ throw devtools.motifError('MJX601');
202
+ }
203
+ return this.source[0];
204
+ }
205
+ firstOrDefault() {
206
+ return this.source[0];
207
+ }
208
+ any(predicate) {
209
+ return predicate ? this.source.some(predicate) : this.source.length > 0;
210
+ }
211
+ all(predicate) {
212
+ return this.source.every(predicate);
213
+ }
214
+ aggregate(seed, func) {
215
+ return this.source.reduce(func, seed);
216
+ }
217
+ toArray() {
218
+ return [...this.source];
219
+ }
220
+ [Symbol.iterator]() {
221
+ return this.source[Symbol.iterator]();
222
+ }
223
+ }
224
+
225
+ const preprocessitem = new Set();
226
+ function preProcessing(callback) {
227
+ preprocessitem.add(callback);
228
+ renderPreProcessing();
229
+ }
230
+ function renderPreProcessing() {
231
+ preprocessitem.forEach(i => {
232
+ i();
233
+ });
234
+ }
235
+
236
+ // const ContentBodyCollection = new Map<string, ContentBody>();
237
+ const ContentBodyCollectionHandable = new Map();
238
+ const changeBodyCollectionHandler = Symbol('changeBodyCollectionHandler');
239
+ class ContentBlock extends internal.Component {
240
+ constructor(props) {
241
+ super(props);
242
+ // var cb = ContentBodyCollectionHandable.get(props.target);
243
+ // if (cb) {
244
+ // } else {
245
+ // var cb = ContentBodyCollectionHandable.get(props.target);
246
+ // if (cb) {
247
+ this.controls.onAdd = (control) => {
248
+ var cb = ContentBodyCollectionHandable.get(this.props.target);
249
+ if (cb) {
250
+ control.motif.options["ownerContentBlock"] = this;
251
+ cb.controls.add(control);
252
+ }
253
+ };
254
+ this.controls.onAddBeforeBuild = (control) => {
255
+ var cb = ContentBodyCollectionHandable.get(this.props.target);
256
+ if (cb) {
257
+ control.motif.options["ownerContentBlock"] = this;
258
+ cb.controls.add(control);
259
+ }
260
+ };
261
+ if (this.childs) {
262
+ this.controls.add(...this.childs);
263
+ }
264
+ }
265
+ onConfigured(sender, e) {
266
+ var cb = ContentBodyCollectionHandable.get(this.props.target);
267
+ if (cb) {
268
+ this.controls.items.forEach(x => { x.motif.options["ownerContentBlock"] = this; });
269
+ cb.controls.add(...this.controls.items);
270
+ }
271
+ else {
272
+ this.context.on(changeBodyCollectionHandler, () => {
273
+ var cb = ContentBodyCollectionHandable.get(this.props.target);
274
+ if (cb) {
275
+ this.controls.items.forEach(x => { x.motif.options["ownerContentBlock"] = this; });
276
+ cb.controls.add(...this.controls.items);
277
+ }
278
+ });
279
+ }
280
+ }
281
+ onDisposing(sender, e) {
282
+ var cb = ContentBodyCollectionHandable.get(this.props.target);
283
+ if (cb) {
284
+ for (const element of [...cb.controls.items]) {
285
+ if (element.motif.options["ownerContentBlock"] !== this)
286
+ continue;
287
+ cb.controls.remove(element);
288
+ devtools.reportWarning('MJX109', [], element);
289
+ }
290
+ }
291
+ }
292
+ ondisposing(sender) {
293
+ // var cb = ContentBodyCollectionHandable.get(this.props.target);
294
+ // if (cb) {
295
+ }
296
+ }
297
+ class ContentBody extends internal.Component {
298
+ constructor(props) {
299
+ super(props);
300
+ ContentBodyCollectionHandable.set(this.props.name, this);
301
+ this.context.fire(changeBodyCollectionHandler);
302
+ }
303
+ ondisposing(sender) {
304
+ ContentBodyCollectionHandable.delete(this.props.name);
305
+ }
306
+ }
307
+
308
+ const SLOT_REGISTERED_EVENT = Symbol('slotRegistered');
309
+ const SLOT_UNREGISTERED_EVENT = Symbol('slotUnregistered');
310
+ class TransportRegistry {
311
+ static slots = new Map();
312
+ static registerSlot(name, slot) {
313
+ this.slots.set(name, slot);
314
+ internal.Application.main.fire(SLOT_REGISTERED_EVENT, { name, slot });
315
+ }
316
+ static unregisterSlot(name, slot) {
317
+ if (this.slots.get(name) === slot) {
318
+ this.slots.delete(name);
319
+ internal.Application.main.fire(SLOT_UNREGISTERED_EVENT, { name, slot });
320
+ }
321
+ }
322
+ static getSlot(name) {
323
+ return this.slots.get(name);
324
+ }
325
+ }
326
+
327
+ class Transport extends internal.Component {
328
+ mode;
329
+ constructor(props) {
330
+ super(props);
331
+ this.mode = props.mode || 'replace';
332
+ }
333
+ initializeComponent(sender) {
334
+ TransportRegistry.registerSlot(this.props.name, this);
335
+ this.onDisposing = () => {
336
+ (this.controls.items || []).forEach(child => {
337
+ this.controls.remove(child);
338
+ child.dispose?.();
339
+ });
340
+ TransportRegistry.unregisterSlot(this.props.name, this);
341
+ };
342
+ }
343
+ clearSlot() {
344
+ (this.controls.items || []).forEach(child => {
345
+ this.controls.remove(child);
346
+ child.dispose?.();
347
+ });
348
+ }
349
+ }
350
+
351
+ class Transporter {
352
+ static transport(child, newParent, options = {}) {
353
+ if (!child || !newParent)
354
+ return;
355
+ if (child.parent === newParent && newParent.controls.items.includes(child))
356
+ return;
357
+ if (child.parent && child.parent !== newParent) {
358
+ child.parent.controls.remove(child);
359
+ }
360
+ if (options.owner) {
361
+ child.motif.options.ownerTransporter = options.owner;
362
+ }
363
+ if (typeof options.index === "number") {
364
+ if (!newParent.controls.items.includes(child)) {
365
+ newParent.controls.items.splice(options.index, 0, child);
366
+ }
367
+ }
368
+ else {
369
+ if (!newParent.controls.items.includes(child)) {
370
+ newParent.controls.add(child);
371
+ }
372
+ }
373
+ child.parent = newParent;
374
+ if (!options.keepState) {
375
+ child.reState();
376
+ }
377
+ }
378
+ static transportMany(children, newParent, options = {}) {
379
+ if (!Array.isArray(children))
380
+ return;
381
+ children.forEach(child => this.transport(child, newParent, options));
382
+ }
383
+ static createSlot(name, parent) {
384
+ const slot = {
385
+ name,
386
+ children: [],
387
+ parent: parent,
388
+ mount(child, options = {}) {
389
+ if (!this.parent)
390
+ throw devtools.motifError('MJX113');
391
+ if (!this.children.includes(child)) {
392
+ Transporter.transport(child, this.parent, options);
393
+ this.children.push(child);
394
+ }
395
+ },
396
+ unmount(child) {
397
+ if (!this.parent)
398
+ throw devtools.motifError('MJX113');
399
+ this.children = this.children.filter(c => c !== child);
400
+ this.parent.controls.remove(child);
401
+ },
402
+ detachAll() {
403
+ if (!this.parent)
404
+ return;
405
+ this.children.forEach(child => {
406
+ this.parent.controls.remove(child);
407
+ });
408
+ this.children = [];
409
+ }
410
+ };
411
+ return slot;
412
+ }
413
+ }
414
+
415
+ class TransportTo extends internal.Component {
416
+ _onAddRef;
417
+ _onRemoveRef;
418
+ _slotRegisteredListener;
419
+ _slotUnregisteredListener;
420
+ _transported = [];
421
+ constructor(props) {
422
+ super('div', props);
423
+ }
424
+ _handleSlotChange = (eventArgs) => {
425
+ if (eventArgs.name === this.props.name) {
426
+ const slot = eventArgs.slot;
427
+ if (slot.mode !== 'merge') {
428
+ slot.clearSlot?.();
429
+ }
430
+ const all = [...(this.childs || []), ...this.controls.items];
431
+ Transporter.transportMany(all, slot);
432
+ this._transported = all;
433
+ }
434
+ };
435
+ _clearChildrenFromSlot = (slot) => {
436
+ (this.childs || []).forEach(child => {
437
+ slot.controls.remove(child);
438
+ child.dispose();
439
+ });
440
+ (this.controls.items || []).forEach(child => {
441
+ slot.controls.remove(child);
442
+ child.dispose();
443
+ });
444
+ };
445
+ initializeComponent(sender) {
446
+ let slot = TransportRegistry.getSlot(this.props.name);
447
+ if (slot) {
448
+ if (slot.mode !== 'merge') {
449
+ slot.clearSlot?.();
450
+ }
451
+ const all = [...(this.childs || []), ...this.controls.items];
452
+ Transporter.transportMany(all, slot);
453
+ this._transported = all;
454
+ }
455
+ this._slotRegisteredListener = internal.Application.main.on(SLOT_REGISTERED_EVENT, this._handleSlotChange);
456
+ this._slotUnregisteredListener = internal.Application.main.on(SLOT_UNREGISTERED_EVENT, (eventArgs) => {
457
+ if (eventArgs.name === this.props.name) {
458
+ this._clearChildrenFromSlot(eventArgs.slot);
459
+ }
460
+ });
461
+ this._onAddRef = (child) => {
462
+ const currentSlot = TransportRegistry.getSlot(this.props.name);
463
+ if (currentSlot) {
464
+ Transporter.transport(child, currentSlot);
465
+ }
466
+ };
467
+ this._onRemoveRef = (child) => {
468
+ const currentSlot = TransportRegistry.getSlot(this.props.name);
469
+ if (currentSlot) {
470
+ currentSlot.controls.remove(child);
471
+ }
472
+ };
473
+ this.controls.onAdd = this._onAddRef;
474
+ this.controls.onRemove = this._onRemoveRef;
475
+ }
476
+ onDisposing(sender, e) {
477
+ const currentSlot = TransportRegistry.getSlot(this.props.name);
478
+ if (currentSlot) {
479
+ (this._transported || []).forEach(child => {
480
+ currentSlot.controls.remove(child);
481
+ child.dispose();
482
+ });
483
+ }
484
+ if (this._slotRegisteredListener) {
485
+ internal.Application.main.off(SLOT_REGISTERED_EVENT, this._handleSlotChange);
486
+ this._slotRegisteredListener = undefined;
487
+ }
488
+ if (this._slotUnregisteredListener) {
489
+ internal.Application.main.off(SLOT_UNREGISTERED_EVENT, this._slotUnregisteredListener);
490
+ this._slotUnregisteredListener = undefined;
491
+ }
492
+ if (this.controls.onAdd === this._onAddRef)
493
+ this.controls.onAdd = undefined;
494
+ if (this.controls.onRemove === this._onRemoveRef)
495
+ this.controls.onRemove = undefined;
496
+ this._onAddRef = undefined;
497
+ this._onRemoveRef = undefined;
498
+ this._transported = [];
499
+ }
500
+ }
501
+
502
+ class Virtualization extends internal.Component {
503
+ _state;
504
+ _virtualContent;
505
+ _topSpacer;
506
+ _bottomSpacer;
507
+ _cache = new Map();
508
+ _view = [];
509
+ _occurrence = [];
510
+ _occurrenceKeys = new WeakMap();
511
+ _isLoadingMore = false;
512
+ _emptyRendered = false;
513
+ _renderPending = false;
514
+ constructor(props) {
515
+ super('div', props);
516
+ if (props.className)
517
+ this.class.add(props.className);
518
+ if (props.style)
519
+ Object.assign(this.element.style, props.style);
520
+ this._state = this.useModel({
521
+ isLoading: false,
522
+ isInitialized: false,
523
+ currentPage: 0,
524
+ totalCount: 0,
525
+ hasMore: true,
526
+ error: undefined,
527
+ data: []
528
+ });
529
+ this._loadMore = this._loadMore.bind(this);
530
+ this._renderLoadingState = this._renderLoadingState.bind(this);
531
+ this._renderErrorState = this._renderErrorState.bind(this);
532
+ this._renderEmptyState = this._renderEmptyState.bind(this);
533
+ this._loadInitial = this._loadInitial.bind(this);
534
+ this.renderViewport = this.renderViewport.bind(this);
535
+ this._makeView();
536
+ }
537
+ contentWrapper = new internal.Component();
538
+ wrapper;
539
+ _makeView() {
540
+ this._topSpacer = new internal.Component('div');
541
+ this._topSpacer.element.style.cssText = 'height: 0px;';
542
+ this._topSpacer.class.add('motif-virtualization-top-spacer');
543
+ this._bottomSpacer = new internal.Component('div');
544
+ this._bottomSpacer.element.style.cssText = 'height: 0px;';
545
+ this._bottomSpacer.class.add('motif-virtualization-bottom-spacer');
546
+ this._virtualContent = new internal.Component(document.createComment(''));
547
+ if (this.props.mainTemplate) {
548
+ this.contentWrapper.controls.add(this._topSpacer, this._virtualContent, this._bottomSpacer);
549
+ this.contentWrapper.onBuilding = ((s) => {
550
+ var el = internal.findAppendableComponent(s.parent);
551
+ if (el) {
552
+ this.wrapper = el;
553
+ this._loadInitial();
554
+ el.style({ overflowY: 'auto', position: 'relative' });
555
+ el.motif.on('scroll', this._handleScroll);
556
+ }
557
+ });
558
+ this.controls.add(this.props.mainTemplate(this.contentWrapper, this._state));
559
+ }
560
+ else {
561
+ this.wrapper = this;
562
+ this.element.style.cssText = 'overflow-y: auto; height: 100%; position: relative;';
563
+ this.controls.add(this._topSpacer, this._virtualContent, this._bottomSpacer);
564
+ this.motif.on('scroll', this._handleScroll);
565
+ }
566
+ }
567
+ _initialLoadStarted = false;
568
+ onBuilding() {
569
+ if (this.props.mainTemplate || this._initialLoadStarted)
570
+ return;
571
+ this._initialLoadStarted = true;
572
+ this._loadInitial();
573
+ }
574
+ onMounted() {
575
+ this._observeResize();
576
+ if (this._renderPending)
577
+ this.renderViewport();
578
+ }
579
+ onDisposing() {
580
+ this._stopResizeObserver();
581
+ this._stopDataWatch();
582
+ this._clearContent();
583
+ }
584
+ _offsets = null;
585
+ _resizeObserver;
586
+ _observed;
587
+ _observedHeight = -1;
588
+ _fixedHeight() {
589
+ const h = this.props.itemHeight;
590
+ return typeof h === 'function' ? null : h;
591
+ }
592
+ _computeOffsets() {
593
+ const fn = this.props.itemHeight;
594
+ if (typeof fn !== 'function') {
595
+ this._offsets = null;
596
+ return;
597
+ }
598
+ const view = this._view;
599
+ const offsets = new Array(view.length + 1);
600
+ offsets[0] = 0;
601
+ for (let i = 0; i < view.length; i++) {
602
+ let h = 0;
603
+ try {
604
+ h = Number(fn(view[i], i));
605
+ }
606
+ catch {
607
+ h = 0;
608
+ }
609
+ offsets[i + 1] = offsets[i] + (h > 0 && Number.isFinite(h) ? h : 0);
610
+ }
611
+ this._offsets = offsets;
612
+ }
613
+ _layoutOffsets() {
614
+ if (!this._offsets || this._offsets.length !== this._view.length + 1)
615
+ this._computeOffsets();
616
+ return this._offsets;
617
+ }
618
+ _offsetOf(index) {
619
+ const h = this._fixedHeight();
620
+ if (h !== null)
621
+ return index * h;
622
+ const offsets = this._layoutOffsets();
623
+ return offsets[Math.min(Math.max(0, index), offsets.length - 1)];
624
+ }
625
+ _indexAt(y, offsets) {
626
+ const total = offsets.length - 1;
627
+ if (total <= 0)
628
+ return 0;
629
+ let lo = 0, hi = total - 1;
630
+ while (lo < hi) {
631
+ const mid = (lo + hi + 1) >> 1;
632
+ if (offsets[mid] <= y)
633
+ lo = mid;
634
+ else
635
+ hi = mid - 1;
636
+ }
637
+ return lo;
638
+ }
639
+ _observeResize() {
640
+ const el = this.wrapper?.element;
641
+ if (!el || this._observed === el || this.isDisposed)
642
+ return;
643
+ const RO = globalThis.ResizeObserver;
644
+ if (typeof RO !== 'function')
645
+ return;
646
+ this._stopResizeObserver();
647
+ this._observedHeight = el.clientHeight;
648
+ const observer = new RO(() => {
649
+ if (this.isDisposed)
650
+ return;
651
+ const h = el.clientHeight;
652
+ if (h === this._observedHeight)
653
+ return;
654
+ this._observedHeight = h;
655
+ this.renderViewport();
656
+ });
657
+ observer.observe(el);
658
+ this._resizeObserver = observer;
659
+ this._observed = el;
660
+ }
661
+ _stopResizeObserver() {
662
+ try {
663
+ this._resizeObserver?.disconnect();
664
+ }
665
+ catch { }
666
+ this._resizeObserver = undefined;
667
+ this._observed = undefined;
668
+ }
669
+ _loadSeq = 0;
670
+ _dataWatchStop;
671
+ _reloadScheduled = false;
672
+ _reloadTimes = [];
673
+ _stopDataWatch() {
674
+ this._dataWatchStop?.();
675
+ this._dataWatchStop = undefined;
676
+ }
677
+ /**
678
+ * dataRequest'i çağırır. `watch` açıksa çağrının senkron kısmında okunan reaktif veriyi izler;
679
+ * değişince yeniden yükleme planlar. Aksi hâlde çağrı hiçbir dış effect'e bağımlılık sızdırmaz.
680
+ */
681
+ _request(request, watch) {
682
+ const call = () => {
683
+ try {
684
+ return Promise.resolve(this.props.dataRequest(request));
685
+ }
686
+ catch (error) {
687
+ return Promise.reject(error);
688
+ }
689
+ };
690
+ if (!watch || this.props.autoRefresh === false)
691
+ return devtools.untracked(call);
692
+ this._stopDataWatch();
693
+ let result;
694
+ let first = true;
695
+ this._dataWatchStop = devtools.effect(() => {
696
+ if (first) {
697
+ first = false;
698
+ try {
699
+ this.props.watch?.();
700
+ }
701
+ catch (error) {
702
+ devtools.reportError('MJX205', error);
703
+ }
704
+ result = call();
705
+ return;
706
+ }
707
+ this._scheduleReload();
708
+ });
709
+ return result;
710
+ }
711
+ _scheduleReload() {
712
+ if (this._reloadScheduled || this.isDisposed)
713
+ return;
714
+ this._reloadScheduled = true;
715
+ queueMicrotask(() => {
716
+ this._reloadScheduled = false;
717
+ if (this.isDisposed)
718
+ return;
719
+ // Sonsuz döngü koruması, 1 sn'de 30'u aşınca dur.
720
+ const now = Date.now();
721
+ this._reloadTimes = this._reloadTimes.filter(t => now - t < 1000);
722
+ this._reloadTimes.push(now);
723
+ if (this._reloadTimes.length > 30) {
724
+ this._stopDataWatch();
725
+ devtools.reportWarning('MJX206', []);
726
+ return;
727
+ }
728
+ if (this._state.isInitialized)
729
+ void this._reloadLoaded();
730
+ else
731
+ void this._loadInitial();
732
+ });
733
+ }
734
+ /** Yüklü aralığı (0..currentPage) tek istekte yeniden alır; içerik yanıt gelene kadar kalır. */
735
+ async _reloadLoaded() {
736
+ const seq = ++this._loadSeq;
737
+ const pageSize = this.props.pageSize || 50;
738
+ const pages = this._state.currentPage + 1;
739
+ try {
740
+ const response = await this._request({
741
+ page: 0,
742
+ pageSize: pageSize * pages,
743
+ scrollTop: this.wrapper?.element?.scrollTop ?? 0
744
+ }, true);
745
+ if (this.isDisposed || seq !== this._loadSeq)
746
+ return;
747
+ const el = this.wrapper?.element;
748
+ const top = el?.scrollTop ?? 0;
749
+ this._state.currentPage = pages - 1;
750
+ this._state.totalCount = response.totalCount;
751
+ this._state.hasMore = response.hasMore;
752
+ this._state.error = undefined;
753
+ this._state.data = response.items;
754
+ this._rebuildView();
755
+ // Satırlar sökülürken içerik kısalmasın: kısalırsa tarayıcı kaydırmayı kırpar.
756
+ // Boşluğu geçici olarak yeni listenin tam boyuna sabitle; renderViewport düzeltir.
757
+ this._topSpacer.style({ height: '0px' });
758
+ this._bottomSpacer.style({ height: this._offsetOf(this._view.length) + 'px' });
759
+ this._clearContent();
760
+ if (el && el.scrollTop !== top)
761
+ el.scrollTop = top;
762
+ this.renderViewport();
763
+ }
764
+ catch (error) {
765
+ if (this.isDisposed || seq !== this._loadSeq)
766
+ return;
767
+ this._state.error = error;
768
+ this._renderErrorState(error);
769
+ }
770
+ }
771
+ _handleScroll = (_sender, _event) => {
772
+ this.renderViewport();
773
+ if (this.props.autoLoad === false)
774
+ return;
775
+ if (!this._state.hasMore || this._isLoadingMore || !this._state.isInitialized)
776
+ return;
777
+ const el = this.wrapper.element;
778
+ const fixed = this._fixedHeight();
779
+ const loadedBottom = fixed !== null ? this._state.data.length * fixed : this._offsetOf(this._view.length);
780
+ const distanceToLoaded = loadedBottom - (el.scrollTop + el.clientHeight);
781
+ if (distanceToLoaded < (this.props.autoLoadThreshold ?? 100))
782
+ void this._loadMore();
783
+ };
784
+ async _loadInitial() {
785
+ const seq = ++this._loadSeq;
786
+ this._state.isLoading = true;
787
+ this._renderLoadingState();
788
+ try {
789
+ const pageSize = this.props.pageSize || 50;
790
+ const response = await this._request({
791
+ page: 0,
792
+ pageSize,
793
+ scrollTop: 0
794
+ }, true);
795
+ if (this.isDisposed || seq !== this._loadSeq)
796
+ return;
797
+ this._state.currentPage = 0;
798
+ this._state.totalCount = response.totalCount;
799
+ this._state.hasMore = response.hasMore;
800
+ this._state.isInitialized = true;
801
+ this._state.isLoading = false;
802
+ this._state.error = undefined;
803
+ this._state.data = response.items;
804
+ this._clearContent();
805
+ this._rebuildView();
806
+ this.renderViewport();
807
+ }
808
+ catch (error) {
809
+ if (this.isDisposed || seq !== this._loadSeq)
810
+ return;
811
+ this._state.isLoading = false;
812
+ this._state.error = error;
813
+ this._renderErrorState(error);
814
+ }
815
+ }
816
+ async _loadMore() {
817
+ if (this._isLoadingMore || !this._state.hasMore || !this._state.isInitialized)
818
+ return;
819
+ const seq = this._loadSeq;
820
+ try {
821
+ this._isLoadingMore = true;
822
+ const nextPage = this._state.currentPage + 1;
823
+ const pageSize = this.props.pageSize || 50;
824
+ const response = await this._request({
825
+ page: nextPage,
826
+ pageSize,
827
+ scrollTop: this.wrapper?.element?.scrollTop ?? 0
828
+ }, false);
829
+ if (this.isDisposed || seq !== this._loadSeq)
830
+ return;
831
+ this._state.totalCount = response.totalCount;
832
+ this._state.currentPage = nextPage;
833
+ this._state.hasMore = response.hasMore;
834
+ this._state.error = undefined;
835
+ this._state.data.push(...response.items);
836
+ this._rebuildView();
837
+ this.renderViewport();
838
+ }
839
+ catch (error) {
840
+ if (this.isDisposed || seq !== this._loadSeq)
841
+ return;
842
+ this._state.error = error;
843
+ devtools.reportError('MJX207', error);
844
+ }
845
+ finally {
846
+ this._isLoadingMore = false;
847
+ }
848
+ }
849
+ _rebuildView() {
850
+ this._view = this.props.filter ? this.props.filter(this._state.data) : this._state.data;
851
+ const seen = new Map();
852
+ this._occurrence = this._view.map(item => {
853
+ if (typeof item !== 'object' || item === null)
854
+ return 0;
855
+ const n = seen.get(item) ?? 0;
856
+ seen.set(item, n + 1);
857
+ return n;
858
+ });
859
+ if (typeof this.props.itemHeight === 'function')
860
+ this._computeOffsets();
861
+ else
862
+ this._offsets = null;
863
+ }
864
+ _clearContent() {
865
+ if (!this._virtualContent)
866
+ return;
867
+ const controls = this._virtualContent.controls;
868
+ for (const c of this._cache.values()) {
869
+ controls.silentUnlink(c);
870
+ if (!c.isDisposed)
871
+ void c.dispose();
872
+ }
873
+ this._cache.clear();
874
+ controls.clear();
875
+ this._emptyRendered = false;
876
+ }
877
+ renderViewport() {
878
+ if (this.isDisposed || !this.wrapper || !this._state.isInitialized)
879
+ return;
880
+ const el = this.wrapper.element;
881
+ this._observeResize();
882
+ const view = this._view;
883
+ const total = view.length;
884
+ if (total === 0) {
885
+ if (!this._emptyRendered) {
886
+ this._clearContent();
887
+ this._renderEmptyState();
888
+ }
889
+ this._topSpacer.style({ height: '0px' });
890
+ this._bottomSpacer.style({ height: '0px' });
891
+ return;
892
+ }
893
+ if (this._emptyRendered)
894
+ this._clearContent();
895
+ const h = this._fixedHeight();
896
+ let overscan, first, last, topPx, bottomPx;
897
+ if (h !== null) {
898
+ const visible = Math.floor(el.clientHeight / h);
899
+ if (visible <= 0) {
900
+ this._renderPending = !el.isConnected;
901
+ return;
902
+ }
903
+ this._renderPending = false;
904
+ overscan = Math.max(0, this.props.overscan ?? visible);
905
+ const anchor = Math.min(Math.max(0, Math.floor(el.scrollTop / h)), total - 1);
906
+ first = Math.max(0, anchor - overscan);
907
+ last = Math.min(total, anchor + visible + overscan);
908
+ topPx = first * h;
909
+ bottomPx = Math.max(0, total - last) * h;
910
+ }
911
+ else {
912
+ if (el.clientHeight <= 0) {
913
+ this._renderPending = !el.isConnected;
914
+ return;
915
+ }
916
+ this._renderPending = false;
917
+ const offsets = this._layoutOffsets();
918
+ const top = Math.max(0, el.scrollTop);
919
+ const bottom = top + el.clientHeight;
920
+ const anchor = this._indexAt(top, offsets);
921
+ let end = anchor;
922
+ while (end < total && offsets[end] < bottom)
923
+ end++;
924
+ const visible = Math.max(1, end - anchor);
925
+ overscan = Math.max(0, this.props.overscan ?? visible);
926
+ first = Math.max(0, anchor - overscan);
927
+ last = Math.min(total, Math.max(end, anchor + 1) + overscan);
928
+ topPx = offsets[first];
929
+ bottomPx = Math.max(0, offsets[total] - offsets[last]);
930
+ }
931
+ const rows = new Array(last - first);
932
+ const keep = new Set();
933
+ for (let i = first; i < last; i++) {
934
+ const c = this._rowFor(view[i], i);
935
+ rows[i - first] = c;
936
+ keep.add(c);
937
+ }
938
+ const inDom = this._virtualContent.controls.items;
939
+ for (const c of inDom.slice()) {
940
+ if (!keep.has(c))
941
+ this._detachRow(c);
942
+ }
943
+ for (let pos = 0; pos < rows.length; pos++) {
944
+ const c = rows[pos];
945
+ if (inDom[pos] === c)
946
+ continue;
947
+ if (c.parent === this._virtualContent)
948
+ this._detachRow(c);
949
+ this._virtualContent.controls.insert(pos, c);
950
+ }
951
+ this._topSpacer.style({ height: topPx + 'px' });
952
+ this._bottomSpacer.style({ height: bottomPx + 'px' });
953
+ this._evictCache(Math.max(200, (last - first) * 3));
954
+ if (this.props.autoLoad !== false && this._state.hasMore && !this._isLoadingMore && total < last + overscan) {
955
+ void this._loadMore();
956
+ }
957
+ }
958
+ _occurrenceKey(item, occurrence) {
959
+ let keys = this._occurrenceKeys.get(item);
960
+ if (!keys) {
961
+ keys = [];
962
+ this._occurrenceKeys.set(item, keys);
963
+ }
964
+ return keys[occurrence] ??= {};
965
+ }
966
+ _rowFor(item, index) {
967
+ const occurrence = this._occurrence[index] ?? 0;
968
+ const key = (typeof item === 'object' && item !== null)
969
+ ? (occurrence === 0 ? item : this._occurrenceKey(item, occurrence))
970
+ : index;
971
+ let component = this._cache.get(key);
972
+ if (component && component.isDisposed) {
973
+ this._cache.delete(key);
974
+ component = undefined;
975
+ }
976
+ if (component) {
977
+ this._cache.delete(key);
978
+ this._cache.set(key, component);
979
+ return component;
980
+ }
981
+ const rendered = this.props.itemTemplate(item, index);
982
+ component = rendered instanceof internal.ComponentBase ? rendered : new internal.Component(rendered);
983
+ component.__listItemRef = item;
984
+ this._cache.set(key, component);
985
+ return component;
986
+ }
987
+ _detachRow(c) {
988
+ const controls = this._virtualContent.controls;
989
+ if (c.isDisposed) {
990
+ controls.silentUnlink(c);
991
+ return;
992
+ }
993
+ const node = c.element;
994
+ if (node.nodeType === Node.COMMENT_NODE) {
995
+ controls.silentUnlink(c);
996
+ const close = c.motif.options.closeFragment;
997
+ const frag = c.motif.options.cache ?? (c.motif.options.cache = document.createDocumentFragment());
998
+ let cur = node;
999
+ while (cur) {
1000
+ const next = cur.nextSibling;
1001
+ frag.appendChild(cur);
1002
+ if (cur === close)
1003
+ break;
1004
+ cur = next;
1005
+ }
1006
+ internal.notifyDeactivated(c);
1007
+ }
1008
+ else {
1009
+ controls.silentDetach(c);
1010
+ }
1011
+ }
1012
+ _evictCache(limit) {
1013
+ const max = this.props.cacheSize ?? limit;
1014
+ if (this._cache.size <= max)
1015
+ return;
1016
+ for (const [key, c] of this._cache) {
1017
+ if (this._cache.size <= max)
1018
+ break;
1019
+ if (c.parent === this._virtualContent)
1020
+ continue;
1021
+ this._cache.delete(key);
1022
+ if (!c.isDisposed)
1023
+ void c.dispose();
1024
+ }
1025
+ }
1026
+ _renderLoadingState() {
1027
+ if (!this._virtualContent || !this.props.loadingTemplate)
1028
+ return;
1029
+ this._clearContent();
1030
+ const loadingElement = this.props.loadingTemplate(this._state);
1031
+ this._virtualContent.controls.add(loadingElement);
1032
+ }
1033
+ _renderEmptyState() {
1034
+ if (!this._virtualContent || !this.props.emptyTemplate)
1035
+ return;
1036
+ this._clearContent();
1037
+ const emptyElement = this.props.emptyTemplate();
1038
+ this._virtualContent.controls.add(emptyElement);
1039
+ this._emptyRendered = true;
1040
+ }
1041
+ _renderErrorState(error) {
1042
+ if (!this._virtualContent) {
1043
+ devtools.reportError('MJX207', error);
1044
+ return;
1045
+ }
1046
+ this._clearContent();
1047
+ if (this.props.errorTemplate) {
1048
+ const errorElement = this.props.errorTemplate(error);
1049
+ this._virtualContent.controls.add(errorElement);
1050
+ }
1051
+ else {
1052
+ devtools.reportError('MJX207', error);
1053
+ }
1054
+ }
1055
+ refresh() {
1056
+ this._state.data = [];
1057
+ this._state.currentPage = 0;
1058
+ this._state.isInitialized = false;
1059
+ this._state.hasMore = true;
1060
+ this._rebuildView();
1061
+ return this._loadInitial();
1062
+ }
1063
+ setData(data) {
1064
+ this._loadSeq++;
1065
+ this._stopDataWatch();
1066
+ this._state.data = data;
1067
+ this._state.currentPage = 0;
1068
+ this._state.totalCount = data.length;
1069
+ this._state.hasMore = false;
1070
+ this._state.isInitialized = true;
1071
+ this._state.isLoading = false;
1072
+ this._state.error = undefined;
1073
+ this._clearContent();
1074
+ this._rebuildView();
1075
+ this.renderViewport();
1076
+ }
1077
+ scrollToIndex(index) {
1078
+ if (!this.wrapper)
1079
+ return;
1080
+ const total = this._view.length;
1081
+ const i = Math.min(Math.max(0, index), Math.max(0, total - 1));
1082
+ this.wrapper.element.scrollTop = this._offsetOf(i);
1083
+ this.renderViewport();
1084
+ }
1085
+ getState() {
1086
+ return { ...this._state };
1087
+ }
1088
+ }
1089
+
1090
+ class RouterLink extends internal.Component {
1091
+ constructor(props) {
1092
+ super(props.el ?? 'a', props);
1093
+ if (props.showHref !== false)
1094
+ this.attr.add({ href: props.to });
1095
+ if (props.target)
1096
+ this.attr.add({ target: props.target });
1097
+ this.motif.on('click', (s, e) => {
1098
+ if (props.bypass)
1099
+ return;
1100
+ if (props.target && props.target !== '_self')
1101
+ return;
1102
+ if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey)
1103
+ return;
1104
+ e.preventDefault();
1105
+ const router = internal.Application.main.router;
1106
+ if (router)
1107
+ router.navigate(props.to);
1108
+ });
1109
+ if (this.childs && this.childs.length) {
1110
+ this.controls.add(...this.childs);
1111
+ }
1112
+ else if (props.text != null) {
1113
+ this.attr.add({ textContent: props.text });
1114
+ }
1115
+ }
1116
+ onBuilt(sender, e) {
1117
+ this.motif.options.enableRouterClassing = {
1118
+ to: 'all',
1119
+ path: this.props.to,
1120
+ activeClass: this.props.activeClass,
1121
+ exactClass: this.props.exactClass,
1122
+ onActive: this.props.onActive,
1123
+ offActive: this.props.offActive,
1124
+ onExact: this.props.onExact,
1125
+ offExact: this.props.offExact
1126
+ };
1127
+ }
1128
+ }
1129
+
1130
+ function Injectable(options) {
1131
+ return (target) => {
1132
+ internal.autoRegistry.set(target, {
1133
+ lifetime: options?.lifetime ?? "transient",
1134
+ deps: options?.deps
1135
+ });
1136
+ };
1137
+ }
1138
+ function FromService(token) {
1139
+ try {
1140
+ return internal.Application.main.provider.get(token);
1141
+ }
1142
+ catch (error) {
1143
+ devtools.reportWarning('MJX414', [describeServiceToken(token), String(error?.message ?? error)], { token, error });
1144
+ return null;
1145
+ }
1146
+ }
1147
+ function describeServiceToken(token) {
1148
+ if (typeof token === 'function')
1149
+ return token.name || '[AnonymousClass]';
1150
+ return String(token);
1151
+ }
1152
+
1153
+ function isTimeoutError(err) {
1154
+ return err && err.name === 'TimeoutError';
1155
+ }
1156
+ class TimeoutError extends devtools.MotifError {
1157
+ constructor() {
1158
+ super('MJX605', devtools.formatMotifMessage('MJX605'));
1159
+ this.name = 'TimeoutError';
1160
+ }
1161
+ }
1162
+ function delay(ms) {
1163
+ return new Promise(res => setTimeout(res, ms));
1164
+ }
1165
+ function addJitter(base, jitterFactor = 0.1) {
1166
+ const jitter = (Math.random() * 2 - 1) * jitterFactor * base;
1167
+ return Math.max(0, Math.floor(base + jitter));
1168
+ }
1169
+ class Policy {
1170
+ }
1171
+ class RetryPolicy extends Policy {
1172
+ retries;
1173
+ backoff;
1174
+ delayMs;
1175
+ jitter;
1176
+ shouldHandle;
1177
+ onRetry;
1178
+ constructor(options = {}) {
1179
+ super();
1180
+ this.retries = options.retries ?? 3;
1181
+ this.backoff = options.backoff ?? 'exponential';
1182
+ this.delayMs = options.delay ?? 100;
1183
+ this.jitter = Math.min(Math.max(options.jitter ?? 0.1, 0), 1);
1184
+ this.shouldHandle = options.shouldHandle ?? ((err) => !!err && !isTimeoutError(err));
1185
+ this.onRetry = options.onRetry;
1186
+ }
1187
+ calcDelay(attempt) {
1188
+ if (this.backoff === 'none')
1189
+ return 0;
1190
+ if (this.backoff === 'fixed')
1191
+ return addJitter(this.delayMs, this.jitter);
1192
+ const base = this.delayMs * Math.pow(2, attempt - 1);
1193
+ return addJitter(base, this.jitter);
1194
+ }
1195
+ async execute(action, ctx) {
1196
+ let lastErr;
1197
+ for (let attempt = 1; attempt <= this.retries + 1; attempt++) {
1198
+ try {
1199
+ return await Promise.resolve(action(ctx));
1200
+ }
1201
+ catch (err) {
1202
+ lastErr = err;
1203
+ if (!this.shouldHandle(err) || attempt > this.retries)
1204
+ break;
1205
+ const wait = this.calcDelay(attempt);
1206
+ if (this.onRetry)
1207
+ await this.onRetry(attempt, err, wait, ctx);
1208
+ if (wait > 0)
1209
+ await delay(wait);
1210
+ }
1211
+ }
1212
+ throw lastErr;
1213
+ }
1214
+ }
1215
+ class TimeoutPolicy extends Policy {
1216
+ timeoutMs;
1217
+ constructor(opts) {
1218
+ super();
1219
+ this.timeoutMs = opts.timeoutMs;
1220
+ }
1221
+ async execute(action, ctx) {
1222
+ let timer;
1223
+ const p = Promise.resolve(action(ctx));
1224
+ const t = new Promise((_, rej) => {
1225
+ timer = setTimeout(() => rej(new TimeoutError()), this.timeoutMs);
1226
+ });
1227
+ try {
1228
+ return await Promise.race([p, t]);
1229
+ }
1230
+ finally {
1231
+ clearTimeout(timer);
1232
+ }
1233
+ }
1234
+ }
1235
+ class CircuitBreakerPolicy extends Policy {
1236
+ failureThreshold;
1237
+ successThreshold;
1238
+ durationOfBreakMs;
1239
+ shouldHandle;
1240
+ onStateChange;
1241
+ state = 'CLOSED';
1242
+ failureCount = 0;
1243
+ successCount = 0;
1244
+ nextAttemptTime = 0;
1245
+ constructor(opts = {}) {
1246
+ super();
1247
+ this.failureThreshold = opts.failureThreshold ?? 5;
1248
+ this.successThreshold = opts.successThreshold ?? 2;
1249
+ this.durationOfBreakMs = opts.durationOfBreakMs ?? 60000;
1250
+ this.shouldHandle = opts.shouldHandle ?? ((err) => !!err && !isTimeoutError(err));
1251
+ this.onStateChange = opts.onStateChange;
1252
+ }
1253
+ async changeState(newState) {
1254
+ const old = this.state;
1255
+ this.state = newState;
1256
+ this.failureCount = 0;
1257
+ this.successCount = 0;
1258
+ if (newState === 'OPEN')
1259
+ this.nextAttemptTime = Date.now() + this.durationOfBreakMs;
1260
+ if (this.onStateChange)
1261
+ await this.onStateChange(old, newState);
1262
+ }
1263
+ async execute(action, ctx) {
1264
+ if (this.state === 'OPEN') {
1265
+ if (Date.now() >= this.nextAttemptTime) {
1266
+ await this.changeState('HALF_OPEN');
1267
+ }
1268
+ else {
1269
+ throw devtools.motifError('MJX602');
1270
+ }
1271
+ }
1272
+ try {
1273
+ const result = await Promise.resolve(action(ctx));
1274
+ if (this.state === 'HALF_OPEN') {
1275
+ this.successCount++;
1276
+ if (this.successCount >= this.successThreshold)
1277
+ await this.changeState('CLOSED');
1278
+ }
1279
+ else if (this.state === 'CLOSED') {
1280
+ this.failureCount = 0;
1281
+ }
1282
+ return result;
1283
+ }
1284
+ catch (err) {
1285
+ if (this.shouldHandle(err)) {
1286
+ this.failureCount++;
1287
+ if (this.state === 'HALF_OPEN' || (this.state === 'CLOSED' && this.failureCount >= this.failureThreshold)) {
1288
+ await this.changeState('OPEN');
1289
+ }
1290
+ }
1291
+ throw err;
1292
+ }
1293
+ }
1294
+ getState() {
1295
+ return this.state;
1296
+ }
1297
+ }
1298
+ class BulkheadPolicy extends Policy {
1299
+ maxConcurrent;
1300
+ maxQueue;
1301
+ active = 0;
1302
+ queue = [];
1303
+ constructor(opts = {}) {
1304
+ super();
1305
+ this.maxConcurrent = opts.maxConcurrent ?? 10;
1306
+ this.maxQueue = opts.maxQueue ?? 50;
1307
+ }
1308
+ dequeue() {
1309
+ if (this.queue.length === 0)
1310
+ return;
1311
+ if (this.active >= this.maxConcurrent)
1312
+ return;
1313
+ const resolver = this.queue.shift();
1314
+ resolver();
1315
+ }
1316
+ async execute(action, ctx) {
1317
+ if (this.active >= this.maxConcurrent) {
1318
+ if (this.queue.length >= this.maxQueue) {
1319
+ throw devtools.motifError('MJX603');
1320
+ }
1321
+ await new Promise((res) => {
1322
+ this.queue.push(res);
1323
+ });
1324
+ }
1325
+ this.active++;
1326
+ try {
1327
+ const result = await Promise.resolve(action(ctx));
1328
+ return result;
1329
+ }
1330
+ finally {
1331
+ this.active--;
1332
+ this.dequeue();
1333
+ }
1334
+ }
1335
+ }
1336
+ class RateLimiterPolicy extends Policy {
1337
+ tokensPerInterval;
1338
+ intervalMs;
1339
+ capacity;
1340
+ tokens;
1341
+ lastRefill;
1342
+ constructor(opts = {}) {
1343
+ super();
1344
+ this.tokensPerInterval = opts.tokensPerInterval ?? 1;
1345
+ this.intervalMs = opts.intervalMs ?? 1000;
1346
+ this.capacity = opts.capacity ?? 1000;
1347
+ this.tokens = this.capacity;
1348
+ this.lastRefill = Date.now();
1349
+ }
1350
+ refill() {
1351
+ const now = Date.now();
1352
+ const elapsed = now - this.lastRefill;
1353
+ if (elapsed <= 0)
1354
+ return;
1355
+ const tokensToAdd = Math.floor(elapsed / this.intervalMs) * this.tokensPerInterval;
1356
+ if (tokensToAdd > 0) {
1357
+ this.tokens = Math.min(this.capacity, this.tokens + tokensToAdd);
1358
+ this.lastRefill = now;
1359
+ }
1360
+ }
1361
+ async execute(action, ctx) {
1362
+ this.refill();
1363
+ if (this.tokens <= 0) {
1364
+ throw devtools.motifError('MJX604');
1365
+ }
1366
+ this.tokens -= 1;
1367
+ return Promise.resolve(action(ctx));
1368
+ }
1369
+ }
1370
+ class FallbackPolicy extends Policy {
1371
+ fallback;
1372
+ shouldHandle;
1373
+ constructor(opts) {
1374
+ super();
1375
+ this.fallback = opts.fallback;
1376
+ this.shouldHandle = opts.shouldHandle ?? (() => true);
1377
+ }
1378
+ async execute(action, ctx) {
1379
+ try {
1380
+ return await Promise.resolve(action(ctx));
1381
+ }
1382
+ catch (err) {
1383
+ if (!this.shouldHandle(err))
1384
+ throw err;
1385
+ return await Promise.resolve(this.fallback(err, ctx));
1386
+ }
1387
+ }
1388
+ }
1389
+ class PolicyWrap extends Policy {
1390
+ policies;
1391
+ constructor(...policies) {
1392
+ super();
1393
+ this.policies = policies;
1394
+ }
1395
+ async execute(action, ctx) {
1396
+ const wrapped = this.policies.reduceRight((next, p) => {
1397
+ return (c) => p.execute(() => next(c), c);
1398
+ }, action);
1399
+ return wrapped(ctx);
1400
+ }
1401
+ }
1402
+ const resilience = {
1403
+ retry: (opts) => new RetryPolicy(opts),
1404
+ timeout: (opts) => new TimeoutPolicy(opts),
1405
+ circuitBreaker: (opts) => new CircuitBreakerPolicy(opts),
1406
+ bulkhead: (opts) => new BulkheadPolicy(opts),
1407
+ rateLimiter: (opts) => new RateLimiterPolicy(opts),
1408
+ fallback: (opts) => new FallbackPolicy(opts),
1409
+ wrap: (...policies) => new PolicyWrap(...policies),
1410
+ };
1411
+ function decorate(policy, fn) {
1412
+ return (ctx) => policy.execute(fn, ctx);
1413
+ }
1414
+ class Resilience {
1415
+ static get create() {
1416
+ return new Resilience();
1417
+ }
1418
+ resiliences = [];
1419
+ retry = (opts) => {
1420
+ this.resiliences.push(resilience.retry(opts));
1421
+ return this;
1422
+ };
1423
+ timeout = (opts) => {
1424
+ this.resiliences.push(resilience.timeout(opts));
1425
+ return this;
1426
+ };
1427
+ circuitBreaker = (opts) => {
1428
+ this.resiliences.push(resilience.circuitBreaker(opts));
1429
+ return this;
1430
+ };
1431
+ bulkhead = (opts) => {
1432
+ this.resiliences.push(resilience.bulkhead(opts));
1433
+ return this;
1434
+ };
1435
+ rateLimiter = (opts) => {
1436
+ this.resiliences.push(resilience.rateLimiter(opts));
1437
+ return this;
1438
+ };
1439
+ fallback = (opts) => {
1440
+ this.resiliences.push(resilience.fallback(opts));
1441
+ return this;
1442
+ };
1443
+ async execute(action, ctx) {
1444
+ return resilience.wrap(...this.resiliences).execute(action, ctx);
1445
+ }
1446
+ }
1447
+
1448
+ exports.Application = internal.Application;
1449
+ exports.ApplicationBuilder = internal.ApplicationBuilder;
1450
+ exports.Component = internal.Component;
1451
+ exports.ComponentBase = internal.ComponentBase;
1452
+ exports.ComponentMotif = internal.ComponentMotif;
1453
+ exports.ControlCollection = internal.ControlCollection;
1454
+ exports.Disposable = internal.Disposable;
1455
+ exports.DisposableStore = internal.DisposableStore;
1456
+ exports.Emitter = internal.Emitter;
1457
+ exports.FNComponent = internal.FNComponent;
1458
+ exports.FragmentNode = internal.FragmentNode;
1459
+ exports.Frame = internal.Frame;
1460
+ exports.Lazy = internal.Lazy;
1461
+ exports.RouterView = internal.RouterView;
1462
+ exports.ServiceCollection = internal.ServiceCollection;
1463
+ exports.ServiceProvider = internal.ServiceProvider;
1464
+ exports.disposableCore = internal.disposableCore;
1465
+ exports.inject = internal.inject;
1466
+ exports.motifCompiled = internal.motifCompiled;
1467
+ exports.motifComponent = internal.motifComponent;
1468
+ exports.motifFragment = internal.motifFragment;
1469
+ exports.toDisposable = internal.toDisposable;
1470
+ exports.useApplication = internal.useApplication;
1471
+ exports.useNavigation = internal.useNavigation;
1472
+ exports.Computed = devtools.Computed;
1473
+ exports.ErrorHandler = devtools.ErrorHandler;
1474
+ exports.LazyComputed = devtools.LazyComputed;
1475
+ exports.LinkedList = devtools.LinkedList;
1476
+ exports.MotifError = devtools.MotifError;
1477
+ Object.defineProperty(exports, "NodeTypes", {
1478
+ enumerable: true,
1479
+ get: function () { return devtools.NodeTypes; }
1480
+ });
1481
+ exports.Signal = devtools.Signal;
1482
+ exports.asyncTracking = devtools.asyncTracking;
1483
+ exports.clearModel = devtools.clearModel;
1484
+ exports.configureReactivityLeakMonitor = devtools.configureReactivityLeakMonitor;
1485
+ exports.createComputed = devtools.createComputed;
1486
+ exports.createLazyComputed = devtools.createLazyComputed;
1487
+ exports.createSignal = devtools.createSignal;
1488
+ exports.deepClone = devtools.deepClone;
1489
+ exports.dom = devtools.dom;
1490
+ exports.effect = devtools.effect;
1491
+ exports.errorHandler = devtools.errorHandler;
1492
+ exports.reactive = devtools.reactive;
1493
+ exports.safeCall = devtools.safeCall;
1494
+ exports.safeCallAsync = devtools.safeCallAsync;
1495
+ exports.safeCallSilent = devtools.safeCallSilent;
1496
+ exports.setUnexpectedErrorHandler = devtools.setUnexpectedErrorHandler;
1497
+ exports.untracked = devtools.untracked;
1498
+ exports.useModel = devtools.useModel;
1499
+ exports.ContentBlock = ContentBlock;
1500
+ exports.ContentBody = ContentBody;
1501
+ exports.Dictionary = Dictionary;
1502
+ exports.FromService = FromService;
1503
+ exports.Injectable = Injectable;
1504
+ exports.List = List;
1505
+ exports.NameValuePair = NameValuePair;
1506
+ exports.Query = Query;
1507
+ exports.Resilience = Resilience;
1508
+ exports.RouterLink = RouterLink;
1509
+ exports.Transport = Transport;
1510
+ exports.TransportTo = TransportTo;
1511
+ exports.Transporter = Transporter;
1512
+ exports.Virtualization = Virtualization;
1513
+ exports.decorate = decorate;
1514
+ exports.preProcessing = preProcessing;
1515
+ exports.read = read;
1516
+ exports.toGetter = toGetter;
1517
+ //# sourceMappingURL=index.cjs.map