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