@yuneta/gobj-js 7.26.21 → 7.26.23
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 +57 -5
- package/dist/gobj-js.cjs.js +861 -200
- package/dist/gobj-js.cjs.js.map +1 -1
- package/dist/gobj-js.cjs.min.js +2316 -1846
- package/dist/gobj-js.cjs.min.js.map +1 -1
- package/dist/gobj-js.es.js +860 -201
- package/dist/gobj-js.es.js.map +1 -1
- package/dist/gobj-js.es.min.js +2165 -1693
- package/dist/gobj-js.es.min.js.map +1 -1
- package/dist/gobj-js.iife.js +861 -200
- package/dist/gobj-js.iife.js.map +1 -1
- package/dist/gobj-js.iife.min.js +2120 -1650
- package/dist/gobj-js.iife.min.js.map +1 -1
- package/dist/gobj-js.umd.js +861 -200
- package/dist/gobj-js.umd.js.map +1 -1
- package/dist/gobj-js.umd.min.js +2120 -1650
- package/dist/gobj-js.umd.min.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -282,7 +282,9 @@ const attrs_table = [
|
|
|
282
282
|
|
|
283
283
|
**Data types (`data_type_t`):** `DTP_STRING`, `DTP_BOOLEAN`, `DTP_INTEGER`, `DTP_REAL`, `DTP_LIST`, `DTP_DICT`, `DTP_JSON`, `DTP_POINTER`
|
|
284
284
|
|
|
285
|
-
**Flags (`sdata_flag_t`):** `SDF_RD`, `SDF_WR`, `SDF_PERSIST`, `SDF_STATS`, `SDF_AUTHZ_R`, `SDF_AUTHZ_W`, `SDF_REQUIRED`, `SDF_VOLATIL`
|
|
285
|
+
**Flags (`sdata_flag_t`):** `SDF_RD`, `SDF_WR`, `SDF_PERSIST`, `SDF_STATS`, `SDF_AUTHZ_R`, `SDF_AUTHZ_W`, `SDF_REQUIRED`, `SDF_VOLATIL`, `SDF_SECRET`
|
|
286
|
+
|
|
287
|
+
**A value is read as the attribute's type, as in C** (`gobj_write_attr()`, the kw of `gobj_create()`, `gobj_write_attrs()`, the persistent attrs; 7.26.22+): a string for a boolean, integer, real, list or dict is read from its text by the C command parser's grammar (`command_parameter_from_json()`: `"yes"` is `true`, `"42"` is 42, `"007"` and `"12abc"` are refused), a number or a boolean as the exact type (`2.7` to an integer is refused). A refused value is not written: one `log_error` names the attr, its type, why and the value (masked, capped; a `SDF_SECRET` one never shown). A key of a kw whose value is `undefined` is an absent key; `gobj_write_attr()` of `undefined` to a typed attr is refused. The typed writers read the value as THEIR type by the same grammar (`gobj_write_integer_attr(g, "x", 2.5)` is refused, `gobj_write_bool_attr(g, "on", "yes")` is `true`), and `gobj_write_str_attr()` writes `null`/`undefined` as `""`, never the text `"null"`.
|
|
286
288
|
|
|
287
289
|
### Events & Pub-Sub
|
|
288
290
|
|
|
@@ -415,6 +417,45 @@ gobj_is_volatil(gobj) // → boolean
|
|
|
415
417
|
gobj_is_pure_child(gobj) // → boolean
|
|
416
418
|
```
|
|
417
419
|
|
|
420
|
+
**A gobj is not destroyed under code that still runs on it** (7.26.22+, as the
|
|
421
|
+
C kernel since 7.26.10). `gobj_publish_event()` and `gobj_send_event()` run
|
|
422
|
+
synchronously, and the code of the publisher (or of the outer action) goes on
|
|
423
|
+
when they return. So `gobj_destroy()` logs an ERROR with the stack when it
|
|
424
|
+
destroys the publisher of a publication in progress, or one of its ancestors —
|
|
425
|
+
*"Destroying a gobj while its tree is publishing"* — or a gobj whose outer
|
|
426
|
+
action is still running — *"Destroying a gobj while one of its actions is
|
|
427
|
+
still running"*. The line names `destroying`, `publisher`/`running`, `event`,
|
|
428
|
+
`destroyer` and `inner_event`. The destroy is done all the same. A gobj that
|
|
429
|
+
destroys itself in its own action, and a host that destroys its transport in
|
|
430
|
+
the transport's `EV_STOPPED`, are not errors.
|
|
431
|
+
|
|
432
|
+
The fix is to leave the stack: post an event to yourself, and destroy in its
|
|
433
|
+
action. The event is an INPUT event of your gclass (FSM and `event_types`):
|
|
434
|
+
|
|
435
|
+
```javascript
|
|
436
|
+
// Wrong: EV_TIMEOUT comes from the C_TIMER child, inside its publication.
|
|
437
|
+
function ac_timeout(gobj, event, kw, src) {
|
|
438
|
+
gobj_stop(src);
|
|
439
|
+
gobj_destroy(src);
|
|
440
|
+
return 0;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// Right: the destroy runs on the next turn, from a clean stack.
|
|
444
|
+
function ac_timeout(gobj, event, kw, src) {
|
|
445
|
+
gobj_post_event(gobj, "EV_TIMER_DONE", {timer: gobj_name(src)}, gobj);
|
|
446
|
+
return 0;
|
|
447
|
+
}
|
|
448
|
+
function ac_timer_done(gobj, event, kw, src) {
|
|
449
|
+
let timer = gobj.priv.timer; // resolve the identity the kw carries
|
|
450
|
+
if(timer && gobj_name(timer) === kw.timer) {
|
|
451
|
+
gobj_stop(timer);
|
|
452
|
+
gobj_destroy(timer);
|
|
453
|
+
gobj.priv.timer = null;
|
|
454
|
+
}
|
|
455
|
+
return 0;
|
|
456
|
+
}
|
|
457
|
+
```
|
|
458
|
+
|
|
418
459
|
### State Machine
|
|
419
460
|
|
|
420
461
|
```javascript
|
|
@@ -678,6 +719,7 @@ mask_secrets_inline("curl -H 'Authorization: Bearer abc' u")
|
|
|
678
719
|
mask_secrets_inline("sent Bearer mF_9.B5f-4.1JqM") // → "sent Bearer ********"
|
|
679
720
|
mask_secrets_inline("the bearer of this letter") // → null: prose
|
|
680
721
|
mask_secrets_inline("\"password\": hunter2") // → "\"password\": ********"
|
|
722
|
+
mask_secrets_inline("GET https://h/get?token=abc&x=1") // → "GET https://h/get?token=********&x=1"
|
|
681
723
|
json_mask_secrets({user: "a", password: "x"}) // → {user: "a", password: "********"}
|
|
682
724
|
json_mask_secrets({note: "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ4In0.c2ln"})
|
|
683
725
|
// → {note: "********"}: a JWT under any key
|
|
@@ -692,9 +734,13 @@ one a cap cut), and after `Bearer` or `Basic` the word that can be a credential
|
|
|
692
734
|
-- quoted, after the scheme doubled, or not a word of prose (a digit, a symbol,
|
|
693
735
|
a character that is no ASCII, its case mixed, 24 characters or more; for
|
|
694
736
|
`Bearer` 8 at least, for `Basic` a run of base64 that decodes to a
|
|
695
|
-
`user:password`).
|
|
696
|
-
characters
|
|
697
|
-
|
|
737
|
+
`user:password`). The name of a `name=value` is also the run of name
|
|
738
|
+
characters before the `=`, as in a query string (`https://h/get?token=x`). A
|
|
739
|
+
name is judged by its last 128 bytes of UTF-8 and its case folded in ASCII, as
|
|
740
|
+
C judges it. Each rule judges the text as it came, and a run of characters to
|
|
741
|
+
mask is one `********`: nothing that 7.26.19 or 7.26.20 masked is shown, but
|
|
742
|
+
the word after a bare `Bearer` that cannot be a credential, and a name that C
|
|
743
|
+
judges otherwise (over 128 bytes, or with a letter that is no ASCII). A key
|
|
698
744
|
is judged as a name, never as a value: a key that is itself a credential (a
|
|
699
745
|
dict keyed by tokens, `{"eyJ...": 1}`) is shown as it is. A NUL in a string is
|
|
700
746
|
read as a blank; linear and bounded (a text over 4 MB is not shown at all).
|
|
@@ -910,7 +956,11 @@ set_timeout_periodic(timer_gobj, 1000);
|
|
|
910
956
|
clear_timeout(timer_gobj);
|
|
911
957
|
```
|
|
912
958
|
|
|
913
|
-
Events published: `EV_TIMEOUT`, `EV_TIMEOUT_PERIODIC
|
|
959
|
+
Events published: `EV_TIMEOUT`, `EV_TIMEOUT_PERIODIC`. They go to the
|
|
960
|
+
`subscriber` attr, else, for a pure child, to its parent, which the timer
|
|
961
|
+
subscribes in `mt_create` — the C timer's rule. Up to 7.26.21 a pure child
|
|
962
|
+
SENT the timeout to its parent instead of publishing it (and to its parent
|
|
963
|
+
even when it had a `subscriber`).
|
|
914
964
|
|
|
915
965
|
Attributes: `subscriber`, `periodic`, `msec`
|
|
916
966
|
|
|
@@ -932,6 +982,8 @@ let remote = gobj_create_service("backend", "C_IEVENT_CLI", {
|
|
|
932
982
|
|
|
933
983
|
Key attributes: `url`, `jwt`, `wanted_yuno_role`, `wanted_yuno_name`, `wanted_yuno_service`, `remote_yuno_role`, `remote_yuno_name`, `remote_yuno_service`, `required_services`, `timeout_retry`, `timeout_retry_max`
|
|
934
984
|
|
|
985
|
+
Its events (`EV_ON_OPEN`, `EV_ON_CLOSE`, `EV_ON_OPEN_ERROR`, `EV_ON_ID_NAK` and every message that names no service) are PUBLISHED: to the `subscriber` attr, else, for a pure child, to its parent, which it subscribes in `mt_create` — one subscription, as the C transport. Up to 7.26.21 a pure child SENT three of them to its parent and subscribed nobody, so its parent never heard `EV_ON_CLOSE` / `EV_ON_OPEN_ERROR`.
|
|
986
|
+
|
|
935
987
|
**`required_services`** (default `[]`) is the list this link advertises in its
|
|
936
988
|
identity_card, which the remote's `C_AUTHZ` uses to authorize commands. It is
|
|
937
989
|
**per link**: empty falls back to the yuno's own `required_services`, so a
|