native-document 1.0.91 → 1.0.93
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/native-document.components.min.js +1168 -138
- package/dist/native-document.dev.js +792 -217
- package/dist/native-document.dev.js.map +1 -1
- package/dist/native-document.devtools.min.js +1 -1
- package/dist/native-document.min.js +1 -1
- package/docs/advanced-components.md +814 -0
- package/docs/anchor.md +71 -11
- package/docs/cache.md +888 -0
- package/docs/conditional-rendering.md +91 -1
- package/docs/core-concepts.md +9 -2
- package/docs/elements.md +127 -2
- package/docs/extending-native-document-element.md +7 -1
- package/docs/filters.md +1216 -0
- package/docs/getting-started.md +12 -3
- package/docs/lifecycle-events.md +10 -2
- package/docs/list-rendering.md +453 -54
- package/docs/memory-management.md +9 -7
- package/docs/native-document-element.md +30 -9
- package/docs/native-fetch.md +744 -0
- package/docs/observables.md +135 -6
- package/docs/routing.md +7 -1
- package/docs/state-management.md +7 -1
- package/docs/validation.md +8 -1
- package/eslint.config.js +3 -3
- package/package.json +3 -2
- package/readme.md +53 -14
- package/src/components/$traits/HasItems.js +42 -1
- package/src/components/BaseComponent.js +4 -1
- package/src/components/accordion/Accordion.js +112 -8
- package/src/components/accordion/AccordionItem.js +93 -4
- package/src/components/alert/Alert.js +164 -4
- package/src/components/avatar/Avatar.js +236 -22
- package/src/components/menu/index.js +1 -2
- package/src/core/data/ObservableArray.js +120 -2
- package/src/core/data/ObservableChecker.js +50 -0
- package/src/core/data/ObservableItem.js +223 -80
- package/src/core/data/ObservableWhen.js +36 -6
- package/src/core/data/observable-helpers/array.js +12 -3
- package/src/core/data/observable-helpers/computed.js +17 -4
- package/src/core/data/observable-helpers/object.js +19 -3
- package/src/core/elements/control/for-each-array.js +21 -3
- package/src/core/elements/control/for-each.js +17 -5
- package/src/core/elements/control/show-if.js +31 -15
- package/src/core/elements/control/show-when.js +23 -0
- package/src/core/elements/control/switch.js +40 -10
- package/src/core/utils/cache.js +5 -0
- package/src/core/utils/memoize.js +25 -16
- package/src/core/utils/prototypes.js +3 -2
- package/src/core/wrappers/AttributesWrapper.js +1 -1
- package/src/core/wrappers/NDElement.js +41 -1
- package/src/core/wrappers/NdPrototype.js +4 -0
- package/src/core/wrappers/TemplateCloner.js +13 -10
- package/src/core/wrappers/prototypes/bind-class-extensions.js +1 -1
- package/src/core/wrappers/prototypes/nd-element-extensions.js +3 -0
- package/src/router/Route.js +9 -4
- package/src/router/Router.js +28 -9
- package/src/router/errors/RouterError.js +0 -1
- package/types/control-flow.d.ts +9 -6
- package/types/elements.d.ts +6 -3
- package/types/filters/index.d.ts +4 -0
- package/types/nd-element.d.ts +5 -238
- package/types/observable.d.ts +9 -3
- package/types/router.d.ts +5 -1
- package/types/template-cloner.ts +1 -0
- package/types/validator.ts +11 -1
- package/utils.d.ts +2 -1
- package/utils.js +4 -4
- package/src/core/utils/service.js +0 -6
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
var NativeDocument = (function (exports) {
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
|
-
let DebugManager
|
|
4
|
+
let DebugManager = {};
|
|
5
5
|
|
|
6
6
|
{
|
|
7
|
-
DebugManager
|
|
7
|
+
DebugManager = {
|
|
8
8
|
enabled: false,
|
|
9
9
|
|
|
10
10
|
enable() {
|
|
@@ -35,7 +35,7 @@ var NativeDocument = (function (exports) {
|
|
|
35
35
|
};
|
|
36
36
|
|
|
37
37
|
}
|
|
38
|
-
var DebugManager = DebugManager
|
|
38
|
+
var DebugManager$1 = DebugManager;
|
|
39
39
|
|
|
40
40
|
const MemoryManager = (function() {
|
|
41
41
|
|
|
@@ -84,7 +84,7 @@ var NativeDocument = (function (exports) {
|
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
if (cleanedCount > 0) {
|
|
87
|
-
DebugManager.log('Memory Auto Clean', `🧹 Cleaned ${cleanedCount} orphaned observables`);
|
|
87
|
+
DebugManager$1.log('Memory Auto Clean', `🧹 Cleaned ${cleanedCount} orphaned observables`);
|
|
88
88
|
}
|
|
89
89
|
}
|
|
90
90
|
};
|
|
@@ -113,6 +113,16 @@ var NativeDocument = (function (exports) {
|
|
|
113
113
|
|
|
114
114
|
ObservableChecker.prototype.__$isObservableChecker = true;
|
|
115
115
|
|
|
116
|
+
/**
|
|
117
|
+
* Subscribes to changes in the checked/transformed value.
|
|
118
|
+
*
|
|
119
|
+
* @param {Function} callback - Function called with the transformed value when observable changes
|
|
120
|
+
* @returns {Function} Unsubscribe function
|
|
121
|
+
* @example
|
|
122
|
+
* const count = Observable(5);
|
|
123
|
+
* const doubled = count.check(n => n * 2);
|
|
124
|
+
* doubled.subscribe(value => console.log(value)); // Logs: 10
|
|
125
|
+
*/
|
|
116
126
|
ObservableChecker.prototype.subscribe = function(callback) {
|
|
117
127
|
const unSubscribe = this.observable.subscribe((value) => {
|
|
118
128
|
callback && callback(this.checker(value));
|
|
@@ -121,30 +131,70 @@ var NativeDocument = (function (exports) {
|
|
|
121
131
|
return unSubscribe;
|
|
122
132
|
};
|
|
123
133
|
|
|
134
|
+
/**
|
|
135
|
+
* Creates a new ObservableChecker by applying another transformation.
|
|
136
|
+
* Allows chaining transformations.
|
|
137
|
+
*
|
|
138
|
+
* @param {(value: *) => *} callback - Transformation function to apply to the current checked value
|
|
139
|
+
* @returns {ObservableChecker} New ObservableChecker with chained transformation
|
|
140
|
+
* @example
|
|
141
|
+
* const count = Observable(5);
|
|
142
|
+
* const result = count.check(n => n * 2).check(n => n + 1);
|
|
143
|
+
* result.val(); // 11
|
|
144
|
+
*/
|
|
124
145
|
ObservableChecker.prototype.check = function(callback) {
|
|
125
146
|
return this.observable.check(() => callback(this.val()));
|
|
126
147
|
};
|
|
127
148
|
|
|
149
|
+
/**
|
|
150
|
+
* Gets the current transformed/checked value.
|
|
151
|
+
*
|
|
152
|
+
* @returns {*} The result of applying the checker function to the observable's current value
|
|
153
|
+
* @example
|
|
154
|
+
* const count = Observable(5);
|
|
155
|
+
* const doubled = count.check(n => n * 2);
|
|
156
|
+
* doubled.val(); // 10
|
|
157
|
+
*/
|
|
128
158
|
ObservableChecker.prototype.val = function() {
|
|
129
159
|
return this.checker && this.checker(this.observable.val());
|
|
130
160
|
};
|
|
131
161
|
|
|
162
|
+
/**
|
|
163
|
+
* Sets the value of the underlying observable (not the transformed value).
|
|
164
|
+
*
|
|
165
|
+
* @param {*} value - New value for the underlying observable
|
|
166
|
+
* @example
|
|
167
|
+
* const count = Observable(5);
|
|
168
|
+
* const doubled = count.check(n => n * 2);
|
|
169
|
+
* doubled.set(10); // Sets count to 10, doubled.val() returns 20
|
|
170
|
+
*/
|
|
132
171
|
ObservableChecker.prototype.set = function(value) {
|
|
133
172
|
return this.observable.set(value);
|
|
134
173
|
};
|
|
135
174
|
|
|
175
|
+
/**
|
|
176
|
+
* Manually triggers the underlying observable to notify subscribers.
|
|
177
|
+
*
|
|
178
|
+
* @example
|
|
179
|
+
* const count = Observable(5);
|
|
180
|
+
* const doubled = count.check(n => n * 2);
|
|
181
|
+
* doubled.trigger(); // Notifies all subscribers
|
|
182
|
+
*/
|
|
136
183
|
ObservableChecker.prototype.trigger = function() {
|
|
137
184
|
return this.observable.trigger();
|
|
138
185
|
};
|
|
139
186
|
|
|
187
|
+
/**
|
|
188
|
+
* Cleans up the underlying observable and all its subscriptions.
|
|
189
|
+
*/
|
|
140
190
|
ObservableChecker.prototype.cleanup = function() {
|
|
141
191
|
return this.observable.cleanup();
|
|
142
192
|
};
|
|
143
193
|
|
|
144
|
-
let PluginsManager
|
|
194
|
+
let PluginsManager = null;
|
|
145
195
|
|
|
146
196
|
{
|
|
147
|
-
PluginsManager
|
|
197
|
+
PluginsManager = (function() {
|
|
148
198
|
|
|
149
199
|
const $plugins = new Map();
|
|
150
200
|
const $pluginByEvents = new Map();
|
|
@@ -210,7 +260,7 @@ var NativeDocument = (function (exports) {
|
|
|
210
260
|
try{
|
|
211
261
|
callback.call(plugin, ...data);
|
|
212
262
|
} catch (error) {
|
|
213
|
-
DebugManager.error('Plugin Manager', `Error in plugin ${plugin.$name} for event ${eventName}`, error);
|
|
263
|
+
DebugManager$1.error('Plugin Manager', `Error in plugin ${plugin.$name} for event ${eventName}`, error);
|
|
214
264
|
}
|
|
215
265
|
}
|
|
216
266
|
}
|
|
@@ -219,8 +269,15 @@ var NativeDocument = (function (exports) {
|
|
|
219
269
|
}());
|
|
220
270
|
}
|
|
221
271
|
|
|
222
|
-
var PluginsManager = PluginsManager
|
|
272
|
+
var PluginsManager$1 = PluginsManager;
|
|
223
273
|
|
|
274
|
+
/**
|
|
275
|
+
* Creates an ObservableWhen that tracks whether an observable equals a specific value.
|
|
276
|
+
*
|
|
277
|
+
* @param {ObservableItem} observer - The observable to watch
|
|
278
|
+
* @param {*} value - The value to compare against
|
|
279
|
+
* @class ObservableWhen
|
|
280
|
+
*/
|
|
224
281
|
const ObservableWhen = function(observer, value) {
|
|
225
282
|
this.$target = value;
|
|
226
283
|
this.$observer = observer;
|
|
@@ -228,21 +285,44 @@ var NativeDocument = (function (exports) {
|
|
|
228
285
|
|
|
229
286
|
ObservableWhen.prototype.__$isObservableWhen = true;
|
|
230
287
|
|
|
288
|
+
/**
|
|
289
|
+
* Subscribes to changes in the match status (true when observable equals target value).
|
|
290
|
+
*
|
|
291
|
+
* @param {Function} callback - Function called with boolean indicating if values match
|
|
292
|
+
* @returns {Function} Unsubscribe function
|
|
293
|
+
* @example
|
|
294
|
+
* const status = Observable('idle');
|
|
295
|
+
* const isLoading = status.when('loading');
|
|
296
|
+
* isLoading.subscribe(active => console.log('Loading:', active));
|
|
297
|
+
*/
|
|
231
298
|
ObservableWhen.prototype.subscribe = function(callback) {
|
|
232
299
|
return this.$observer.on(this.$target, callback);
|
|
233
300
|
};
|
|
234
301
|
|
|
302
|
+
/**
|
|
303
|
+
* Returns true if the observable's current value equals the target value.
|
|
304
|
+
*
|
|
305
|
+
* @returns {boolean} True if observable value matches target value
|
|
306
|
+
*/
|
|
235
307
|
ObservableWhen.prototype.val = function() {
|
|
236
308
|
return this.$observer.$currentValue === this.$target;
|
|
237
309
|
};
|
|
238
310
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
311
|
+
/**
|
|
312
|
+
* Returns true if the observable's current value equals the target value.
|
|
313
|
+
* Alias for val().
|
|
314
|
+
*
|
|
315
|
+
* @returns {boolean} True if observable value matches target value
|
|
316
|
+
*/
|
|
317
|
+
ObservableWhen.prototype.isMatch = ObservableWhen.prototype.val;
|
|
242
318
|
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
319
|
+
/**
|
|
320
|
+
* Returns true if the observable's current value equals the target value.
|
|
321
|
+
* Alias for val().
|
|
322
|
+
*
|
|
323
|
+
* @returns {boolean} True if observable value matches target value
|
|
324
|
+
*/
|
|
325
|
+
ObservableWhen.prototype.isActive = ObservableWhen.prototype.val;
|
|
246
326
|
|
|
247
327
|
const nextTick = function(fn) {
|
|
248
328
|
let pending = false;
|
|
@@ -326,7 +406,9 @@ var NativeDocument = (function (exports) {
|
|
|
326
406
|
|
|
327
407
|
this.$previousValue = null;
|
|
328
408
|
this.$currentValue = value;
|
|
329
|
-
|
|
409
|
+
{
|
|
410
|
+
this.$isCleanedUp = false;
|
|
411
|
+
}
|
|
330
412
|
|
|
331
413
|
this.$firstListener = null;
|
|
332
414
|
this.$listeners = null;
|
|
@@ -341,7 +423,7 @@ var NativeDocument = (function (exports) {
|
|
|
341
423
|
}
|
|
342
424
|
}
|
|
343
425
|
{
|
|
344
|
-
PluginsManager.emit('CreateObservable', this);
|
|
426
|
+
PluginsManager$1.emit('CreateObservable', this);
|
|
345
427
|
}
|
|
346
428
|
}
|
|
347
429
|
|
|
@@ -356,16 +438,26 @@ var NativeDocument = (function (exports) {
|
|
|
356
438
|
});
|
|
357
439
|
|
|
358
440
|
ObservableItem.prototype.__$isObservable = true;
|
|
359
|
-
const DEFAULT_OPERATIONS = {};
|
|
360
441
|
const noneTrigger = function() {};
|
|
361
442
|
|
|
443
|
+
/**
|
|
444
|
+
* Intercepts and transforms values before they are set on the observable.
|
|
445
|
+
* The interceptor can modify the value or return undefined to use the original value.
|
|
446
|
+
*
|
|
447
|
+
* @param {(value) => any} callback - Interceptor function that receives (newValue, currentValue) and returns the transformed value or undefined
|
|
448
|
+
* @returns {ObservableItem} The observable instance for chaining
|
|
449
|
+
* @example
|
|
450
|
+
* const count = Observable(0);
|
|
451
|
+
* count.intercept((newVal, oldVal) => Math.max(0, newVal)); // Prevent negative values
|
|
452
|
+
*/
|
|
362
453
|
ObservableItem.prototype.intercept = function(callback) {
|
|
363
454
|
this.$interceptor = callback;
|
|
455
|
+
this.set = this.$setWithInterceptor;
|
|
364
456
|
return this;
|
|
365
457
|
};
|
|
366
458
|
|
|
367
459
|
ObservableItem.prototype.triggerFirstListener = function(operations) {
|
|
368
|
-
this.$firstListener(this.$currentValue, this.$previousValue, operations
|
|
460
|
+
this.$firstListener(this.$currentValue, this.$previousValue, operations);
|
|
369
461
|
};
|
|
370
462
|
|
|
371
463
|
ObservableItem.prototype.triggerListeners = function(operations) {
|
|
@@ -373,33 +465,12 @@ var NativeDocument = (function (exports) {
|
|
|
373
465
|
const $previousValue = this.$previousValue;
|
|
374
466
|
const $currentValue = this.$currentValue;
|
|
375
467
|
|
|
376
|
-
operations = operations || DEFAULT_OPERATIONS;
|
|
377
468
|
for(let i = 0, length = $listeners.length; i < length; i++) {
|
|
378
469
|
$listeners[i]($currentValue, $previousValue, operations);
|
|
379
470
|
}
|
|
380
471
|
};
|
|
381
472
|
|
|
382
|
-
|
|
383
|
-
if(typeof callbacks === "function") {
|
|
384
|
-
callbacks(value);
|
|
385
|
-
return;
|
|
386
|
-
}
|
|
387
|
-
if (callbacks.set) {
|
|
388
|
-
callbacks.set(value);
|
|
389
|
-
return;
|
|
390
|
-
}
|
|
391
|
-
for(let i = 0, length = callbacks.length; i < length; i++) {
|
|
392
|
-
const callback = callbacks[i];
|
|
393
|
-
callback.set ? callback.set(value) : callback(value);
|
|
394
|
-
|
|
395
|
-
}
|
|
396
|
-
};
|
|
397
|
-
|
|
398
|
-
ObservableItem.prototype.triggerWatchers = function() {
|
|
399
|
-
if(!this.$watchers) {
|
|
400
|
-
return;
|
|
401
|
-
}
|
|
402
|
-
|
|
473
|
+
ObservableItem.prototype.triggerWatchers = function(operations) {
|
|
403
474
|
const $watchers = this.$watchers;
|
|
404
475
|
const $previousValue = this.$previousValue;
|
|
405
476
|
const $currentValue = this.$currentValue;
|
|
@@ -407,20 +478,20 @@ var NativeDocument = (function (exports) {
|
|
|
407
478
|
const $currentValueCallbacks = $watchers.get($currentValue);
|
|
408
479
|
const $previousValueCallbacks = $watchers.get($previousValue);
|
|
409
480
|
if($currentValueCallbacks) {
|
|
410
|
-
|
|
481
|
+
$currentValueCallbacks(true, $previousValue, operations);
|
|
411
482
|
}
|
|
412
483
|
if($previousValueCallbacks) {
|
|
413
|
-
|
|
484
|
+
$previousValueCallbacks(false, $currentValue, operations);
|
|
414
485
|
}
|
|
415
486
|
};
|
|
416
487
|
|
|
417
488
|
ObservableItem.prototype.triggerAll = function(operations) {
|
|
418
|
-
this.triggerWatchers();
|
|
489
|
+
this.triggerWatchers(operations);
|
|
419
490
|
this.triggerListeners(operations);
|
|
420
491
|
};
|
|
421
492
|
|
|
422
493
|
ObservableItem.prototype.triggerWatchersAndFirstListener = function(operations) {
|
|
423
|
-
this.triggerWatchers();
|
|
494
|
+
this.triggerWatchers(operations);
|
|
424
495
|
this.triggerFirstListener(operations);
|
|
425
496
|
};
|
|
426
497
|
|
|
@@ -448,36 +519,47 @@ var NativeDocument = (function (exports) {
|
|
|
448
519
|
};
|
|
449
520
|
ObservableItem.prototype.trigger = noneTrigger;
|
|
450
521
|
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
*/
|
|
454
|
-
ObservableItem.prototype.set = function(data) {
|
|
455
|
-
let newValue = (typeof data === 'function') ? data(this.$currentValue) : data;
|
|
456
|
-
newValue = Validator.isObservable(newValue) ? newValue.val() : newValue;
|
|
457
|
-
|
|
458
|
-
if (this.$interceptor) {
|
|
459
|
-
const result = this.$interceptor(newValue, this.$currentValue);
|
|
460
|
-
|
|
461
|
-
if (result !== undefined) {
|
|
462
|
-
newValue = result;
|
|
463
|
-
}
|
|
464
|
-
}
|
|
465
|
-
|
|
522
|
+
ObservableItem.prototype.$updateWithNewValue = function(newValue) {
|
|
523
|
+
newValue = newValue?.__$isObservable ? newValue.val() : newValue;
|
|
466
524
|
if(this.$currentValue === newValue) {
|
|
467
525
|
return;
|
|
468
526
|
}
|
|
469
527
|
this.$previousValue = this.$currentValue;
|
|
470
528
|
this.$currentValue = newValue;
|
|
471
529
|
{
|
|
472
|
-
PluginsManager.emit('ObservableBeforeChange', this);
|
|
530
|
+
PluginsManager$1.emit('ObservableBeforeChange', this);
|
|
473
531
|
}
|
|
474
532
|
this.trigger();
|
|
475
533
|
this.$previousValue = null;
|
|
476
534
|
{
|
|
477
|
-
PluginsManager.emit('ObservableAfterChange', this);
|
|
535
|
+
PluginsManager$1.emit('ObservableAfterChange', this);
|
|
478
536
|
}
|
|
479
537
|
};
|
|
480
538
|
|
|
539
|
+
/**
|
|
540
|
+
* @param {*} data
|
|
541
|
+
*/
|
|
542
|
+
ObservableItem.prototype.$setWithInterceptor = function(data) {
|
|
543
|
+
let newValue = (typeof data === 'function') ? data(this.$currentValue) : data;
|
|
544
|
+
const result = this.$interceptor(newValue, this.$currentValue);
|
|
545
|
+
|
|
546
|
+
if (result !== undefined) {
|
|
547
|
+
newValue = result;
|
|
548
|
+
}
|
|
549
|
+
|
|
550
|
+
this.$updateWithNewValue(newValue);
|
|
551
|
+
};
|
|
552
|
+
|
|
553
|
+
/**
|
|
554
|
+
* @param {*} data
|
|
555
|
+
*/
|
|
556
|
+
ObservableItem.prototype.$basicSet = function(data) {
|
|
557
|
+
let newValue = (typeof data === 'function') ? data(this.$currentValue) : data;
|
|
558
|
+
this.$updateWithNewValue(newValue);
|
|
559
|
+
};
|
|
560
|
+
|
|
561
|
+
ObservableItem.prototype.set = ObservableItem.prototype.$basicSet;
|
|
562
|
+
|
|
481
563
|
ObservableItem.prototype.val = function() {
|
|
482
564
|
return this.$currentValue;
|
|
483
565
|
};
|
|
@@ -499,6 +581,16 @@ var NativeDocument = (function (exports) {
|
|
|
499
581
|
this.trigger = noneTrigger;
|
|
500
582
|
};
|
|
501
583
|
|
|
584
|
+
/**
|
|
585
|
+
* Registers a cleanup callback that will be executed when the observable is cleaned up.
|
|
586
|
+
* Useful for disposing resources, removing event listeners, or other cleanup tasks.
|
|
587
|
+
*
|
|
588
|
+
* @param {Function} callback - Cleanup function to execute on observable disposal
|
|
589
|
+
* @example
|
|
590
|
+
* const obs = Observable(0);
|
|
591
|
+
* obs.onCleanup(() => console.log('Cleaned up!'));
|
|
592
|
+
* obs.cleanup(); // Logs: "Cleaned up!"
|
|
593
|
+
*/
|
|
502
594
|
ObservableItem.prototype.onCleanup = function(callback) {
|
|
503
595
|
this.$cleanupListeners = this.$cleanupListeners ?? [];
|
|
504
596
|
this.$cleanupListeners.push(callback);
|
|
@@ -513,79 +605,129 @@ var NativeDocument = (function (exports) {
|
|
|
513
605
|
}
|
|
514
606
|
MemoryManager.unregister(this.$memoryId);
|
|
515
607
|
this.disconnectAll();
|
|
516
|
-
|
|
608
|
+
{
|
|
609
|
+
this.$isCleanedUp = true;
|
|
610
|
+
}
|
|
517
611
|
delete this.$value;
|
|
518
612
|
};
|
|
519
613
|
|
|
520
614
|
/**
|
|
521
615
|
*
|
|
522
616
|
* @param {Function} callback
|
|
523
|
-
* @param {any} target
|
|
524
617
|
* @returns {(function(): void)}
|
|
525
618
|
*/
|
|
526
|
-
ObservableItem.prototype.subscribe = function(callback
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
619
|
+
ObservableItem.prototype.subscribe = function(callback) {
|
|
620
|
+
{
|
|
621
|
+
if (this.$isCleanedUp) {
|
|
622
|
+
DebugManager$1.warn('Observable subscription', '⚠️ Attempted to subscribe to a cleaned up observable.');
|
|
623
|
+
return;
|
|
624
|
+
}
|
|
625
|
+
if (typeof callback !== 'function') {
|
|
626
|
+
throw new NativeDocumentError('Callback must be a function');
|
|
627
|
+
}
|
|
534
628
|
}
|
|
629
|
+
this.$listeners = this.$listeners ?? [];
|
|
535
630
|
|
|
536
631
|
this.$listeners.push(callback);
|
|
537
632
|
this.assocTrigger();
|
|
538
633
|
{
|
|
539
|
-
PluginsManager.emit('ObservableSubscribe', this
|
|
634
|
+
PluginsManager$1.emit('ObservableSubscribe', this);
|
|
540
635
|
}
|
|
541
|
-
return () => {
|
|
542
|
-
this.unsubscribe(callback);
|
|
543
|
-
this.assocTrigger();
|
|
544
|
-
{
|
|
545
|
-
PluginsManager.emit('ObservableUnsubscribe', this);
|
|
546
|
-
}
|
|
547
|
-
};
|
|
548
636
|
};
|
|
549
637
|
|
|
638
|
+
/**
|
|
639
|
+
* Watches for a specific value and executes callback when the observable equals that value.
|
|
640
|
+
* Creates a watcher that only triggers when the observable changes to the specified value.
|
|
641
|
+
*
|
|
642
|
+
* @param {*} value - The value to watch for
|
|
643
|
+
* @param {(value) => void|ObservableItem} callback - Callback function or observable to set when value matches
|
|
644
|
+
* @example
|
|
645
|
+
* const status = Observable('idle');
|
|
646
|
+
* status.on('loading', () => console.log('Started loading'));
|
|
647
|
+
* status.on('error', isError); // Set another observable
|
|
648
|
+
*/
|
|
550
649
|
ObservableItem.prototype.on = function(value, callback) {
|
|
551
650
|
this.$watchers = this.$watchers ?? new Map();
|
|
552
651
|
|
|
553
652
|
let watchValueList = this.$watchers.get(value);
|
|
554
653
|
|
|
654
|
+
if(callback.__$isObservable) {
|
|
655
|
+
callback = callback.set.bind(callback);
|
|
656
|
+
}
|
|
657
|
+
|
|
555
658
|
if(!watchValueList) {
|
|
659
|
+
watchValueList = callback;
|
|
556
660
|
this.$watchers.set(value, callback);
|
|
557
|
-
} else if(!Validator.isArray(watchValueList)) {
|
|
661
|
+
} else if(!Validator.isArray(watchValueList.list)) {
|
|
558
662
|
watchValueList = [watchValueList, callback];
|
|
559
|
-
|
|
663
|
+
callback = (value) => {
|
|
664
|
+
for(let i = 0, length = watchValueList.length; i < length; i++) {
|
|
665
|
+
watchValueList[i](value);
|
|
666
|
+
}
|
|
667
|
+
};
|
|
668
|
+
callback.list = watchValueList;
|
|
669
|
+
this.$watchers.set(value, callback);
|
|
560
670
|
} else {
|
|
561
|
-
watchValueList.push(callback);
|
|
671
|
+
watchValueList.list.push(callback);
|
|
562
672
|
}
|
|
563
673
|
|
|
564
674
|
this.assocTrigger();
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
675
|
+
};
|
|
676
|
+
|
|
677
|
+
/**
|
|
678
|
+
* Removes a watcher for a specific value. If no callback is provided, removes all watchers for that value.
|
|
679
|
+
*
|
|
680
|
+
* @param {*} value - The value to stop watching
|
|
681
|
+
* @param {Function} [callback] - Specific callback to remove. If omitted, removes all watchers for this value
|
|
682
|
+
* @example
|
|
683
|
+
* const status = Observable('idle');
|
|
684
|
+
* const handler = () => console.log('Loading');
|
|
685
|
+
* status.on('loading', handler);
|
|
686
|
+
* status.off('loading', handler); // Remove specific handler
|
|
687
|
+
* status.off('loading'); // Remove all handlers for 'loading'
|
|
688
|
+
*/
|
|
689
|
+
ObservableItem.prototype.off = function(value, callback) {
|
|
690
|
+
if(!this.$watchers) return;
|
|
691
|
+
|
|
692
|
+
const watchValueList = this.$watchers.get(value);
|
|
693
|
+
if(!watchValueList) return;
|
|
694
|
+
|
|
695
|
+
if(!callback || !Array.isArray(watchValueList.list)) {
|
|
696
|
+
this.$watchers?.delete(value);
|
|
575
697
|
this.assocTrigger();
|
|
576
|
-
|
|
698
|
+
return;
|
|
699
|
+
}
|
|
700
|
+
const index = watchValueList.indexOf(callback);
|
|
701
|
+
watchValueList?.splice(index, 1);
|
|
702
|
+
if(watchValueList.length === 1) {
|
|
703
|
+
this.$watchers.set(value, watchValueList[0]);
|
|
704
|
+
}
|
|
705
|
+
else if(watchValueList.length === 0) {
|
|
706
|
+
this.$watchers?.delete(value);
|
|
707
|
+
}
|
|
708
|
+
this.assocTrigger();
|
|
577
709
|
};
|
|
578
710
|
|
|
711
|
+
/**
|
|
712
|
+
* Subscribes to the observable but automatically unsubscribes after the first time the predicate matches.
|
|
713
|
+
*
|
|
714
|
+
* @param {(value) => Boolean|any} predicate - Value to match or function that returns true when condition is met
|
|
715
|
+
* @param {(value) => void} callback - Callback to execute when predicate matches, receives the matched value
|
|
716
|
+
* @example
|
|
717
|
+
* const status = Observable('loading');
|
|
718
|
+
* status.once('ready', (val) => console.log('Ready!'));
|
|
719
|
+
* status.once(val => val === 'error', (val) => console.log('Error occurred'));
|
|
720
|
+
*/
|
|
579
721
|
ObservableItem.prototype.once = function(predicate, callback) {
|
|
580
722
|
const fn = typeof predicate === 'function' ? predicate : (v) => v === predicate;
|
|
581
723
|
|
|
582
|
-
const
|
|
724
|
+
const handler = (val) => {
|
|
583
725
|
if (fn(val)) {
|
|
584
|
-
|
|
726
|
+
this.unsubscribe(handler);
|
|
585
727
|
callback(val);
|
|
586
728
|
}
|
|
587
|
-
}
|
|
588
|
-
|
|
729
|
+
};
|
|
730
|
+
this.subscribe(handler);
|
|
589
731
|
};
|
|
590
732
|
|
|
591
733
|
/**
|
|
@@ -593,11 +735,15 @@ var NativeDocument = (function (exports) {
|
|
|
593
735
|
* @param {Function} callback
|
|
594
736
|
*/
|
|
595
737
|
ObservableItem.prototype.unsubscribe = function(callback) {
|
|
738
|
+
if(!this.$listeners) return;
|
|
596
739
|
const index = this.$listeners.indexOf(callback);
|
|
597
740
|
if (index > -1) {
|
|
598
741
|
this.$listeners.splice(index, 1);
|
|
599
742
|
}
|
|
600
743
|
this.assocTrigger();
|
|
744
|
+
{
|
|
745
|
+
PluginsManager$1.emit('ObservableUnsubscribe', this);
|
|
746
|
+
}
|
|
601
747
|
};
|
|
602
748
|
|
|
603
749
|
/**
|
|
@@ -609,15 +755,50 @@ var NativeDocument = (function (exports) {
|
|
|
609
755
|
return new ObservableChecker(this, callback)
|
|
610
756
|
};
|
|
611
757
|
|
|
758
|
+
/**
|
|
759
|
+
* Gets a property value from the observable's current value.
|
|
760
|
+
* If the property is an observable, returns its value.
|
|
761
|
+
*
|
|
762
|
+
* @param {string|number} key - Property key to retrieve
|
|
763
|
+
* @returns {*} The value of the property, unwrapped if it's an observable
|
|
764
|
+
* @example
|
|
765
|
+
* const user = Observable({ name: 'John', age: Observable(25) });
|
|
766
|
+
* user.get('name'); // 'John'
|
|
767
|
+
* user.get('age'); // 25 (unwrapped from observable)
|
|
768
|
+
*/
|
|
612
769
|
ObservableItem.prototype.get = function(key) {
|
|
613
770
|
const item = this.$currentValue[key];
|
|
614
771
|
return Validator.isObservable(item) ? item.val() : item;
|
|
615
772
|
};
|
|
616
773
|
|
|
774
|
+
/**
|
|
775
|
+
* Creates an ObservableWhen that represents whether the observable equals a specific value.
|
|
776
|
+
* Returns an object that can be subscribed to and will emit true/false.
|
|
777
|
+
*
|
|
778
|
+
* @param {*} value - The value to compare against
|
|
779
|
+
* @returns {ObservableWhen} An ObservableWhen instance that tracks when the observable equals the value
|
|
780
|
+
* @example
|
|
781
|
+
* const status = Observable('idle');
|
|
782
|
+
* const isLoading = status.when('loading');
|
|
783
|
+
* isLoading.subscribe(active => console.log('Loading:', active));
|
|
784
|
+
* status.set('loading'); // Logs: "Loading: true"
|
|
785
|
+
*/
|
|
617
786
|
ObservableItem.prototype.when = function(value) {
|
|
618
787
|
return new ObservableWhen(this, value);
|
|
619
788
|
};
|
|
620
789
|
|
|
790
|
+
/**
|
|
791
|
+
* Compares the observable's current value with another value or observable.
|
|
792
|
+
*
|
|
793
|
+
* @param {*|ObservableItem} other - Value or observable to compare against
|
|
794
|
+
* @returns {boolean} True if values are equal
|
|
795
|
+
* @example
|
|
796
|
+
* const a = Observable(5);
|
|
797
|
+
* const b = Observable(5);
|
|
798
|
+
* a.equals(5); // true
|
|
799
|
+
* a.equals(b); // true
|
|
800
|
+
* a.equals(10); // false
|
|
801
|
+
*/
|
|
621
802
|
ObservableItem.prototype.equals = function(other) {
|
|
622
803
|
if(Validator.isObservable(other)) {
|
|
623
804
|
return this.$currentValue === other.$currentValue;
|
|
@@ -625,14 +806,41 @@ var NativeDocument = (function (exports) {
|
|
|
625
806
|
return this.$currentValue === other;
|
|
626
807
|
};
|
|
627
808
|
|
|
809
|
+
/**
|
|
810
|
+
* Converts the observable's current value to a boolean.
|
|
811
|
+
*
|
|
812
|
+
* @returns {boolean} The boolean representation of the current value
|
|
813
|
+
* @example
|
|
814
|
+
* const count = Observable(0);
|
|
815
|
+
* count.toBool(); // false
|
|
816
|
+
* count.set(5);
|
|
817
|
+
* count.toBool(); // true
|
|
818
|
+
*/
|
|
628
819
|
ObservableItem.prototype.toBool = function() {
|
|
629
820
|
return !!this.$currentValue;
|
|
630
821
|
};
|
|
631
822
|
|
|
823
|
+
/**
|
|
824
|
+
* Toggles the boolean value of the observable (false becomes true, true becomes false).
|
|
825
|
+
*
|
|
826
|
+
* @example
|
|
827
|
+
* const isOpen = Observable(false);
|
|
828
|
+
* isOpen.toggle(); // Now true
|
|
829
|
+
* isOpen.toggle(); // Now false
|
|
830
|
+
*/
|
|
632
831
|
ObservableItem.prototype.toggle = function() {
|
|
633
832
|
this.set(!this.$currentValue);
|
|
634
833
|
};
|
|
635
834
|
|
|
835
|
+
/**
|
|
836
|
+
* Resets the observable to its initial value.
|
|
837
|
+
* Only works if the observable was created with { reset: true } config.
|
|
838
|
+
*
|
|
839
|
+
* @example
|
|
840
|
+
* const count = Observable(0, { reset: true });
|
|
841
|
+
* count.set(10);
|
|
842
|
+
* count.reset(); // Back to 0
|
|
843
|
+
*/
|
|
636
844
|
ObservableItem.prototype.reset = function() {
|
|
637
845
|
if(!this.configs?.reset) {
|
|
638
846
|
return;
|
|
@@ -645,11 +853,25 @@ var NativeDocument = (function (exports) {
|
|
|
645
853
|
this.set(resetValue);
|
|
646
854
|
};
|
|
647
855
|
|
|
648
|
-
|
|
856
|
+
/**
|
|
857
|
+
* Returns a string representation of the observable's current value.
|
|
858
|
+
*
|
|
859
|
+
* @returns {string} String representation of the current value
|
|
860
|
+
*/
|
|
649
861
|
ObservableItem.prototype.toString = function() {
|
|
650
862
|
return String(this.$currentValue);
|
|
651
863
|
};
|
|
652
864
|
|
|
865
|
+
/**
|
|
866
|
+
* Returns the primitive value of the observable (its current value).
|
|
867
|
+
* Called automatically in type coercion contexts.
|
|
868
|
+
*
|
|
869
|
+
* @returns {*} The current value of the observable
|
|
870
|
+
*/
|
|
871
|
+
ObservableItem.prototype.valueOf = function() {
|
|
872
|
+
return this.$currentValue;
|
|
873
|
+
};
|
|
874
|
+
|
|
653
875
|
const DocumentObserver = {
|
|
654
876
|
mounted: new WeakMap(),
|
|
655
877
|
mountedSupposedSize: 0,
|
|
@@ -757,7 +979,7 @@ var NativeDocument = (function (exports) {
|
|
|
757
979
|
this.$element = element;
|
|
758
980
|
this.$observer = null;
|
|
759
981
|
{
|
|
760
|
-
PluginsManager.emit('NDElementCreated', element, this);
|
|
982
|
+
PluginsManager$1.emit('NDElementCreated', element, this);
|
|
761
983
|
}
|
|
762
984
|
}
|
|
763
985
|
|
|
@@ -853,12 +1075,35 @@ var NativeDocument = (function (exports) {
|
|
|
853
1075
|
return this.shadow('closed', style);
|
|
854
1076
|
};
|
|
855
1077
|
|
|
1078
|
+
/**
|
|
1079
|
+
* Attaches a template binding to the element by hydrating it with the specified method.
|
|
1080
|
+
*
|
|
1081
|
+
* @param {string} methodName - Name of the hydration method to call
|
|
1082
|
+
* @param {BindingHydrator} bindingHydrator - Template binding with $hydrate method
|
|
1083
|
+
* @returns {HTMLElement} The underlying HTML element
|
|
1084
|
+
* @example
|
|
1085
|
+
* const onClick = $binder.attach((event, data) => console.log(data));
|
|
1086
|
+
* element.nd.attach('onClick', onClick);
|
|
1087
|
+
*/
|
|
856
1088
|
NDElement.prototype.attach = function(methodName, bindingHydrator) {
|
|
857
1089
|
bindingHydrator.$hydrate(this.$element, methodName);
|
|
858
1090
|
return this.$element;
|
|
859
1091
|
};
|
|
860
1092
|
|
|
861
|
-
|
|
1093
|
+
/**
|
|
1094
|
+
* Extends the current NDElement instance with custom methods.
|
|
1095
|
+
* Methods are bound to the instance and available for chaining.
|
|
1096
|
+
*
|
|
1097
|
+
* @param {Object} methods - Object containing method definitions
|
|
1098
|
+
* @returns {this} The NDElement instance with added methods for chaining
|
|
1099
|
+
* @example
|
|
1100
|
+
* element.nd.with({
|
|
1101
|
+
* highlight() {
|
|
1102
|
+
* this.$element.style.background = 'yellow';
|
|
1103
|
+
* return this;
|
|
1104
|
+
* }
|
|
1105
|
+
* }).highlight().onClick(() => console.log('Clicked'));
|
|
1106
|
+
*/
|
|
862
1107
|
NDElement.prototype.with = function(methods) {
|
|
863
1108
|
if (!methods || typeof methods !== 'object') {
|
|
864
1109
|
throw new NativeDocumentError('extend() requires an object of methods');
|
|
@@ -878,7 +1123,7 @@ var NativeDocument = (function (exports) {
|
|
|
878
1123
|
}
|
|
879
1124
|
{
|
|
880
1125
|
if (this[name] && !this.$localExtensions.has(name)) {
|
|
881
|
-
DebugManager.warn('NDElement.extend', `Method "${name}" already exists and will be overwritten`);
|
|
1126
|
+
DebugManager$1.warn('NDElement.extend', `Method "${name}" already exists and will be overwritten`);
|
|
882
1127
|
}
|
|
883
1128
|
this.$localExtensions.set(name, method);
|
|
884
1129
|
}
|
|
@@ -889,6 +1134,23 @@ var NativeDocument = (function (exports) {
|
|
|
889
1134
|
return this;
|
|
890
1135
|
};
|
|
891
1136
|
|
|
1137
|
+
/**
|
|
1138
|
+
* Extends the NDElement prototype with new methods available to all NDElement instances.
|
|
1139
|
+
* Use this to add global methods to all NDElements.
|
|
1140
|
+
*
|
|
1141
|
+
* @param {Object} methods - Object containing method definitions to add to prototype
|
|
1142
|
+
* @returns {typeof NDElement} The NDElement constructor
|
|
1143
|
+
* @throws {NativeDocumentError} If methods is not an object or contains non-function values
|
|
1144
|
+
* @example
|
|
1145
|
+
* NDElement.extend({
|
|
1146
|
+
* fadeIn() {
|
|
1147
|
+
* this.$element.style.opacity = '1';
|
|
1148
|
+
* return this;
|
|
1149
|
+
* }
|
|
1150
|
+
* });
|
|
1151
|
+
* // Now all NDElements have .fadeIn() method
|
|
1152
|
+
* Div().nd.fadeIn();
|
|
1153
|
+
*/
|
|
892
1154
|
NDElement.extend = function(methods) {
|
|
893
1155
|
if (!methods || typeof methods !== 'object') {
|
|
894
1156
|
throw new NativeDocumentError('NDElement.extend() requires an object of methods');
|
|
@@ -912,23 +1174,23 @@ var NativeDocument = (function (exports) {
|
|
|
912
1174
|
const method = methods[name];
|
|
913
1175
|
|
|
914
1176
|
if (typeof method !== 'function') {
|
|
915
|
-
DebugManager.warn('NDElement.extend', `"${name}" is not a function, skipping`);
|
|
1177
|
+
DebugManager$1.warn('NDElement.extend', `"${name}" is not a function, skipping`);
|
|
916
1178
|
continue;
|
|
917
1179
|
}
|
|
918
1180
|
|
|
919
1181
|
if (protectedMethods.has(name)) {
|
|
920
|
-
DebugManager.error('NDElement.extend', `Cannot override protected method "${name}"`);
|
|
1182
|
+
DebugManager$1.error('NDElement.extend', `Cannot override protected method "${name}"`);
|
|
921
1183
|
throw new NativeDocumentError(`Cannot override protected method "${name}"`);
|
|
922
1184
|
}
|
|
923
1185
|
|
|
924
1186
|
if (NDElement.prototype[name]) {
|
|
925
|
-
DebugManager.warn('NDElement.extend', `Overwriting existing prototype method "${name}"`);
|
|
1187
|
+
DebugManager$1.warn('NDElement.extend', `Overwriting existing prototype method "${name}"`);
|
|
926
1188
|
}
|
|
927
1189
|
|
|
928
1190
|
NDElement.prototype[name] = method;
|
|
929
1191
|
}
|
|
930
1192
|
{
|
|
931
|
-
PluginsManager.emit('NDElementExtended', methods);
|
|
1193
|
+
PluginsManager$1.emit('NDElementExtended', methods);
|
|
932
1194
|
}
|
|
933
1195
|
|
|
934
1196
|
return NDElement;
|
|
@@ -1081,7 +1343,7 @@ var NativeDocument = (function (exports) {
|
|
|
1081
1343
|
const foundReserved = Object.keys(attributes).filter(key => reserved.includes(key));
|
|
1082
1344
|
|
|
1083
1345
|
if (foundReserved.length > 0) {
|
|
1084
|
-
DebugManager.warn('Validator', `Reserved attributes found: ${foundReserved.join(', ')}`);
|
|
1346
|
+
DebugManager$1.warn('Validator', `Reserved attributes found: ${foundReserved.join(', ')}`);
|
|
1085
1347
|
}
|
|
1086
1348
|
|
|
1087
1349
|
return attributes;
|
|
@@ -1129,7 +1391,7 @@ var NativeDocument = (function (exports) {
|
|
|
1129
1391
|
anchorFragment.appendChild = function(child, before = null) {
|
|
1130
1392
|
const parent = anchorEnd.parentNode;
|
|
1131
1393
|
if(!parent) {
|
|
1132
|
-
DebugManager.error('Anchor', 'Anchor : parent not found', child);
|
|
1394
|
+
DebugManager$1.error('Anchor', 'Anchor : parent not found', child);
|
|
1133
1395
|
return;
|
|
1134
1396
|
}
|
|
1135
1397
|
before = before ?? anchorEnd;
|
|
@@ -1357,7 +1619,7 @@ var NativeDocument = (function (exports) {
|
|
|
1357
1619
|
continue;
|
|
1358
1620
|
}
|
|
1359
1621
|
if(value.__$isObservableWhen) {
|
|
1360
|
-
element.classes.toggle(className, value.
|
|
1622
|
+
element.classes.toggle(className, value.isActive());
|
|
1361
1623
|
value.subscribe((shouldAdd) => element.classes.toggle(className, shouldAdd));
|
|
1362
1624
|
continue;
|
|
1363
1625
|
}
|
|
@@ -1503,6 +1765,8 @@ var NativeDocument = (function (exports) {
|
|
|
1503
1765
|
return ElementCreator.createObservableNode(null, this);
|
|
1504
1766
|
};
|
|
1505
1767
|
|
|
1768
|
+
ObservableChecker.prototype.toNdElement = ObservableItem.prototype.toNdElement;
|
|
1769
|
+
|
|
1506
1770
|
NDElement.prototype.toNdElement = function () {
|
|
1507
1771
|
return this.$element ?? this.$build?.() ?? this.build?.() ?? null;
|
|
1508
1772
|
};
|
|
@@ -1520,7 +1784,7 @@ var NativeDocument = (function (exports) {
|
|
|
1520
1784
|
Function.prototype.toNdElement = function () {
|
|
1521
1785
|
const child = this;
|
|
1522
1786
|
{
|
|
1523
|
-
PluginsManager.emit('BeforeProcessComponent', child);
|
|
1787
|
+
PluginsManager$1.emit('BeforeProcessComponent', child);
|
|
1524
1788
|
}
|
|
1525
1789
|
return ElementCreator.getChild(child());
|
|
1526
1790
|
};
|
|
@@ -1626,14 +1890,14 @@ var NativeDocument = (function (exports) {
|
|
|
1626
1890
|
processChildren(children, parent) {
|
|
1627
1891
|
if(children === null) return;
|
|
1628
1892
|
{
|
|
1629
|
-
PluginsManager.emit('BeforeProcessChildren', parent);
|
|
1893
|
+
PluginsManager$1.emit('BeforeProcessChildren', parent);
|
|
1630
1894
|
}
|
|
1631
1895
|
let child = this.getChild(children);
|
|
1632
1896
|
if(child) {
|
|
1633
1897
|
parent.appendChild(child);
|
|
1634
1898
|
}
|
|
1635
1899
|
{
|
|
1636
|
-
PluginsManager.emit('AfterProcessChildren', parent);
|
|
1900
|
+
PluginsManager$1.emit('AfterProcessChildren', parent);
|
|
1637
1901
|
}
|
|
1638
1902
|
},
|
|
1639
1903
|
getChild(child) {
|
|
@@ -1849,6 +2113,10 @@ var NativeDocument = (function (exports) {
|
|
|
1849
2113
|
_stop(this.$element, eventName, callback);
|
|
1850
2114
|
return this;
|
|
1851
2115
|
};
|
|
2116
|
+
NDElement.prototype['onPreventStop'+eventSourceName] = function(callback = null) {
|
|
2117
|
+
_preventStop(this.$element, eventName, callback);
|
|
2118
|
+
return this;
|
|
2119
|
+
};
|
|
1852
2120
|
});
|
|
1853
2121
|
|
|
1854
2122
|
EVENTS_WITH_PREVENT.forEach(eventSourceName => {
|
|
@@ -1882,6 +2150,16 @@ var NativeDocument = (function (exports) {
|
|
|
1882
2150
|
return this;
|
|
1883
2151
|
};
|
|
1884
2152
|
|
|
2153
|
+
const _preventStop = function(element, eventName, callback) {
|
|
2154
|
+
const handler = (event) => {
|
|
2155
|
+
event.stopPropagation();
|
|
2156
|
+
event.preventDefault();
|
|
2157
|
+
callback && callback.call(element, event);
|
|
2158
|
+
};
|
|
2159
|
+
element.addEventListener(eventName, handler);
|
|
2160
|
+
return this;
|
|
2161
|
+
};
|
|
2162
|
+
|
|
1885
2163
|
|
|
1886
2164
|
|
|
1887
2165
|
// ----------------------------------------------------------------
|
|
@@ -2154,7 +2432,12 @@ var NativeDocument = (function (exports) {
|
|
|
2154
2432
|
|
|
2155
2433
|
const applyBindingTreePath = (root, target, data, path) => {
|
|
2156
2434
|
if(path.fn) {
|
|
2157
|
-
path.fn
|
|
2435
|
+
if(typeof path.fn === 'string') {
|
|
2436
|
+
ElementCreator.bindTextNode(target, data[0][path.fn]);
|
|
2437
|
+
}
|
|
2438
|
+
else {
|
|
2439
|
+
path.fn(data, target, root);
|
|
2440
|
+
}
|
|
2158
2441
|
}
|
|
2159
2442
|
if(path.children) {
|
|
2160
2443
|
for(let i = 0, length = path.children.length; i < length; i++) {
|
|
@@ -2180,15 +2463,16 @@ var NativeDocument = (function (exports) {
|
|
|
2180
2463
|
if(bindDingData && bindDingData.value) {
|
|
2181
2464
|
currentPath.fn = bindDingData.value;
|
|
2182
2465
|
const textNode = node.cloneNode();
|
|
2466
|
+
if(typeof bindDingData.value === 'string') {
|
|
2467
|
+
ElementCreator.bindTextNode(textNode, data[0][bindDingData.value]);
|
|
2468
|
+
return textNode;
|
|
2469
|
+
}
|
|
2183
2470
|
bindDingData.value(data, textNode);
|
|
2184
2471
|
return textNode;
|
|
2185
2472
|
}
|
|
2186
2473
|
return node.cloneNode(true);
|
|
2187
2474
|
}
|
|
2188
|
-
const nodeCloned = node.cloneNode(
|
|
2189
|
-
if(node.fullCloneNode) {
|
|
2190
|
-
return nodeCloned;
|
|
2191
|
-
}
|
|
2475
|
+
const nodeCloned = node.cloneNode();
|
|
2192
2476
|
if(bindDingData) {
|
|
2193
2477
|
bindAttributes(nodeCloned, bindDingData, data);
|
|
2194
2478
|
bindAttachMethods(nodeCloned, bindDingData, data);
|
|
@@ -2253,12 +2537,9 @@ var NativeDocument = (function (exports) {
|
|
|
2253
2537
|
};
|
|
2254
2538
|
this.value = (callbackOrProperty) => {
|
|
2255
2539
|
if(typeof callbackOrProperty !== 'function') {
|
|
2256
|
-
return createBinding(
|
|
2257
|
-
const firstArgument = data[0];
|
|
2258
|
-
ElementCreator.bindTextNode(textNode, firstArgument[callbackOrProperty]);
|
|
2259
|
-
}, 'value');
|
|
2540
|
+
return createBinding(callbackOrProperty, 'value');
|
|
2260
2541
|
}
|
|
2261
|
-
return createBinding(
|
|
2542
|
+
return createBinding((data, textNode) => {
|
|
2262
2543
|
ElementCreator.bindTextNode(textNode, callbackOrProperty(...data));
|
|
2263
2544
|
}, 'value');
|
|
2264
2545
|
};
|
|
@@ -2360,13 +2641,14 @@ var NativeDocument = (function (exports) {
|
|
|
2360
2641
|
};
|
|
2361
2642
|
|
|
2362
2643
|
Function.prototype.errorBoundary = function(callback) {
|
|
2363
|
-
|
|
2644
|
+
const handler = (...args) => {
|
|
2364
2645
|
try {
|
|
2365
2646
|
return this.apply(this, args);
|
|
2366
2647
|
} catch(e) {
|
|
2367
|
-
return callback(e);
|
|
2648
|
+
return callback(e, {caller: handler, args: args });
|
|
2368
2649
|
}
|
|
2369
2650
|
};
|
|
2651
|
+
return handler;
|
|
2370
2652
|
};
|
|
2371
2653
|
|
|
2372
2654
|
String.prototype.use = function(args) {
|
|
@@ -2438,12 +2720,13 @@ var NativeDocument = (function (exports) {
|
|
|
2438
2720
|
};
|
|
2439
2721
|
};
|
|
2440
2722
|
|
|
2441
|
-
const once = (fn) => {
|
|
2723
|
+
const once$1 = (fn) => {
|
|
2442
2724
|
let result = null;
|
|
2443
2725
|
return (...args) => {
|
|
2444
|
-
if(result
|
|
2445
|
-
result
|
|
2726
|
+
if(result) {
|
|
2727
|
+
return result;
|
|
2446
2728
|
}
|
|
2729
|
+
result = fn(...args);
|
|
2447
2730
|
return result;
|
|
2448
2731
|
};
|
|
2449
2732
|
};
|
|
@@ -2452,22 +2735,26 @@ var NativeDocument = (function (exports) {
|
|
|
2452
2735
|
let target = null;
|
|
2453
2736
|
return new Proxy({}, {
|
|
2454
2737
|
get: (_, key) => {
|
|
2455
|
-
if(target
|
|
2456
|
-
target
|
|
2738
|
+
if(target) {
|
|
2739
|
+
return target[key];
|
|
2457
2740
|
}
|
|
2741
|
+
target = fn();
|
|
2458
2742
|
return target[key];
|
|
2459
2743
|
}
|
|
2460
2744
|
});
|
|
2461
2745
|
};
|
|
2462
2746
|
|
|
2463
|
-
const memoize = (fn) => {
|
|
2747
|
+
const memoize$1 = (fn) => {
|
|
2464
2748
|
const cache = new Map();
|
|
2465
2749
|
return (...args) => {
|
|
2466
2750
|
const [key, ...rest] = args;
|
|
2467
|
-
|
|
2468
|
-
|
|
2751
|
+
const cached = cache.get(key);
|
|
2752
|
+
if(cached) {
|
|
2753
|
+
return cached;
|
|
2469
2754
|
}
|
|
2470
|
-
|
|
2755
|
+
const result = fn(...rest);
|
|
2756
|
+
cache.set(key, result);
|
|
2757
|
+
return result;
|
|
2471
2758
|
};
|
|
2472
2759
|
};
|
|
2473
2760
|
|
|
@@ -2475,17 +2762,21 @@ var NativeDocument = (function (exports) {
|
|
|
2475
2762
|
const cache = new Map();
|
|
2476
2763
|
return new Proxy({}, {
|
|
2477
2764
|
get: (_, key) => {
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
|
|
2483
|
-
|
|
2484
|
-
|
|
2765
|
+
const cached = cache.get(key);
|
|
2766
|
+
if(cached) {
|
|
2767
|
+
return cached;
|
|
2768
|
+
}
|
|
2769
|
+
|
|
2770
|
+
if(fn.length > 0) {
|
|
2771
|
+
return (...args) => {
|
|
2772
|
+
const result = fn(...args, key);
|
|
2773
|
+
cache.set(key, result);
|
|
2774
|
+
return result;
|
|
2485
2775
|
}
|
|
2486
|
-
cache.set(key, fn());
|
|
2487
2776
|
}
|
|
2488
|
-
|
|
2777
|
+
const result = fn(key);
|
|
2778
|
+
cache.set(key, result);
|
|
2779
|
+
return result;
|
|
2489
2780
|
}
|
|
2490
2781
|
});
|
|
2491
2782
|
};
|
|
@@ -2858,7 +3149,7 @@ var NativeDocument = (function (exports) {
|
|
|
2858
3149
|
|
|
2859
3150
|
ObservableItem.call(this, target, configs);
|
|
2860
3151
|
{
|
|
2861
|
-
PluginsManager.emit('CreateObservableArray', this);
|
|
3152
|
+
PluginsManager$1.emit('CreateObservableArray', this);
|
|
2862
3153
|
}
|
|
2863
3154
|
};
|
|
2864
3155
|
|
|
@@ -2887,6 +3178,14 @@ var NativeDocument = (function (exports) {
|
|
|
2887
3178
|
};
|
|
2888
3179
|
});
|
|
2889
3180
|
|
|
3181
|
+
/**
|
|
3182
|
+
* Removes all items from the array and triggers an update.
|
|
3183
|
+
*
|
|
3184
|
+
* @returns {boolean} True if array was cleared, false if it was already empty
|
|
3185
|
+
* @example
|
|
3186
|
+
* const items = Observable.array([1, 2, 3]);
|
|
3187
|
+
* items.clear(); // []
|
|
3188
|
+
*/
|
|
2890
3189
|
ObservableArray.prototype.clear = function() {
|
|
2891
3190
|
if(this.$currentValue.length === 0) {
|
|
2892
3191
|
return;
|
|
@@ -2896,19 +3195,42 @@ var NativeDocument = (function (exports) {
|
|
|
2896
3195
|
return true;
|
|
2897
3196
|
};
|
|
2898
3197
|
|
|
3198
|
+
/**
|
|
3199
|
+
* Returns the element at the specified index in the array.
|
|
3200
|
+
*
|
|
3201
|
+
* @param {number} index - Zero-based index of the element to retrieve
|
|
3202
|
+
* @returns {*} The element at the specified index
|
|
3203
|
+
* @example
|
|
3204
|
+
* const items = Observable.array(['a', 'b', 'c']);
|
|
3205
|
+
* items.at(1); // 'b'
|
|
3206
|
+
*/
|
|
2899
3207
|
ObservableArray.prototype.at = function(index) {
|
|
2900
3208
|
return this.$currentValue[index];
|
|
2901
3209
|
};
|
|
2902
3210
|
|
|
3211
|
+
|
|
3212
|
+
/**
|
|
3213
|
+
* Merges multiple values into the array and triggers an update.
|
|
3214
|
+
* Similar to push but with a different operation name.
|
|
3215
|
+
*
|
|
3216
|
+
* @param {Array} values - Array of values to merge
|
|
3217
|
+
* @example
|
|
3218
|
+
* const items = Observable.array([1, 2]);
|
|
3219
|
+
* items.merge([3, 4]); // [1, 2, 3, 4]
|
|
3220
|
+
*/
|
|
2903
3221
|
ObservableArray.prototype.merge = function(values) {
|
|
2904
3222
|
this.$currentValue.push.apply(this.$currentValue, values);
|
|
2905
3223
|
this.trigger({ action: 'merge', args: values });
|
|
2906
3224
|
};
|
|
2907
3225
|
|
|
2908
3226
|
/**
|
|
3227
|
+
* Counts the number of elements that satisfy the provided condition.
|
|
2909
3228
|
*
|
|
2910
|
-
* @param {
|
|
2911
|
-
* @returns {number}
|
|
3229
|
+
* @param {(value: *, index: number) => Boolean} condition - Function that tests each element (item, index) => boolean
|
|
3230
|
+
* @returns {number} The count of elements that satisfy the condition
|
|
3231
|
+
* @example
|
|
3232
|
+
* const numbers = Observable.array([1, 2, 3, 4, 5]);
|
|
3233
|
+
* numbers.count(n => n > 3); // 2
|
|
2912
3234
|
*/
|
|
2913
3235
|
ObservableArray.prototype.count = function(condition) {
|
|
2914
3236
|
let count = 0;
|
|
@@ -2920,6 +3242,16 @@ var NativeDocument = (function (exports) {
|
|
|
2920
3242
|
return count;
|
|
2921
3243
|
};
|
|
2922
3244
|
|
|
3245
|
+
/**
|
|
3246
|
+
* Swaps two elements at the specified indices and triggers an update.
|
|
3247
|
+
*
|
|
3248
|
+
* @param {number} indexA - Index of the first element
|
|
3249
|
+
* @param {number} indexB - Index of the second element
|
|
3250
|
+
* @returns {boolean} True if swap was successful, false if indices are out of bounds
|
|
3251
|
+
* @example
|
|
3252
|
+
* const items = Observable.array(['a', 'b', 'c']);
|
|
3253
|
+
* items.swap(0, 2); // ['c', 'b', 'a']
|
|
3254
|
+
*/
|
|
2923
3255
|
ObservableArray.prototype.swap = function(indexA, indexB) {
|
|
2924
3256
|
const value = this.$currentValue;
|
|
2925
3257
|
const length = value.length;
|
|
@@ -2940,6 +3272,15 @@ var NativeDocument = (function (exports) {
|
|
|
2940
3272
|
return true;
|
|
2941
3273
|
};
|
|
2942
3274
|
|
|
3275
|
+
/**
|
|
3276
|
+
* Removes the element at the specified index and triggers an update.
|
|
3277
|
+
*
|
|
3278
|
+
* @param {number} index - Index of the element to remove
|
|
3279
|
+
* @returns {Array} Array containing the removed element, or empty array if index is invalid
|
|
3280
|
+
* @example
|
|
3281
|
+
* const items = Observable.array(['a', 'b', 'c']);
|
|
3282
|
+
* items.remove(1); // ['b'] - Array is now ['a', 'c']
|
|
3283
|
+
*/
|
|
2943
3284
|
ObservableArray.prototype.remove = function(index) {
|
|
2944
3285
|
const deleted = this.$currentValue.splice(index, 1);
|
|
2945
3286
|
if(deleted.length === 0) {
|
|
@@ -2949,20 +3290,60 @@ var NativeDocument = (function (exports) {
|
|
|
2949
3290
|
return deleted;
|
|
2950
3291
|
};
|
|
2951
3292
|
|
|
3293
|
+
/**
|
|
3294
|
+
* Removes the first occurrence of the specified item from the array.
|
|
3295
|
+
*
|
|
3296
|
+
* @param {*} item - The item to remove
|
|
3297
|
+
* @returns {Array} Array containing the removed element, or empty array if item not found
|
|
3298
|
+
* @example
|
|
3299
|
+
* const items = Observable.array(['a', 'b', 'c']);
|
|
3300
|
+
* items.removeItem('b'); // ['b'] - Array is now ['a', 'c']
|
|
3301
|
+
*/
|
|
2952
3302
|
ObservableArray.prototype.removeItem = function(item) {
|
|
2953
3303
|
const indexOfItem = this.$currentValue.indexOf(item);
|
|
3304
|
+
if(indexOfItem === -1) {
|
|
3305
|
+
return [];
|
|
3306
|
+
}
|
|
2954
3307
|
return this.remove(indexOfItem);
|
|
2955
3308
|
};
|
|
2956
3309
|
|
|
3310
|
+
/**
|
|
3311
|
+
* Checks if the array is empty.
|
|
3312
|
+
*
|
|
3313
|
+
* @returns {boolean} True if array has no elements
|
|
3314
|
+
* @example
|
|
3315
|
+
* const items = Observable.array([]);
|
|
3316
|
+
* items.isEmpty(); // true
|
|
3317
|
+
*/
|
|
2957
3318
|
ObservableArray.prototype.isEmpty = function() {
|
|
2958
3319
|
return this.$currentValue.length === 0;
|
|
2959
3320
|
};
|
|
2960
3321
|
|
|
3322
|
+
/**
|
|
3323
|
+
* Triggers a populate operation with the current array, iteration count, and callback.
|
|
3324
|
+
* Used internally for rendering optimizations.
|
|
3325
|
+
*
|
|
3326
|
+
* @param {number} iteration - Iteration count for rendering
|
|
3327
|
+
* @param {Function} callback - Callback function for rendering items
|
|
3328
|
+
*/
|
|
2961
3329
|
ObservableArray.prototype.populateAndRender = function(iteration, callback) {
|
|
2962
3330
|
this.trigger({ action: 'populate', args: [this.$currentValue, iteration, callback] });
|
|
2963
3331
|
};
|
|
2964
3332
|
|
|
2965
3333
|
|
|
3334
|
+
/**
|
|
3335
|
+
* Creates a filtered view of the array based on predicates.
|
|
3336
|
+
* The filtered array updates automatically when source data or predicates change.
|
|
3337
|
+
*
|
|
3338
|
+
* @param {Object} predicates - Object mapping property names to filter conditions or functions
|
|
3339
|
+
* @returns {ObservableArray} A new observable array containing filtered items
|
|
3340
|
+
* @example
|
|
3341
|
+
* const users = Observable.array([
|
|
3342
|
+
* { name: 'John', age: 25 },
|
|
3343
|
+
* { name: 'Jane', age: 30 }
|
|
3344
|
+
* ]);
|
|
3345
|
+
* const adults = users.where({ age: (val) => val >= 18 });
|
|
3346
|
+
*/
|
|
2966
3347
|
ObservableArray.prototype.where = function(predicates) {
|
|
2967
3348
|
const sourceArray = this;
|
|
2968
3349
|
const observableDependencies = [sourceArray];
|
|
@@ -3011,6 +3392,20 @@ var NativeDocument = (function (exports) {
|
|
|
3011
3392
|
return viewArray;
|
|
3012
3393
|
};
|
|
3013
3394
|
|
|
3395
|
+
/**
|
|
3396
|
+
* Creates a filtered view where at least one of the specified fields matches the filter.
|
|
3397
|
+
*
|
|
3398
|
+
* @param {Array<string>} fields - Array of field names to check
|
|
3399
|
+
* @param {FilterResult} filter - Filter condition with callback and dependencies
|
|
3400
|
+
* @returns {ObservableArray} A new observable array containing filtered items
|
|
3401
|
+
* @example
|
|
3402
|
+
* const products = Observable.array([
|
|
3403
|
+
* { name: 'Apple', category: 'Fruit' },
|
|
3404
|
+
* { name: 'Carrot', category: 'Vegetable' }
|
|
3405
|
+
* ]);
|
|
3406
|
+
* const searchTerm = Observable('App');
|
|
3407
|
+
* const filtered = products.whereSome(['name', 'category'], match(searchTerm));
|
|
3408
|
+
*/
|
|
3014
3409
|
ObservableArray.prototype.whereSome = function(fields, filter) {
|
|
3015
3410
|
return this.where({
|
|
3016
3411
|
_: {
|
|
@@ -3020,6 +3415,20 @@ var NativeDocument = (function (exports) {
|
|
|
3020
3415
|
});
|
|
3021
3416
|
};
|
|
3022
3417
|
|
|
3418
|
+
/**
|
|
3419
|
+
* Creates a filtered view where all specified fields match the filter.
|
|
3420
|
+
*
|
|
3421
|
+
* @param {Array<string>} fields - Array of field names to check
|
|
3422
|
+
* @param {FilterResult} filter - Filter condition with callback and dependencies
|
|
3423
|
+
* @returns {ObservableArray} A new observable array containing filtered items
|
|
3424
|
+
* @example
|
|
3425
|
+
* const items = Observable.array([
|
|
3426
|
+
* { status: 'active', verified: true },
|
|
3427
|
+
* { status: 'active', verified: false }
|
|
3428
|
+
* ]);
|
|
3429
|
+
* const activeFilter = equals('active');
|
|
3430
|
+
* const filtered = items.whereEvery(['status', 'verified'], activeFilter);
|
|
3431
|
+
*/
|
|
3023
3432
|
ObservableArray.prototype.whereEvery = function(fields, filter) {
|
|
3024
3433
|
return this.where({
|
|
3025
3434
|
_: {
|
|
@@ -3030,10 +3439,19 @@ var NativeDocument = (function (exports) {
|
|
|
3030
3439
|
};
|
|
3031
3440
|
|
|
3032
3441
|
/**
|
|
3442
|
+
* Creates an observable array with reactive array methods.
|
|
3443
|
+
* All mutations trigger updates automatically.
|
|
3033
3444
|
*
|
|
3034
|
-
* @param {Array} target
|
|
3035
|
-
* @param {
|
|
3036
|
-
* @
|
|
3445
|
+
* @param {Array} [target=[]] - Initial array value
|
|
3446
|
+
* @param {Object|null} [configs=null] - Configuration options
|
|
3447
|
+
* // @param {boolean} [configs.propagation=true] - Whether to propagate changes to parent observables
|
|
3448
|
+
* // @param {boolean} [configs.deep=false] - Whether to make nested objects observable
|
|
3449
|
+
* @param {boolean} [configs.reset=false] - Whether to store initial value for reset()
|
|
3450
|
+
* @returns {ObservableArray} An observable array with reactive methods
|
|
3451
|
+
* @example
|
|
3452
|
+
* const items = Observable.array([1, 2, 3]);
|
|
3453
|
+
* items.push(4); // Triggers update
|
|
3454
|
+
* items.subscribe((arr) => console.log(arr));
|
|
3037
3455
|
*/
|
|
3038
3456
|
Observable.array = function(target = [], configs = null) {
|
|
3039
3457
|
return new ObservableArray(target, configs);
|
|
@@ -3098,10 +3516,26 @@ var NativeDocument = (function (exports) {
|
|
|
3098
3516
|
};
|
|
3099
3517
|
|
|
3100
3518
|
/**
|
|
3519
|
+
* Creates an observable proxy for an object where each property becomes an observable.
|
|
3520
|
+
* Properties can be accessed directly or via getter methods.
|
|
3101
3521
|
*
|
|
3102
|
-
* @param {Object} initialValue
|
|
3103
|
-
* @param {
|
|
3104
|
-
* @
|
|
3522
|
+
* @param {Object} initialValue - Initial object value
|
|
3523
|
+
* @param {Object|null} [configs=null] - Configuration options
|
|
3524
|
+
* // @param {boolean} [configs.propagation=true] - Whether changes propagate to parent
|
|
3525
|
+
* @param {boolean} [configs.deep=false] - Whether to make nested objects observable
|
|
3526
|
+
* @param {boolean} [configs.reset=false] - Whether to enable reset() method
|
|
3527
|
+
* @returns {ObservableProxy} A proxy where each property is an observable
|
|
3528
|
+
* @example
|
|
3529
|
+
* const user = Observable.init({
|
|
3530
|
+
* name: 'John',
|
|
3531
|
+
* age: 25,
|
|
3532
|
+
* address: { city: 'NYC' }
|
|
3533
|
+
* }, { deep: true });
|
|
3534
|
+
*
|
|
3535
|
+
* user.name.val(); // 'John'
|
|
3536
|
+
* user.name.set('Jane');
|
|
3537
|
+
* user.name = 'Jane X'
|
|
3538
|
+
* user.age.subscribe(val => console.log('Age:', val));
|
|
3105
3539
|
*/
|
|
3106
3540
|
Observable.init = function(initialValue, configs = null) {
|
|
3107
3541
|
const data = {};
|
|
@@ -3249,17 +3683,30 @@ var NativeDocument = (function (exports) {
|
|
|
3249
3683
|
Observable.json = Observable.init;
|
|
3250
3684
|
|
|
3251
3685
|
/**
|
|
3686
|
+
* Creates a computed observable that automatically updates when its dependencies change.
|
|
3687
|
+
* The callback is re-executed whenever any dependency observable changes.
|
|
3252
3688
|
*
|
|
3253
|
-
* @param {Function} callback
|
|
3254
|
-
* @param {Array|Function} dependencies
|
|
3255
|
-
* @returns {ObservableItem}
|
|
3256
|
-
|
|
3689
|
+
* @param {Function} callback - Function that returns the computed value
|
|
3690
|
+
* @param {Array<ObservableItem|ObservableChecker|ObservableProxy>|Function} [dependencies=[]] - Array of observables to watch, or batch function
|
|
3691
|
+
* @returns {ObservableItem} A new observable that updates automatically
|
|
3692
|
+
* @example
|
|
3693
|
+
* const firstName = Observable('John');
|
|
3694
|
+
* const lastName = Observable('Doe');
|
|
3695
|
+
* const fullName = Observable.computed(
|
|
3696
|
+
* () => `${firstName.val()} ${lastName.val()}`,
|
|
3697
|
+
* [firstName, lastName]
|
|
3698
|
+
* );
|
|
3699
|
+
*
|
|
3700
|
+
* // With batch function
|
|
3701
|
+
* const batch = Observable.batch(() => { ... });
|
|
3702
|
+
* const computed = Observable.computed(() => { ... }, batch);
|
|
3703
|
+
*/
|
|
3257
3704
|
Observable.computed = function(callback, dependencies = []) {
|
|
3258
3705
|
const initialValue = callback();
|
|
3259
3706
|
const observable = new ObservableItem(initialValue);
|
|
3260
3707
|
const updatedValue = nextTick(() => observable.set(callback()));
|
|
3261
3708
|
{
|
|
3262
|
-
PluginsManager.emit('CreateObservableComputed', observable, dependencies);
|
|
3709
|
+
PluginsManager$1.emit('CreateObservableComputed', observable, dependencies);
|
|
3263
3710
|
}
|
|
3264
3711
|
|
|
3265
3712
|
if(Validator.isFunction(dependencies)) {
|
|
@@ -3357,12 +3804,24 @@ var NativeDocument = (function (exports) {
|
|
|
3357
3804
|
}());
|
|
3358
3805
|
|
|
3359
3806
|
/**
|
|
3807
|
+
* Renders a list of items from an observable array or object, automatically updating when data changes.
|
|
3808
|
+
* Efficiently manages DOM updates by tracking items with keys.
|
|
3360
3809
|
*
|
|
3361
|
-
* @param {Array|Object
|
|
3362
|
-
* @param {Function} callback
|
|
3363
|
-
* @param {
|
|
3364
|
-
* @param {{
|
|
3365
|
-
* @
|
|
3810
|
+
* @param {ObservableItem<Array|Object>} data - Observable containing array or object to iterate over
|
|
3811
|
+
* @param {Function} callback - Function that renders each item (item, index) => ValidChild
|
|
3812
|
+
* @param {string|Function} [key] - Property name or function to generate unique keys for items
|
|
3813
|
+
* @param {Object} [options={}] - Configuration options
|
|
3814
|
+
* @param {boolean} [options.shouldKeepItemsInCache=false] - Whether to cache rendered items
|
|
3815
|
+
* @returns {AnchorDocumentFragment} Fragment managing the list rendering
|
|
3816
|
+
* @example
|
|
3817
|
+
* const users = Observable([
|
|
3818
|
+
* { id: 1, name: 'John' },
|
|
3819
|
+
* { id: 2, name: 'Jane' }
|
|
3820
|
+
* ]);
|
|
3821
|
+
* ForEach(users, (user) => Div({}, user.name), 'id');
|
|
3822
|
+
*
|
|
3823
|
+
* // With function key
|
|
3824
|
+
* ForEach(items, (item) => Div({}, item), (item) => item.id);
|
|
3366
3825
|
*/
|
|
3367
3826
|
function ForEach(data, callback, key, { shouldKeepItemsInCache = false } = {}) {
|
|
3368
3827
|
const element = Anchor('ForEach');
|
|
@@ -3419,7 +3878,7 @@ var NativeDocument = (function (exports) {
|
|
|
3419
3878
|
}
|
|
3420
3879
|
cache.set(keyId, { keyId, isNew: true, child: new WeakRef(child), indexObserver});
|
|
3421
3880
|
} catch (e) {
|
|
3422
|
-
DebugManager.error('ForEach', `Error creating element for key ${keyId}` , e);
|
|
3881
|
+
DebugManager$1.error('ForEach', `Error creating element for key ${keyId}` , e);
|
|
3423
3882
|
throw e;
|
|
3424
3883
|
}
|
|
3425
3884
|
return keyId;
|
|
@@ -3501,8 +3960,26 @@ var NativeDocument = (function (exports) {
|
|
|
3501
3960
|
return element;
|
|
3502
3961
|
}
|
|
3503
3962
|
|
|
3963
|
+
/**
|
|
3964
|
+
* Renders items from an ObservableArray with optimized array-specific updates.
|
|
3965
|
+
* Provides index observables and handles array mutations efficiently.
|
|
3966
|
+
*
|
|
3967
|
+
* @param {ObservableArray} data - ObservableArray to iterate over
|
|
3968
|
+
* @param {Function} callback - Function that renders each item (item, indexObservable) => ValidChild
|
|
3969
|
+
* @param {Object} [configs={}] - Configuration options
|
|
3970
|
+
* @param {boolean} [configs.shouldKeepItemsInCache] - Whether to cache rendered items
|
|
3971
|
+
* @param {boolean} [configs.isParentUniqueChild] - When it's the only child of the parent
|
|
3972
|
+
* @returns {AnchorDocumentFragment} Fragment managing the list rendering
|
|
3973
|
+
* @example
|
|
3974
|
+
* const items = Observable.array([1, 2, 3]);
|
|
3975
|
+
* ForEachArray(items, (item, index) =>
|
|
3976
|
+
* Div({}, `Item ${item} at index ${index.val()}`)
|
|
3977
|
+
* );
|
|
3978
|
+
*
|
|
3979
|
+
* items.push(4); // Automatically updates DOM
|
|
3980
|
+
*/
|
|
3504
3981
|
function ForEachArray(data, callback, configs = {}) {
|
|
3505
|
-
const element = Anchor('ForEach Array');
|
|
3982
|
+
const element = Anchor('ForEach Array', configs.isParentUniqueChild);
|
|
3506
3983
|
const blockEnd = element.endElement();
|
|
3507
3984
|
const blockStart = element.startElement();
|
|
3508
3985
|
|
|
@@ -3677,7 +4154,7 @@ var NativeDocument = (function (exports) {
|
|
|
3677
4154
|
elementBeforeFirst = firstChildRemoved?.previousSibling;
|
|
3678
4155
|
|
|
3679
4156
|
for(let i = 0; i < deleted.length; i++) {
|
|
3680
|
-
|
|
4157
|
+
removeByItem(deleted[i], garbageFragment);
|
|
3681
4158
|
}
|
|
3682
4159
|
}
|
|
3683
4160
|
} else {
|
|
@@ -3723,7 +4200,7 @@ var NativeDocument = (function (exports) {
|
|
|
3723
4200
|
};
|
|
3724
4201
|
|
|
3725
4202
|
const buildContent = (items, _, operations) => {
|
|
3726
|
-
if(operations
|
|
4203
|
+
if(operations?.action === 'clear' || !items.length) {
|
|
3727
4204
|
if(lastNumberOfItems === 0) {
|
|
3728
4205
|
return;
|
|
3729
4206
|
}
|
|
@@ -3756,16 +4233,22 @@ var NativeDocument = (function (exports) {
|
|
|
3756
4233
|
}
|
|
3757
4234
|
|
|
3758
4235
|
/**
|
|
3759
|
-
*
|
|
4236
|
+
* Conditionally shows an element based on an observable condition.
|
|
4237
|
+
* The element is mounted/unmounted from the DOM as the condition changes.
|
|
3760
4238
|
*
|
|
3761
|
-
* @param {ObservableItem
|
|
3762
|
-
* @param {
|
|
3763
|
-
* @param {{
|
|
3764
|
-
* @
|
|
4239
|
+
* @param {ObservableItem<boolean>|ObservableChecker<boolean>|ObservableWhen} condition - Observable condition to watch
|
|
4240
|
+
* @param {ValidChild} child - Element or content to show/hide
|
|
4241
|
+
* @param {Object} [options={}] - Configuration options
|
|
4242
|
+
* @param {string|null} [options.comment=null] - Comment for debugging
|
|
4243
|
+
* @param {boolean} [options.shouldKeepInCache=true] - Whether to cache the element when hidden
|
|
4244
|
+
* @returns {AnchorDocumentFragment} Anchor fragment managing the conditional content
|
|
4245
|
+
* @example
|
|
4246
|
+
* const isVisible = Observable(false);
|
|
4247
|
+
* ShowIf(isVisible, Div({}, 'Hello World'));
|
|
3765
4248
|
*/
|
|
3766
4249
|
const ShowIf = function(condition, child, { comment = null, shouldKeepInCache = true} = {}) {
|
|
3767
4250
|
if(!(Validator.isObservable(condition)) && !Validator.isObservableWhenResult(condition)) {
|
|
3768
|
-
return DebugManager.warn('ShowIf', "ShowIf : condition must be an Observable / "+comment, condition);
|
|
4251
|
+
return DebugManager$1.warn('ShowIf', "ShowIf : condition must be an Observable / "+comment, condition);
|
|
3769
4252
|
}
|
|
3770
4253
|
const element = Anchor('Show if : '+(comment || ''));
|
|
3771
4254
|
|
|
@@ -3798,11 +4281,18 @@ var NativeDocument = (function (exports) {
|
|
|
3798
4281
|
};
|
|
3799
4282
|
|
|
3800
4283
|
/**
|
|
3801
|
-
*
|
|
3802
|
-
*
|
|
3803
|
-
*
|
|
3804
|
-
* @param {
|
|
3805
|
-
* @
|
|
4284
|
+
* Conditionally hides an element when the observable condition is true.
|
|
4285
|
+
* Inverse of ShowIf - element is shown when condition is false.
|
|
4286
|
+
*
|
|
4287
|
+
* @param {ObservableItem<boolean>|ObservableChecker<boolean>} condition - Observable condition to watch
|
|
4288
|
+
* @param {ValidChild} child - Element or content to show/hide
|
|
4289
|
+
* @param {Object} [configs] - Configuration options
|
|
4290
|
+
* @param {string|null} [configs.comment] - Comment for debugging
|
|
4291
|
+
* @param {boolean} [configs.shouldKeepInCache] - Whether to cache element when hidden
|
|
4292
|
+
* @returns {AnchorDocumentFragment} Anchor fragment managing the conditional content
|
|
4293
|
+
* @example
|
|
4294
|
+
* const hasError = Observable(false);
|
|
4295
|
+
* HideIf(hasError, Div({}, 'Content'));
|
|
3806
4296
|
*/
|
|
3807
4297
|
const HideIf = function(condition, child, configs) {
|
|
3808
4298
|
const hideCondition = Observable(!condition.val());
|
|
@@ -3812,17 +4302,43 @@ var NativeDocument = (function (exports) {
|
|
|
3812
4302
|
};
|
|
3813
4303
|
|
|
3814
4304
|
/**
|
|
3815
|
-
*
|
|
4305
|
+
* Conditionally hides an element when the observable condition is false.
|
|
4306
|
+
* Same as ShowIf - element is shown when condition is true.
|
|
3816
4307
|
*
|
|
3817
|
-
* @param {ObservableItem
|
|
3818
|
-
* @param {
|
|
3819
|
-
* @param {
|
|
3820
|
-
* @
|
|
4308
|
+
* @param {ObservableItem<boolean>|ObservableChecker<boolean>|ObservableWhen} condition - Observable condition to watch
|
|
4309
|
+
* @param {ValidChild} child - Element or content to show/hide
|
|
4310
|
+
* @param {Object} [configs] - Configuration options
|
|
4311
|
+
* @param {string|null} [configs.comment] - Comment for debugging
|
|
4312
|
+
* @param {boolean} [configs.shouldKeepInCache] - Whether to cache element when hidden
|
|
4313
|
+
* @returns {AnchorDocumentFragment} Anchor fragment managing the conditional content
|
|
3821
4314
|
*/
|
|
3822
4315
|
const HideIfNot = function(condition, child, configs) {
|
|
3823
4316
|
return ShowIf(condition, child, configs);
|
|
3824
4317
|
};
|
|
3825
4318
|
|
|
4319
|
+
/**
|
|
4320
|
+
* Shows content when an observable equals a specific value.
|
|
4321
|
+
* Can be called with 2 or 3 arguments.
|
|
4322
|
+
*
|
|
4323
|
+
* @overload
|
|
4324
|
+
* @param {ObservableWhen} observerWhenResult - Result from observable.when(value)
|
|
4325
|
+
* @param {ValidChild} view - Content to show when condition matches
|
|
4326
|
+
* @returns {AnchorDocumentFragment}
|
|
4327
|
+
*
|
|
4328
|
+
* @overload
|
|
4329
|
+
* @param {ObservableItem} observer - Observable to watch
|
|
4330
|
+
* @param {*} target - Value to match
|
|
4331
|
+
* @param {ValidChild} view - Content to show when observable equals target
|
|
4332
|
+
* @returns {AnchorDocumentFragment}
|
|
4333
|
+
*
|
|
4334
|
+
* @example
|
|
4335
|
+
* // 2 arguments
|
|
4336
|
+
* const status = Observable('idle');
|
|
4337
|
+
* ShowWhen(status.when('loading'), LoadingSpinner());
|
|
4338
|
+
*
|
|
4339
|
+
* // 3 arguments
|
|
4340
|
+
* ShowWhen(status, 'loading', LoadingSpinner());
|
|
4341
|
+
*/
|
|
3826
4342
|
const ShowWhen = function() {
|
|
3827
4343
|
if(arguments.length === 2) {
|
|
3828
4344
|
const [observer, target] = arguments;
|
|
@@ -3852,11 +4368,24 @@ var NativeDocument = (function (exports) {
|
|
|
3852
4368
|
};
|
|
3853
4369
|
|
|
3854
4370
|
/**
|
|
4371
|
+
* Displays different content based on the current value of an observable.
|
|
4372
|
+
* Like a switch statement for UI - shows the content corresponding to current value.
|
|
3855
4373
|
*
|
|
3856
|
-
* @param {ObservableItem|ObservableChecker} $condition
|
|
3857
|
-
* @param {
|
|
3858
|
-
* @param {
|
|
3859
|
-
* @returns {
|
|
4374
|
+
* @param {ObservableItem|ObservableChecker} $condition - Observable to watch
|
|
4375
|
+
* @param {Object<string|number, ValidChild>} values - Map of values to their corresponding content
|
|
4376
|
+
* @param {boolean} [shouldKeepInCache=true] - Whether to cache rendered views
|
|
4377
|
+
* @returns {AnchorDocumentFragment & {add: Function, remove: Function}} Fragment with dynamic methods
|
|
4378
|
+
* @example
|
|
4379
|
+
* const status = Observable('idle');
|
|
4380
|
+
* const view = Match(status, {
|
|
4381
|
+
* idle: Div({}, 'Ready'),
|
|
4382
|
+
* loading: Div({}, 'Loading...'),
|
|
4383
|
+
* error: Div({}, 'Error occurred')
|
|
4384
|
+
* });
|
|
4385
|
+
*
|
|
4386
|
+
* // Dynamic addition
|
|
4387
|
+
* view.add('success', Div({}, 'Success!'));
|
|
4388
|
+
* view.remove('idle');
|
|
3860
4389
|
*/
|
|
3861
4390
|
const Match = function($condition, values, shouldKeepInCache = true) {
|
|
3862
4391
|
|
|
@@ -3913,11 +4442,19 @@ var NativeDocument = (function (exports) {
|
|
|
3913
4442
|
|
|
3914
4443
|
|
|
3915
4444
|
/**
|
|
4445
|
+
* Displays one of two views based on a boolean observable condition.
|
|
4446
|
+
* Simplified version of Match for true/false cases.
|
|
3916
4447
|
*
|
|
3917
|
-
* @param {ObservableItem
|
|
3918
|
-
* @param {
|
|
3919
|
-
* @param {
|
|
3920
|
-
* @returns {
|
|
4448
|
+
* @param {ObservableItem<boolean>|ObservableChecker<boolean>} $condition - Boolean observable to watch
|
|
4449
|
+
* @param {ValidChild} onTrue - Content to show when condition is true
|
|
4450
|
+
* @param {ValidChild} onFalse - Content to show when condition is false
|
|
4451
|
+
* @returns {AnchorDocumentFragment} Fragment managing the conditional content
|
|
4452
|
+
* @example
|
|
4453
|
+
* const isLoggedIn = Observable(false);
|
|
4454
|
+
* Switch(isLoggedIn,
|
|
4455
|
+
* Div({}, 'Welcome back!'),
|
|
4456
|
+
* Div({}, 'Please login')
|
|
4457
|
+
* );
|
|
3921
4458
|
*/
|
|
3922
4459
|
const Switch = function ($condition, onTrue, onFalse) {
|
|
3923
4460
|
if(!Validator.isObservable($condition)) {
|
|
@@ -3931,9 +4468,15 @@ var NativeDocument = (function (exports) {
|
|
|
3931
4468
|
};
|
|
3932
4469
|
|
|
3933
4470
|
/**
|
|
4471
|
+
* Provides a fluent API for conditional rendering with show/otherwise pattern.
|
|
3934
4472
|
*
|
|
3935
|
-
* @param {ObservableItem
|
|
3936
|
-
* @returns {{show: Function, otherwise:
|
|
4473
|
+
* @param {ObservableItem<boolean>|ObservableChecker<boolean>} $condition - Boolean observable to watch
|
|
4474
|
+
* @returns {{show: Function, otherwise: Function}} Object with fluent methods
|
|
4475
|
+
* @example
|
|
4476
|
+
* const isLoading = Observable(false);
|
|
4477
|
+
* When(isLoading)
|
|
4478
|
+
* .show(LoadingSpinner())
|
|
4479
|
+
* .otherwise(Content());
|
|
3937
4480
|
*/
|
|
3938
4481
|
const When = function($condition) {
|
|
3939
4482
|
if(!Validator.isObservable($condition)) {
|
|
@@ -3951,6 +4494,9 @@ var NativeDocument = (function (exports) {
|
|
|
3951
4494
|
otherwise(onFalse) {
|
|
3952
4495
|
$onFalse = onFalse;
|
|
3953
4496
|
return Switch($condition, $onTrue, $onFalse);
|
|
4497
|
+
},
|
|
4498
|
+
toNdElement() {
|
|
4499
|
+
return Switch($condition, $onTrue, $onFalse);
|
|
3954
4500
|
}
|
|
3955
4501
|
}
|
|
3956
4502
|
};
|
|
@@ -4290,11 +4836,16 @@ var NativeDocument = (function (exports) {
|
|
|
4290
4836
|
};
|
|
4291
4837
|
|
|
4292
4838
|
/**
|
|
4839
|
+
* Creates a new Route instance.
|
|
4293
4840
|
*
|
|
4294
|
-
* @param {string} $path
|
|
4295
|
-
* @param {Function} $component
|
|
4296
|
-
* @param {
|
|
4297
|
-
* @
|
|
4841
|
+
* @param {string} $path - URL pattern with optional parameters (e.g., '/user/{id:number}')
|
|
4842
|
+
* @param {Function} $component - Component function that returns HTMLElement or DocumentFragment
|
|
4843
|
+
* @param {Object} [$options={}] - Route configuration options
|
|
4844
|
+
* @param {string} [$options.name] - Unique name for the route (used for navigation)
|
|
4845
|
+
* @param {Function[]} [$options.middlewares] - Array of middleware functions
|
|
4846
|
+
* @param {boolean} [$options.shouldRebuild] - Whether to rebuild component on each navigation
|
|
4847
|
+
* @param {Object} [$options.with] - Custom parameter validation patterns
|
|
4848
|
+
* @param {Function} [$options.layout] - Layout component wrapper function
|
|
4298
4849
|
*/
|
|
4299
4850
|
function Route($path, $component, $options = {}) {
|
|
4300
4851
|
|
|
@@ -4393,7 +4944,6 @@ var NativeDocument = (function (exports) {
|
|
|
4393
4944
|
super(message);
|
|
4394
4945
|
this.context = context;
|
|
4395
4946
|
}
|
|
4396
|
-
|
|
4397
4947
|
}
|
|
4398
4948
|
|
|
4399
4949
|
const RouteGroupHelper = {
|
|
@@ -4552,7 +5102,7 @@ var NativeDocument = (function (exports) {
|
|
|
4552
5102
|
window.history.pushState({ name: route.name(), params, path}, route.name() || path , path);
|
|
4553
5103
|
this.handleRouteChange(route, params, query, path);
|
|
4554
5104
|
} catch (e) {
|
|
4555
|
-
DebugManager.error('HistoryRouter', 'Error in pushState', e);
|
|
5105
|
+
DebugManager$1.error('HistoryRouter', 'Error in pushState', e);
|
|
4556
5106
|
}
|
|
4557
5107
|
};
|
|
4558
5108
|
/**
|
|
@@ -4565,7 +5115,7 @@ var NativeDocument = (function (exports) {
|
|
|
4565
5115
|
window.history.replaceState({ name: route.name(), params, path}, route.name() || path , path);
|
|
4566
5116
|
this.handleRouteChange(route, params, {}, path);
|
|
4567
5117
|
} catch(e) {
|
|
4568
|
-
DebugManager.error('HistoryRouter', 'Error in replaceState', e);
|
|
5118
|
+
DebugManager$1.error('HistoryRouter', 'Error in replaceState', e);
|
|
4569
5119
|
}
|
|
4570
5120
|
};
|
|
4571
5121
|
this.forward = function() {
|
|
@@ -4592,7 +5142,7 @@ var NativeDocument = (function (exports) {
|
|
|
4592
5142
|
}
|
|
4593
5143
|
this.handleRouteChange(route, params, query, path);
|
|
4594
5144
|
} catch(e) {
|
|
4595
|
-
DebugManager.error('HistoryRouter', 'Error in popstate event', e);
|
|
5145
|
+
DebugManager$1.error('HistoryRouter', 'Error in popstate event', e);
|
|
4596
5146
|
}
|
|
4597
5147
|
});
|
|
4598
5148
|
const { route, params, query, path } = this.resolve(defaultPath || (window.location.pathname+window.location.search));
|
|
@@ -4789,7 +5339,7 @@ var NativeDocument = (function (exports) {
|
|
|
4789
5339
|
/**
|
|
4790
5340
|
*
|
|
4791
5341
|
* @param {{mode: 'memory'|'history'|'hash'}} $options
|
|
4792
|
-
* @
|
|
5342
|
+
* @class
|
|
4793
5343
|
*/
|
|
4794
5344
|
function Router($options = {}) {
|
|
4795
5345
|
|
|
@@ -4817,7 +5367,7 @@ var NativeDocument = (function (exports) {
|
|
|
4817
5367
|
listener(request);
|
|
4818
5368
|
next && next(request);
|
|
4819
5369
|
} catch (e) {
|
|
4820
|
-
DebugManager.warn('Route Listener', 'Error in listener:', e);
|
|
5370
|
+
DebugManager$1.warn('Route Listener', 'Error in listener:', e);
|
|
4821
5371
|
}
|
|
4822
5372
|
}
|
|
4823
5373
|
};
|
|
@@ -4847,11 +5397,20 @@ var NativeDocument = (function (exports) {
|
|
|
4847
5397
|
};
|
|
4848
5398
|
|
|
4849
5399
|
/**
|
|
5400
|
+
* Groups routes under a common path prefix with shared options.
|
|
4850
5401
|
*
|
|
4851
|
-
* @param {string} suffix
|
|
4852
|
-
* @param {
|
|
4853
|
-
* @param {Function}
|
|
4854
|
-
* @
|
|
5402
|
+
* @param {string} suffix - Path prefix to prepend to all routes in the group
|
|
5403
|
+
* @param {Object} options - Group configuration options
|
|
5404
|
+
* @param {Function[]} [options.middlewares] - Middlewares applied to all routes in group
|
|
5405
|
+
* @param {string} [options.name] - Name prefix for all routes in group
|
|
5406
|
+
* @param {Function} [options.layout] - Layout component for all routes in group
|
|
5407
|
+
* @param {Function} callback - Function that defines routes within the group
|
|
5408
|
+
* @returns {this} Router instance for chaining
|
|
5409
|
+
* @example
|
|
5410
|
+
* router.group('/admin', { middlewares: [authMiddleware], layout: AdminLayout }, () => {
|
|
5411
|
+
* router.add('/users', UsersPage, { name: 'users' });
|
|
5412
|
+
* router.add('/settings', SettingsPage, { name: 'settings' });
|
|
5413
|
+
* });
|
|
4855
5414
|
*/
|
|
4856
5415
|
this.group = function(suffix, options, callback) {
|
|
4857
5416
|
if(!Validator.isFunction(callback)) {
|
|
@@ -4969,14 +5528,24 @@ var NativeDocument = (function (exports) {
|
|
|
4969
5528
|
Router.routers = {};
|
|
4970
5529
|
|
|
4971
5530
|
/**
|
|
5531
|
+
* Creates and initializes a new router instance.
|
|
4972
5532
|
*
|
|
4973
|
-
* @param {
|
|
4974
|
-
* @param {
|
|
4975
|
-
* @param {
|
|
5533
|
+
* @param {Object} options - Router configuration
|
|
5534
|
+
* @param {'memory'|'history'|'hash'} options.mode - Routing mode
|
|
5535
|
+
* @param {string} [options.name] - Router name for multi-router apps
|
|
5536
|
+
* @param {string} [options.entry] - Initial route path
|
|
5537
|
+
* @param {Function} callback - Setup function that receives the router instance
|
|
5538
|
+
* @returns {Router} The configured router instance with mount() method
|
|
5539
|
+
* @example
|
|
5540
|
+
* const router = Router.create({ mode: 'history' }, (r) => {
|
|
5541
|
+
* r.add('/home', HomePage, { name: 'home' });
|
|
5542
|
+
* r.add('/about', AboutPage, { name: 'about' });
|
|
5543
|
+
* });
|
|
5544
|
+
* router.mount('#app');
|
|
4976
5545
|
*/
|
|
4977
5546
|
Router.create = function(options, callback) {
|
|
4978
5547
|
if(!Validator.isFunction(callback)) {
|
|
4979
|
-
DebugManager.error('Router', 'Callback must be a function'
|
|
5548
|
+
DebugManager$1.error('Router', 'Callback must be a function');
|
|
4980
5549
|
throw new RouterError('Callback must be a function');
|
|
4981
5550
|
}
|
|
4982
5551
|
const router = new Router(options);
|
|
@@ -5143,16 +5712,22 @@ var NativeDocument = (function (exports) {
|
|
|
5143
5712
|
};
|
|
5144
5713
|
}
|
|
5145
5714
|
|
|
5146
|
-
const
|
|
5147
|
-
|
|
5148
|
-
|
|
5149
|
-
|
|
5715
|
+
const once = fn => autoOnce(fn);
|
|
5716
|
+
const singleton = fn => once$1(fn);
|
|
5717
|
+
const memoize = fn => autoMemoize(fn);
|
|
5718
|
+
|
|
5719
|
+
var cache = /*#__PURE__*/Object.freeze({
|
|
5720
|
+
__proto__: null,
|
|
5721
|
+
memoize: memoize,
|
|
5722
|
+
once: once,
|
|
5723
|
+
singleton: singleton
|
|
5724
|
+
});
|
|
5150
5725
|
|
|
5151
5726
|
var utils = /*#__PURE__*/Object.freeze({
|
|
5152
5727
|
__proto__: null,
|
|
5153
|
-
|
|
5728
|
+
Cache: cache,
|
|
5154
5729
|
NativeFetch: NativeFetch,
|
|
5155
|
-
|
|
5730
|
+
filters: index
|
|
5156
5731
|
});
|
|
5157
5732
|
|
|
5158
5733
|
exports.$ = $;
|
|
@@ -5160,7 +5735,7 @@ var NativeDocument = (function (exports) {
|
|
|
5160
5735
|
exports.HtmlElementWrapper = HtmlElementWrapper;
|
|
5161
5736
|
exports.NDElement = NDElement;
|
|
5162
5737
|
exports.Observable = Observable;
|
|
5163
|
-
exports.PluginsManager = PluginsManager;
|
|
5738
|
+
exports.PluginsManager = PluginsManager$1;
|
|
5164
5739
|
exports.SingletonView = SingletonView;
|
|
5165
5740
|
exports.Store = Store;
|
|
5166
5741
|
exports.TemplateCloner = TemplateCloner;
|
|
@@ -5171,10 +5746,10 @@ var NativeDocument = (function (exports) {
|
|
|
5171
5746
|
exports.createTextNode = createTextNode;
|
|
5172
5747
|
exports.cssPropertyAccumulator = cssPropertyAccumulator;
|
|
5173
5748
|
exports.elements = elements;
|
|
5174
|
-
exports.memoize = memoize;
|
|
5749
|
+
exports.memoize = memoize$1;
|
|
5175
5750
|
exports.normalizeComponentArgs = normalizeComponentArgs;
|
|
5176
5751
|
exports.obs = obs;
|
|
5177
|
-
exports.once = once;
|
|
5752
|
+
exports.once = once$1;
|
|
5178
5753
|
exports.router = router;
|
|
5179
5754
|
exports.useCache = useCache;
|
|
5180
5755
|
exports.useSingleton = useSingleton;
|