nv-facutil-basic
install
- npm install nv-facutil-basic
usage
example
const fac_bsc = require("nv-facutil-basic");
is_node
> fac_bsc.is_node()
true
>
ref AND external TYPE
const {creat_external,is_external,creat_ref,is_ref} = require("nv-facutil-basic")
external (NOT real External, just a-TYPE-NOT-Object,to stop visit)
> var ex = creat_external()
> ex
___External___ {}
> ex.a = 100
100
> ex.b =100
100
> ex
___External___ { a: 100, b: 100 }
>
> ex instanceof Object
false
>
> JSON.stringify(ex)
'{"a":100,"b":100}'
>
> is_external(ex)
true
>
> ex.
ex.constructor
ex.a ex.b
> Object.getOwnPropertyDescriptors(ex)
{
a: { value: 100, writable: true, enumerable: true, configurable: true },
b: { value: 100, writable: true, enumerable: true, configurable: true }
}
>
> Object.getPrototypeOf(ex)
[Object: null prototype] {}
>
ref (NOT real weakref ,just a-TYPE-NOT-Object,to stop visit AND to hold circular)
> var ref = creat_ref([1,2,3])
> ref
___Ref___ { _ptr: [ 1, 2, 3 ] }
> ref instanceof Object
false
> is_ref(ref)
true
>
repr and display
class Cls {
constructor(){
this.tag="div"
}
}
function repr(that,stag,etag) {
return(stag+that.tag+etag)
}
fac_bsc.add_repr(Cls,repr,'<','>')
> var o = new Cls()
> o
<div>
>
> class SomeCls {}
> fac_bsc.add_string_tag(SomeCls,that=>'kkk')
> var o = new SomeCls()
> o
SomeCls [kkk] {}
>
indent
> var s = `
... aaa
... bbb
... ccc
... `
>
> s
'\naaa\nbbb\nccc\n'
>
> console.log(fac_bsc.indent(s,2))
aaa
bbb
ccc
> console.log(fac_bsc.indent(s,2,"\t"))
aaa
bbb
ccc
> console.log(fac_bsc.indent(s,3,"@"))
@@@
@@@aaa
@@@bbb
@@@ccc
@@@
>
id
> fac_bsc.creat_id()
'5055a812-2b24-4c9e-ab11-87088e51203c'
> fac_bsc.get_abbr('5055a812-2b24-4c9e-ab11-87088e51203c')
'5055a812'
>
global consts
fac_bsc.creat_reserved(['EPSILON','ε'],['LAMBDA','λ'])
> EPSILON
'ε'
> LAMBDA
'λ'
> Object.getOwnPropertyDescriptors(global).EPSILON
{ value: 'ε', writable: false, enumerable: false, configurable: false }
> Object.getOwnPropertyDescriptors(global).LAMBDA
{ value: 'λ', writable: false, enumerable: false, configurable: false }
>
nc and nullish
> var d = {a:{b:{c:200}}}
> fac_bsc.optional_chaining(d,'a','b')
{ c: 200 }
> fac_bsc.optional_chaining(d,'a','b','e','c')
undefined
>
> fac_bsc.nullish(null,200)
200
> fac_bsc.nullish(undefined,200)
200
> fac_bsc.nullish(false,200)
false
> fac_bsc.nullish(true,200)
true
>
iflet
var a = 3
var x = iflet(
a<=1,100,
a<=2,200,
300
)
>300
aif
var ctx = {i:0}
async function conder(ctx) {
let p = new Promise(
(rs,rj)=> {
setTimeout(()=>{
rs(ctx.i<5);
},3000);
}
);
return(p)
}
async function ifhandler(ctx) {
let p = new Promise(
(rs,rj)=> {
setTimeout(()=>{
console.log(new Date);
rs([new Date,ctx.i]);
},2000);
}
);
return(p)
}
async function elhandler(ctx) {
console.log("invalid")
}
> ctx
{ i: 0 }
>
> await aif(ctx,conder,ifhandler,elhandler)
2021-09-14T09:46:47.202Z
[ 2021-09-14T09:46:47.203Z, 0 ]
>
> ctx.i =6
6
> await aif(ctx,conder,ifhandler,elhandler)
invalid
undefined
>
ifrtrn
var condf0 = (ctx)=> (ctx.a<ctx.b);
var condf1 = (ctx)=> (ctx.a>ctx.b);
var actf0 = (ctx)=>(ctx.b-ctx.a);
var actf1 = (ctx)=>(ctx.a-ctx.b);
var dfltf = (ctx)=> 0;
ifrtrn(
ctx, //data-ctx
condf0,actf0, // cond : action
condf1,actf1, // cond : action
dfltf // otherwise-action
)
>1
>
ifdo similiar to ifrtrn, but write-the-return-value to ctx
var ctx = {a:2,b:3,_rslt:-1}
var condf0 = (ctx)=> (ctx.a<ctx.b);
var condf1 = (ctx)=> (ctx.a>ctx.b);
var actf0 = (ctx)=>(ctx._rslt = ctx.b-ctx.a);
var actf1 = (ctx)=>(ctx._rslt = ctx.a-ctx.b);
var dfltf = (ctx)=>(ctx._rslt =0);
ifdo(
ctx, //data-ctx
condf0,actf0, // cond : action
condf1,actf1, // cond : action
dfltf // otherwise-action
);
> ctx
{ a: 2, b: 3, _rslt: 1 }
>
creat_ifgoto;
- to avoid using while/for
- while/for is hard for auto-generate code in runtime
var condf0 = (ctx)=>(ctx.idx %7===0) ;
var condf1 = (ctx)=>(ctx.idx %7===1) ;
var condf2 = (ctx)=>(ctx.idx %7===2) ;
var action0 = (ctx)=>{
ctx.zero.add(ctx.idx);
ctx.idx=parseInt(Math.random()*1000)
}
var action1 = (ctx)=>{
ctx.one.add(ctx.idx);
ctx.idx=parseInt(Math.random()*1000)
}
var action2 = (ctx)=>{
ctx.two.add(ctx.idx);
ctx.idx=parseInt(Math.random()*1000)
}
var action_dflt = (ctx)=>{
ctx.other.add(ctx.idx);
ctx.idx=parseInt(Math.random()*1000);
if(ctx.other.size>2) {
ctx.__break()
} else {
ctx.__goto(0)
}
}
var ifgoto = creat_ifgoto(
condf0,action0,
condf1,action1,
condf2,action2,
action_dflt
);
/*
> ifgoto.builtin
[
[Function: __goto],
[Function: __goto_fst],
[Function: __goto_lst],
[Function: __continue],
[Function: __break],
[Function: __prev]
]
>
> ifgoto.reset
[Function: reset]
>
*/
var ctx = {
idx:0,
zero:new Set(),
one:new Set(),
two:new Set(),
other:new Set()
}
> ifgoto(ctx)
{
idx: 182,
zero: Set(1) { 0 },
one: Set(1) { 498 },
two: Set(0) {},
other: Set(3) { 494, 867, 273 },
__goto: [Function: __goto],
__goto_fst: [Function: __goto_fst],
__goto_lst: [Function: __goto_lst],
__continue: [Function: __continue],
__break: [Function: __break],
__prev: [Function: __prev]
}
var ctx = {
idx:0,
zero:new Set(),
one:new Set(),
two:new Set(),
other:new Set()
}
ifgoto.reset() //must reset run-enviroment before resuing
/*
> ifgoto.reset() //must reset run-enviroment before resuing
> ifgoto(ctx)
{
idx: 370,
zero: Set(1) { 0 },
one: Set(2) { 785, 820 },
two: Set(1) { 163 },
other: Set(4) { 231, 305, 230, 368 },
__goto: [Function: __goto],
__goto_fst: [Function: __goto_fst],
__goto_lst: [Function: __goto_lst],
__continue: [Function: __continue],
__break: [Function: __break],
__prev: [Function: __prev]
}
>
*/
forof
> var o = {a:100,b:200}
> for(let e of forof(o)) {console.log(e)}
[ 100,'a' ]
[ 200,'b' ]
forin
- similiar to for(... in ...), but with a filter
- forin(o,handle=(odesc,acc)=>{acc.push(odesc)},acc<#0>=[]):acc<&0>
> forin.ODESC_HELP
{
enumerable: 'Boolean',
writable: 'Boolean',
configurable: 'Boolean',
is_sym_key: 'Boolean',
is_str_key: 'Boolean',
key: 'String|Symbol',
depth: 'Int',
is_value: 'Boolean',
is_get: 'Boolean',
is_set: 'Boolean',
data: 'Any'
}
>
var sym = Symbol("d");
class C0 {
x=undefined;
get a() {}
get c(){}
set c(v){}
method() {}
}
class C1 extends C0 {
[sym]=200;
method() {}
}
var o = new C1()
var handle=(odesc,acc)=>{
if(odesc.is_str_key && odesc.depth ===0) {
acc.push([odesc.key,odesc.data])
}
}
var acc = forin(o,handle)
/*
> acc
[ [ 'x', undefined ] ]
>
*/
var handle=(odesc,acc)=>{
if(odesc.depth ===0) {
acc.push([odesc.key,odesc.data])
}
}
var acc = forin(o,handle)
/*
> acc
[ [ 'x', undefined ], [ Symbol(d), 200 ] ]
>
*/
var handle=(odesc,acc)=>{
if(odesc.depth ===1) {
acc.push([odesc.key,odesc.data])
}
}
var acc = forin(o,handle)
/*
> acc
[
[ 'constructor', [class C1 extends C0] ],
[ 'method', [Function: method] ]
]
>
*/
var handle=(odesc,acc)=>{
if(odesc.depth ===2) {
acc.push([odesc.key,odesc.data])
}
}
var acc = forin(o,handle)
/*
> acc
[
[ 'constructor', [class C0] ],
[ 'a', { get: [Function: get a] } ],
[ 'c', { get: [Function: get c], set: [Function: set c] } ],
[ 'method', [Function: method] ]
]
>
*/
forlst
> x.forlst([10,20,30,40],(r,i)=>console.log(r,i))
40 3
30 2
20 1
10 0
undefined
>
mirror
> fac_bsc.mirr([11,21,31])
SimpleMirr(6) [Map] {
0 => 11,
11 => 0,
1 => 21,
21 => 1,
2 => 31,
31 => 2
}
> fac_bsc.mirr({a:11,b:21,c:31})
SimpleMirr(6) [Map] {
'a' => 11,
11 => 'a',
'b' => 21,
21 => 'b',
'c' => 31,
31 => 'c'
}
>
mirrd dmirr mirra amirr
> x.amirr(['a','b'])
{ a: 0, b: 1 }
> x.mirra(['a','b'])
{ '0': 'a', '1': 'b', a: 0, b: 1 }
>
> x.dmirr({a:'xxx',b:'yyy'})
{ xxx: 'a', yyy: 'b' }
> x.mirrd({a:'xxx',b:'yyy'})
{ a: 'xxx', xxx: 'a', b: 'yyy', yyy: 'b' }
>
json
map operator
> var j0 = {a:1,b:[2,3,{c:4}]}
> var j1 = {a:10,b:[20,30,{c:40}]}
> jadd(j0,j1)
{ a: 11, b: [ 22, 33, { c: 44 } ] }
>
> joper((a,b)=>a+':'+b,j0,j1)
{ a: '1:10', b: [ '2:20', '3:30', { c: '4:40' } ] }
>
> jmul(j0,j1)
{ a: 10, b: [ 40, 90, { c: 160 } ] }
>
> jdiv(j0,j1)
{ a: 0.1, b: [ 0.1, 0.1, { c: 0.1 } ] }
>
> jmod(j0,j1)
{ a: 1, b: [ 2, 3, { c: 4 } ] }
>
> jquo(j0,j1)
{ a: 0, b: [ 0, 0, { c: 0 } ] }
>
> jlnot(j0)
{ a: false, b: [ false, false, { c: false } ] }
>
> jlnot(j1)
{ a: true, b: [ true, true, { c: true } ] }
>
> j0
{ a: true, b: [ true, true, { c: true } ] }
> j1
{ a: false, b: [ false, false, { c: false } ] }
>
> jland(j0,j1)
{ a: false, b: [ false, false, { c: false } ] }
>
> jlor(j0,j1)
{ a: true, b: [ true, true, { c: true } ] }
>
> jlxor(j0,j1)
{ a: true, b: [ true, true, { c: true } ] }
>
replace
var ary=[[1,2],3,[4,[[6]]]]
jrplc(ary,(r)=>r*2)
//[[2,4],6,[8,[[12]]]]
var d = {1:100,x:{2:{3:300}}}
jrplc(d,(r,i,k)=>r+k)
//{ '1': '1001', x: { '2': { '3': '3003' } } }
flat
> jflat(foo)
[
[ [ 'foundation' ], 'Mozilla' ],
[ [ 'model' ], 'box' ],
[ [ 'd', 'week' ], 45 ],
[ [ 'd', 'transport' ], 'car' ],
[ [ 'd', 'month' ], 7 ],
[ [ 'ary', 0 ], 10 ],
[ [ 'ary', 2 ], 30 ],
[ [ 'ary', 1, 'v' ], 20 ]
]
>
> var g = jgen(foo)
> var [val,index,key,parent,is_prop,is_ele] = (g.next().value)
> val
{
foundation: 'Mozilla',
model: 'box',
d: { week: 45, transport: 'car', month: 7 },
ary: [ 10, { v: 20 }, 30 ]
}
> index
Symbol(noexist)
> key
Symbol(noexist)
> parent
Symbol(noexist)
> is_prop
false
> is_ele
false
>
> var [val,index,key,parent,is_prop,is_ele] = (g.next().value)
> val
'Mozilla'
> index
0
> key
'foundation'
> parent
{
foundation: 'Mozilla',
model: 'box',
d: { week: 45, transport: 'car', month: 7 },
ary: [ 10, { v: 20 }, 30 ]
}
> is_prop
true
> is_ele
false
>
shape and type
const x = require("nv-facutil-basic")
> var j = {a:100,b:[[2],{c:'s'},null]}
> x.jtypes_(j)
{
a: [Function: is_normal_num],
b: [
[ [Function: is_normal_num] ],
{ c: [Function: is_str] },
[Function: is_null]
]
}
>
> x.jpathv(j)
{ a: 100, 'b/2': null, 'b/0/0': 2, 'b/1/c': 's' }
> x.jpathv(j,':')
{ a: 100, 'b:2': null, 'b:0:0': 2, 'b:1:c': 's' }
>
> x.jreset(j)
{ a: undefined, b: [ [ undefined ], { c: undefined }, undefined ] }
> j
{ a: undefined, b: [ [ undefined ], { c: undefined }, undefined ] }
>
> x.ja_paths_(j)
[
'', 'a',
'b', 'b/0',
'b/1', 'b/2',
'b/0/0', 'b/1/c'
]
> x.jc_paths_(j)
[ '', 'b', 'b/0', 'b/1' ]
> x.jv_paths_(j)
[ 'a', 'b/2', 'b/0/0', 'b/1/c' ]
>
loose search with k path
var j = {a:100,b:[[2],{c:'s'},null,{c:true}]}
> x.jktxt_srch(j,'c')
[ [ 'b.1.c', 's' ], [ 'b.3.c', true ] ]
>
> x.jktxt_srch(j,/[bB].*[0-9]+/)
[
[ 'b.2', null ],
[ 'b.0.0', 2 ],
[ 'b.1.c', 's' ],
[ 'b.3.c', true ]
]
async json
serial
function creat_promise_fac(delay,v) {
let _f = ()=>{
let p = new Promise(
(rs,rj)=> {
setTimeout(
()=>{
console.log(`set ${v} at: `,new Date())
rs(v)
},
delay
)
}
);
return(p)
}
return(_f)
}
var J = {
a:creat_promise_fac(5000,'A'),
b:[
creat_promise_fac(3000,111),
creat_promise_fac(8000,222),
{
c:creat_promise_fac(3500,'C')
}
]
}
var start = new Date().getTime()/1000
await jserial_await(J)
var end = new Date().getTime()/1000
console.log(end-start)
/*
> var start = new Date().getTime()/1000
undefined
> await jserial_await(J)
set A at: 2022-01-22T14:33:02.097Z
set 111 at: 2022-01-22T14:33:05.099Z
set 222 at: 2022-01-22T14:33:13.101Z
set C at: 2022-01-22T14:33:16.603Z
{ a: 'A', b: [ 111, 222, { c: 'C' } ] }
> var end = new Date().getTime()/1000
undefined
> console.log(end-start)
19.516000032424927
> J
{ a: 'A', b: [ 111, 222, { c: 'C' } ] }
>
*/
parallel
var J = {
a:creat_promise_fac(5000,'A'),
b:[
creat_promise_fac(3000,111),
creat_promise_fac(8000,222),
{
c:creat_promise_fac(3500,'C')
}
]
}
var start = new Date().getTime()/1000
await jparallel_await(J)
var end = new Date().getTime()/1000
console.log(end-start)
/*
> var start = new Date().getTime()/1000
undefined
> await jparallel_await(J)
set 111 at: 2022-01-22T14:38:44.560Z
set C at: 2022-01-22T14:38:45.059Z
set A at: 2022-01-22T14:38:46.559Z
set 222 at: 2022-01-22T14:38:49.561Z
{ a: 'A', b: [ 111, 222, { c: 'C' } ] }
> var end = new Date().getTime()/1000
undefined
> console.log(end-start)
8.009999990463257
undefined
> J
{ a: 'A', b: [ 111, 222, { c: 'C' } ] }
>
*/
function creat_promise(delay,v) {
let p = new Promise(
(rs,rj)=> {
setTimeout(
()=>{
console.log(`set ${v} at: `,new Date())
rs(v)
},
delay
)
}
);
return(p)
}
var J = {
a:creat_promise(5000,'A'),
b:[
creat_promise(3000,111),
creat_promise(8000,222),
{
c:creat_promise(3500,'C')
}
]
}
var start = new Date().getTime()/1000
await jparallel_await(J)
var end = new Date().getTime()/1000
console.log(end-start)
/*
set 111 at: 2022-01-22T14:20:44.380Z
set C at: 2022-01-22T14:20:44.879Z
set A at: 2022-01-22T14:20:46.378Z
set 222 at: 2022-01-22T14:20:49.377Z
{ a: 'A', b: [ 111, 222, { c: 'C' } ] }
> console.log(end-start)
8.003000020980835
> J
{ a: 'A', b: [ 111, 222, { c: 'C' } ] }
>
*/
fary, fchain
> const f1 = (a)=>a+1;
> const f2 = (a)=>a*2;
> const f3 = (a)=>a-1;
> fchain(5,f1,f2,f3)
11
> fary([f1,f2,f3],5)
11
> f3(f2(f1(5)))
11
>
frepeat
f: (ctx#0:Object) => ctx&0:Object
such as :
(ctx)=> {do-somthing; return(ctx)}
function f(ctx) {
//
ctx.prop = ctx.prop +2
//
return(ctx)
}
var F = creat_sync_frepeat(f,6)
var ctx = {prop:0}
> F(ctx)
{ prop: 12 }
> ctx
{ prop: 12 }
>
const {setTimeout} = require("timers/promises");
async function af(ctx) {
ctx.prop = await setTimeout(1000,ctx.prop+3) ;
return(ctx)
}
var AF = creat_async_frepeat(af,3)
var ctx = {prop:0}
> await AF(ctx)
{ prop: 9 }
> ctx
{ prop: 9 }
>
set_safely
// set array,map,set,weakmap,weakset, dict
// only-if k exist
var arr =[1,2,3]
set_safely(arr,4,888)
> var arr =[1,2,3]
> set_safely(arr,4,888)
> arr
[ 1, 2, 3 ]
> set_safely(arr,2,888)
> arr
[ 1, 2, 888 ]
>
> var d = {a:100,b:200}
> set_safely(d,'c',888)
> d
{ a: 100, b: 200 }
>
> set_safely(d,'a',888)
> d
{ a: 888, b: 200 }
>
var st = new Set([5,6,7])
set_safely(st,8,888)
> st
Set(3) { 5, 6, 7 }
>
set_safely(st,6,888)
> st
Set(3) { 5, 7, 888 }
>
ary
> ary_split_at([10,20,30,40,50,60],2,5)
[ [ 10, 20 ], [ 30, 40, 50 ], [ 60 ] ]
>
Pair is just a array-of-size-2 ,with only one method: swap()
> var pair = new Pair('a',100)
> pair.k_
'a'
> pair.v_
100
> pair
Pair(2) [ 'a', 100 ]
> pair.swap()
> pair
Pair(2) [ 100, 'a' ]
> pair.k_
100
> pair.v_
'a'
>
swap
> x.swap([1,2])
[ 2, 1 ]
> x.swap({a:1,b:2})
{ a: 2, b: 1 }
>
mat
> mat_transpo([[1,2],[3,4],[5,6]])
[ [ 1, 3, 5 ], [ 2, 4, 6 ] ]
>
> mat_transpo([ [ 1, 3, 5 ], [ 2, 4, 6 ] ])
[ [ 1, 2 ], [ 3, 4 ], [ 5, 6 ] ]
>
DcD
var d = new DcD({a:100,b:200})
> d.add('c','d').del('b').set({a:'AAAA'})
DcD { a: 'AAAA', c: undefined, d: undefined }
>
d.add d.add_with_d d.asgn d.clear
d.clone d.del d.del_asgn
d.del_with_d d.initv_ d.set d.unset
d.unset_all d.unset_with_d
McM
var mp = new McM({a:100,b:200})
> mp.add('c','d','e').del('b').set({c:[1,2,3,4]})
McM(4) [Map] {
'a' => 100,
'c' => [ 1, 2, 3, 4 ],
'd' => undefined,
'e' => undefined
}
mp.add mp.add_with_o mp.asgn
mp.clear mp.clone
mp.del mp.del_asgn mp.del_with_o
mp.initv_ mp.set mp.unset
mp.unset_all mp.unset_with_o
API
-
fac_bsc.is_node() //if the runtime is nodejs
-
fac_bsc.add_repr(Cls,repr_func,...other_repr_func_args) //[util.inspect.custom] in nodejs , else .prototype.repr
-
fac_bsc.add_string_tag(Cls,repr_func,...other_repr_func_args) //get [Symbol.toStringTag]() {}
-
fac_bsc.optional_chaining(obj,...keys) //same as ?., for api-compatible
-
fac_bsc.nullish(a,b); // same as ?? ,for api-compatible
-
fac_bsc.nc(a,b); //same as nullish, for api-compatible
-
fac_bsc.is_null(o);
-
fac_bsc.is_undefined(o);
-
fac_bsc.is_nullish(o); //null or undefined
-
fac_bsc.is_nothing(o); //Nil None nil nullptr NULL empty hole, refer to CONSTS
-
fac_bsc.is_assignable(o); //o !== noexist
-
fac_bsc.is_symbol(o)
-
fac_bsc.is_bool(o)
-
fac_bsc.is_num(o)
-
fac_bsc.is_float(o)
-
fac_bsc.is_int(o)
-
fac_bsc.is_nan(o)
-
fac_bsc.is_infinity(o)
-
fac_bsc.is_abnormal_num(o)
-
fac_bsc.is_normal_num(o)
-
fac_bsc.is_str(o)
-
fac_bsc.is_prim(o)
-
fac_bsc.is_bigint(o)
-
fac_bsc.is_ary(o)
-
fac_bsc.is_u8ary(o)
-
fac_bsc.is_buf(o) //buffer is same as u8ary
-
fac_bsc.is_u8cary(o) //clamped uint8-array
-
fac_bsc.is_u16ary(o)
-
fac_bsc.is_u32ary(o)
-
fac_bsc.is_i8ary(o)
-
fac_bsc.is_i16ary(o)
-
fac_bsc.is_i32ary(o)
-
fac_bsc.is_f32ary(o)
-
fac_bsc.is_f64ary(o)
-
fac_bsc.is_bu64ary(o)
-
fac_bsc.is_bi64ary(o)
-
fac_bsc.is_typed_ary(o)
-
fac_bsc.is_set(o)
-
fac_bsc.is_map(o)
-
fac_bsc.is_wkset(o)
-
fac_bsc.is_wkmap(o)
-
fac_bsc.is_wkref(o)
-
fac_bsc.is_weak(o)
-
fac_bsc.is_dict(o) //object NOT array|typed-array|weak|set|map|cls|func|promise|proxy|
// regex|date|data-view|generator
-
fac_bsc.is_normal_dict(o) //dict but NOT promise| proxy | generator
-
fac_bsc.is_promise(o)
-
fac_bsc.is_proxy(o) //only work in nodejs
-
fac_bsc.is_sync_generator(o)
-
fac_bsc.is_async_generator(o)
-
fac_bsc.is_generator(o)
-
fac_bsc.is_ppg(o) //promise| proxy | generator
-
fac_bsc.is_regex(o)
-
fac_bsc.is_cls_or_func(o)
-
fac_bsc.is_cls(o)
-
fac_bsc.is_async_func(o)
-
fac_bsc.is_sync_gen(o)
-
fac_bsc.is_async_gen(o)
-
fac_bsc.is_gen(o) //sync_gen or async_gen
-
fac_bsc.is_normal_func(o) //func but NOT gen | async_func
-
fac_bsc.is_lambda(o) //()=>{} or async()=>{}
-
fac_bsc.is_func(o) //
-
fac_bsc.is_date(o)
-
fac_bsc.is_dv(o) //dataview
-
fac_bsc.is_arybuf(o) //array-buf
-
fac_bsc.is_int8(o)
-
fac_bsc.is_int16(o)
-
fac_bsc.is_int32(o)
-
fac_bsc.is_int64(o)
-
fac_bsc.is_neg_zero(o) //-0
-
fac_bsc.is_pos_zero(o) //+0
-
fac_bsc.is_js_non_nullish_empty(o)
//'' | false | new Number() | new String() | 0 | 0n | []
-
fac_bsc.is_js_empty(o)
//null | undefined | '' | false | new Number() | new String() | 0 | 0n | []
-
fac_bsc.is_enum_iter_leaf(o) //when typed-array |array |map |set: return true if size/length === 0
//when object : return true if Object.keys(o).length === 0
//others return false
-
fac_bsc.is_falsy(o) // '',0,0n,[],{},and empty Set/Map and empty typed-array
-
fac_bsc.is_truthy(o)
-
fac_get_dtype(o) //return a string of data-type
//refer to CONSTS DTYPE_NUM
-
fac_get_dtype_num(o) //return a big-int number of data-type
-
fac_bsc.iflet(cond,rslt,cond,rslt,....else)
-
fac_bsc.aif(ctx,conder,ifhandler,elhandler=(r)=>r)
-
fac_bsc.ifrtrn(
ctx,
cond_func0,action0,
cond_func1,action1,
....
cond_funck,actionk,
default_action
)
-
fac_bsc.ifdo(
ctx,
cond_func0,action0,
cond_func1,action1,
....
cond_funck,actionk,
default_action
)
-
fac_bsc.creat_ifgoto(
cond_func0,action0,
cond_func1,action1,
....
cond_funck,actionk,
default_action
);
//var ifgoto = creat_ifgoto(...);
//ifgoto(ctx);
//ifgoto.reset()
-
fac_bsc.forof(o) //if o has [Symbol.iterator] return o,
//else try for-in and return a generator
//for api-compatible and consistency
-
fac_bsc.fary(funcs,param)
-
fac_bsc.fchain(param,...funcs)
// fary([f1,f2,f3],param)
// equals f3(f2(f1(param)))
-
fac_bsc.artrn(f,...params) //for-impl-performance-test-purpose , normally USELESS
-
fac_bsc.aloop(ctx,conder,handler,post_handler)
-
fac_bsc.aswitch(v,entries) // entry: {case:Any,handler:Function,break:Boolean}
-
fac_bsc.set_safely(o,key-or-index,v)
//set [array|map|set|weakmap|weakset|dict] element at k-or-i
//only-if k-or-i exist
-
fac_bsc.creat_reserved(...kvpairs) //creat global reserved variables, similar to usage of undefined
-
fac_bsc.creat_id() // if nodejs call crypto.randomUUID, else using nanoid
//nanoid is slightly faster than uuidv4
-
fac_bsc.get_abbr(id) // the first-8 of a uuid
-
fac_bsc.creat_bigint_id() //convert uuid to a bigint
-
fac_bsc.creat_nodash_id() //remove dash in uuid
-
fac_bsc.creat_4int_id_ary() //convert uuid to 4-int-array
-
fac_bsc.SNidPool //a int or bigint ID,
//useful when using adj-table as data structure
//similiar with SNidPool,used in fixed-size scenario;
//these are used in fixed-size array-pool ,
// useful when using sharedArrayBuffer,otherwise useless
-
fac_bsc.AidPool //(Array);
-
fac_bsc.T8AidPool //(Uint8Array);
-
fac_bsc.T16AidPool //(Uint16Array);
-
fac_bsc.T32AidPool //(Uint32Array);
-
fac_bsc.T64AidPool //(BigUint64Array);
-
fac_bsc.jdcp(jsond) //JSON.parse(JSON.stringify(jsond))
-
fac_bsc.jrplc(jsond,f) // f: (val,index,key,parent) => {...}
-
fac_bsc.jmap(jsond,f) // f: (val,index,key,parent) => {...}
-
fac_bsc.jkvl(j,include_self=true) // [[str_key,value].....]
-
fac_bsc.jlength(j,include_self=true) //
-
fac_bsc.jprim_length(j,include_self=true) // not-array and not-dict
-
fac_bsc.jnonprim_length(j,include_self=true) // array-or-dict,
-
fac_bsc.jleaf_length(j,include_self=true) // not-array and not-dict and [] and {}
-
fac_bsc.jnonleaf_length(j,include_self=true) // array-or-dict but-not []-or-{}
-
fac_bsc.jgen(j) //yield [val,index,key,parent,is_prop,is_ele]
-
fac_bsc.jflat(j) //[[key_list,val]...]
-
fac_bsc.jfltr(j,filter=(val,index,key,parent,is_prop,is_ele)=>true,rtrn_func=(e)=>e[0])
-
fac_bsc.jnleaf_(j,with_key=false)
-
fac_bsc.jleaf_(j,with_key=false)
-
fac_bsc.jnprim_(j,with_key=false)
-
fac_bsc.jprim_(j,with_key=false)
-
fac_bsc.jary_(j,with_key=false)
-
fac_bsc.jdict_(j,with_key=false)
-
fac_bsc.jvacant_(j,with_key=false)
-
fac_bsc.jnull_(j,with_key=false)
-
fac_bsc.jnum_(j,with_key=false)
-
fac_bsc.jstr_(j,with_key=false)
-
fac_bsc.jbool_(j,with_key=false)
-
fac_bsc.jtru_(j,with_key=false)
-
fac_bsc.jfls_(j,with_key=false)
-
fac_bsc.unescq(s) //JSON.parse('"'+s+'"')
-
fac_bsc.typof(o,str);
-
fac_bsc.instof(o,Instance);
-
fac_bsc.eqany(o,...opts); // opts.includes(o)
// this is used to avoid too many ===
// coz too-many === will make code unreadable, too long
-
fac_bsc.d2kvlist(d) // {a:100,b:200} => [['a','b'],[10,200]]
-
fac_bsc.kvlist2d(kl,vl) // [['a','b'],[10,200]] => {a:100,b:200}
-
fac_bsc.dlngth(d) // {a:100,b:200} => 2
-
fac_bsc.kvl2md(kl,vl)
-
fac_bsc.dsome(d,...ks) // dsome({a:100,b:200,c:300},'a','c') => {a:100,c:300}
-
fac_bsc.drekey(d,...ks) // drekey({a:100,b:200,c:300},'A','B','C') => {A:100,B:200,C:300}
-
fac_bsc.dreval(d,...vs) // dreval({a:100,b:200,c:300},10,20,30) => {a:10,b:20,c:30}
-
fac_bsc.d2pairl(d)
//> d2pairl({a:100,b:200,c:300})
//[ 'a', 100, 'b', 200, 'c', 300 ]
-
fac_bsc.pairl2d(d)
//> pairl2d([ 'a', 100, 'b', 200, 'c', 300 ])
//{ a: 100, b: 200, c: 300 }
-
fac_bsc.SimpleStack //Just Array with a lst(top) setter/getter to handle last-element
//and generator from-last-to-first
-
fac_bsc/SimpleMirr
-
fac_bsc.ary_lst_index(ary) {return(ary.length-1)}
-
fac_bsc.ary_lsti(ary) //same as ary_lst_index
-
fac_bsc.get_ary_lst(ary) {return(ary[ary.length-1])}
-
fac_bsc.ary_glst(ary) //same as get_ary_lst
-
fac_bsc.set_ary_lst(ary,v) {ary[ary.length-1] = v}
-
fac_bsc.ary_slst(ary) //same as set_ary_lst
-
fac_bsc.ary_ibfr(ary,index,v) // insert before : ary.splice(index,0,v)
-
fac_bsc.ary_iaft(ary,index,v) // insert after : ary.splice(index+1,0,v)
-
fac_bsc.ary_rm(ary,index) // remove at : ary.splice(index,1)
-
fac_bsc.ary_fltrg(ary,fltr,not=false) //Iterator ,similar as filter, just yield [r,i]
// fltr : (r:any,i:number) => Boolean
// type Entry = [any,number] //tuple of (r,i)
// type IteratorResult = {done: boolean;value:Entry}
// type Iterator = {
// next(value?: any): IteratorResult;
// return?(value?: any): IteratorResult;
// throw?(e?: any): IteratorResult;
// }
-
fac_bsc.ary_freq(ary,v) // ary=[2,2,3,2,4] ary_freq(ary,2) : 3
-
fac_bsc.ary_foreach_brk(arr,f,brkf=(r,i)=>false)
-
fac_bsc.ary_foreach_skip(arr,f,skipf=(r,i)=>false)
-
fac_bsc.rename_func(f,new_name)
-
fac_bsc.rename_cls(Cls,new_name)
-
fac_bsc.def_cls_instof(Cls,f) // f: (Cls,inst)=>Boolean
-
fac_bsc.add_method(Cls,method)
-
fac_bsc.rm_method(Cls,method_name)
-
class //the below
//for dynamic-add from outside, #priv can NOT support dynamic-add from outside;
-
fac_bsc.add_getter(cls,prop,getter,...priv_props) //getter : (that,priv_props)=>any
-
fac_bsc.add_setter(cls,prop,setter,...priv_props) //setter : (that,v,priv_props)=>{...}
-
fac_bsc.add_gseter(cls,prop,getter,setter,...priv_props) // add both getter AND setter
-
fac_bsc.add_priv_prop(cls,prop) //(cls,prop)=>{priv_initer,priv_prop}
//add public_getter AND public_setter for one prop
//for compatible, if without #priv support
-
fac_bsc.DP //abbr of Object.defineProperty
-
fac_bsc.DPV(o,k,v) //abbr of Object.defineProperty(o,k,{value:v})
-
fac_bsc.DPGT //simple version of add_getter to a obj-instance
//> var d = {_a:100}
//> DPGT(d,'a')
//> d.a
//100
-
fac_bsc.DPST //simple version of add_setter to a obj-instance
//var d = {_a:100}
//>DPST(d,'a')
//>d.a=999
//999
//{ _a: 999 }
-
fac_bsc.DPGTST
//var d = {_a:100}
//> var d = {_a:100}
//> DPGTST(d,'a')
//> d
//{ _a: 100 }
//> d.a ='AAAA'
//'AAAA'
//> d
//{ _a: 'AAAA' }
//>
//> d.a
//'AAAA'
//>
-
fac_bsc.gopds //abbr of Object.getOwnPropertyDescriptors
-
fac_bsc.gopes //abbr of Object.entries(Object.getOwnPropertyDescriptors(o))
-
fac_bsc.dtuple(...params) //x.dtuple(1,2) { '1': 2 }
-
fac_bsc.from_dtuple(d) //x.from_dtuple({ '1': 2 }) ['1',2]
CONSTS
> fac_bsc
{
////the below is just for api-compatible when migrating some code from other coding language
Nil: [class Nil],
nfunc: [Function: nfunc],
None: None,
nil: [Object: null prototype] {},
nullptr: [Object: null prototype] {},
NULL: [Object: null prototype] {},
//// the 4 global symbol to avoid conflicting with undefined , just a semantic-undefined
empty: Symbol("empty"),
unknown: Symbol("unknown"),
impossible: Symbol("impossible"),
maybe: Symbol("maybe"),
any: Symbol("any"),
hole: Symbol("hole"), // for special handling <empty slot> in Array
////to avoid conflicting with null, just a semantic-null-sign
root: Symbol("root")
///to present noexist, such as when arr=[0,1,2] arr[4]
///currently js will return undefined which ambigious with <empty slot>
///noexist should be NOT assignable ,
/// its IM-possible to implement {assignable:false} in JS layer
/// so just use a symbol
noexist: Symbol("noexist")
//// for add_repr or add_string_tag
NUL: '\x00',
NBSP: ' ',
LS: '�',
PS: '�',
ZWNJ: '',
ZWJ: '',
BOM: '',
}
>
STATE_LABEL_DICT: {
init: Symbol(init),
ready: Symbol(ready),
waiting: Symbol(waiting),
executing: Symbol(executing),
pending: Symbol(pending),
paused: Symbol(paused),
skipped: Symbol(skipped),
stopped: Symbol(stopped),
finished: Symbol(finished),
resolved: Symbol(resolved),
rejected: Symbol(rejected)
eof: Symbol(eof)
},
const DTYPE_NUM = {
'undefined': 0b1n,
'null': 0b10n,
'symbol': 0b100n,
'bool': 0b1000n,
'int': 0b10000n,
'float': 0b100000n,
'nan': 0b1000000n,
'infinity': 0b10000000n,
'str': 0b100000000n,
'bigint': 0b1000000000n,
'u8ary': 0b10000000000n,
'u8cary': 0b100000000000n,
'u16ary': 0b1000000000000n,
'u32ary': 0b10000000000000n,
'i8ary': 0b100000000000000n,
'i16ary': 0b1000000000000000n,
'i32ary': 0b10000000000000000n,
'f32ary': 0b100000000000000000n,
'f64ary': 0b1000000000000000000n,
'bu64ary': 0b10000000000000000000n,
'bi64ary': 0b100000000000000000000n,
'ary': 0b1000000000000000000000n,
'set': 0b10000000000000000000000n,
'map': 0b100000000000000000000000n,
'wkset': 0b1000000000000000000000000n,
'wkmap': 0b10000000000000000000000000n,
'wkref': 0b100000000000000000000000000n,
'regex': 0b1000000000000000000000000000n,
'date': 0b10000000000000000000000000000n,
'dv': 0b100000000000000000000000000000n,
'arybuf': 0b1000000000000000000000000000000n,
'sarybuf': 0b10000000000000000000000000000000n,
'promise': 0b100000000000000000000000000000000n,
'proxy': 0b1000000000000000000000000000000000n,
'sync_generator': 0b10000000000000000000000000000000000n,
'async_generator': 0b100000000000000000000000000000000000n,
'normal_dict': 0b1000000000000000000000000000000000000n,
'cls': 0b10000000000000000000000000000000000000n,
'sync_gen': 0b100000000000000000000000000000000000000n,
'async_gen': 0b1000000000000000000000000000000000000000n,
'async_func': 0b10000000000000000000000000000000000000000n,
'normal_func': 0b100000000000000000000000000000000000000000n,
'external': 0b1000000000000000000000000000000000000000000n,
'ref': 0b10000000000000000000000000000000000000000000n
}
//// this is used to implement kvtree, which can uniform map/dict/array/set
//// which support both nest-at-key-position and nest-at-value-position
//// its a super-table structure
STYPE_DICT: {
root: -1,
ele: 0, //element of array
prop: 1, //prop of dict
stele: 2, //element of set
mpk: 3, //key of mp-element
mpv: 4, //value of mp-element
leaf: 5
////////////////////////////////////////////////
dk: 51, // key-of-dict (which is leaf position,for performance tuning)
idx: 52, // index-node (which is leaf position AND hidden,for performance tuning)
},
GLOBAL_ERROR_DICT = {
noexist_is_not_assignable:"noexist_is_not_assignable"
}
Class
for dynamic change. used in testbed
class B {}
var b = new B()
> b instanceof B
true
>
def_cls_instof(B,(Cls,inst)=>false)
> b instanceof B
false
>
def_cls_instof(B,(Cls,inst)=>true)
> b instanceof B
true
>
for compatible when #priv is NOT suitable
class A {}
var {priv_initer,priv_prop} = add_priv_prop(A,'pub')
> priv_initer
[Function: priv_initer]
> priv_prop
Symbol(pub)
>
> var a = new A()
priv_initer(a,999999)
> a.pub
999999
> a.pub =8888
8888
> a
A {}
> a.pub
8888
>
> gopds(a)
{
[Symbol(pub)]: {
value: 999999,
writable: true,
enumerable: false,
configurable: true
}
}
>
ptuple
-
for macro tool using
-
just a {name:value} pair
var pt = new PTuple('a',{type:'i32'})
pt.notation_
'a'
pt.attribs_
{ type: 'i32' }
pt
PTuple { a: { type: 'i32' } }
pt.notation_ = 'b'
'b'
pt
PTuple { b: { type: 'i32' } }
pt
PTuple { A: { type: 'notation' } }
pt.attribs_.type = 'str'
'str'
pt.attribs_.value = 'xxxxxx'
'xxxxxx'
pt
PTuple { A: { type: 'str', value: 'xxxxxx' } }
Completion
-
to avoid using return/throw/break/continue directly
> var cr = new CompletionRecord()
> cr.
cr._break
cr._continue
cr._return
cr._throw
cr.is_breaked
cr.is_completed
cr.is_continued
cr.is_returned
cr.is_throwed
cr.val_
> cr._return(888)
> cr.is_returned()
true
> cr.val_
888
>
> var cr = new CompletionRecord()
> cr._break('x')
> cr.is_returned()
false
> cr.is_breaked()
true
> cr.val_
'x'
>
history
> var hist = new SimpleHistory()
> hist
SimpleHistory(0) [ max_size: Infinity, noexist: Symbol(noexist) ]
>
> hist.push(100)
> hist.push(200)
> hist.push(300)
> hist
SimpleHistory(3) [
100,
200,
300,
max_size: Infinity,
noexist: Symbol(noexist)
]
> hist.curr_
300
>
> hist.back(2)
100
> hist.curr_
100
>
> hist
SimpleHistory(1) [ 100, max_size: Infinity, noexist: Symbol(noexist) ]
>
const ject
> const STAGES = meject(
... "Stage",
... ["init",'entering','leaving'],
... -1,
... );
>
> STAGES
Stage {
'0': 'entering',
'1': 'leaving',
init: -1,
'-1': 'init',
entering: 0,
leaving: 1
}
>
> const ACTIONS = kiject(
... 'Action',[
... 'skip',
... 'replace_with',
... 'disconn',
... 'insert_before',
... 'insert_after',
... 'append_fstch',
... 'rename_key'
... ]
... )
>
> ACTIONS
Action {
skip: 0,
replace_with: 1,
disconn: 2,
insert_before: 3,
insert_after: 4,
append_fstch: 5,
rename_key: 6
}
>
simple sort
> var dtbl = [{a:100,b:200,c:'x'},{a:200,b:100,c:'x'}]
> sort_dtbl(dtb,['a','b'])
[ { a: 100, b: 200, c: 'x' }, { a: 200, b: 100, c: 'x' } ]
>
> sort_dtbl(dtb,['b','a'])
[ { a: 200, b: 100, c: 'x' }, { a: 100, b: 200, c: 'x' } ]
>
> sort_dtbl(dtb,['a','b'],{reverse:true})
[ { a: 200, b: 100, c: 'x' }, { a: 100, b: 200, c: 'x' } ]
>
push only AND no check Array,for performance tuning, normally useless
> var pl = new PL()
> pl
PL(0) [ ei: 0 ]
> pl.push('a')
> pl
PL(1) [ 'a', ei: 1 ]
> pl.push('b')
> pl
PL(2) [ 'a', 'b', ei: 2 ]
> pl.push('c')
> pl
PL(3) [ 'a', 'b', 'c', ei: 3 ]
> pl.copy()
[ 'a', 'b', 'c' ]
>
> pl.back()
> pl
PL(3) [ 'a', 'b', 'c', ei: 2 ]
> pl.copy()
[ 'a', 'b' ]
>
> pl.forward()
> pl.copy()
[ 'a', 'b', 'c' ]
> pl
PL(3) [ 'a', 'b', 'c', ei: 3 ]
> pl.back()
> pl.back()
> pl
PL(3) [ 'a', 'b', 'c', ei: 1 ]
> pl.copy()
[ 'a' ]
> pl.back()
> pl.copy()
[]
> pl
PL(3) [ 'a', 'b', 'c', ei: 0 ]
>
> pl.forward()
> pl.curr_
'a'
> pl
PL(3) [ 'a', 'b', 'c', ei: 1 ]
>
structured-clone odcp
> var st = new Set([1,2,3])
> var st1 = odcp(st)
> st
Set(3) { 1, 2, 3 }
> st1
Set(3) { 1, 2, 3 }
> st===st1
false
>
generator
add_gnext
- for endless generator, coz .value AND .done is boring
>
function *gen() {
while(true) {
yield(Math.random())
}
}
> var g = gen()
> add_gnext(g)
Object [Generator] {}
> g.next_
0.4015309369238944
> g.next_
0.5163742858365246
> g.next_
0.24116741087156357
> g.next_
0.9318495201911445
> g.next_
0.8398284939175704
> g.next_
0.5207830356096523
>
const {setTimeout:wait} = require("timers/promises");
async function *agen() {
while(true) {
await wait(1000)
yield(Math.random())
}
}
> var ag = agen()
> add_gnext(ag)
Object [AsyncGenerator] {}
>
> await ag.next_
0.3152634531920726
> await ag.next_
0.055978210133172945
> await ag.next_
0.08074477794083923
>
gen_qr_interval
> g = x.gen_qr_interval(10,3)
Object [Generator] {}
> g.next()
{ value: [ 0, 3 ], done: false }
> g.next()
{ value: [ 3, 6 ], done: false }
> g.next()
{ value: [ 6, 9 ], done: false }
> g.next()
{ value: [ 9, 10 ], done: false }
> g.next()
{ value: undefined, done: true }
>
dot , to avoid using . AND [computed]
> var mp = new Map()
> var d = {a:222}
> mp.set(1,d)
Map(1) { 1 => { a: 222 } }
>
> dot(mp,[1,"a"])
222
>
proto chain
//(o,including_self=false,using_reflect=false)=>Array<O>
class OO extends Object {}
var o = new OO()
> x.get_proto_chain(o)
[ {}, [Object: null prototype] {} ]
>
//same as get_proto_chain, return a generator
> x.gen_proto_chain
[GeneratorFunction: gen_proto_chain]
>
get own entries
- similiar to Object.entries ,but includes symbol-keys
- get_own_entries(o,include_unenumerable=false)
var sym = Symbol("d");
var o = {
x:100,
get a(){} ,
set b(v){} ,
get c(){} ,
set c(v){} ,
[sym]:200,
method(){}
}
> x.get_own_entries(o)
[
[ 'x', 100 ],
[ 'a', undefined ],
[ 'b', undefined ],
[ 'c', undefined ],
[ 'method', [Function: method] ],
[ Symbol(d), 200 ]
]
>
get_own_odescs
- similiar to Object.getOwnPropertyDescriptors, but with get/set/key_type info in odesc
> x.get_own_odescs.ODESC_HELP
{
enumerable: 'Boolean',
writable: 'Boolean',
configurable: 'Boolean',
is_sym_key: 'Boolean',
is_str_key: 'Boolean',
key: 'String|Symbol',
depth: 'Int', //always 0
is_value: 'Boolean',
is_get: 'Boolean',
is_set: 'Boolean',
data: 'Any'
}
>
var sym = Symbol("d");
var o = {
x:100,
get a(){} ,
set b(v){} ,
get c(){} ,
set c(v){} ,
[sym]:200,
method(){}
}
> x.get_own_odescs(o)
[
_Odesc {
enumerable: true,
writable: true,
configurable: true,
is_sym_key: false,
is_str_key: true,
key: 'x',
depth: 0,
is_value: true,
is_get: false,
is_set: false,
data: 100
},
_Odesc {
enumerable: true,
writable: undefined,
configurable: true,
is_sym_key: false,
is_str_key: true,
key: 'a',
depth: 0,
is_value: false,
is_get: true,
is_set: false,
data: { get: [Function: get a] }
},
_Odesc {
enumerable: true,
writable: undefined,
configurable: true,
is_sym_key: false,
is_str_key: true,
key: 'b',
depth: 0,
is_value: false,
is_get: false,
is_set: true,
data: { set: [Function: set b] }
},
_Odesc {
enumerable: true,
writable: undefined,
configurable: true,
is_sym_key: false,
is_str_key: true,
key: 'c',
depth: 0,
is_value: false,
is_get: true,
is_set: true,
data: { get: [Function: get c], set: [Function: set c] }
},
_Odesc {
enumerable: true,
writable: true,
configurable: true,
is_sym_key: false,
is_str_key: true,
key: 'method',
depth: 0,
is_value: true,
is_get: false,
is_set: false,
data: [Function: method]
},
_Odesc {
enumerable: true,
writable: true,
configurable: true,
is_sym_key: true,
is_str_key: false,
key: Symbol(d),
depth: 0,
is_value: true,
is_get: false,
is_set: false,
data: 200
}
]
>
get_odescs gen_odesc
- similiar to get_own_odescs, but include the prototype chain, and with a filter
- get_odescs(o,filter=(odesc)=>true):Array<_Odesc>
- gen_odesc(o,filter=(odesc)=>true):SyncGenerator<_Odesc>
filter
({
enumerable: 'Boolean',
writable: 'Boolean',
configurable: 'Boolean',
is_sym_key: 'Boolean',
is_str_key: 'Boolean',
key: 'String|Symbol',
depth: 'Int', // 0 means own
is_value: 'Boolean',
is_get: 'Boolean',
is_set: 'Boolean',
data: 'Any'
})=>Boolean
class C0 {
x=undefined;
get a() {}
get c(){}
set c(v){}
method() {}
}
class C1 extends C0 {
[sym]=200;
method() {}
}
var o = new C1()
var g = x.gen_odesc(o,(odesc)=>true)
> (Array.from(g)).map(odesc=>[odesc.key,odesc.depth])
[
[ 'x', 0 ],
[ Symbol(d), 0 ],
[ 'constructor', 1 ],
[ 'method', 1 ],
[ 'constructor', 2 ],
[ 'a', 2 ],
[ 'c', 2 ],
[ 'method', 2 ],
[ 'constructor', 3 ],
[ '__defineGetter__', 3 ],
[ '__defineSetter__', 3 ],
[ 'hasOwnProperty', 3 ],
[ '__lookupGetter__', 3 ],
[ '__lookupSetter__', 3 ],
[ 'isPrototypeOf', 3 ],
[ 'propertyIsEnumerable', 3 ],
[ 'toString', 3 ],
[ 'valueOf', 3 ],
[ '__proto__', 3 ],
[ 'toLocaleString', 3 ]
]
>
try_until_succ
param-ctx
{
f:()=>{},
args:[],
condf:(r)=>true,
max_repeat:5,
}
async
var fail = require("nv-random-fail");
async
var af = async ()=>await fail.async({rslt_creater:()=>100})
/*
> await af()
Uncaught Error
at DFLT_ERR_CREATER (/opt/JS/NV6-/nvfac/pkgs/nv-facutil-basic/node_modules/nv-random-fail/index.js:3:31)
> await af()
Uncaught Error
at DFLT_ERR_CREATER (/opt/JS/NV6-/nvfac/pkgs/nv-facutil-basic/node_modules/nv-random-fail/index.js:3:31)
> await af()
100
>
*/
> await x.async_try_until_succ({f:af})
100
> await x.async_try_until_succ({f:af})
100
>
sync
var sf = ()=>fail.sync({rslt_creater:()=>100})
x.sync_try_until_succ({f:sf})
> x.sync_try_until_succ({f:sf})
100
>
LICENSE