You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805
  1. // This file creates and syncs msto
  2. // msto is a recursive proxy that synchronizes itself between all meeting participants
  3. // you can get a clone of the object by typing jc(msto) into your dev console
  4. dlog = nop
  5. // dlog = clog
  6. function match(mx,m,o){
  7. var k,v,k2,v2
  8. var r = 0
  9. for ([k,v] of Object.entries(m || {})){
  10. v2 = o[k]
  11. if (typeof(v) == "string" && typeof(v2) == "string") {
  12. r += !(v==v2)
  13. } else if (Array.isArray(v) && Array.isArray(v2)){
  14. r += !(isSubset_arr(v,v2))
  15. } else if (Array.isArray(v) && typeof(v2) == "string"){
  16. // r += !(isSubset_arr(v2,v))
  17. r += !v.includes(v2)
  18. } else if (Array.isArray(v2) && typeof(v) == "string"){
  19. r += !(v2.includes(v))
  20. }
  21. if (r){
  22. return !r
  23. }
  24. }
  25. return !r
  26. }
  27. function isSubset(subset,superset){
  28. for (var elem of subset) {
  29. if (!superset.includes(elem)) {
  30. return false;
  31. }
  32. }
  33. return true;
  34. }
  35. function isSubset_arr(subset,superset){
  36. for (var elem of subset) {
  37. if (Array.isArray(elem)){
  38. if (!new Set(elem).intersection(superset).size){
  39. return false
  40. }
  41. } else if (!superset.includes(elem)) {
  42. return false;
  43. }
  44. }
  45. return true;
  46. }
  47. function dispatch_ws_events3(e,key){
  48. var k,v
  49. // let dlog =clog
  50. clog("dispatch_ws_events3",e,{that:this,e,key})
  51. // return
  52. // e.payload.etype ? 1 : e.payload.etype = "null"
  53. e.parsed.etype ? 1 : e.parsed.etype = "null"
  54. var mflag =0
  55. dlog("dispatch_events??",e,key)
  56. for ([k,v] of Object.entries(glob_mx.ws_event_handlers || {}) ) {
  57. dlog("dispatch_events:",k)
  58. if (v.m){
  59. // mflag = match({},v.m,e.payload)
  60. mflag = match({},v.m,e.parsed)
  61. mflag ? v.fn(e,key) : 1
  62. }
  63. }
  64. }
  65. function dispatch_ws_events(e,key){
  66. var k,v
  67. // let dlog =clog
  68. clog("dispatch_ws_events",{that:this,e,key})
  69. // return
  70. // e.payload.etype ? 1 : e.payload.etype = "null"
  71. e.parsed.etype ? 1 : e.parsed.etype = "null"
  72. var mflag =0
  73. dlog("dispatch_events??",e,key)
  74. for ([k,v] of Object.entries(glob_mx.ws_event_handlers || {}) ) {
  75. dlog("dispatch_events:",k)
  76. if (v.m){
  77. // mflag = match({},v.m,e.payload)
  78. mflag = match({},v.m,e.parsed)
  79. mflag ? v.fn(e,key) : 1
  80. }
  81. }
  82. }
  83. function dispatch_events(e,key){
  84. var k,v
  85. // clog("dispatch_events_z",{that:this,e,key})
  86. e.parsed.etype ? 1 : e.parsed.etype = "null"
  87. var mflag =0
  88. dlog("dispatch_events??",e,key)
  89. for ([k,v] of Object.entries(glob_mx.event_handlers || {}) ) {
  90. dlog("dispatch_events:",k)
  91. if (v.m){
  92. mflag = match({},v.m,e.parsed)
  93. mflag ? v.fn(e) : 1
  94. }
  95. }
  96. }
  97. function run_cbs(key){
  98. jlog("RCB","run_cbs")
  99. var k,v
  100. dlog("RUN_CB??",key,glob_mx.cb[key])
  101. for ([k,v] of Object.entries(glob_mx.cb[key]|| {}) ) {
  102. dlog("RUN_CB:",k)
  103. v()
  104. }
  105. }
  106. function run_hook_cbs(key,o){
  107. jlog("RCB","run_hook_cbs")
  108. var k,v
  109. // dlog("RUN_HOOK_CB??",key,glob_mx.hook_cb[key])
  110. for ([k,v] of Object.entries(glob_mx.hook_cb[key]|| {}) ) {
  111. // dlog("RUN_HOOK_CB:",k)
  112. v(o)
  113. }
  114. }
  115. function wait(ms) {
  116. return new Promise(r => setTimeout(r, ms));
  117. }
  118. function attr_info(n){
  119. var k,v
  120. var ret ={}
  121. // clog(".")
  122. for (k in n.attributes){
  123. // clog(k)
  124. }
  125. // clog("~")
  126. for (k of n.attributes){
  127. // for (k of n.attributes){
  128. // clog(k)
  129. }
  130. // clog("--")
  131. for ([k,v] of Object.entries(n.attributes)){
  132. // clog(k,v,v+"+")
  133. // clog("+",[k,v],v)
  134. ret[v.name]= v.value
  135. // clog(typeof(k),typeof(v))
  136. }
  137. return ret
  138. }
  139. // ai.from.split((a0,a1,a2,a3)=>{clog({a0,a1,a2,a3});return "z"})
  140. // tmsgx3({type:"db_sync_request"})
  141. function mhndlr_rld(that,m){
  142. try {
  143. window.mx=m
  144. var n = m.querySelector(`code`)
  145. if (!n){return}
  146. var parsed = JSON.parse(n.innerHTML)
  147. var ai = attr_info(m)
  148. window.ai=ai
  149. // clog("FROM",ai.from == glob_mx.all_jids[0])
  150. // var id = ai.from.split().slice(-1)[0]
  151. var id = ai.from.split("/").pop()
  152. dlog("mhndlr_rld2",m,parsed,n,n.dataset)
  153. var o = parsed.payload
  154. switch (parsed.type){
  155. case "set_msg":
  156. pf._set_recv(o.path,o.key,o.val)
  157. window._set_recv_cb ? window._set_recv_cb({that:this,m,n,o,ai,id}): 0
  158. // TODO DEV BODGE?
  159. if (window.glob_td && glob_td.cb._set_recv_cb){
  160. // run_cbs_td("_set_recv_cb",{that:this,m,n,o,ai,id})
  161. run_cbs_td("_set_recv_cb",{that:this,m,n,o,ai,id,parsed,innerHTML:n.innerHTML,p2:JSON.parse(n.innerHTML)})
  162. // glob_td.cb._set_recv_cb("_set_recv_cb",{that:this,m,n,o,ai,id})
  163. }
  164. // window?._set_recv_cb?.({that:this,m,n,o,ai,id}) opt_chain
  165. break;
  166. case "event":
  167. dlog("~event~",parsed)
  168. dispatch_events({parsed,ai,m,that})
  169. break;
  170. case "msg_test":
  171. dlog("msg_test",parsed)
  172. break;
  173. case "db_sync_request":
  174. // tmsgx3({type:"db_sync_response",payload:pf.root})
  175. tmsgx3({type:"db_sync_response",payload:pf.root},{to:ai.from})
  176. // dlog("db_sync_request",parsed)
  177. clog("db_sync_request",parsed)
  178. break;
  179. case "db_sync_response":
  180. if (id == glob_mx.local_id){
  181. dlog( "db_sync_response ...")
  182. break
  183. }
  184. if (glob_mx.prom.init_db_resolve){
  185. glob_mx.prom.init_db_resolve({aaa:"dsr",pl:parsed.payload})
  186. }
  187. clog("db_sync_response",ai.from == glob_mx.local_id,ai.from,parsed)
  188. break;
  189. }
  190. /*
  191. if (parsed.type == "set_msg"){
  192. var o = parsed.payload
  193. pf._set_recv(o.path,o.key,o.val)
  194. }
  195. if (parsed.type == "msg_test"){
  196. clog("msg_test",parsed)
  197. }
  198. */
  199. } catch (err) {
  200. clog("mhndlr err:",err)
  201. }
  202. return true
  203. }
  204. isProxy = Symbol("isProxy")
  205. tlu = {
  206. object:"",
  207. string:true,
  208. number:true,
  209. undefined:true,
  210. boolean:true,
  211. }
  212. function type_info(o){
  213. var t
  214. var flags = {
  215. leaf:false,
  216. deep_not_prx:false,
  217. prx:false,
  218. isObj:false,
  219. isArr:false,
  220. els:false,
  221. }
  222. t = typeof(o)
  223. flags.t=t
  224. if (!(o === null)){
  225. flags.isArr = Array.isArray(o)
  226. flags.isObj = Object.prototype == o.__proto__
  227. }
  228. if (tlu[t] === true || o === null){
  229. flags.leaf = true
  230. } else if (t == "object" && o.__prx){
  231. flags.prx = true
  232. } else if (t == "object" && (flags.isArr || flags.isObj)){
  233. flags.prx = false
  234. flags.deep_not_prx = true
  235. } else {
  236. clog("ELSE")
  237. flags.els = true
  238. }
  239. return flags
  240. clog(t,flags)
  241. }
  242. function deep_prop_v0(o,p){
  243. try {
  244. var arr = jc(p)
  245. var ret = o
  246. while (arr.length){
  247. // clog("deep_prop",arr,ret)
  248. ret = ret[arr.shift()]
  249. }
  250. // clog("deep_prop ret",ret)
  251. return ret
  252. } catch(err){console.error("DEEP_PROP ERR:",err)}
  253. }
  254. delete Proxy_Factory
  255. {
  256. class Proxy_Factory {
  257. constructor(o,n="dflt"){
  258. this.db = o
  259. this.n = n
  260. this.hidden_props = ["add_proxy","_set","walker","walker_start","prxy","_sett","_sett2"]
  261. this._pub_cb =[]
  262. this.__prx = true
  263. this.SymPrx = Symbol("SymPrx")
  264. // clog("pfx",{o,n,that:this})
  265. }
  266. init(o){
  267. // dlog("BP",this,this.baseProp,this.__proto__.baseProp,window.baseProp)
  268. // clog("pfx init",{o,that:this})
  269. this.root = o
  270. }
  271. sync(o){
  272. this.root = jc(o.root)
  273. o._pub_cb.push(this._set_recv.bind(this))
  274. }
  275. get prxy(){
  276. return this
  277. }
  278. _set(o,k,v,prx,a0){
  279. this.obj[k]=prx
  280. }
  281. _sett(o,k,v,prx,a0){
  282. dlog("_SETT",this,arguments)
  283. }
  284. _sett2(o,k,v,prx,a0){
  285. dlog("_SETT2",this,arguments)
  286. }
  287. set_pub(obj, prop, val,receiver){
  288. // dlog("qia_pub",obj, prop, val,receiver)
  289. // dlog("qia_pub2",this.n,obj.__path_arr, prop, jx(val))
  290. this._set_pub(obj.__path_arr, prop, jx(val))
  291. }
  292. _set_pub(path,key,val){
  293. var k,v
  294. /*
  295. tmsgx({
  296. "type":"set_msg",
  297. "payload":{path,key,val},
  298. },"code")
  299. // */
  300. tmsgx3({
  301. "type":"set_msg",
  302. "payload":{path,key,val},},
  303. // window.tmsgx_to || {}
  304. // {to:"nl4qbyiz61z-mce1@specplot.com/FlUkwrLs"},
  305. // {to:"maf@conference.i.specplot.com/0695c1e4"},
  306. // {},
  307. )
  308. for (v of this._pub_cb){
  309. v(path,key,val)
  310. }
  311. }
  312. _set_recv(path,prop,val){
  313. // return
  314. var p = path
  315. var nprop = deep_prop_v0(this.root,p)
  316. var dpth = nprop.__dpth
  317. if (tlu[typeof(val)]){
  318. nprop._set(nprop,prop,val,val)
  319. } else {
  320. nprop._set(nprop,prop,val,new Proxy(val,this))
  321. nprop[prop].add_proxy(nprop,prop,val,dpth+1)
  322. }
  323. // var tf = {}
  324. // this.walker(nprop[prop],tf,dpth+2)
  325. this.walker(nprop[prop],{},dpth+2)
  326. }
  327. set(obj, prop, val,receiver){
  328. // dlog("prx_db set ",this,obj, prop, val,receiver,val.__prx)
  329. // clog("prx_db set ",{that:this,obj, prop, val,receiver},val.__prx)
  330. // clog("prx_db set ",obj.__path_arr)
  331. if (obj[prop] === val){
  332. return Reflect.set(...arguments)
  333. }
  334. this.set_pub(obj, prop, val,receiver)
  335. this.event_proc("set")
  336. if ("__prx" == prop){
  337. this.__prx=val
  338. return this.__prx
  339. }
  340. if (typeof(val) === "object" && val != null && !(val.__prx)){
  341. var ret = Reflect.set(...arguments)
  342. this.set_obj(obj, prop, val,receiver)
  343. return ret
  344. }
  345. return Reflect.set(...arguments)
  346. }
  347. get(obj, prop,receiver){
  348. // dlog("prx_db get ...",prop==isProxy,this,obj, prop,receiver)
  349. if (this.hidden_props.includes(prop)){
  350. switch (prop){
  351. case "add_proxy":
  352. return this.add_proxy.bind(this)
  353. break;
  354. case "prxy":
  355. return this
  356. case "_set":
  357. // dlog("_SET")
  358. // return this._set.bind({this})
  359. return this._set.bind({that:this,obj, prop,receiver})
  360. case "_sett":
  361. return this._sett.bind({that:this,obj, prop,receiver})
  362. case "_sett2":
  363. return this._sett2.bind({that:this})
  364. case "walker_start":
  365. return this.walker_start
  366. case "walker":
  367. return this.walker
  368. break;
  369. }
  370. }
  371. if (isProxy == prop){ return true }
  372. if ("__prx" == prop){ return this.__prx }
  373. return Reflect.get(...arguments)
  374. }
  375. add_proxy(o,k,v,dpth){
  376. // clog("~add_proxy~",o,k,v,dpth)
  377. // clog("~add_proxy~",o.__prx,o,k,v,dpth,xpath)
  378. var xpath = o.__path
  379. var apath = o.__path_arr
  380. this.event_proc("add_proxy")
  381. if (!apath){
  382. apath=[]
  383. }
  384. if (!xpath){
  385. xpath="ROOT!"
  386. }
  387. Object.defineProperty(v,"__path_arr",Object.assign({value:apath.concat(k),},this.baseProp))
  388. Object.defineProperty(v,"__path",Object.assign({value:xpath+":"+k,},this.baseProp))
  389. Object.defineProperty(v,"__dpth",Object.assign({value:dpth,},this.baseProp))
  390. // Object.defineProperty(v,"__dbg",Object.assign({value:{},},this.baseProp))
  391. }
  392. set_obj(obj, prop, val,receiver){
  393. var dpth = obj.__dpth
  394. var tf = {}
  395. this.walker(receiver,tf,dpth)
  396. }
  397. walker(o,tfo,dpth=0){
  398. // dlog("qia WALK",this)
  399. if (dpth > 7){
  400. console.error("MAX DEPTH")
  401. return
  402. }
  403. var k,v
  404. var tf
  405. for ([k,v] of Object.entries(o)){
  406. tf = type_info(v)
  407. if (tf.deep_not_prx){
  408. o._set(o,k,v,new Proxy(v,this.prxy))
  409. o[k].add_proxy(o,k,v,dpth)
  410. this.walker(o[k],tf,dpth+1)
  411. }
  412. }
  413. }
  414. walker_start(o,dpth){
  415. var tf = type_info(o)
  416. o.add_proxy({},[],o,-1)
  417. this.walker(o,tf,0)
  418. }
  419. event_proc(e){}
  420. }
  421. window.Proxy_Factory = Proxy_Factory
  422. Proxy_Factory.prototype.baseProp={
  423. writable: true,
  424. // enumerable: true,
  425. enumerable: false,
  426. configurable: true,
  427. }
  428. }
  429. function arr_match(m,o){
  430. var k,v
  431. var r = 0
  432. for ([k,v] of Object.entries(m || {})){
  433. if (o[k] != v.valueOf()){
  434. r += 1
  435. return !r
  436. }
  437. // for ([k,v] in m){
  438. // case
  439. // dlog(k,v)
  440. }
  441. return !r
  442. }
  443. permissions_def = {
  444. participants:{
  445. m:["participants"],
  446. fn(set_scope,match){
  447. // clog("FN....",match.fp,match.fp[1] == window.glob_mx.local_id)
  448. if (match.fp[1] != window.glob_mx.local_id)
  449. throw "permission err"
  450. return
  451. },
  452. }
  453. }
  454. //
  455. // msto.my_data.prxy.__proto__.__proto__.set.call(msto.my_data.prxy,msto.participants,"abc2",{})
  456. permissions_def__set = {
  457. participants:{
  458. m:["participants"],
  459. fn(set_scope,match){
  460. dlog("FN....",match.fp,match.fp[1] == window.glob_mx.local_id)
  461. if (match.fp[1] != window.glob_mx.local_id)
  462. // throw "permission err"
  463. return
  464. },
  465. }
  466. }
  467. {
  468. class Proxy_Permissions extends Proxy_Factory {
  469. constructor(a,a1){
  470. super(...arguments)
  471. }
  472. set(obj, prop, val,receiver){
  473. // clog("PRX_PERM",obj.__path_arr,prop)
  474. var k,v
  475. var r
  476. var matched
  477. var fp = obj.__path_arr.concat(prop)
  478. for ([k,v] of Object.entries(permissions_def)){
  479. matched = arr_match(v.m,fp)
  480. if (matched){
  481. r = v.fn({that:this,obj, prop, val,receiver},{fp,k,v}) || {}
  482. }
  483. // if (r.return)
  484. }
  485. // case
  486. // if (obj.__path_arr && obj.__path_arr.length){}
  487. return super.set(obj, prop, val,receiver)
  488. }
  489. _set(){
  490. // clog("Proxy_Permissions _set")
  491. super._set(...arguments)
  492. }
  493. }
  494. window.Proxy_Permissions = Proxy_Permissions
  495. }
  496. msto_z = {
  497. // private_local:{},
  498. // participant_local:{},
  499. conference:{},
  500. participants:{
  501. },
  502. }
  503. function pfnf(o){
  504. return function(resolve, reject){
  505. o.resolve=resolve
  506. o.reject=reject
  507. // clog(arguments)
  508. }
  509. }
  510. function init_db_cb(){
  511. msto.participants[glob_mx.local_id] = msto.my_data
  512. }
  513. function init_sync_participant(){
  514. }
  515. function init_db(objx){
  516. var obj
  517. if (objx.participants){
  518. obj = objx
  519. } else {
  520. obj = objx.pl
  521. }
  522. window.objx_1 = objx
  523. // var obj = obj.pl
  524. clog("INIT DB...",objx,obj)
  525. pf = new Proxy_Permissions({},"pf")
  526. msto_prx = new Proxy(obj,pf)
  527. window.msto_prx0 =msto_prx
  528. // msto_prx = new Proxy(msto_z,pf)
  529. pf.init(msto_prx)
  530. msto_prx.walker_start(msto_prx)
  531. pf.root.participants[glob_mx.local_id] = {}
  532. glob_mx.flags.init_db = true
  533. setTimeout(init_db_cb,2000)
  534. window.msto= {
  535. participants:pf.root.participants,
  536. conference:pf.root.conference,
  537. // my_data:pf.root.participants[glob_mx.local_id],
  538. get my_data(){
  539. return msto.participants[glob_mx.local_id]
  540. // my_data("pfx get k1")
  541. },
  542. set my_data(val){
  543. clog("pfx set my_data")
  544. msto.participants[glob_mx.local_id] = val
  545. },
  546. private_local:{},
  547. set_listeners:{
  548. },
  549. }
  550. // var k,v
  551. clog("RUN_CB...")
  552. run_cbs("init_db")
  553. }
  554. function init_mu(persistent_mods){
  555. // .role == "moderator"
  556. // clog(">>>>>>>>>>>>>>>>>>>.. RUN_CB")
  557. var participants = get_participants()
  558. // clog(participants)
  559. var local = get_local(participants)
  560. if (window.glob_mx.local_id && persistent_mods && local.role=="moderator"){
  561. // if window.glob_mx.local_id
  562. // clog("no RUN_CB")
  563. return
  564. }
  565. window.glob_mx.local_id = local.id
  566. var k,v
  567. window.glob_mx.all_ids = []
  568. window.glob_mx.all_jids = []
  569. for (v of participants){
  570. window.glob_mx.all_ids.push(v.id)
  571. window.glob_mx.all_jids.push(`nnnx@conference.jfidev.com/${v.id}`)
  572. }
  573. var rr = {}
  574. var prom1 = new Promise(pfnf(rr));
  575. prom1.then(init_db)
  576. // setTimeout(rr.reject,2000,"RESP DB Timeout")
  577. // setTimeout(rr.resolve,4000,"RESP DB Timeout")
  578. // setTimeout(rr.resolve,4000,msto_z)
  579. // setTimeout(rr.resolve,4000,{aaa:"timedout",pl:msto_z})
  580. setTimeout(rr.resolve,5000,{aaa:"timedout",pl:msto_z})
  581. if (participants.length > 1){
  582. glob_mx.prom.init_db_resolve = rr.resolve
  583. clog("MSTO > 1")
  584. tmsgx3({type:"db_sync_request"})
  585. } else {
  586. clog("MSTO INIT!")
  587. // glob_mx.prom.init_db_resolve(msto_z)
  588. rr.resolve(msto_z)
  589. // init_db()
  590. }
  591. }
  592. function create_db(){
  593. }
  594. function isident(){
  595. return JSON.stringify(pf.root) == JSON.stringify(pf2.root)
  596. }
  597. function init_mu_runner(){
  598. if (window.glob_mx.conf_joined){
  599. init_mu(...arguments)
  600. }
  601. }
  602. function init_mx2(){
  603. clog("INITMX3")
  604. window.glob_mx.conf_joined =1
  605. init_mu_runner()
  606. // add_handler_m(mhndlr)
  607. }
  608. ifn_obj.init_conf_join.push(init_mx2)
  609. // init_mu_runner("auto")
  610. init_mu_runner("")