@yuneta/gobj-js 7.9.11 → 7.10.0

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.
@@ -1414,6 +1414,7 @@ function gobj_destroy(gobj) {
1414
1414
  gobj_stop(gobj);
1415
1415
  }
1416
1416
  gobj.obflag |= obflag_t.obflag_destroying;
1417
+ purge_posted_events(gobj);
1417
1418
  let trace_creation = __trace_gobj_create_delete__(gobj);
1418
1419
  if (trace_creation) trace_machine(sprintf("💔💔⏩ destroying: %s", gobj_full_name(gobj)));
1419
1420
  let parent = gobj_parent(gobj);
@@ -2353,13 +2354,97 @@ function gobj_has_output_event(gobj, event, event_flag) {
2353
2354
  return true;
2354
2355
  }
2355
2356
  /************************************************************
2356
- * post_event, by now only in js
2357
+ * Posted events: gobj_send_event(), but on the next turn
2358
+ *
2359
+ * Same contract as the C side (see gobj.h). It exists to get out of the
2360
+ * stack you are standing on: gobj_publish_event() dispatches synchronously,
2361
+ * so a subscriber action runs inside the publisher's own stack, and
2362
+ * destroying that publisher there dismantles what is still iterating.
2363
+ *
2364
+ * The queue is drained with setTimeout(0) and NOT with queueMicrotask():
2365
+ * a microtask runs before the browser can paint or handle an input, so a
2366
+ * chain of posted events would hold the page exactly the way it used to
2367
+ * hold the event loop in C. A macrotask gives the browser its turn between
2368
+ * one event and the next.
2369
+ *
2370
+ * Delivery is a SNAPSHOT: the events queued when the drain begins are the
2371
+ * ones delivered in it, and whatever an action posts while it runs waits
2372
+ * for the following turn.
2357
2373
  ************************************************************/
2358
- function gobj_post_event(gobj, event, kw, src) {
2359
- setTimeout(() => {
2360
- if (gobj_is_destroying(gobj)) return;
2361
- gobj_send_event(gobj, event, kw, src);
2362
- }, 10);
2374
+ var MAX_POSTED_EVENTS = 1e4;
2375
+ var __dl_posted_events__ = [];
2376
+ var __posted_events_scheduled__ = false;
2377
+ function gobj_post_event(dst, event, kw, src) {
2378
+ if (!dst || !(dst instanceof GObj)) {
2379
+ log_error(`gobj_post_event(): gobj dst NULL, event ${event}`);
2380
+ return -1;
2381
+ }
2382
+ if (dst.obflag & (obflag_t.obflag_destroyed | obflag_t.obflag_destroying)) {
2383
+ log_error(`gobj_post_event(): gobj dst DESTROYING, event ${event}`);
2384
+ return -1;
2385
+ }
2386
+ if (empty_string(event)) {
2387
+ log_error(`gobj_post_event(): event EMPTY`);
2388
+ return -1;
2389
+ }
2390
+ if (!gobj_has_event(dst, event, 0)) {
2391
+ log_error(`gobj_post_event(): event NOT DEFINED in gclass ${gobj_gclass_name(dst)}, event ${event}`);
2392
+ return -1;
2393
+ }
2394
+ if (__dl_posted_events__.length >= MAX_POSTED_EVENTS) {
2395
+ log_error(`gobj_post_event(): too many posted events, this is NOT a work queue, event ${event}, pending ${__dl_posted_events__.length}`);
2396
+ return -1;
2397
+ }
2398
+ __dl_posted_events__.push({
2399
+ dst,
2400
+ event,
2401
+ kw,
2402
+ src
2403
+ });
2404
+ if (is_machine_tracing(dst, event) && !is_machine_not_tracing(src, event)) trace_machine(sprintf("📬 posted(%s%s), ev: %s, pending: %d", !dst.running ? "!!" : "", gobj_short_name(dst), event, __dl_posted_events__.length));
2405
+ if (!__posted_events_scheduled__) {
2406
+ __posted_events_scheduled__ = true;
2407
+ setTimeout(gobj_deliver_posted_events, 0);
2408
+ }
2409
+ return 0;
2410
+ }
2411
+ /************************************************************
2412
+ * How many posted events wait for delivery
2413
+ ************************************************************/
2414
+ function gobj_posted_events_size() {
2415
+ return __dl_posted_events__.length;
2416
+ }
2417
+ /************************************************************
2418
+ * Deliver the posted events. One turn, one snapshot.
2419
+ ************************************************************/
2420
+ function gobj_deliver_posted_events() {
2421
+ __posted_events_scheduled__ = false;
2422
+ let snapshot = __dl_posted_events__;
2423
+ __dl_posted_events__ = [];
2424
+ let delivered = 0;
2425
+ for (let msg of snapshot) {
2426
+ if (msg.dst.obflag & (obflag_t.obflag_destroyed | obflag_t.obflag_destroying)) continue;
2427
+ gobj_send_event(msg.dst, msg.event, msg.kw, msg.src);
2428
+ delivered++;
2429
+ }
2430
+ if (__dl_posted_events__.length > 0 && !__posted_events_scheduled__) {
2431
+ __posted_events_scheduled__ = true;
2432
+ setTimeout(gobj_deliver_posted_events, 0);
2433
+ }
2434
+ return delivered;
2435
+ }
2436
+ /************************************************************
2437
+ * Take a gobj out of the queue of posted events.
2438
+ *
2439
+ * Called from gobj_destroy(), and the two halves are not the same thing:
2440
+ * as DESTINATION the entry is dropped, as SOURCE only the pointer is
2441
+ * cleared -- the destination still wants its event, and it arrives with
2442
+ * src null, which every action already has to accept.
2443
+ ************************************************************/
2444
+ function purge_posted_events(gobj) {
2445
+ if (__dl_posted_events__.length === 0) return;
2446
+ for (let msg of __dl_posted_events__) if (msg.src === gobj) msg.src = null;
2447
+ __dl_posted_events__ = __dl_posted_events__.filter((msg) => msg.dst !== gobj);
2363
2448
  }
2364
2449
  /************************************************************
2365
2450
  * send_event
@@ -6511,6 +6596,6 @@ function register_c_ievent_cli() {
6511
6596
  return create_gclass(GCLASS_NAME);
6512
6597
  }
6513
6598
  //#endregion
6514
- export { GObj, SDATA, SDATAAUTHZ, SDATACM, SDATACM2, SDATADF, SDATAPM, SDATAPM0, SDATA_END, SDataDesc, YUNETA_VERSION, __yuno__, build_command_response, build_path, build_stats_response, clean_name, clear_timeout, cmp_two_simple_json, command_parser, createElement2, createOneHtml, create_json_record, create_template_record, current_timestamp, data_type_t, db_list_persistent_attrs, db_load_persistent_attrs, db_remove_persistent_attrs, db_save_persistent_attrs, debounce, delete_from_list, duplicate_objects, empty_string, escapeHtml, event_flag_t, gclass_add_ev_action, gclass_add_event_type, gclass_add_state, gclass_check_fsm, gclass_create, gclass_event_type, gclass_find_by_name, gclass_flag_t, gclass_unregister, getPositionRelativeToBody, get_function_name, get_now, gobj_bottom_gobj, gobj_change_parent, gobj_change_state, gobj_command, gobj_create, gobj_create2, gobj_create_default_service, gobj_create_pure_child, gobj_create_service, gobj_create_volatil, gobj_create_yuno, gobj_current_state, gobj_default_service, gobj_destroy, gobj_find_child, gobj_find_gobj, gobj_find_service, gobj_find_subscribings, gobj_find_subscriptions, gobj_flag_t, gobj_full_name, gobj_gclass_name, gobj_global_trace_level, gobj_has_attr, gobj_has_event, gobj_has_output_event, gobj_hsdata, gobj_is_destroying, gobj_is_playing, gobj_is_pure_child, gobj_is_running, gobj_is_service, gobj_is_volatil, gobj_list_persistent_attrs, gobj_list_subscriptions, gobj_load_persistent_attrs, gobj_match_children, gobj_match_children_tree, gobj_match_gobj, gobj_name, gobj_parent, gobj_pause, gobj_play, gobj_post_event, gobj_publish_event, gobj_read_attr, gobj_read_attrs, gobj_read_bool_attr, gobj_read_integer_attr, gobj_read_pointer_attr, gobj_read_str_attr, gobj_remove_persistent_attrs, gobj_repr_global_trace_levels, gobj_reset_volatil_attrs, gobj_save_persistent_attrs, gobj_search_path, gobj_send_event, gobj_services, gobj_set_bottom_gobj, gobj_set_deep_trace, gobj_set_gclass_no_trace, gobj_set_gclass_trace, gobj_set_global_no_trace, gobj_set_global_trace, gobj_set_gobj_no_trace, gobj_set_gobj_trace, gobj_set_trace_machine_format, gobj_short_name, gobj_start, gobj_start_children, gobj_start_tree, gobj_start_up, gobj_stats, gobj_stop, gobj_stop_children, gobj_stop_tree, gobj_subscribe_event, gobj_trace_level, gobj_trace_machine_format, gobj_trace_no_level, gobj_unsubscribe_event, gobj_unsubscribe_list, gobj_walk_gobj_children, gobj_walk_gobj_children_tree, gobj_write_attr, gobj_write_attrs, gobj_write_bool_attr, gobj_write_integer_attr, gobj_write_str_attr, gobj_yuno, gobj_yuno_id, gobj_yuno_name, gobj_yuno_role, id_index_in_obj_list, index_in_list, is_array, is_boolean, is_date, is_function, is_gobj, is_metadata_key, is_null, is_number, is_object, is_private_key, is_pure_number, is_string, jdb_delete, jdb_get, jdb_get_by_idx, jdb_get_topic, jdb_init, jdb_update, json_array_append, json_array_append_new, json_array_extend, json_array_remove, json_array_size, json_deep_copy, json_is_identical, json_object_del, json_object_get, json_object_set, json_object_set_new, json_object_size, json_object_update, json_object_update_existing, json_object_update_missing, json_size, jwt2json, jwtDecode, kw_clone_by_keys, kw_clone_by_not_keys, kw_collect, kw_delete, kw_find_json_in_list, kw_find_path, kw_flag_t, kw_get_bool, kw_get_dict, kw_get_dict_value, kw_get_int, kw_get_list, kw_get_local_storage_value, kw_get_pointer, kw_get_real, kw_get_str, kw_has_key, kw_match_simple, kw_pop, kw_remove_local_storage_value, kw_select, kw_set_dict_value, kw_set_local_storage_value, kw_set_subdict_value, kwid_collect, kwid_find_one_record, kwid_get_ids, kwid_match_id, kwid_new_dict, list2options, load_json_file, log_debug, log_error, log_info, log_warning, msg_iev_get_msg_type, msg_iev_get_stack, msg_iev_push_stack, msg_iev_read_key, msg_iev_set_msg_type, msg_iev_write_key, node_uuid, parseBoolean, parseSVG, refresh_language, register_c_ievent_cli, register_c_timer, register_c_yuno, safeSrc, sdata_flag_t, send_http_json_post, set_console_log_enabled, set_log_callback, set_remote_log_functions, set_timeout, set_timeout_periodic, sprintf, stats_parser, str_in_list, strcasecmp, strcmp, strncmp, strs_in_list, strstr, template_get_field_desc, timeTracker, trace_json, trace_level_t, trace_msg, treedb_decoder_fkey, treedb_decoder_hook, treedb_encoder_fkey, treedb_get_field_desc, treedb_hook_data_size, vsprintf };
6599
+ export { GObj, SDATA, SDATAAUTHZ, SDATACM, SDATACM2, SDATADF, SDATAPM, SDATAPM0, SDATA_END, SDataDesc, YUNETA_VERSION, __yuno__, build_command_response, build_path, build_stats_response, clean_name, clear_timeout, cmp_two_simple_json, command_parser, createElement2, createOneHtml, create_json_record, create_template_record, current_timestamp, data_type_t, db_list_persistent_attrs, db_load_persistent_attrs, db_remove_persistent_attrs, db_save_persistent_attrs, debounce, delete_from_list, duplicate_objects, empty_string, escapeHtml, event_flag_t, gclass_add_ev_action, gclass_add_event_type, gclass_add_state, gclass_check_fsm, gclass_create, gclass_event_type, gclass_find_by_name, gclass_flag_t, gclass_unregister, getPositionRelativeToBody, get_function_name, get_now, gobj_bottom_gobj, gobj_change_parent, gobj_change_state, gobj_command, gobj_create, gobj_create2, gobj_create_default_service, gobj_create_pure_child, gobj_create_service, gobj_create_volatil, gobj_create_yuno, gobj_current_state, gobj_default_service, gobj_deliver_posted_events, gobj_destroy, gobj_find_child, gobj_find_gobj, gobj_find_service, gobj_find_subscribings, gobj_find_subscriptions, gobj_flag_t, gobj_full_name, gobj_gclass_name, gobj_global_trace_level, gobj_has_attr, gobj_has_event, gobj_has_output_event, gobj_hsdata, gobj_is_destroying, gobj_is_playing, gobj_is_pure_child, gobj_is_running, gobj_is_service, gobj_is_volatil, gobj_list_persistent_attrs, gobj_list_subscriptions, gobj_load_persistent_attrs, gobj_match_children, gobj_match_children_tree, gobj_match_gobj, gobj_name, gobj_parent, gobj_pause, gobj_play, gobj_post_event, gobj_posted_events_size, gobj_publish_event, gobj_read_attr, gobj_read_attrs, gobj_read_bool_attr, gobj_read_integer_attr, gobj_read_pointer_attr, gobj_read_str_attr, gobj_remove_persistent_attrs, gobj_repr_global_trace_levels, gobj_reset_volatil_attrs, gobj_save_persistent_attrs, gobj_search_path, gobj_send_event, gobj_services, gobj_set_bottom_gobj, gobj_set_deep_trace, gobj_set_gclass_no_trace, gobj_set_gclass_trace, gobj_set_global_no_trace, gobj_set_global_trace, gobj_set_gobj_no_trace, gobj_set_gobj_trace, gobj_set_trace_machine_format, gobj_short_name, gobj_start, gobj_start_children, gobj_start_tree, gobj_start_up, gobj_stats, gobj_stop, gobj_stop_children, gobj_stop_tree, gobj_subscribe_event, gobj_trace_level, gobj_trace_machine_format, gobj_trace_no_level, gobj_unsubscribe_event, gobj_unsubscribe_list, gobj_walk_gobj_children, gobj_walk_gobj_children_tree, gobj_write_attr, gobj_write_attrs, gobj_write_bool_attr, gobj_write_integer_attr, gobj_write_str_attr, gobj_yuno, gobj_yuno_id, gobj_yuno_name, gobj_yuno_role, id_index_in_obj_list, index_in_list, is_array, is_boolean, is_date, is_function, is_gobj, is_metadata_key, is_null, is_number, is_object, is_private_key, is_pure_number, is_string, jdb_delete, jdb_get, jdb_get_by_idx, jdb_get_topic, jdb_init, jdb_update, json_array_append, json_array_append_new, json_array_extend, json_array_remove, json_array_size, json_deep_copy, json_is_identical, json_object_del, json_object_get, json_object_set, json_object_set_new, json_object_size, json_object_update, json_object_update_existing, json_object_update_missing, json_size, jwt2json, jwtDecode, kw_clone_by_keys, kw_clone_by_not_keys, kw_collect, kw_delete, kw_find_json_in_list, kw_find_path, kw_flag_t, kw_get_bool, kw_get_dict, kw_get_dict_value, kw_get_int, kw_get_list, kw_get_local_storage_value, kw_get_pointer, kw_get_real, kw_get_str, kw_has_key, kw_match_simple, kw_pop, kw_remove_local_storage_value, kw_select, kw_set_dict_value, kw_set_local_storage_value, kw_set_subdict_value, kwid_collect, kwid_find_one_record, kwid_get_ids, kwid_match_id, kwid_new_dict, list2options, load_json_file, log_debug, log_error, log_info, log_warning, msg_iev_get_msg_type, msg_iev_get_stack, msg_iev_push_stack, msg_iev_read_key, msg_iev_set_msg_type, msg_iev_write_key, node_uuid, parseBoolean, parseSVG, refresh_language, register_c_ievent_cli, register_c_timer, register_c_yuno, safeSrc, sdata_flag_t, send_http_json_post, set_console_log_enabled, set_log_callback, set_remote_log_functions, set_timeout, set_timeout_periodic, sprintf, stats_parser, str_in_list, strcasecmp, strcmp, strncmp, strs_in_list, strstr, template_get_field_desc, timeTracker, trace_json, trace_level_t, trace_msg, treedb_decoder_fkey, treedb_decoder_hook, treedb_encoder_fkey, treedb_get_field_desc, treedb_hook_data_size, vsprintf };
6515
6600
 
6516
6601
  //# sourceMappingURL=gobj-js.es.js.map