@xuda.io/runtime-bundle 1.0.1421 → 1.0.1423

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.
@@ -1988,6 +1988,13 @@ func.runtime.session.create_state = function (SESSION_ID, options) {
1988
1988
  func.runtime.workers.ensure_registry(SESSION_ID);
1989
1989
  return SESSION_OBJ[SESSION_ID];
1990
1990
  };
1991
+ func.runtime.session.is_slim = function (SESSION_ID) {
1992
+ const session = typeof SESSION_ID === 'undefined' || SESSION_ID === null ? null : SESSION_OBJ?.[SESSION_ID];
1993
+ if (session && typeof session.SLIM_BUNDLE !== 'undefined') {
1994
+ return !!session.SLIM_BUNDLE;
1995
+ }
1996
+ return !!glb.SLIM_BUNDLE;
1997
+ };
1991
1998
  func.runtime.session.set_default_value = function (_session, key, value) {
1992
1999
  _session[key] = value || func.runtime.env.get_default_session_value(key);
1993
2000
  return _session[key];
@@ -2115,11 +2122,12 @@ func.runtime.render.get_root_data_system = function (SESSION_ID) {
2115
2122
  func.runtime.render.resolve_xu_for_source = async function (SESSION_ID, dsSessionP, value) {
2116
2123
  let arr = value;
2117
2124
  let reference_source_obj;
2125
+ const normalized_reference = typeof value === 'string' && value.startsWith('@') ? value.substring(1) : value;
2118
2126
  const _progFields = await func.datasource.get_progFields(SESSION_ID, dsSessionP);
2119
- let view_field_obj = func.common.find_item_by_key(_progFields, 'field_id', value);
2127
+ let view_field_obj = func.common.find_item_by_key(_progFields, 'field_id', normalized_reference);
2120
2128
 
2121
- if (view_field_obj) {
2122
- reference_source_obj = await func.datasource.get_value(SESSION_ID, value, dsSessionP);
2129
+ if (view_field_obj || normalized_reference !== value) {
2130
+ reference_source_obj = await func.datasource.get_value(SESSION_ID, normalized_reference, dsSessionP);
2123
2131
  arr = reference_source_obj?.ret?.value;
2124
2132
  } else {
2125
2133
  if (typeof value === 'string') {
@@ -2238,6 +2246,135 @@ func.runtime.bind.build_datasource_changes = function (dsSessionP, currentRecord
2238
2246
  },
2239
2247
  };
2240
2248
  };
2249
+ func.runtime.bind.get_native_adapter = function () {
2250
+ const has_explicit_value = function (elm) {
2251
+ return !!elm?.hasAttribute?.('value');
2252
+ };
2253
+ const get_listener_event = function (elm) {
2254
+ const tag_name = elm?.tagName?.toLowerCase?.();
2255
+ const type = (elm?.type || '').toLowerCase();
2256
+
2257
+ if (tag_name === 'select' || ['checkbox', 'radio'].includes(type)) {
2258
+ return 'change';
2259
+ }
2260
+ return 'input';
2261
+ };
2262
+
2263
+ return {
2264
+ getter: function (elm) {
2265
+ if (!elm) {
2266
+ return undefined;
2267
+ }
2268
+
2269
+ const tag_name = elm?.tagName?.toLowerCase?.();
2270
+ const type = (elm?.type || '').toLowerCase();
2271
+
2272
+ if (tag_name === 'select' && elm.multiple) {
2273
+ return Array.from(elm.options || [])
2274
+ .filter(function (option) {
2275
+ return option.selected;
2276
+ })
2277
+ .map(function (option) {
2278
+ return option.value;
2279
+ });
2280
+ }
2281
+
2282
+ if (type === 'checkbox') {
2283
+ return has_explicit_value(elm) ? elm.value : !!elm.checked;
2284
+ }
2285
+
2286
+ if (type === 'radio') {
2287
+ return elm.value;
2288
+ }
2289
+
2290
+ return typeof elm.value !== 'undefined' ? elm.value : undefined;
2291
+ },
2292
+ setter: function (elm, value) {
2293
+ if (!elm) {
2294
+ return false;
2295
+ }
2296
+
2297
+ const tag_name = elm?.tagName?.toLowerCase?.();
2298
+ const type = (elm?.type || '').toLowerCase();
2299
+
2300
+ if (tag_name === 'select' && elm.multiple) {
2301
+ const selected_values = Array.isArray(value)
2302
+ ? value.map(function (item) {
2303
+ return String(item);
2304
+ })
2305
+ : [String(value)];
2306
+ Array.from(elm.options || []).forEach(function (option) {
2307
+ option.selected = selected_values.includes(String(option.value));
2308
+ });
2309
+ return true;
2310
+ }
2311
+
2312
+ if (type === 'checkbox' || type === 'radio') {
2313
+ return true;
2314
+ }
2315
+
2316
+ if (typeof elm.value !== 'undefined') {
2317
+ elm.value = value === null || typeof value === 'undefined' ? '' : String(value);
2318
+ }
2319
+ return true;
2320
+ },
2321
+ listener: function (elm, handler) {
2322
+ if (!elm?.addEventListener || typeof handler !== 'function') {
2323
+ return false;
2324
+ }
2325
+
2326
+ const event_name = get_listener_event(elm);
2327
+ const listener_key = '__xuda_native_bind_listener_' + event_name;
2328
+ if (elm[listener_key]) {
2329
+ elm.removeEventListener(event_name, elm[listener_key]);
2330
+ }
2331
+ elm.addEventListener(event_name, handler);
2332
+ elm[listener_key] = handler;
2333
+ return true;
2334
+ },
2335
+ };
2336
+ };
2337
+ func.runtime.bind.is_valid_adapter = function (adapter) {
2338
+ return !!(
2339
+ adapter &&
2340
+ typeof adapter.getter === 'function' &&
2341
+ typeof adapter.setter === 'function' &&
2342
+ typeof adapter.listener === 'function'
2343
+ );
2344
+ };
2345
+ func.runtime.bind.get_adapter = function (SESSION_ID) {
2346
+ const native_adapter = func.runtime.bind.get_native_adapter();
2347
+ if (func.runtime.session.is_slim(SESSION_ID)) {
2348
+ return native_adapter;
2349
+ }
2350
+
2351
+ const plugin_bind = UI_FRAMEWORK_PLUGIN?.bind;
2352
+ if (!plugin_bind) {
2353
+ return native_adapter;
2354
+ }
2355
+
2356
+ if (func.runtime.bind.is_valid_adapter(plugin_bind)) {
2357
+ return plugin_bind;
2358
+ }
2359
+
2360
+ if (typeof plugin_bind === 'function') {
2361
+ try {
2362
+ const bind_instance = new plugin_bind();
2363
+ if (func.runtime.bind.is_valid_adapter(bind_instance)) {
2364
+ return bind_instance;
2365
+ }
2366
+ } catch (error) {}
2367
+
2368
+ try {
2369
+ const bind_factory = plugin_bind();
2370
+ if (func.runtime.bind.is_valid_adapter(bind_factory)) {
2371
+ return bind_factory;
2372
+ }
2373
+ } catch (error) {}
2374
+ }
2375
+
2376
+ return native_adapter;
2377
+ };
2241
2378
  func.runtime.bind.resolve_field = async function (SESSION_ID, prog_id, dsSessionP, field_id, iterate_info) {
2242
2379
  let _prog_id = prog_id;
2243
2380
  let _dsP = dsSessionP;
@@ -8907,7 +9044,10 @@ func.runtime.ui.find_in_root = function (SESSION_ID, selector) {
8907
9044
  };
8908
9045
  func.runtime.ui.get_root_tag_name = function () {
8909
9046
  let root_tag_name = 'div';
8910
- if (typeof glb.SLIM_BUNDLE === 'undefined' && !glb.SLIM_BUNDLE) {
9047
+ if (!func.runtime.session.is_slim()) {
9048
+ if (typeof UI_FRAMEWORK_PLUGIN?.core !== 'function') {
9049
+ return root_tag_name;
9050
+ }
8911
9051
  const ui_plugin_core = new UI_FRAMEWORK_PLUGIN.core();
8912
9052
  root_tag_name = ui_plugin_core?.rootTagName() || root_tag_name;
8913
9053
  }
@@ -12734,6 +12874,12 @@ func.runtime.ui.close_modal_session = async function (SESSION_ID, modal_id) {
12734
12874
  func.runtime.ui.render_screen_type = async function (options) {
12735
12875
  const $div_content = func.runtime.ui.get_children(options.$div);
12736
12876
  func.runtime.ui.sync_child_parent_container(options.$div);
12877
+ const assert_framework_screen_supported = function (screen_type) {
12878
+ if (!func.runtime.session.is_slim(options.SESSION_ID)) {
12879
+ return;
12880
+ }
12881
+ throw new Error('Slim mode does not support "' + screen_type + '" screens without a UI framework plugin');
12882
+ };
12737
12883
 
12738
12884
  let $ret = options.$div;
12739
12885
  let $nav = func.runtime.ui.get_nav(options.SESSION_ID);
@@ -12741,6 +12887,7 @@ func.runtime.ui.render_screen_type = async function (options) {
12741
12887
 
12742
12888
  switch (options.paramsP.screen_type) {
12743
12889
  case 'modal': {
12890
+ assert_framework_screen_supported('modal');
12744
12891
  params = func.runtime.ui.build_modal_params(options.paramsP, options.$div, options.$container, options.close_modal);
12745
12892
  const modal_id = params.modal_id;
12746
12893
  func.runtime.ui.set_modal_params(options.SESSION_ID, modal_id, params);
@@ -12757,6 +12904,7 @@ func.runtime.ui.render_screen_type = async function (options) {
12757
12904
  }
12758
12905
 
12759
12906
  case 'popover': {
12907
+ assert_framework_screen_supported('popover');
12760
12908
  const xu_popover_controller = func.UI.component.create_app_popover_component(options.SESSION_ID);
12761
12909
  params = func.runtime.ui.build_popover_params(options.paramsP, options.$div, options.$container);
12762
12910
 
@@ -12771,6 +12919,7 @@ func.runtime.ui.render_screen_type = async function (options) {
12771
12919
  }
12772
12920
 
12773
12921
  case 'page': {
12922
+ assert_framework_screen_supported('page');
12774
12923
  const nav = func.runtime.ui.get_first_node($nav);
12775
12924
 
12776
12925
  params = func.runtime.ui.build_page_params(options.SESSION_ID, options.paramsP, $div_content, options.$container, nav);
@@ -16347,8 +16496,8 @@ func.runtime.render.get_xu_for_iterators = function ($elm) {
16347
16496
  return {
16348
16497
  iterator_key: custom_iterator_key || '_FOR_KEY',
16349
16498
  iterator_val: custom_iterator_val || '_FOR_VAL',
16350
- is_key_dynamic_field: !custom_iterator_key,
16351
- is_val_dynamic_field: !custom_iterator_val,
16499
+ is_key_dynamic_field: true,
16500
+ is_val_dynamic_field: true,
16352
16501
  };
16353
16502
  };
16354
16503
  func.runtime.render.attach_iterate_info_to_children = function ($divP, iterate_info) {
@@ -17374,7 +17523,7 @@ func.runtime.render.handle_xu_bind = async function (options) {
17374
17523
  return {};
17375
17524
  }
17376
17525
 
17377
- const bind = new UI_FRAMEWORK_PLUGIN.bind();
17526
+ const bind = func.runtime.bind.get_adapter(options.SESSION_ID);
17378
17527
  const field_changed = async function () {
17379
17528
  const _ds = SESSION_OBJ[options.SESSION_ID].DS_GLB[_dsP];
17380
17529
  const field_type = func.runtime.bind.get_field_type(field_prop);
@@ -22432,13 +22581,22 @@ func.index.call_worker = async function (SESSION_ID, obj, params, promiseP) {
22432
22581
  };
22433
22582
 
22434
22583
  func.index.init_SCREEN_BLOCKER = async function (SESSION_ID) {
22584
+ const get_loader = async function () {
22585
+ if (func.runtime.session.is_slim(SESSION_ID) || typeof UI_FRAMEWORK_PLUGIN?.loader !== 'function') {
22586
+ return {
22587
+ dismiss: function () {},
22588
+ };
22589
+ }
22590
+ return await UI_FRAMEWORK_PLUGIN.loader(LOADER_TEXT);
22591
+ };
22592
+
22435
22593
  setInterval(async function () {
22436
22594
  if (glb.CURRENT_APP_LOADING || (!LOADER_ACTIVE && xu_isEmpty(SCREEN_BLOCKER_OBJ))) {
22437
22595
  return;
22438
22596
  }
22439
22597
  glb.CURRENT_APP_LOADING = 1;
22440
22598
 
22441
- const loader = await UI_FRAMEWORK_PLUGIN.loader(LOADER_TEXT);
22599
+ const loader = await get_loader();
22442
22600
 
22443
22601
  glb.CURRENT_APP_LOADING = loader;
22444
22602
 
@@ -1914,6 +1914,13 @@ func.runtime.session.create_state = function (SESSION_ID, options) {
1914
1914
  func.runtime.workers.ensure_registry(SESSION_ID);
1915
1915
  return SESSION_OBJ[SESSION_ID];
1916
1916
  };
1917
+ func.runtime.session.is_slim = function (SESSION_ID) {
1918
+ const session = typeof SESSION_ID === 'undefined' || SESSION_ID === null ? null : SESSION_OBJ?.[SESSION_ID];
1919
+ if (session && typeof session.SLIM_BUNDLE !== 'undefined') {
1920
+ return !!session.SLIM_BUNDLE;
1921
+ }
1922
+ return !!glb.SLIM_BUNDLE;
1923
+ };
1917
1924
  func.runtime.session.set_default_value = function (_session, key, value) {
1918
1925
  _session[key] = value || func.runtime.env.get_default_session_value(key);
1919
1926
  return _session[key];
@@ -2041,11 +2048,12 @@ func.runtime.render.get_root_data_system = function (SESSION_ID) {
2041
2048
  func.runtime.render.resolve_xu_for_source = async function (SESSION_ID, dsSessionP, value) {
2042
2049
  let arr = value;
2043
2050
  let reference_source_obj;
2051
+ const normalized_reference = typeof value === 'string' && value.startsWith('@') ? value.substring(1) : value;
2044
2052
  const _progFields = await func.datasource.get_progFields(SESSION_ID, dsSessionP);
2045
- let view_field_obj = func.common.find_item_by_key(_progFields, 'field_id', value);
2053
+ let view_field_obj = func.common.find_item_by_key(_progFields, 'field_id', normalized_reference);
2046
2054
 
2047
- if (view_field_obj) {
2048
- reference_source_obj = await func.datasource.get_value(SESSION_ID, value, dsSessionP);
2055
+ if (view_field_obj || normalized_reference !== value) {
2056
+ reference_source_obj = await func.datasource.get_value(SESSION_ID, normalized_reference, dsSessionP);
2049
2057
  arr = reference_source_obj?.ret?.value;
2050
2058
  } else {
2051
2059
  if (typeof value === 'string') {
@@ -2164,6 +2172,135 @@ func.runtime.bind.build_datasource_changes = function (dsSessionP, currentRecord
2164
2172
  },
2165
2173
  };
2166
2174
  };
2175
+ func.runtime.bind.get_native_adapter = function () {
2176
+ const has_explicit_value = function (elm) {
2177
+ return !!elm?.hasAttribute?.('value');
2178
+ };
2179
+ const get_listener_event = function (elm) {
2180
+ const tag_name = elm?.tagName?.toLowerCase?.();
2181
+ const type = (elm?.type || '').toLowerCase();
2182
+
2183
+ if (tag_name === 'select' || ['checkbox', 'radio'].includes(type)) {
2184
+ return 'change';
2185
+ }
2186
+ return 'input';
2187
+ };
2188
+
2189
+ return {
2190
+ getter: function (elm) {
2191
+ if (!elm) {
2192
+ return undefined;
2193
+ }
2194
+
2195
+ const tag_name = elm?.tagName?.toLowerCase?.();
2196
+ const type = (elm?.type || '').toLowerCase();
2197
+
2198
+ if (tag_name === 'select' && elm.multiple) {
2199
+ return Array.from(elm.options || [])
2200
+ .filter(function (option) {
2201
+ return option.selected;
2202
+ })
2203
+ .map(function (option) {
2204
+ return option.value;
2205
+ });
2206
+ }
2207
+
2208
+ if (type === 'checkbox') {
2209
+ return has_explicit_value(elm) ? elm.value : !!elm.checked;
2210
+ }
2211
+
2212
+ if (type === 'radio') {
2213
+ return elm.value;
2214
+ }
2215
+
2216
+ return typeof elm.value !== 'undefined' ? elm.value : undefined;
2217
+ },
2218
+ setter: function (elm, value) {
2219
+ if (!elm) {
2220
+ return false;
2221
+ }
2222
+
2223
+ const tag_name = elm?.tagName?.toLowerCase?.();
2224
+ const type = (elm?.type || '').toLowerCase();
2225
+
2226
+ if (tag_name === 'select' && elm.multiple) {
2227
+ const selected_values = Array.isArray(value)
2228
+ ? value.map(function (item) {
2229
+ return String(item);
2230
+ })
2231
+ : [String(value)];
2232
+ Array.from(elm.options || []).forEach(function (option) {
2233
+ option.selected = selected_values.includes(String(option.value));
2234
+ });
2235
+ return true;
2236
+ }
2237
+
2238
+ if (type === 'checkbox' || type === 'radio') {
2239
+ return true;
2240
+ }
2241
+
2242
+ if (typeof elm.value !== 'undefined') {
2243
+ elm.value = value === null || typeof value === 'undefined' ? '' : String(value);
2244
+ }
2245
+ return true;
2246
+ },
2247
+ listener: function (elm, handler) {
2248
+ if (!elm?.addEventListener || typeof handler !== 'function') {
2249
+ return false;
2250
+ }
2251
+
2252
+ const event_name = get_listener_event(elm);
2253
+ const listener_key = '__xuda_native_bind_listener_' + event_name;
2254
+ if (elm[listener_key]) {
2255
+ elm.removeEventListener(event_name, elm[listener_key]);
2256
+ }
2257
+ elm.addEventListener(event_name, handler);
2258
+ elm[listener_key] = handler;
2259
+ return true;
2260
+ },
2261
+ };
2262
+ };
2263
+ func.runtime.bind.is_valid_adapter = function (adapter) {
2264
+ return !!(
2265
+ adapter &&
2266
+ typeof adapter.getter === 'function' &&
2267
+ typeof adapter.setter === 'function' &&
2268
+ typeof adapter.listener === 'function'
2269
+ );
2270
+ };
2271
+ func.runtime.bind.get_adapter = function (SESSION_ID) {
2272
+ const native_adapter = func.runtime.bind.get_native_adapter();
2273
+ if (func.runtime.session.is_slim(SESSION_ID)) {
2274
+ return native_adapter;
2275
+ }
2276
+
2277
+ const plugin_bind = UI_FRAMEWORK_PLUGIN?.bind;
2278
+ if (!plugin_bind) {
2279
+ return native_adapter;
2280
+ }
2281
+
2282
+ if (func.runtime.bind.is_valid_adapter(plugin_bind)) {
2283
+ return plugin_bind;
2284
+ }
2285
+
2286
+ if (typeof plugin_bind === 'function') {
2287
+ try {
2288
+ const bind_instance = new plugin_bind();
2289
+ if (func.runtime.bind.is_valid_adapter(bind_instance)) {
2290
+ return bind_instance;
2291
+ }
2292
+ } catch (error) {}
2293
+
2294
+ try {
2295
+ const bind_factory = plugin_bind();
2296
+ if (func.runtime.bind.is_valid_adapter(bind_factory)) {
2297
+ return bind_factory;
2298
+ }
2299
+ } catch (error) {}
2300
+ }
2301
+
2302
+ return native_adapter;
2303
+ };
2167
2304
  func.runtime.bind.resolve_field = async function (SESSION_ID, prog_id, dsSessionP, field_id, iterate_info) {
2168
2305
  let _prog_id = prog_id;
2169
2306
  let _dsP = dsSessionP;
@@ -8833,7 +8970,10 @@ func.runtime.ui.find_in_root = function (SESSION_ID, selector) {
8833
8970
  };
8834
8971
  func.runtime.ui.get_root_tag_name = function () {
8835
8972
  let root_tag_name = 'div';
8836
- if (typeof glb.SLIM_BUNDLE === 'undefined' && !glb.SLIM_BUNDLE) {
8973
+ if (!func.runtime.session.is_slim()) {
8974
+ if (typeof UI_FRAMEWORK_PLUGIN?.core !== 'function') {
8975
+ return root_tag_name;
8976
+ }
8837
8977
  const ui_plugin_core = new UI_FRAMEWORK_PLUGIN.core();
8838
8978
  root_tag_name = ui_plugin_core?.rootTagName() || root_tag_name;
8839
8979
  }
@@ -12660,6 +12800,12 @@ func.runtime.ui.close_modal_session = async function (SESSION_ID, modal_id) {
12660
12800
  func.runtime.ui.render_screen_type = async function (options) {
12661
12801
  const $div_content = func.runtime.ui.get_children(options.$div);
12662
12802
  func.runtime.ui.sync_child_parent_container(options.$div);
12803
+ const assert_framework_screen_supported = function (screen_type) {
12804
+ if (!func.runtime.session.is_slim(options.SESSION_ID)) {
12805
+ return;
12806
+ }
12807
+ throw new Error('Slim mode does not support "' + screen_type + '" screens without a UI framework plugin');
12808
+ };
12663
12809
 
12664
12810
  let $ret = options.$div;
12665
12811
  let $nav = func.runtime.ui.get_nav(options.SESSION_ID);
@@ -12667,6 +12813,7 @@ func.runtime.ui.render_screen_type = async function (options) {
12667
12813
 
12668
12814
  switch (options.paramsP.screen_type) {
12669
12815
  case 'modal': {
12816
+ assert_framework_screen_supported('modal');
12670
12817
  params = func.runtime.ui.build_modal_params(options.paramsP, options.$div, options.$container, options.close_modal);
12671
12818
  const modal_id = params.modal_id;
12672
12819
  func.runtime.ui.set_modal_params(options.SESSION_ID, modal_id, params);
@@ -12683,6 +12830,7 @@ func.runtime.ui.render_screen_type = async function (options) {
12683
12830
  }
12684
12831
 
12685
12832
  case 'popover': {
12833
+ assert_framework_screen_supported('popover');
12686
12834
  const xu_popover_controller = func.UI.component.create_app_popover_component(options.SESSION_ID);
12687
12835
  params = func.runtime.ui.build_popover_params(options.paramsP, options.$div, options.$container);
12688
12836
 
@@ -12697,6 +12845,7 @@ func.runtime.ui.render_screen_type = async function (options) {
12697
12845
  }
12698
12846
 
12699
12847
  case 'page': {
12848
+ assert_framework_screen_supported('page');
12700
12849
  const nav = func.runtime.ui.get_first_node($nav);
12701
12850
 
12702
12851
  params = func.runtime.ui.build_page_params(options.SESSION_ID, options.paramsP, $div_content, options.$container, nav);
@@ -16273,8 +16422,8 @@ func.runtime.render.get_xu_for_iterators = function ($elm) {
16273
16422
  return {
16274
16423
  iterator_key: custom_iterator_key || '_FOR_KEY',
16275
16424
  iterator_val: custom_iterator_val || '_FOR_VAL',
16276
- is_key_dynamic_field: !custom_iterator_key,
16277
- is_val_dynamic_field: !custom_iterator_val,
16425
+ is_key_dynamic_field: true,
16426
+ is_val_dynamic_field: true,
16278
16427
  };
16279
16428
  };
16280
16429
  func.runtime.render.attach_iterate_info_to_children = function ($divP, iterate_info) {
@@ -17300,7 +17449,7 @@ func.runtime.render.handle_xu_bind = async function (options) {
17300
17449
  return {};
17301
17450
  }
17302
17451
 
17303
- const bind = new UI_FRAMEWORK_PLUGIN.bind();
17452
+ const bind = func.runtime.bind.get_adapter(options.SESSION_ID);
17304
17453
  const field_changed = async function () {
17305
17454
  const _ds = SESSION_OBJ[options.SESSION_ID].DS_GLB[_dsP];
17306
17455
  const field_type = func.runtime.bind.get_field_type(field_prop);
@@ -22358,13 +22507,22 @@ func.index.call_worker = async function (SESSION_ID, obj, params, promiseP) {
22358
22507
  };
22359
22508
 
22360
22509
  func.index.init_SCREEN_BLOCKER = async function (SESSION_ID) {
22510
+ const get_loader = async function () {
22511
+ if (func.runtime.session.is_slim(SESSION_ID) || typeof UI_FRAMEWORK_PLUGIN?.loader !== 'function') {
22512
+ return {
22513
+ dismiss: function () {},
22514
+ };
22515
+ }
22516
+ return await UI_FRAMEWORK_PLUGIN.loader(LOADER_TEXT);
22517
+ };
22518
+
22361
22519
  setInterval(async function () {
22362
22520
  if (glb.CURRENT_APP_LOADING || (!LOADER_ACTIVE && xu_isEmpty(SCREEN_BLOCKER_OBJ))) {
22363
22521
  return;
22364
22522
  }
22365
22523
  glb.CURRENT_APP_LOADING = 1;
22366
22524
 
22367
- const loader = await UI_FRAMEWORK_PLUGIN.loader(LOADER_TEXT);
22525
+ const loader = await get_loader();
22368
22526
 
22369
22527
  glb.CURRENT_APP_LOADING = loader;
22370
22528