@yuneta/gobj-js 7.25.9 → 7.26.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.
- package/README.md +85 -24
- package/dist/gobj-js.cjs.js +176 -72
- package/dist/gobj-js.cjs.js.map +1 -1
- package/dist/gobj-js.cjs.min.js +916 -862
- package/dist/gobj-js.cjs.min.js.map +1 -1
- package/dist/gobj-js.es.js +176 -72
- package/dist/gobj-js.es.js.map +1 -1
- package/dist/gobj-js.es.min.js +1032 -978
- package/dist/gobj-js.es.min.js.map +1 -1
- package/dist/gobj-js.iife.js +176 -72
- package/dist/gobj-js.iife.js.map +1 -1
- package/dist/gobj-js.iife.min.js +923 -869
- package/dist/gobj-js.iife.min.js.map +1 -1
- package/dist/gobj-js.umd.js +176 -72
- package/dist/gobj-js.umd.js.map +1 -1
- package/dist/gobj-js.umd.min.js +923 -869
- package/dist/gobj-js.umd.min.js.map +1 -1
- package/package.json +2 -2
package/dist/gobj-js.es.js
CHANGED
|
@@ -157,7 +157,7 @@ function command_parser(gobj, command, kw, src) {}
|
|
|
157
157
|
function build_command_response(gobj, result, comment, schema, data) {
|
|
158
158
|
return {
|
|
159
159
|
result,
|
|
160
|
-
comment: comment ||
|
|
160
|
+
comment: comment || "",
|
|
161
161
|
schema: schema || {},
|
|
162
162
|
data: data || []
|
|
163
163
|
};
|
|
@@ -211,7 +211,7 @@ var __global_command_parser_fn__ = null;
|
|
|
211
211
|
var __global_stats_parser_fn__ = null;
|
|
212
212
|
var dl_global_event_types = [];
|
|
213
213
|
var _gclass_register = Object.create(null);
|
|
214
|
-
var __jn_services__ =
|
|
214
|
+
var __jn_services__ = Object.create(null);
|
|
215
215
|
var __yuno__ = null;
|
|
216
216
|
var __default_service__ = null;
|
|
217
217
|
var __inside__ = 0;
|
|
@@ -820,7 +820,8 @@ function set_default(gobj, sdata, it) {
|
|
|
820
820
|
if (!is_object(jn_value)) jn_value = {};
|
|
821
821
|
break;
|
|
822
822
|
case data_type_t.DTP_JSON:
|
|
823
|
-
if (
|
|
823
|
+
if (svalue === "" || svalue === void 0) jn_value = null;
|
|
824
|
+
else if (is_string(svalue)) try {
|
|
824
825
|
jn_value = JSON.parse(svalue);
|
|
825
826
|
} catch (error) {
|
|
826
827
|
log_error(`JSON parse error: ${error.message}`);
|
|
@@ -855,11 +856,17 @@ function json2item(gobj, sdata, it, jn_value_) {
|
|
|
855
856
|
break;
|
|
856
857
|
case data_type_t.DTP_INTEGER:
|
|
857
858
|
jn_value2 = parseInt(jn_value_);
|
|
858
|
-
if (isNaN(jn_value2))
|
|
859
|
+
if (isNaN(jn_value2)) {
|
|
860
|
+
log_error(`${gobj_short_name(gobj)}: attr NaN: ${it.name}`);
|
|
861
|
+
return -1;
|
|
862
|
+
}
|
|
859
863
|
break;
|
|
860
864
|
case data_type_t.DTP_REAL:
|
|
861
865
|
jn_value2 = Number(jn_value_);
|
|
862
|
-
if (isNaN(jn_value2))
|
|
866
|
+
if (isNaN(jn_value2)) {
|
|
867
|
+
log_error(`${gobj_short_name(gobj)}: attr NaN: ${it.name}`);
|
|
868
|
+
return -1;
|
|
869
|
+
}
|
|
863
870
|
break;
|
|
864
871
|
case data_type_t.DTP_LIST:
|
|
865
872
|
if (is_string(jn_value_)) try {
|
|
@@ -886,15 +893,11 @@ function json2item(gobj, sdata, it, jn_value_) {
|
|
|
886
893
|
}
|
|
887
894
|
break;
|
|
888
895
|
case data_type_t.DTP_JSON:
|
|
896
|
+
jn_value2 = jn_value_;
|
|
889
897
|
if (is_string(jn_value_)) try {
|
|
890
898
|
jn_value2 = JSON.parse(jn_value_);
|
|
891
899
|
} catch (error) {
|
|
892
|
-
|
|
893
|
-
}
|
|
894
|
-
else jn_value2 = jn_value_;
|
|
895
|
-
if (!is_array(jn_value2) && !is_object(jn_value2)) {
|
|
896
|
-
log_error(`attr must be a json dict/list: ${it.name}`);
|
|
897
|
-
return -1;
|
|
900
|
+
jn_value2 = jn_value_;
|
|
898
901
|
}
|
|
899
902
|
break;
|
|
900
903
|
case data_type_t.DTP_POINTER: jn_value2 = jn_value_;
|
|
@@ -1199,6 +1202,10 @@ function gobj_default_service() {
|
|
|
1199
1202
|
* find a service
|
|
1200
1203
|
************************************************************/
|
|
1201
1204
|
function gobj_find_service(service_name, verbose) {
|
|
1205
|
+
if (!is_string(service_name)) {
|
|
1206
|
+
log_error(`gobj_find_service(): service name must be a string: ${service_name}`);
|
|
1207
|
+
return null;
|
|
1208
|
+
}
|
|
1202
1209
|
service_name = service_name.toLowerCase();
|
|
1203
1210
|
let service_gobj = __jn_services__[service_name];
|
|
1204
1211
|
if (!service_gobj) {
|
|
@@ -1356,9 +1363,10 @@ function gobj_create2(gobj_name, gclass_name, kw, parent, gobj_flag) {
|
|
|
1356
1363
|
return null;
|
|
1357
1364
|
}
|
|
1358
1365
|
if (is_string(parent)) {
|
|
1359
|
-
|
|
1366
|
+
const parent_name = parent;
|
|
1367
|
+
parent = gobj_find_service(parent_name);
|
|
1360
1368
|
if (!parent) {
|
|
1361
|
-
log_warning(`parent service not found: ${
|
|
1369
|
+
log_warning(`parent service not found: ${parent_name}`);
|
|
1362
1370
|
return null;
|
|
1363
1371
|
}
|
|
1364
1372
|
}
|
|
@@ -1471,6 +1479,7 @@ function gobj_destroy(gobj) {
|
|
|
1471
1479
|
parent.gclass.gmt.mt_child_removed(parent, gobj);
|
|
1472
1480
|
}
|
|
1473
1481
|
if (gobj.gobj_flag & gobj_flag_t.gobj_flag_service) _deregister_service(gobj);
|
|
1482
|
+
if (gobj === __default_service__) __default_service__ = null;
|
|
1474
1483
|
gobj_unsubscribe_list(gobj, gobj.dl_subscriptions, true);
|
|
1475
1484
|
gobj_unsubscribe_list(gobj, gobj.dl_subscribings, true);
|
|
1476
1485
|
if (parent) {
|
|
@@ -1816,7 +1825,7 @@ function gobj_set_bottom_gobj(gobj, bottom_gobj) {
|
|
|
1816
1825
|
log_error(`gobj NULL of bad type`);
|
|
1817
1826
|
return null;
|
|
1818
1827
|
}
|
|
1819
|
-
if (gobj.bottom_gobj) log_warning(`${gobj_short_name(gobj)}: bottom_gobj already set`);
|
|
1828
|
+
if (gobj.bottom_gobj && bottom_gobj) log_warning(`${gobj_short_name(gobj)}: bottom_gobj already set`);
|
|
1820
1829
|
gobj.bottom_gobj = bottom_gobj;
|
|
1821
1830
|
}
|
|
1822
1831
|
/***************************************************************************
|
|
@@ -2231,7 +2240,7 @@ function gobj_write_attr(gobj, path, value, src) {
|
|
|
2231
2240
|
jn_attrs[key] = value;
|
|
2232
2241
|
if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(key)) gobj.priv[key] = value;
|
|
2233
2242
|
if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
|
|
2234
|
-
if (gobj.mt_writing) gobj.mt_writing(gobj, key);
|
|
2243
|
+
if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, key);
|
|
2235
2244
|
}
|
|
2236
2245
|
return 0;
|
|
2237
2246
|
}
|
|
@@ -2255,8 +2264,8 @@ function sdata_write_default_values(gobj, include_flag, exclude_flag) {
|
|
|
2255
2264
|
if (!it.name) continue;
|
|
2256
2265
|
if (exclude_flag && it.flag & exclude_flag) continue;
|
|
2257
2266
|
if (include_flag === -1 || it.flag & include_flag) {
|
|
2258
|
-
|
|
2259
|
-
if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(it.name)) gobj.priv[it.name] =
|
|
2267
|
+
set_default(gobj, gobj.jn_attrs, it);
|
|
2268
|
+
if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(it.name)) gobj.priv[it.name] = gobj.jn_attrs[it.name];
|
|
2260
2269
|
if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, it.name);
|
|
2261
2270
|
}
|
|
2262
2271
|
}
|
|
@@ -2290,7 +2299,7 @@ function gobj_write_bool_attr(gobj, name, value) {
|
|
|
2290
2299
|
let hs = gobj_hsdata2(gobj, name, false);
|
|
2291
2300
|
if (hs) {
|
|
2292
2301
|
hs[name] = parseBoolean(value);
|
|
2293
|
-
if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(name)) gobj.priv[name] =
|
|
2302
|
+
if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(name)) gobj.priv[name] = hs[name];
|
|
2294
2303
|
if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
|
|
2295
2304
|
if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, name);
|
|
2296
2305
|
}
|
|
@@ -2306,7 +2315,7 @@ function gobj_write_integer_attr(gobj, name, value) {
|
|
|
2306
2315
|
let hs = gobj_hsdata2(gobj, name, false);
|
|
2307
2316
|
if (hs) {
|
|
2308
2317
|
hs[name] = parseInt(value);
|
|
2309
|
-
if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(name)) gobj.priv[name] =
|
|
2318
|
+
if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(name)) gobj.priv[name] = hs[name];
|
|
2310
2319
|
if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
|
|
2311
2320
|
if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, name);
|
|
2312
2321
|
}
|
|
@@ -2322,7 +2331,7 @@ function gobj_write_str_attr(gobj, name, value) {
|
|
|
2322
2331
|
let hs = gobj_hsdata2(gobj, name, false);
|
|
2323
2332
|
if (hs) {
|
|
2324
2333
|
hs[name] = String(value);
|
|
2325
|
-
if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(name)) gobj.priv[name] =
|
|
2334
|
+
if (is_object(gobj.priv) && gobj.priv.hasOwnProperty(name)) gobj.priv[name] = hs[name];
|
|
2326
2335
|
if (gobj.obflag & obflag_t.obflag_created && !(gobj.obflag & obflag_t.obflag_destroyed)) {
|
|
2327
2336
|
if (gobj.gclass.gmt.mt_writing) gobj.gclass.gmt.mt_writing(gobj, name);
|
|
2328
2337
|
}
|
|
@@ -2376,15 +2385,15 @@ function gobj_change_parent(gobj, parent) {
|
|
|
2376
2385
|
log_error(`${gobj_short_name(gobj)}: gobj_change_parent() BAD TYPE of parent`);
|
|
2377
2386
|
return -1;
|
|
2378
2387
|
}
|
|
2379
|
-
if (gobj.parent && gobj.parent.mt_child_removed) gobj.parent.mt_child_removed(gobj.parent, gobj);
|
|
2388
|
+
if (gobj.parent && gobj.parent.gclass.gmt.mt_child_removed) gobj.parent.gclass.gmt.mt_child_removed(gobj.parent, gobj);
|
|
2380
2389
|
if (gobj.parent) {
|
|
2381
2390
|
_remove_child(gobj.parent, gobj);
|
|
2382
2391
|
gobj.parent = null;
|
|
2383
2392
|
}
|
|
2384
2393
|
_add_child(parent, gobj);
|
|
2385
|
-
if (parent.mt_child_added) {
|
|
2394
|
+
if (parent.gclass.gmt.mt_child_added) {
|
|
2386
2395
|
if (__trace_gobj_create_delete__(gobj)) log_debug(sprintf("👦👦🔵 child_added(%s): %s", gobj_full_name(parent), gobj_short_name(gobj)));
|
|
2387
|
-
parent.mt_child_added(parent, gobj);
|
|
2396
|
+
parent.gclass.gmt.mt_child_added(parent, gobj);
|
|
2388
2397
|
}
|
|
2389
2398
|
return 0;
|
|
2390
2399
|
}
|
|
@@ -2496,9 +2505,19 @@ function gobj_deliver_posted_events() {
|
|
|
2496
2505
|
let snapshot = __dl_posted_events__;
|
|
2497
2506
|
__dl_posted_events__ = [];
|
|
2498
2507
|
let delivered = 0;
|
|
2499
|
-
for (let
|
|
2508
|
+
for (let i = 0; i < snapshot.length; i++) {
|
|
2509
|
+
const msg = snapshot[i];
|
|
2500
2510
|
if (msg.dst.obflag & (obflag_t.obflag_destroyed | obflag_t.obflag_destroying)) continue;
|
|
2501
|
-
|
|
2511
|
+
try {
|
|
2512
|
+
gobj_send_event(msg.dst, msg.event, msg.kw, msg.src);
|
|
2513
|
+
} catch (e) {
|
|
2514
|
+
__dl_posted_events__ = snapshot.slice(i + 1).concat(__dl_posted_events__);
|
|
2515
|
+
if (__dl_posted_events__.length > 0 && !__posted_events_scheduled__) {
|
|
2516
|
+
__posted_events_scheduled__ = true;
|
|
2517
|
+
setTimeout(gobj_deliver_posted_events, 0);
|
|
2518
|
+
}
|
|
2519
|
+
throw e;
|
|
2520
|
+
}
|
|
2502
2521
|
delivered++;
|
|
2503
2522
|
}
|
|
2504
2523
|
if (__dl_posted_events__.length > 0 && !__posted_events_scheduled__) {
|
|
@@ -2576,7 +2595,16 @@ function gobj_send_event(dst, event, kw, src) {
|
|
|
2576
2595
|
let ret = -1;
|
|
2577
2596
|
try {
|
|
2578
2597
|
if (event_action.action) ret = event_action.action(dst, event, kw, src);
|
|
2579
|
-
}
|
|
2598
|
+
} catch (e) {
|
|
2599
|
+
__inside__--;
|
|
2600
|
+
if (!(e && e.__gobj_logged__)) {
|
|
2601
|
+
log_error(`${gobj_short_name(dst)}: action of ${event} in ${dst.current_state.state_name} THREW: ${e && e.stack ? e.stack : e}`);
|
|
2602
|
+
try {
|
|
2603
|
+
e.__gobj_logged__ = true;
|
|
2604
|
+
} catch (e2) {}
|
|
2605
|
+
}
|
|
2606
|
+
throw e;
|
|
2607
|
+
}
|
|
2580
2608
|
if (tracea && __trace_machine_format__ !== 1 && !(dst.obflag & obflag_t.obflag_destroyed)) trace_machine(sprintf("<- mach(%s%s^%s), st: %s, ev: %s, ret: %d", !dst.running ? "!!" : "", gobj_gclass_name(dst), gobj_name(dst), dst.current_state.state_name, event ? event : "", is_number(ret) ? ret : 0));
|
|
2581
2609
|
__inside__--;
|
|
2582
2610
|
return ret;
|
|
@@ -3247,10 +3275,22 @@ function set_remote_log_functions(remote_log_fn) {
|
|
|
3247
3275
|
f_warning = _console.warn;
|
|
3248
3276
|
}
|
|
3249
3277
|
}
|
|
3278
|
+
/************************************************************
|
|
3279
|
+
* JSON.stringify for a log line: a circular object (a gobj,
|
|
3280
|
+
* a DOM node) must not make the log call itself throw.
|
|
3281
|
+
************************************************************/
|
|
3282
|
+
function log_stringify(v) {
|
|
3283
|
+
try {
|
|
3284
|
+
return JSON.stringify(v);
|
|
3285
|
+
} catch (e) {
|
|
3286
|
+
return String(v);
|
|
3287
|
+
}
|
|
3288
|
+
}
|
|
3250
3289
|
function format_log(format) {
|
|
3251
3290
|
const args = Array.prototype.slice.call(arguments);
|
|
3252
3291
|
let output = "";
|
|
3253
3292
|
if (typeof format === "string") {
|
|
3293
|
+
if (args.length === 1) return format;
|
|
3254
3294
|
let i = 1;
|
|
3255
3295
|
output = format.replace(/%[sdifoO]/g, (match) => {
|
|
3256
3296
|
const val = args[i++];
|
|
@@ -3260,17 +3300,17 @@ function format_log(format) {
|
|
|
3260
3300
|
case "%i": return parseInt(val);
|
|
3261
3301
|
case "%f": return parseFloat(val);
|
|
3262
3302
|
case "%o":
|
|
3263
|
-
case "%O": return typeof val === "object" ?
|
|
3303
|
+
case "%O": return typeof val === "object" ? log_stringify(val) : String(val);
|
|
3264
3304
|
default: return match;
|
|
3265
3305
|
}
|
|
3266
3306
|
});
|
|
3267
|
-
const rest = args.slice(i).map((arg) => typeof arg === "object" ?
|
|
3307
|
+
const rest = args.slice(i).map((arg) => typeof arg === "object" ? log_stringify(arg) : String(arg));
|
|
3268
3308
|
if (rest.length > 0) output += " " + rest.join(" ");
|
|
3269
|
-
} else output = args.map((arg) => typeof arg === "object" ?
|
|
3309
|
+
} else output = args.map((arg) => typeof arg === "object" ? log_stringify(arg) : String(arg)).join(" ");
|
|
3270
3310
|
return output;
|
|
3271
3311
|
}
|
|
3272
|
-
function log_error(format) {
|
|
3273
|
-
let msg = format_log(format);
|
|
3312
|
+
function log_error(format, ...args) {
|
|
3313
|
+
let msg = format_log(format, ...args);
|
|
3274
3314
|
let hora = current_timestamp();
|
|
3275
3315
|
if (f_error) {
|
|
3276
3316
|
if (f_error === _console.error) {
|
|
@@ -3282,8 +3322,8 @@ function log_error(format) {
|
|
|
3282
3322
|
}
|
|
3283
3323
|
emit_log_callback("error", msg, hora);
|
|
3284
3324
|
}
|
|
3285
|
-
function log_warning(format) {
|
|
3286
|
-
let msg = format_log(format);
|
|
3325
|
+
function log_warning(format, ...args) {
|
|
3326
|
+
let msg = format_log(format, ...args);
|
|
3287
3327
|
let hora = current_timestamp();
|
|
3288
3328
|
if (f_warning) {
|
|
3289
3329
|
if (f_warning === _console.warn) {
|
|
@@ -3295,24 +3335,24 @@ function log_warning(format) {
|
|
|
3295
3335
|
}
|
|
3296
3336
|
emit_log_callback("warning", msg, hora);
|
|
3297
3337
|
}
|
|
3298
|
-
function log_info(format) {
|
|
3299
|
-
let msg = format_log(format);
|
|
3338
|
+
function log_info(format, ...args) {
|
|
3339
|
+
let msg = format_log(format, ...args);
|
|
3300
3340
|
let hora = current_timestamp();
|
|
3301
3341
|
if (f_info) {
|
|
3302
3342
|
if (console_wants("info", msg)) f_info("%c" + hora + " INFO: " + String(msg), "color:cyan");
|
|
3303
3343
|
}
|
|
3304
3344
|
emit_log_callback("info", msg, hora);
|
|
3305
3345
|
}
|
|
3306
|
-
function log_debug(format) {
|
|
3307
|
-
let msg = format_log(format);
|
|
3346
|
+
function log_debug(format, ...args) {
|
|
3347
|
+
let msg = format_log(format, ...args);
|
|
3308
3348
|
let hora = current_timestamp();
|
|
3309
3349
|
if (f_debug) {
|
|
3310
3350
|
if (console_wants("debug", msg)) f_debug("%c" + hora + " DEBUG: " + String(msg), "color:silver");
|
|
3311
3351
|
}
|
|
3312
3352
|
emit_log_callback("debug", msg, hora);
|
|
3313
3353
|
}
|
|
3314
|
-
function trace_msg(format) {
|
|
3315
|
-
let msg = format_log(format);
|
|
3354
|
+
function trace_msg(format, ...args) {
|
|
3355
|
+
let msg = format_log(format, ...args);
|
|
3316
3356
|
let hora = current_timestamp();
|
|
3317
3357
|
if (f_debug) {
|
|
3318
3358
|
if (console_wants("msg", msg)) f_debug("%c" + hora + " MSG: " + String(msg), "color:cyan");
|
|
@@ -3861,6 +3901,8 @@ function cmp_two_simple_json(jn_var1, jn_var2) {
|
|
|
3861
3901
|
if (is_number(jn_var1) || is_number(jn_var2)) {
|
|
3862
3902
|
let val1 = Number(jn_var1);
|
|
3863
3903
|
let val2 = Number(jn_var2);
|
|
3904
|
+
if (Number.isNaN(val1)) val1 = 0;
|
|
3905
|
+
if (Number.isNaN(val2)) val2 = 0;
|
|
3864
3906
|
if (val1 > val2) return 1;
|
|
3865
3907
|
else if (val1 < val2) return -1;
|
|
3866
3908
|
else return 0;
|
|
@@ -3928,6 +3970,28 @@ function kw_has_key(kw, key) {
|
|
|
3928
3970
|
return false;
|
|
3929
3971
|
}
|
|
3930
3972
|
/************************************************************
|
|
3973
|
+
* A key that reaches the prototype chain instead of the data:
|
|
3974
|
+
* "__proto__", "constructor" or "prototype" when the object
|
|
3975
|
+
* does not hold it as its OWN key. A walk through one of them
|
|
3976
|
+
* read, or WROTE, Object.prototype: the flat id
|
|
3977
|
+
* "__proto__`polluted" set a key on every object of the page.
|
|
3978
|
+
* In C they are keys like any other, so here too: read them
|
|
3979
|
+
* only as own keys, and write "__proto__" as an own key.
|
|
3980
|
+
************************************************************/
|
|
3981
|
+
function is_prototype_segment(obj, key) {
|
|
3982
|
+
if (key === "__proto__" || key === "constructor" || key === "prototype") return !Object.prototype.hasOwnProperty.call(obj, key);
|
|
3983
|
+
return false;
|
|
3984
|
+
}
|
|
3985
|
+
function set_own_key(obj, key, value) {
|
|
3986
|
+
if (key === "__proto__") Object.defineProperty(obj, key, {
|
|
3987
|
+
value,
|
|
3988
|
+
writable: true,
|
|
3989
|
+
enumerable: true,
|
|
3990
|
+
configurable: true
|
|
3991
|
+
});
|
|
3992
|
+
else obj[key] = value;
|
|
3993
|
+
}
|
|
3994
|
+
/************************************************************
|
|
3931
3995
|
* The value at `path` (keys joined by a backtick), as the C
|
|
3932
3996
|
* kw_find_path() finds it: undefined when it is not there.
|
|
3933
3997
|
* A kw that is not a dict or a list is LOGGED ("kw must be list
|
|
@@ -3954,7 +4018,12 @@ function kw_find_path(gobj, kw, path, verbose) {
|
|
|
3954
4018
|
}
|
|
3955
4019
|
let ss = path.split("`");
|
|
3956
4020
|
let len = ss.length;
|
|
3957
|
-
for (let i = 0; i < len
|
|
4021
|
+
for (let i = 0; i < len; i++) {
|
|
4022
|
+
if (is_prototype_segment(kw, ss[i])) {
|
|
4023
|
+
if (verbose) log_error(`${prefix}path not found: '${path}'`);
|
|
4024
|
+
return;
|
|
4025
|
+
}
|
|
4026
|
+
if (i === len - 1) break;
|
|
3958
4027
|
kw = kw[ss[i]];
|
|
3959
4028
|
if (kw === void 0 || kw === null) {
|
|
3960
4029
|
if (verbose) log_error(`${prefix}path not found: '${path}'`);
|
|
@@ -4337,17 +4406,13 @@ function kw_set_dict_value(gobj, kw, path, value) {
|
|
|
4337
4406
|
return -1;
|
|
4338
4407
|
}
|
|
4339
4408
|
let ss = path.split("`");
|
|
4340
|
-
if (ss.length <= 1) {
|
|
4341
|
-
kw[path] = value;
|
|
4342
|
-
return 0;
|
|
4343
|
-
}
|
|
4344
4409
|
let len = ss.length;
|
|
4345
4410
|
for (let i = 0; i < len; i++) {
|
|
4346
4411
|
let key = ss[i];
|
|
4347
|
-
if (i === len - 1) kw
|
|
4412
|
+
if (i === len - 1) set_own_key(kw, key, value);
|
|
4348
4413
|
else {
|
|
4349
|
-
let seg = kw[key];
|
|
4350
|
-
if (seg === void 0) kw
|
|
4414
|
+
let seg = is_prototype_segment(kw, key) ? void 0 : kw[key];
|
|
4415
|
+
if (seg === void 0) set_own_key(kw, key, {});
|
|
4351
4416
|
else if (!is_object(seg) && !is_array(seg)) {
|
|
4352
4417
|
log_error(`${gobj ? gobj_short_name(gobj) + ": " : ""}kw_set_dict_value(): segment '${key}' is not a dict or a list: '${path}'`);
|
|
4353
4418
|
return -1;
|
|
@@ -4402,9 +4467,9 @@ function _kw_match_simple(kw, jn_filter, prefix_path) {
|
|
|
4402
4467
|
if (!matched) break;
|
|
4403
4468
|
continue;
|
|
4404
4469
|
}
|
|
4405
|
-
let jn_record_value = kw_get_dict_value(0, kw, path, 0, 0);
|
|
4406
|
-
if (
|
|
4407
|
-
if (
|
|
4470
|
+
let jn_record_value = kw_get_dict_value(0, kw, path, void 0, 0);
|
|
4471
|
+
if (jn_record_value === void 0) jn_record_value = json_object_get(kw, path);
|
|
4472
|
+
if (jn_record_value === void 0) {
|
|
4408
4473
|
matched = false;
|
|
4409
4474
|
break;
|
|
4410
4475
|
}
|
|
@@ -4523,10 +4588,11 @@ If paths are empty return empty
|
|
|
4523
4588
|
***************************************************************************/
|
|
4524
4589
|
function kw_clone_by_not_keys(gobj, kw, keys, verbose) {
|
|
4525
4590
|
let kw_clone = {};
|
|
4591
|
+
if (!is_object(kw)) return kw_clone;
|
|
4526
4592
|
json_object_update(kw_clone, kw);
|
|
4527
4593
|
if (is_string(keys) && !empty_string(keys)) {
|
|
4528
4594
|
let key = keys;
|
|
4529
|
-
if (
|
|
4595
|
+
if (kw.hasOwnProperty(key)) json_object_del(kw_clone, key);
|
|
4530
4596
|
else if (verbose) log_error(`${gobj_short_name(gobj)}: key not found: ${key}`);
|
|
4531
4597
|
} else if (is_object(keys) && json_object_size(keys) > 0) {
|
|
4532
4598
|
for (let key of Object.keys(keys)) if (kw.hasOwnProperty(key)) json_object_del(kw_clone, key);
|
|
@@ -5486,9 +5552,15 @@ parent: document.body
|
|
|
5486
5552
|
* will be 'data-i18n' attr
|
|
5487
5553
|
*
|
|
5488
5554
|
* content -> string | [createElement2() or parameters of createElement2]
|
|
5555
|
+
* | HTMLElement | SVGElement | Text
|
|
5489
5556
|
* if string begins with '<' then
|
|
5490
5557
|
* it will be converted to HTMLElement
|
|
5491
5558
|
* content = createOneHtml(string)
|
|
5559
|
+
* ⚠️ So a string is MARKUP when it starts with '<': never
|
|
5560
|
+
* pass DATA (a value from a backend, a name a user typed)
|
|
5561
|
+
* as a bare string, or "<img src=x onerror=...>" runs.
|
|
5562
|
+
* Pass it as a Text node, which is always text:
|
|
5563
|
+
* ['span', {}, document.createTextNode(value)]
|
|
5492
5564
|
* if attrs['i18n'] is not empty then (or 'data-i18n' or 'data_i18next')
|
|
5493
5565
|
* it will be overridden with the translation
|
|
5494
5566
|
* content = translate(attrs['i18n']));
|
|
@@ -5927,7 +5999,7 @@ function flat2json(flat) {
|
|
|
5927
5999
|
current[seg] = flat[key];
|
|
5928
6000
|
} else {
|
|
5929
6001
|
if (Object.prototype.hasOwnProperty.call(current, seg)) throw new Error(`flat2json: '${key}' is written twice, or once as a value and once as a container`);
|
|
5930
|
-
current
|
|
6002
|
+
set_own_key(current, seg, flat[key]);
|
|
5931
6003
|
}
|
|
5932
6004
|
break;
|
|
5933
6005
|
}
|
|
@@ -5940,10 +6012,10 @@ function flat2json(flat) {
|
|
|
5940
6012
|
current[seg] = child;
|
|
5941
6013
|
}
|
|
5942
6014
|
} else {
|
|
5943
|
-
child = current[seg];
|
|
6015
|
+
child = is_prototype_segment(current, seg) ? void 0 : current[seg];
|
|
5944
6016
|
if (child === void 0) {
|
|
5945
6017
|
child = next_is_index ? [] : {};
|
|
5946
|
-
current
|
|
6018
|
+
set_own_key(current, seg, child);
|
|
5947
6019
|
}
|
|
5948
6020
|
}
|
|
5949
6021
|
if (child === null || typeof child !== "object") throw new Error(`flat2json: '${key}' walks through a value: the same id is a leaf and a container at once`);
|
|
@@ -6706,6 +6778,7 @@ function mt_stop$1(gobj) {
|
|
|
6706
6778
|
***************************************************************/
|
|
6707
6779
|
function mt_play(gobj) {
|
|
6708
6780
|
let default_service = gobj_default_service();
|
|
6781
|
+
if (!default_service) return 0;
|
|
6709
6782
|
if (!gobj_is_running(default_service)) gobj_start(default_service);
|
|
6710
6783
|
if (!gobj_is_playing(default_service)) gobj_play(default_service);
|
|
6711
6784
|
return 0;
|
|
@@ -6714,7 +6787,8 @@ function mt_play(gobj) {
|
|
|
6714
6787
|
* Framework Method: Pause
|
|
6715
6788
|
***************************************************************/
|
|
6716
6789
|
function mt_pause(gobj) {
|
|
6717
|
-
|
|
6790
|
+
let default_service = gobj_default_service();
|
|
6791
|
+
if (default_service && gobj_is_playing(default_service)) gobj_pause(default_service);
|
|
6718
6792
|
return 0;
|
|
6719
6793
|
}
|
|
6720
6794
|
/***************************************************************
|
|
@@ -6970,6 +7044,7 @@ var __gclass__ = null;
|
|
|
6970
7044
|
function mt_create(gobj) {
|
|
6971
7045
|
let priv = gobj.priv;
|
|
6972
7046
|
priv.gobj_timer = gobj_create_pure_child(gobj_name(gobj), "C_TIMER", {}, gobj);
|
|
7047
|
+
priv.ws_seq = 0;
|
|
6973
7048
|
priv.url = gobj_read_str_attr(gobj, "url");
|
|
6974
7049
|
priv.remote_yuno_name = gobj_read_str_attr(gobj, "remote_yuno_name");
|
|
6975
7050
|
priv.remote_yuno_role = gobj_read_str_attr(gobj, "remote_yuno_role");
|
|
@@ -7004,6 +7079,16 @@ function mt_writing(gobj, path) {
|
|
|
7004
7079
|
function mt_start(gobj) {
|
|
7005
7080
|
let priv = gobj.priv;
|
|
7006
7081
|
priv.retry_ms = 0;
|
|
7082
|
+
if (gobj_current_state(gobj) !== "ST_DISCONNECTED") {
|
|
7083
|
+
gobj_send_event(gobj, "EV_ON_CLOSE", {
|
|
7084
|
+
url: priv.url,
|
|
7085
|
+
ws_seq: priv.ws_seq,
|
|
7086
|
+
code: 1e3,
|
|
7087
|
+
reason: "restarted",
|
|
7088
|
+
was_clean: true
|
|
7089
|
+
}, gobj);
|
|
7090
|
+
clear_timeout(priv.gobj_timer);
|
|
7091
|
+
}
|
|
7007
7092
|
priv.websocket = setup_websocket(gobj);
|
|
7008
7093
|
return 0;
|
|
7009
7094
|
}
|
|
@@ -7138,10 +7223,16 @@ function setup_websocket(gobj) {
|
|
|
7138
7223
|
log_error(`${gobj_short_name(gobj)}: Failed to initialize WebSocket.`);
|
|
7139
7224
|
return null;
|
|
7140
7225
|
}
|
|
7226
|
+
const ws_seq = ++gobj.priv.ws_seq;
|
|
7141
7227
|
websocket.onopen = () => {
|
|
7142
|
-
|
|
7228
|
+
if (ws_seq !== gobj.priv.ws_seq || gobj_is_destroying(gobj)) return;
|
|
7229
|
+
gobj_send_event(gobj, "EV_ON_OPEN", {
|
|
7230
|
+
url,
|
|
7231
|
+
ws_seq
|
|
7232
|
+
}, gobj);
|
|
7143
7233
|
};
|
|
7144
7234
|
websocket.onmessage = (e) => {
|
|
7235
|
+
if (ws_seq !== gobj.priv.ws_seq || gobj_is_destroying(gobj)) return;
|
|
7145
7236
|
gobj_send_event(gobj, "EV_ON_MESSAGE", {
|
|
7146
7237
|
url,
|
|
7147
7238
|
data: e.data
|
|
@@ -7149,9 +7240,13 @@ function setup_websocket(gobj) {
|
|
|
7149
7240
|
};
|
|
7150
7241
|
websocket.onclose = (e) => {
|
|
7151
7242
|
if (gobj_is_destroying(gobj)) return;
|
|
7243
|
+
if (ws_seq !== gobj.priv.ws_seq) return;
|
|
7152
7244
|
if (!gobj_read_bool_attr(gobj_yuno(), "browser_beforeunload")) gobj_send_event(gobj, "EV_ON_CLOSE", {
|
|
7153
7245
|
url,
|
|
7154
|
-
|
|
7246
|
+
ws_seq,
|
|
7247
|
+
code: e.code,
|
|
7248
|
+
reason: e.reason,
|
|
7249
|
+
was_clean: e.wasClean
|
|
7155
7250
|
}, gobj);
|
|
7156
7251
|
else log_warning("Close websocket by unload page");
|
|
7157
7252
|
};
|
|
@@ -7172,7 +7267,7 @@ function close_websocket(gobj, code = 1e3, reason = "") {
|
|
|
7172
7267
|
try {
|
|
7173
7268
|
websocket.close(code, reason);
|
|
7174
7269
|
} catch (e) {
|
|
7175
|
-
log_error(
|
|
7270
|
+
log_error(`${gobj_short_name(gobj)}: Error closing WebSocket: ${e.message}`);
|
|
7176
7271
|
}
|
|
7177
7272
|
}
|
|
7178
7273
|
/***************************************************************
|
|
@@ -7298,29 +7393,29 @@ function iev_create_from_json(gobj, data) {
|
|
|
7298
7393
|
try {
|
|
7299
7394
|
x = JSON.parse(data);
|
|
7300
7395
|
} catch (e) {
|
|
7301
|
-
|
|
7396
|
+
log_warning(`${gobj_short_name(gobj)}: parsing inter_event json: ${e}`);
|
|
7302
7397
|
return null;
|
|
7303
7398
|
}
|
|
7304
7399
|
if (!(x instanceof Object)) {
|
|
7305
|
-
|
|
7400
|
+
log_warning(`${gobj_short_name(gobj)}: parsing inter_event: websocket data not a json object`);
|
|
7306
7401
|
return null;
|
|
7307
7402
|
}
|
|
7308
7403
|
let event = x["event"];
|
|
7309
7404
|
if (!event) {
|
|
7310
|
-
|
|
7405
|
+
log_warning(`${gobj_short_name(gobj)}: parsing inter_event: no event`);
|
|
7311
7406
|
return null;
|
|
7312
7407
|
}
|
|
7313
7408
|
if (typeof event !== "string") {
|
|
7314
|
-
|
|
7409
|
+
log_warning(`${gobj_short_name(gobj)}: parsing inter_event: event not a string`);
|
|
7315
7410
|
return null;
|
|
7316
7411
|
}
|
|
7317
7412
|
let kw = x["kw"];
|
|
7318
7413
|
if (!kw) {
|
|
7319
|
-
|
|
7414
|
+
log_warning(`${gobj_short_name(gobj)}: parsing inter_kw: no kw`);
|
|
7320
7415
|
return null;
|
|
7321
7416
|
}
|
|
7322
7417
|
if (!(kw instanceof Object)) {
|
|
7323
|
-
|
|
7418
|
+
log_warning(`${gobj_short_name(gobj)}: parsing inter_event: kw not a json object`);
|
|
7324
7419
|
return null;
|
|
7325
7420
|
}
|
|
7326
7421
|
return {
|
|
@@ -7380,10 +7475,9 @@ function ac_on_open(gobj, event, kw, src) {
|
|
|
7380
7475
|
***************************************************************/
|
|
7381
7476
|
function ac_on_close(gobj, event, kw, src) {
|
|
7382
7477
|
let priv = gobj.priv;
|
|
7383
|
-
let e = kw.e;
|
|
7384
7478
|
let url = kw.url;
|
|
7385
7479
|
set_remote_log_functions();
|
|
7386
|
-
log_warning(`${gobj_short_name(gobj)}: WebSocket closed ${url} (Code: ${
|
|
7480
|
+
log_warning(`${gobj_short_name(gobj)}: WebSocket closed ${url} (Code: ${kw.code}, Reason: "${kw.reason}", Clean: ${kw.was_clean})`);
|
|
7387
7481
|
if (priv.websocket) {
|
|
7388
7482
|
priv.websocket.onopen = null;
|
|
7389
7483
|
priv.websocket.onmessage = null;
|
|
@@ -7400,15 +7494,15 @@ function ac_on_close(gobj, event, kw, src) {
|
|
|
7400
7494
|
remote_yuno_service: priv.remote_yuno_service
|
|
7401
7495
|
});
|
|
7402
7496
|
} else {
|
|
7403
|
-
log_warning(`${gobj_short_name(gobj)}: EV_ON_OPEN_ERROR cannot open ${url} (Code: ${
|
|
7497
|
+
log_warning(`${gobj_short_name(gobj)}: EV_ON_OPEN_ERROR cannot open ${url} (Code: ${kw.code}, Reason: "${kw.reason}", Clean: ${kw.was_clean})`);
|
|
7404
7498
|
gobj_publish_event(gobj, "EV_ON_OPEN_ERROR", {
|
|
7405
7499
|
url,
|
|
7406
7500
|
remote_yuno_name: priv.remote_yuno_name,
|
|
7407
7501
|
remote_yuno_role: priv.remote_yuno_role,
|
|
7408
7502
|
remote_yuno_service: priv.remote_yuno_service,
|
|
7409
|
-
code:
|
|
7410
|
-
reason:
|
|
7411
|
-
was_clean:
|
|
7503
|
+
code: kw.code,
|
|
7504
|
+
reason: kw.reason,
|
|
7505
|
+
was_clean: kw.was_clean
|
|
7412
7506
|
});
|
|
7413
7507
|
}
|
|
7414
7508
|
if (gobj_is_running(gobj)) set_timeout(priv.gobj_timer, next_retry(gobj));
|
|
@@ -7506,6 +7600,10 @@ function ac_identity_card_ack(gobj, event, kw, src) {
|
|
|
7506
7600
|
function ac_on_message(gobj, event, kw, src) {
|
|
7507
7601
|
let url = gobj.priv.url;
|
|
7508
7602
|
let iev_msg = iev_create_from_json(gobj, kw.data);
|
|
7603
|
+
if (!iev_msg) {
|
|
7604
|
+
log_warning(`${gobj_short_name(gobj)}: frame dropped from ${url}: ${String(kw.data).substring(0, 256)}`);
|
|
7605
|
+
return -1;
|
|
7606
|
+
}
|
|
7509
7607
|
if (is_traffic_tracing(gobj)) {
|
|
7510
7608
|
let prefix = gobj_name(gobj_yuno()) + " <== " + url;
|
|
7511
7609
|
let size = kw.data.length;
|
|
@@ -7531,8 +7629,14 @@ function ac_on_message(gobj, event, kw, src) {
|
|
|
7531
7629
|
return 0;
|
|
7532
7630
|
}
|
|
7533
7631
|
let iev_dst_service = kw_get_str(gobj, event_id, "dst_service", "");
|
|
7534
|
-
if (msg_type === "__subscribing__")
|
|
7535
|
-
|
|
7632
|
+
if (msg_type === "__subscribing__") {
|
|
7633
|
+
log_warning(`${gobj_short_name(gobj)}: subscription event ignored, I'm client (service: ${iev_dst_service}, event: ${iev_event})`);
|
|
7634
|
+
return -1;
|
|
7635
|
+
}
|
|
7636
|
+
if (msg_type === "__unsubscribing__") {
|
|
7637
|
+
log_warning(`${gobj_short_name(gobj)}: unsubscription event ignored, I'm client (service: ${iev_dst_service}, event: ${iev_event})`);
|
|
7638
|
+
return -1;
|
|
7639
|
+
}
|
|
7536
7640
|
if (gobj_has_event(gobj, iev_event, event_flag_t.EVF_PUBLIC_EVENT)) {
|
|
7537
7641
|
gobj_send_event(gobj, iev_event, iev_kw, gobj);
|
|
7538
7642
|
return 0;
|