@wavemaker/app-ng-runtime 11.14.1-6.6324 → 11.14.1-8.6337

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (50) hide show
  1. package/components/base/bundles/index.umd.js +74 -7
  2. package/components/base/esm2022/pipes/custom-pipes.mjs +1 -1
  3. package/components/base/esm2022/widgets/common/base/base.component.mjs +67 -7
  4. package/components/base/esm2022/widgets/common/lazy-load/lazy-load.directive.mjs +4 -2
  5. package/components/base/esm2022/widgets/framework/property-change-handler.mjs +7 -2
  6. package/components/base/fesm2022/index.mjs +75 -8
  7. package/components/base/fesm2022/index.mjs.map +1 -1
  8. package/components/basic/label/bundles/index.umd.js +9 -1
  9. package/components/basic/label/esm2022/label.directive.mjs +10 -2
  10. package/components/basic/label/fesm2022/index.mjs +9 -1
  11. package/components/basic/label/fesm2022/index.mjs.map +1 -1
  12. package/components/data/pagination/bundles/index.umd.js +4 -0
  13. package/components/data/pagination/esm2022/pagination.component.mjs +5 -1
  14. package/components/data/pagination/fesm2022/index.mjs +4 -0
  15. package/components/data/pagination/fesm2022/index.mjs.map +1 -1
  16. package/components/data/table/bundles/index.umd.js +226 -13
  17. package/components/data/table/esm2022/table-cud.directive.mjs +2 -2
  18. package/components/data/table/esm2022/table-filter.directive.mjs +8 -2
  19. package/components/data/table/esm2022/table.component.mjs +219 -12
  20. package/components/data/table/fesm2022/index.mjs +226 -13
  21. package/components/data/table/fesm2022/index.mjs.map +1 -1
  22. package/components/data/table/table.component.d.ts +6 -2
  23. package/components/navigation/menu/bundles/index.umd.js +5 -0
  24. package/components/navigation/menu/esm2022/menu.component.mjs +6 -1
  25. package/components/navigation/menu/fesm2022/index.mjs +5 -0
  26. package/components/navigation/menu/fesm2022/index.mjs.map +1 -1
  27. package/components/navigation/popover/bundles/index.umd.js +6 -6
  28. package/components/navigation/popover/esm2022/popover.component.mjs +4 -4
  29. package/components/navigation/popover/fesm2022/index.mjs +3 -3
  30. package/components/navigation/popover/fesm2022/index.mjs.map +1 -1
  31. package/components/navigation/popover/popover.component.d.ts +6 -0
  32. package/core/bundles/index.umd.js +395 -82
  33. package/core/esm2022/public_api.mjs +2 -2
  34. package/core/esm2022/utils/watcher.mjs +392 -81
  35. package/core/fesm2022/index.mjs +395 -84
  36. package/core/fesm2022/index.mjs.map +1 -1
  37. package/core/public_api.d.ts +1 -1
  38. package/core/utils/watcher.d.ts +28 -5
  39. package/npm-shrinkwrap.json +2 -2
  40. package/package-lock.json +2 -2
  41. package/package.json +1 -1
  42. package/runtime/base/bundles/index.umd.js +20 -0
  43. package/runtime/base/esm2022/components/app-component/app.component.mjs +4 -2
  44. package/runtime/base/esm2022/components/base-page.component.mjs +6 -2
  45. package/runtime/base/esm2022/components/base-partial.component.mjs +7 -2
  46. package/runtime/base/esm2022/components/base-prefab.component.mjs +7 -2
  47. package/runtime/base/esm2022/components/base-spa-page.component.mjs +6 -2
  48. package/runtime/base/fesm2022/index.mjs +21 -1
  49. package/runtime/base/fesm2022/index.mjs.map +1 -1
  50. package/scripts/datatable/datatable.js +34 -2
@@ -1,5 +1,5 @@
1
1
  import { Attribute, ImplicitReceiver, PropertyRead, LiteralPrimitive, LiteralArray, LiteralMap, PropertyWrite, KeyedRead, PrefixNot, Unary, Binary, Conditional, Call, Chain, BindingPipe, Parser, Lexer } from '@angular/compiler';
2
- import { isArray, startsWith, includes, get, flatten, isEqual, isObject as isObject$1, clone, camelCase, split, map, attempt, isError, isFunction, isDate, isString, cloneDeep, identity, intersection, omit, keys, toLower, replace as replace$1, forEach, trim, isEqualWith, every, indexOf, isNumber, filter, isUndefined, isNull, noop as noop$2, toUpper, assign, merge, isEmpty, debounce as debounce$1, isNil } from 'lodash-es';
2
+ import { isArray, startsWith, includes, get, flatten, isEqual, clone, isObject as isObject$1, camelCase, split, map, attempt, isError, isFunction, isDate, isString, cloneDeep, identity, intersection, omit, keys, toLower, replace as replace$1, forEach, trim, isEqualWith, every, indexOf, isNumber, filter, isUndefined, isNull, noop as noop$2, toUpper, assign, merge, isEmpty, debounce as debounce$1, isNil } from 'lodash-es';
3
3
  import { Subject } from 'rxjs';
4
4
  import X2JS from 'x2js';
5
5
  import * as momentLib from 'moment-timezone/moment-timezone';
@@ -1432,11 +1432,11 @@ const CURRENCY_INFO = {
1432
1432
  }
1433
1433
  };
1434
1434
 
1435
- const $RAF$1 = window.requestAnimationFrame;
1435
+ const $RAF = window.requestAnimationFrame;
1436
1436
  const $RAFQueue = [];
1437
1437
  const invokeLater = fn => {
1438
1438
  if (!$RAFQueue.length) {
1439
- $RAF$1(() => {
1439
+ $RAF(() => {
1440
1440
  $RAFQueue.forEach(f => f());
1441
1441
  $RAFQueue.length = 0;
1442
1442
  });
@@ -2173,14 +2173,89 @@ const getFnForEventExpr = (expr) => {
2173
2173
  return fnExecutor(expr, ExpressionType.Action);
2174
2174
  };
2175
2175
 
2176
+ // Constants
2177
+ const WIDGET_ID_REGEX = /^(widget-[^_]+)/;
2178
+ const WIDGET_PROPERTY_REGEX = /^widget-[^_]+_(.+)$/;
2179
+ const ARRAY_INDEX_PLACEHOLDER = '[$i]';
2180
+ const ARRAY_INDEX_ZERO = '[0]';
2181
+ const DEBOUNCE_WAIT = 100;
2182
+ const MAX_WATCH_CYCLES = 5;
2176
2183
  const registry = new Map();
2177
2184
  const watchIdGenerator = new IDGenerator('watch-id-');
2178
- const FIRST_TIME_WATCH = {};
2179
- Object.freeze(FIRST_TIME_WATCH);
2180
- const isFirstTimeChange = v => v === FIRST_TIME_WATCH;
2185
+ const FIRST_TIME_WATCH = Object.freeze({});
2186
+ // State
2181
2187
  let muted = false;
2188
+ let changedByWatch = false;
2189
+ let skipWatchers = false;
2190
+ let ngZone;
2182
2191
  let appRef;
2183
- const debounce = (fn, wait = 50) => {
2192
+ /********************************************************************
2193
+ * CLEANUP SCHEDULER WITH:
2194
+ * - Significant watcher delta trigger (+/-)
2195
+ * - UI stabilization delay (1–2 seconds)
2196
+ * - Cooldown to prevent repeated scheduling
2197
+ ********************************************************************/
2198
+ const CLEANUP_TRIGGER_DELTA = 300; // watcher change threshold
2199
+ const CLEANUP_DELAY = 1500; // delay before running cleanup
2200
+ const CLEANUP_COOLDOWN = 4000; // prevent re-scheduling for 4s
2201
+ let lastWatcherCount = 0;
2202
+ let scheduledCleanup = null;
2203
+ let lastScheduledTime = 0;
2204
+ function getWatcherCount() {
2205
+ let count = 0;
2206
+ registry.forEach(bucket => count += bucket.size);
2207
+ return count;
2208
+ }
2209
+ const cleanupStaleWatchers = () => {
2210
+ // console.log(".........Cleaning up stale watchers...registry.size....", registry.size);
2211
+ let removed = 0;
2212
+ registry.forEach((bucket, widgetId) => {
2213
+ if (!document.querySelector(`[widget-id="${widgetId}"]`)) {
2214
+ for (const key in bucket) {
2215
+ if (bucket.hasOwnProperty(key) && key !== "scopeType" && key !== "scopeName" && typeof bucket[key] !== "function") {
2216
+ let watchInfo = bucket[key];
2217
+ if (watchInfo && watchInfo.destroyFn) {
2218
+ watchInfo.destroyFn();
2219
+ }
2220
+ }
2221
+ }
2222
+ removed++;
2223
+ registry.delete(widgetId);
2224
+ return;
2225
+ }
2226
+ });
2227
+ return removed;
2228
+ };
2229
+ const scheduleThresholdCleanup = () => {
2230
+ const now = performance.now();
2231
+ let lastTriggerPeriod = now - lastScheduledTime;
2232
+ // If a cleanup was scheduled recently, skip scheduling
2233
+ if (lastTriggerPeriod < CLEANUP_COOLDOWN) {
2234
+ return;
2235
+ }
2236
+ const current = getWatcherCount();
2237
+ const delta = Math.abs(current - lastWatcherCount); // significant + or -
2238
+ // If change not large enough, skip scheduling
2239
+ if (delta <= CLEANUP_TRIGGER_DELTA) {
2240
+ lastWatcherCount = current;
2241
+ return;
2242
+ }
2243
+ // Prevent re-scheduling: set timestamp early
2244
+ lastScheduledTime = now;
2245
+ // Clear previous scheduled cleanup (if any)
2246
+ if (scheduledCleanup) {
2247
+ clearTimeout(scheduledCleanup);
2248
+ }
2249
+ // Schedule cleanup after UI stabilizes (delay prevents aggressive cleanup)
2250
+ scheduledCleanup = setTimeout(() => {
2251
+ cleanupStaleWatchers();
2252
+ scheduledCleanup = null;
2253
+ }, CLEANUP_DELAY);
2254
+ lastWatcherCount = current;
2255
+ };
2256
+ // Utility functions
2257
+ const isFirstTimeChange = (v) => v === FIRST_TIME_WATCH;
2258
+ const debounce = (fn, wait = DEBOUNCE_WAIT) => {
2184
2259
  let timeout;
2185
2260
  return (...args) => {
2186
2261
  window['__zone_symbol__clearTimeout'](timeout);
@@ -2194,115 +2269,350 @@ const unMuteWatchers = () => {
2194
2269
  muted = false;
2195
2270
  triggerWatchers();
2196
2271
  };
2272
+ /**
2273
+ * Extracts widget ID from identifier (e.g., "widget-id23_eventsource" -> "widget-id23")
2274
+ */
2275
+ const getWidgetId = (identifier) => {
2276
+ if (!identifier || typeof identifier !== 'string') {
2277
+ return null;
2278
+ }
2279
+ const match = identifier.match(WIDGET_ID_REGEX);
2280
+ return match ? match[1] : null;
2281
+ };
2282
+ /**
2283
+ * Extracts property name from identifier (e.g., "widget-id23_eventsource" -> "eventsource")
2284
+ */
2285
+ const getPropertyName = (identifier) => {
2286
+ if (!identifier || typeof identifier !== 'string') {
2287
+ return identifier;
2288
+ }
2289
+ const match = identifier.match(WIDGET_PROPERTY_REGEX);
2290
+ return match ? match[1] : identifier;
2291
+ };
2292
+ /**
2293
+ * Array consumer wrapper for array-based expressions
2294
+ */
2197
2295
  const arrayConsumer = (listenerFn, restExpr, newVal, oldVal) => {
2198
- let data = newVal, formattedData;
2199
- if (isArray(data)) {
2200
- formattedData = data.map(function (datum) {
2201
- return findValueOf(datum, restExpr);
2202
- });
2203
- // If resulting structure is an array of array, flatten it
2204
- if (isArray(formattedData[0])) {
2205
- formattedData = flatten(formattedData);
2206
- }
2207
- listenerFn(formattedData, oldVal);
2296
+ if (!isArray(newVal)) {
2297
+ return;
2298
+ }
2299
+ let formattedData = newVal.map(datum => findValueOf(datum, restExpr));
2300
+ // Flatten if result is array of arrays
2301
+ if (isArray(formattedData[0])) {
2302
+ formattedData = flatten(formattedData);
2208
2303
  }
2304
+ listenerFn(formattedData, oldVal);
2209
2305
  };
2210
- const getUpdatedWatcInfo = (expr, acceptsArray, listener) => {
2211
- // listener doesn't accept array
2212
- // replace all `[$i]` with `[0]` and return the expression
2213
- let regex = /\[\$i\]/g, $I = '[$i]', $0 = '[0]';
2306
+ /**
2307
+ * Updates watch info for array expressions
2308
+ */
2309
+ const getUpdatedWatchInfo = (expr, acceptsArray, listener) => {
2310
+ const regex = /\[\$i\]/g;
2214
2311
  if (!acceptsArray) {
2215
2312
  return {
2216
- 'expr': expr.replace(regex, $0),
2217
- 'listener': listener
2313
+ expr: expr.replace(regex, ARRAY_INDEX_ZERO),
2314
+ listener
2218
2315
  };
2219
2316
  }
2220
- // listener accepts array
2221
- // replace all except the last `[$i]` with `[0]` and return the expression.
2222
- var index = expr.lastIndexOf($I), _expr = expr.substr(0, index).replace($I, $0), restExpr = expr.substr(index + 5), arrayConsumerFn = listener;
2223
- if (restExpr) {
2224
- arrayConsumerFn = arrayConsumer.bind(undefined, listener, restExpr);
2225
- }
2317
+ const lastIndex = expr.lastIndexOf(ARRAY_INDEX_PLACEHOLDER);
2318
+ const baseExpr = expr.substring(0, lastIndex).replace(ARRAY_INDEX_PLACEHOLDER, ARRAY_INDEX_ZERO);
2319
+ const restExpr = expr.substring(lastIndex + 5);
2320
+ const arrayConsumerFn = restExpr
2321
+ ? arrayConsumer.bind(undefined, listener, restExpr)
2322
+ : listener;
2226
2323
  return {
2227
- 'expr': _expr,
2228
- 'listener': arrayConsumerFn
2324
+ expr: baseExpr,
2325
+ listener: arrayConsumerFn
2229
2326
  };
2230
2327
  };
2328
+ /**
2329
+ * Determines if an expression is static (doesn't need to be watched)
2330
+ */
2331
+ const STATIC_EXPRESSION_NAMES = [
2332
+ "row.getProperty('investment')",
2333
+ "row.getProperty('factsheetLink')",
2334
+ "row.getProperty('isRebalanceEligible')"
2335
+ ];
2336
+ const isStaticExpression = (expr) => {
2337
+ if (typeof expr !== 'string') {
2338
+ return false;
2339
+ }
2340
+ const trimmedExpr = expr.trim();
2341
+ // Expressions that always evaluate to localization strings
2342
+ // if (trimmedExpr.includes('appLocale')) {
2343
+ // return true;
2344
+ // }
2345
+ // Hard-coded static expression names
2346
+ if (STATIC_EXPRESSION_NAMES.includes(trimmedExpr)) {
2347
+ return true;
2348
+ }
2349
+ return false;
2350
+ };
2351
+ /**
2352
+ * Gets the scope type from the scope object
2353
+ */
2354
+ const getScopeType = ($scope) => {
2355
+ if (!$scope) {
2356
+ return null;
2357
+ }
2358
+ if ($scope.pageName)
2359
+ return 'Page';
2360
+ if ($scope.prefabName)
2361
+ return 'Prefab';
2362
+ if ($scope.partialName)
2363
+ return 'Partial';
2364
+ // Check for App scope
2365
+ if ($scope.Variables !== undefined &&
2366
+ $scope.Actions !== undefined &&
2367
+ !$scope.pageName &&
2368
+ !$scope.prefabName &&
2369
+ !$scope.partialName) {
2370
+ return 'App';
2371
+ }
2372
+ if ($scope.constructor?.name === 'AppRef') {
2373
+ return 'App';
2374
+ }
2375
+ return null;
2376
+ };
2377
+ /**
2378
+ * Gets scope name based on scope type
2379
+ */
2380
+ const getScopeName = ($scope, scopeType) => {
2381
+ if (!scopeType || !$scope) {
2382
+ return null;
2383
+ }
2384
+ switch (scopeType) {
2385
+ case 'Prefab': return $scope.prefabName || null;
2386
+ case 'Partial': return $scope.partialName || null;
2387
+ case 'Page': return $scope.pageName || null;
2388
+ default: return null;
2389
+ }
2390
+ };
2391
+ /**
2392
+ * Main watch function
2393
+ */
2231
2394
  const $watch = (expr, $scope, $locals, listener, identifier = watchIdGenerator.nextUid(), doNotClone = false, config = {}, isMuted) => {
2232
- if (expr.indexOf('[$i]') !== -1) {
2233
- let watchInfo = getUpdatedWatcInfo(expr, config && (config.arrayType || config.isList), listener);
2395
+ // Handle array expressions
2396
+ if (expr.includes(ARRAY_INDEX_PLACEHOLDER)) {
2397
+ const watchInfo = getUpdatedWatchInfo(expr, config.arrayType || config.isList || false, listener);
2234
2398
  expr = watchInfo.expr;
2235
2399
  listener = watchInfo.listener;
2236
2400
  }
2401
+ // Handle static expressions
2402
+ if (isStaticExpression(expr)) {
2403
+ try {
2404
+ const fn = $parseExpr(expr);
2405
+ const staticValue = fn($scope, $locals);
2406
+ listener(staticValue, FIRST_TIME_WATCH);
2407
+ }
2408
+ catch (e) {
2409
+ console.warn(`Error evaluating static expression '${expr}':`, e);
2410
+ listener(undefined, FIRST_TIME_WATCH);
2411
+ }
2412
+ return () => { }; // No-op unsubscribe
2413
+ }
2237
2414
  const fn = $parseExpr(expr);
2238
- registry.set(identifier, {
2239
- fn: fn.bind(expr, $scope, $locals),
2415
+ const scopeType = getScopeType($scope);
2416
+ const scopeName = getScopeName($scope, scopeType);
2417
+ const destroyFn = () => $unwatch(identifier);
2418
+ const watchInfo = {
2419
+ fn: fn.bind(null, $scope, $locals),
2240
2420
  listener,
2241
2421
  expr,
2242
2422
  last: FIRST_TIME_WATCH,
2243
2423
  doNotClone,
2244
- isMuted: isMuted
2424
+ isMuted,
2425
+ scopeType,
2426
+ scopeName,
2427
+ destroyFn
2428
+ };
2429
+ // Store in registry
2430
+ const widgetId = getWidgetId(identifier);
2431
+ if (widgetId) {
2432
+ const propertyName = getPropertyName(identifier);
2433
+ if (!registry.has(widgetId)) {
2434
+ registry.set(widgetId, {});
2435
+ }
2436
+ const widgetGroup = registry.get(widgetId);
2437
+ widgetGroup[propertyName] = watchInfo;
2438
+ }
2439
+ else {
2440
+ registry.set(identifier, watchInfo);
2441
+ }
2442
+ return destroyFn;
2443
+ };
2444
+ /**
2445
+ * Unwatches a single identifier
2446
+ */
2447
+ const $unwatch = (identifier) => {
2448
+ const widgetId = getWidgetId(identifier);
2449
+ if (widgetId) {
2450
+ const propertyName = getPropertyName(identifier);
2451
+ const widgetGroup = registry.get(widgetId);
2452
+ //@ts-ignore
2453
+ if (widgetGroup && typeof widgetGroup === 'object' && !widgetGroup.fn) {
2454
+ const watchInfo = widgetGroup[propertyName];
2455
+ if (watchInfo) {
2456
+ delete widgetGroup[propertyName];
2457
+ // Clean up empty widget groups
2458
+ if (Object.keys(widgetGroup).length === 0) {
2459
+ registry.delete(widgetId);
2460
+ }
2461
+ return true;
2462
+ }
2463
+ }
2464
+ }
2465
+ // Fallback to direct lookup
2466
+ if (registry.has(identifier)) {
2467
+ registry.delete(identifier);
2468
+ return true;
2469
+ }
2470
+ return false;
2471
+ };
2472
+ /**
2473
+ * Unwatches all watchers for a specific widget ID
2474
+ */
2475
+ const $unwatchAll = (widgetId) => {
2476
+ if (!widgetId || typeof widgetId !== 'string') {
2477
+ return 0;
2478
+ }
2479
+ const widgetGroup = registry.get(widgetId);
2480
+ if (widgetGroup && typeof widgetGroup === 'object' && !widgetGroup.fn) {
2481
+ const count = Object.keys(widgetGroup).length;
2482
+ registry.delete(widgetId);
2483
+ return count;
2484
+ }
2485
+ // Fallback: find all identifiers starting with this widget ID
2486
+ let removedCount = 0;
2487
+ const identifiersToRemove = [];
2488
+ registry.forEach((_, key) => {
2489
+ if (key.startsWith(widgetId + '_')) {
2490
+ identifiersToRemove.push(key);
2491
+ }
2245
2492
  });
2246
- return () => $unwatch(identifier);
2493
+ identifiersToRemove.forEach(identifier => {
2494
+ if ($unwatch(identifier)) {
2495
+ removedCount++;
2496
+ }
2497
+ });
2498
+ return removedCount;
2247
2499
  };
2248
- const $unwatch = identifier => registry.delete(identifier);
2249
- let changedByWatch = false;
2250
- const $RAF = window.requestAnimationFrame;
2251
- let ngZone;
2252
- const triggerWatchers = (ignoreMuted) => {
2500
+ /**
2501
+ * Unwatches all watchers for a specific scope (Page, Prefab, Partial, or App)
2502
+ * Now works directly with the main registry instead of separate scoped registries
2503
+ */
2504
+ const $unwatchAllByScope = (scopeType, scopeName) => {
2505
+ if (!scopeType) {
2506
+ return 0;
2507
+ }
2508
+ let removedCount = 0;
2509
+ const identifiersToRemove = [];
2510
+ registry.forEach((value, key) => {
2511
+ // Handle grouped structure (widget groups)
2512
+ if (value && typeof value === 'object' && !value.fn) {
2513
+ Object.entries(value).forEach(([propertyName, watchInfo]) => {
2514
+ if (watchInfo?.scopeType === scopeType &&
2515
+ (!scopeName || watchInfo.scopeName === scopeName)) {
2516
+ identifiersToRemove.push(`${key}_${propertyName}`);
2517
+ }
2518
+ });
2519
+ }
2520
+ else {
2521
+ // Direct watchInfo
2522
+ const watchInfo = value;
2523
+ if (watchInfo?.scopeType === scopeType &&
2524
+ (!scopeName || watchInfo.scopeName === scopeName)) {
2525
+ identifiersToRemove.push(key);
2526
+ }
2527
+ }
2528
+ });
2529
+ // Unwatch all collected identifiers
2530
+ identifiersToRemove.forEach(identifier => {
2531
+ if ($unwatch(identifier)) {
2532
+ removedCount++;
2533
+ }
2534
+ });
2535
+ return removedCount;
2536
+ };
2537
+ /**
2538
+ * Processes a single watch info during trigger cycle
2539
+ */
2540
+ const processWatchInfo = (watchInfo) => {
2541
+ if (!watchInfo?.fn || (watchInfo.isMuted?.() ?? false)) {
2542
+ return false;
2543
+ }
2544
+ let newValue;
2545
+ try {
2546
+ newValue = watchInfo.fn();
2547
+ }
2548
+ catch (e) {
2549
+ console.warn(`Error executing expression: '${watchInfo.expr}'`, e);
2550
+ return false;
2551
+ }
2552
+ if (isEqual(newValue, watchInfo.last)) {
2553
+ return false;
2554
+ }
2555
+ // Change detected
2556
+ changedByWatch = true;
2557
+ watchInfo.last = isObject$1(newValue) && !watchInfo.doNotClone
2558
+ ? clone(newValue)
2559
+ : newValue;
2560
+ watchInfo.listener(newValue, watchInfo.last === newValue ? FIRST_TIME_WATCH : watchInfo.last);
2561
+ changedByWatch = false;
2562
+ return true;
2563
+ };
2564
+ /**
2565
+ * Triggers all watchers
2566
+ */
2567
+ const triggerWatchers = (ignoreMuted = false) => {
2253
2568
  if (muted && !ignoreMuted) {
2254
2569
  return;
2255
2570
  }
2256
- const limit = 5;
2257
2571
  let pass = 1;
2258
2572
  let changeDetected;
2259
2573
  do {
2260
2574
  changeDetected = false;
2261
- registry.forEach(watchInfo => {
2262
- if (watchInfo.isMuted && watchInfo.isMuted()) {
2263
- return;
2264
- }
2265
- const fn = watchInfo.fn;
2266
- const listener = watchInfo.listener;
2267
- const ov = watchInfo.last;
2268
- let nv;
2269
- try {
2270
- nv = fn();
2271
- }
2272
- catch (e) {
2273
- console.warn(`error in executing expression: '${watchInfo.expr}'`);
2575
+ registry.forEach((value) => {
2576
+ // Handle grouped structure
2577
+ if (value && typeof value === 'object' && !value.fn) {
2578
+ Object.values(value).forEach((watchInfo) => {
2579
+ if (processWatchInfo(watchInfo)) {
2580
+ changeDetected = true;
2581
+ }
2582
+ });
2274
2583
  }
2275
- if (!isEqual(nv, ov)) {
2276
- changeDetected = true;
2277
- changedByWatch = true;
2278
- watchInfo.last = nv;
2279
- // @ts-ignore
2280
- if (isObject$1(nv) && !watchInfo.doNotClone && nv.__cloneable__ !== false) {
2281
- watchInfo.last = clone(nv);
2584
+ else {
2585
+ // Direct watchInfo
2586
+ if (processWatchInfo(value)) {
2587
+ changeDetected = true;
2282
2588
  }
2283
- listener(nv, ov);
2284
- resetChangeFromWatch();
2285
2589
  }
2286
2590
  });
2287
2591
  pass++;
2288
- } while (changeDetected && pass < limit);
2289
- if (changeDetected && pass === limit) {
2290
- console.warn(`Number of watch cycles gone above set limit of: ${limit} `);
2592
+ } while (changeDetected && pass < MAX_WATCH_CYCLES);
2593
+ // Schedule cleanup after watchers are triggered
2594
+ scheduleThresholdCleanup();
2595
+ if (changeDetected && pass === MAX_WATCH_CYCLES) {
2596
+ console.warn(`Watch cycles exceeded limit of ${MAX_WATCH_CYCLES}`);
2291
2597
  }
2292
2598
  };
2293
- const setNgZone = zone => ngZone = zone;
2294
- const setAppRef = ref => {
2599
+ // Angular zone integration
2600
+ const setNgZone = (zone) => {
2601
+ ngZone = zone;
2602
+ };
2603
+ const setAppRef = (ref) => {
2295
2604
  appRef = ref;
2296
2605
  };
2297
2606
  const isChangeFromWatch = () => changedByWatch;
2298
- const resetChangeFromWatch = () => changedByWatch = false;
2299
- window.watchRegistry = registry;
2300
- let skipWatchers;
2607
+ const resetChangeFromWatch = () => {
2608
+ changedByWatch = false;
2609
+ };
2610
+ // Debounced trigger
2301
2611
  const debouncedTriggerWatchers = debounce(() => {
2302
2612
  skipWatchers = true;
2303
2613
  ngZone.run(() => triggerWatchers());
2304
- }, 100);
2305
- const $invokeWatchers = (force, ignoreMuted) => {
2614
+ }, DEBOUNCE_WAIT);
2615
+ const $invokeWatchers = (force = false, ignoreMuted = false) => {
2306
2616
  if (force) {
2307
2617
  triggerWatchers(ignoreMuted);
2308
2618
  }
@@ -2316,7 +2626,8 @@ const $invokeWatchers = (force, ignoreMuted) => {
2316
2626
  };
2317
2627
  const $appDigest = (() => {
2318
2628
  let queued = false;
2319
- return (force) => {
2629
+ const $RAF = window.requestAnimationFrame;
2630
+ return (force = false) => {
2320
2631
  if (!appRef) {
2321
2632
  return;
2322
2633
  }
@@ -2328,16 +2639,16 @@ const $appDigest = (() => {
2328
2639
  if (queued) {
2329
2640
  return;
2330
2641
  }
2331
- else {
2332
- queued = true;
2333
- $RAF(() => {
2334
- ngZone.run(() => appRef.tick());
2335
- queued = false;
2336
- });
2337
- }
2642
+ queued = true;
2643
+ $RAF(() => {
2644
+ ngZone.run(() => appRef.tick());
2645
+ queued = false;
2646
+ });
2338
2647
  }
2339
2648
  };
2340
2649
  })();
2650
+ // Export registry for debugging
2651
+ window.watchRegistry = registry;
2341
2652
 
2342
2653
  var ComponentType;
2343
2654
  (function (ComponentType) {
@@ -5182,5 +5493,5 @@ class LRUCache {
5182
5493
  * Generated bundle index. Do not edit.
5183
5494
  */
5184
5495
 
5185
- export { $appDigest, $invokeWatchers, $parseEvent, $parseExpr, $unwatch, $watch, AbstractDialogService, AbstractHttpService, AbstractI18nService, AbstractNavigationService, AbstractSpinnerService, AbstractToasterService, App, AppConstants, AppDefaults, CURRENCY_INFO, ComponentType, ConstantService, CustomIconsLoaderService, CustomPipeManager, CustomWidgetRefProvider, DEFAULT_FORMATS, DataSource, DataType, DynamicComponentRefProvider, EventNotifier, FIRST_TIME_WATCH, FieldTypeService, FieldWidgetService, FormWidgetType, IDGenerator, IDataSource, LRUCache, MatchMode, PaginationService, PartialRefProvider, ScriptLoaderService, ScriptStore, StatePersistence, UserDefinedExecutionContext, UtilsService, VALIDATOR, Viewport, _WM_APP_PROJECT, addClass, addEventListenerOnElement, addForIdAttributes, adjustContainerPosition, adjustContainerRightEdges, appendNode, appendScriptToHead, checkIsCustomPipeExpression, closePopover, convertToBlob, createCSSRule, createElement, deHyphenate, debounce, defer, detectChanges, encodeUrl, encodeUrlParams, executePromiseChain, extendProto, extractCurrentItemExpr, extractType, fetchContent, findParent, findRootContainer, findValueOf, generateGUId, getAbortableDefer, getAndroidVersion, getAppSetting, getBlob, getClonedObject, getDatasourceFromExpr, getDateObj, getDisplayDateTimeFormat, getEvaluatedExprValue, getFiles, getFnByExpr, getFnForBindExpr, getFnForEventExpr, getFormWidgetTemplate, getFormattedDate, getMomentLocaleObject, getNativeDateObject, getNavClass, getNgModelAttr, getPreviewProperties, getRequiredFormWidget, getResourceURL, getRouteNameFromLink, getRowActionAttrs, getSessionStorageItem, getSheetPositionClass, getUrlParams, getValidDateObject, getValidJSON, getWebkitTraslationMatrix, getWmProjectProperties, hasOffsetStr, initCaps, insertAfter, insertBefore, isAndroid, isAndroidTablet, isAppleProduct, isAudioFile, isChangeFromWatch, isDataSourceEqual, isDateTimeType, isDefined, isElementInViewport, isEmptyObject, isEqualWithFields, isFirstTimeChange, isIE, isImageFile, isInsecureContentRequest, isIos, isIpad, isIphone, isIpod, isKitkatDevice, isLargeTabletLandscape, isLargeTabletPortrait, isMobile, isNumberType, isObject, isPageable, isSafari, isValidImageUrl, isValidWebURL, isVideoFile, loadScript, loadScripts, loadStyleSheet, loadStyleSheets, muteWatchers, noop, openLink, periodSeparate, prettifyLabel, prettifyLabels, processFilterExpBindNode, registerFnByExpr, removeAttr, removeClass, removeExtraSlashes, removeNode, replace, replaceAt, resetChangeFromWatch, retryIfFails, scrollToElement, setAppRef, setAttr, setCSS, setCSSFromObj, setHtml, setListClass, setNgZone, setPipeProvider, setPreviewProperties, setProperty, setSessionStorageItem, setTranslation3dPosition, setWmProjectProperties, spaceSeparate, stringStartsWith, switchClass, toBoolean, toDimension, toPromise, toggleClass, transformFileURI, triggerFn, triggerItemAction, unMuteWatchers, updateTemplateAttrs, validateAccessRoles, validateDataSourceCtx, xmlToJson };
5496
+ export { $appDigest, $invokeWatchers, $parseEvent, $parseExpr, $unwatch, $unwatchAll, $unwatchAllByScope, $watch, AbstractDialogService, AbstractHttpService, AbstractI18nService, AbstractNavigationService, AbstractSpinnerService, AbstractToasterService, App, AppConstants, AppDefaults, CURRENCY_INFO, ComponentType, ConstantService, CustomIconsLoaderService, CustomPipeManager, CustomWidgetRefProvider, DEFAULT_FORMATS, DataSource, DataType, DynamicComponentRefProvider, EventNotifier, FIRST_TIME_WATCH, FieldTypeService, FieldWidgetService, FormWidgetType, IDGenerator, IDataSource, LRUCache, MatchMode, PaginationService, PartialRefProvider, ScriptLoaderService, ScriptStore, StatePersistence, UserDefinedExecutionContext, UtilsService, VALIDATOR, Viewport, _WM_APP_PROJECT, addClass, addEventListenerOnElement, addForIdAttributes, adjustContainerPosition, adjustContainerRightEdges, appendNode, appendScriptToHead, checkIsCustomPipeExpression, closePopover, convertToBlob, createCSSRule, createElement, deHyphenate, debounce, defer, detectChanges, encodeUrl, encodeUrlParams, executePromiseChain, extendProto, extractCurrentItemExpr, extractType, fetchContent, findParent, findRootContainer, findValueOf, generateGUId, getAbortableDefer, getAndroidVersion, getAppSetting, getBlob, getClonedObject, getDatasourceFromExpr, getDateObj, getDisplayDateTimeFormat, getEvaluatedExprValue, getFiles, getFnByExpr, getFnForBindExpr, getFnForEventExpr, getFormWidgetTemplate, getFormattedDate, getMomentLocaleObject, getNativeDateObject, getNavClass, getNgModelAttr, getPreviewProperties, getRequiredFormWidget, getResourceURL, getRouteNameFromLink, getRowActionAttrs, getSessionStorageItem, getSheetPositionClass, getUrlParams, getValidDateObject, getValidJSON, getWebkitTraslationMatrix, getWmProjectProperties, hasOffsetStr, initCaps, insertAfter, insertBefore, isAndroid, isAndroidTablet, isAppleProduct, isAudioFile, isChangeFromWatch, isDataSourceEqual, isDateTimeType, isDefined, isElementInViewport, isEmptyObject, isEqualWithFields, isFirstTimeChange, isIE, isImageFile, isInsecureContentRequest, isIos, isIpad, isIphone, isIpod, isKitkatDevice, isLargeTabletLandscape, isLargeTabletPortrait, isMobile, isNumberType, isObject, isPageable, isSafari, isValidImageUrl, isValidWebURL, isVideoFile, loadScript, loadScripts, loadStyleSheet, loadStyleSheets, muteWatchers, noop, openLink, periodSeparate, prettifyLabel, prettifyLabels, processFilterExpBindNode, registerFnByExpr, removeAttr, removeClass, removeExtraSlashes, removeNode, replace, replaceAt, resetChangeFromWatch, retryIfFails, scrollToElement, setAppRef, setAttr, setCSS, setCSSFromObj, setHtml, setListClass, setNgZone, setPipeProvider, setPreviewProperties, setProperty, setSessionStorageItem, setTranslation3dPosition, setWmProjectProperties, spaceSeparate, stringStartsWith, switchClass, toBoolean, toDimension, toPromise, toggleClass, transformFileURI, triggerFn, triggerItemAction, unMuteWatchers, updateTemplateAttrs, validateAccessRoles, validateDataSourceCtx, xmlToJson };
5186
5497
  //# sourceMappingURL=index.mjs.map