Cleanup the diff algorithm product.

Rewrite the script's diff handler.
This commit is contained in:
Robin Guerrier 2024-08-05 00:03:13 -04:00
parent 71697d23c6
commit 6ed80fdafb
2 changed files with 302 additions and 253 deletions

View File

@ -124,99 +124,83 @@ function handleReturnAttr(event, returnAttrVals) {
return returnData;
};
function handleChannelStream(event) {
try {
const streamResponse = JSON.parse(event.data);
if (streamResponse.response !== 'diff') return;
fetch(channelPath, {
method: 'PUT',
body: JSON.stringify(makeAck(streamResponse.id))
});
const htmlData = streamResponse.json;
// console.log(htmlData);
if (!htmlData) return;
let container = document.createElement('template');
container.innerHTML = htmlData;
if (container.content.firstElementChild.childNodes.length === 0) return;
// const navUrl = container.content.firstElementChild.getAttribute('url');
// if (navUrl && (navUrl !== window.location.pathname)) {
// history.pushState({}, '', navUrl);
// };
while (container.content.firstElementChild.children.length > 0) {
let gustChild = container.content.firstElementChild.firstElementChild;
if (gustChild.tagName === 'D') {
for (const att of gustChild.attributes) {
const dkey = att.value;
document.querySelector(`[key="${dkey}"]`).remove();
};
gustChild.remove();
} else if (gustChild.tagName === 'N') {
const nodeKey = gustChild.firstElementChild.getAttribute('key');
const parentKey = gustChild.firstElementChild.getAttribute('pkey');
const appendIndex = gustChild.id;
let domParent = document.querySelector(`[key="${parentKey}"]`);
domParent.insertBefore(gustChild.firstElementChild, domParent.children[appendIndex]);
let appendedChild = domParent.querySelector(`[key="${nodeKey}"]`);
if (appendedChild.getAttribute('event')) {
setEventListeners(appendedChild);
};
if (appendedChild.childElementCount > 0) {
let needingListeners = appendedChild.querySelectorAll('[event]');
needingListeners.forEach(child => setEventListeners(child));
};
appendedChild = appendedChild.nextElementSibling;
gustChild.remove();
} else if (gustChild.tagName === 'M') {
const nodeKey = gustChild.getAttribute('key');
const nodeIndex = gustChild.id;
let existentNode = document.querySelector(`[key="${nodeKey}"]`);
let childAtIndex = existentNode.parentElement.children[nodeIndex];
if (existentNode.nextElementSibling
&& (existentNode.nextElementSibling.getAttribute('key')
=== childAtIndex.getAttribute('key'))) {
existentNode.parentElement.insertBefore(existentNode, childAtIndex.nextElementSibling);
} else {
existentNode.parentElement.insertBefore(existentNode, childAtIndex);
};
gustChild.remove();
} else if (gustChild.tagName === 'C') {
const nodeKey = gustChild.getAttribute('key');
const attToRem = gustChild.getAttribute('rem')?.slice(0, -1).split(' ') ?? [];
let existentNode = document.querySelector(`[key="${nodeKey}"]`);
attToRem.forEach(att => {
if (att === 'event') {
const eventType = existentNode.getAttribute('event').split('/', 2)[1];
existentNode[`on${eventType}`] = null;
};
existentNode.removeAttribute(att);
const streamResponse = JSON.parse(event.data);
fetch(channelPath, {
method: 'PUT',
body: JSON.stringify(makeAck(streamResponse.id))
});
if (streamResponse.response !== 'diff') return;
const gust = streamResponse.json;
if (!gust) return;
// console.log(gust);
gust.forEach(gustObj => {
switch (gustObj.p) {
case 'd':
gustObj.q.forEach(key => {
document.querySelector(`[key="${key}"]`).remove();
});
gustChild.removeAttribute('key');
gustChild.removeAttribute('rem');
for (const att of gustChild.attributes) {
existentNode.setAttribute(att.name, att.value);
if (att.name === 'event') {
const eventType = existentNode.getAttribute('event').split('/', 2)[1];
existentNode[`on${eventType}`] = null;
setEventListeners(existentNode);
break;
case 'n':
let parent = document.querySelector(`[key="${gustObj.q}"]`);
if (gustObj.r === 0) {
parent.insertAdjacentHTML('afterbegin', gustObj.s);
} else if (gustObj.r === parent.childNodes.length) {
parent.insertAdjacentHTML('beforeend', gustObj.s);
} else {
let indexTarget = parent.childNodes[gustObj.r];
if (indexTarget.nodeType === 1) {
indexTarget.insertAdjacentHTML('beforebegin', gustObj.s);
} else {
let placeholder = document.createElement('div');
parent.insertBefore(placeholder, indexTarget);
placeholder = parent.childNodes[gustObj.r];
placeholder.outerHTML = gustObj.s;
};
};
gustChild.remove();
} else {
const nodeKey = gustChild.getAttribute('key');
let existentNode = document.querySelector(`[key="${nodeKey}"]`);
existentNode.replaceWith(gustChild);
let replacedNode = document.querySelector(`[key="${nodeKey}"]`);
if (replacedNode.getAttribute('event')) {
setEventListeners(replacedNode);
let newNode = parent.childNodes[gustObj.r];
if (newNode.getAttribute('event')) {
setEventListeners(newNode);
};
if (replacedNode.childElementCount > 0) {
let needingListeners = replacedNode.querySelectorAll('[event]');
if (newNode.childElementCount > 0) {
let needingListeners = newNode.querySelectorAll('[event]');
needingListeners.forEach(child => setEventListeners(child));
};
};
break;
case 'm':
let fromNode = document.querySelector(`[key="${gustObj.q}"]`);
const fromIndex = [ ...fromNode.parentNode.childNodes ].indexOf(fromNode);
if (fromIndex < gustObj.r) gustObj.r++;
let toNode = fromNode.parentNode.childNodes[gustObj.r];
fromNode.parentNode.insertBefore(fromNode, toNode);
break;
case 'c':
let targetNode = document.querySelector(`[key="${gustObj.q}"]`);
if (gustObj.r.length) {
gustObj.r.forEach(attr => {
if (attr === 'event') {
let eventVal = targetNode.getAttribute('event').split('/');
if (eventVal[0] === '') eventVal.shift();
const eventType = eventVal[0];
targetNode[`on${eventType}`] = null;
};
targetNode.removeAttribute(attr);
});
};
if (gustObj.s.length) {
gustObj.s.forEach(attr => {
const name = attr[0];
const value = attr[1];
targetNode.setAttribute(name, value);
if (name === 'event') setEventListeners(targetNode);
});
};
break;
case 't':
let textWrapperNode = document.querySelector(`[key="${gustObj.q}"]`);
textWrapperNode.textContent = gustObj.r;
break;
};
} catch (error) {
console.error(error);
};
});
};
function makeSubscribeBody() {
channelMessageId++;

View File

@ -221,19 +221,10 @@
:- #/[p/our.bowl]/$/eyre
:- %poke
:- %eyre-chan-gift
!>
^- chan-gift:eyre:neo
!> ^- chan-gift:eyre:neo
:- sub
%- tape:enjs:format
%- en-xml:html
:: ~& >> gust/(algo c.i.t.c.old c.i.t.c.new)
^- manx
;g
=url v.i.a.g.new
;* %+ algo
c.i.t.c.old
c.i.t.c.new
==
^- json
[%a (algo c.i.t.c.old c.i.t.c.new)]
::
++ make-400
|= rid=@ta
@ -274,235 +265,309 @@
--
::
++ hoist
|= root=manx
|^ ^- manx
(tanx root "0" "~")
++ tanx
|= [m=manx key=tape pkey=tape]
=/ fkey=tape (getv a.g.m %key)
=/ nkey=tape ?~(fkey key fkey)
|_ root=manx
++ $
^- manx
(anx root ["" ~])
++ anx
|= [m=manx key=(pair tape (list @))]
^- manx
=/ fkey=@t (getv %key a.g.m)
=/ nkey=(pair tape (list @)) ?~(fkey key [((w-co:co 1) `@uw`(mug fkey)) ~])
=/ ntap=tape (weld p.nkey ((w-co:co 1) `@uw`(jam q.nkey)))
?: =(%$ n.g.m)
;span
=mast "text"
=key nkey
=pkey pkey
;t-
=key ntap
;+ m
==
=: a.g.m %- mart
?~ fkey
[[%key nkey] [[%pkey pkey] a.g.m]]
[[%pkey pkey] a.g.m]
c.m (tarl c.m nkey)
%_ m
a.g
^- mart
?~ fkey
[[%key ntap] a.g.m]
a.g.m
c
(arl c.m nkey)
==
m
++ tarl
|= [m=marl key=tape]
=/ i=@ud 0
++ arl
|= [m=marl key=(pair tape (list @))]
=| i=@
|- ^- marl
?~ m
~
:- %^ tanx
(manx i.m)
(weld (scow %ud i) (weld "-" key))
key
?~ m ~
:- %+ anx
i.m
key(q [i q.key])
$(m t.m, i +(i))
--
::
++ algo
|= [old=marl new=marl]
^- marl
=/ i=@ud 0
=/ acc=marl ~
|-
=| i=@ud
=| pkey=@t
=| acc=(list json)
|- ^- (list json)
?~ new
?. =(~ old)
?: =(%skip -.-.-.old)
$(old +.old)
:_ acc
:_ ~
:- %d
=/ c=@ud 0
|- ^- mart
?~ old
~
:- :- (crip (weld "d" <c>))
(getv a.g.i.old %key)
$(old t.old, c +(c))
acc
?: &(?=(^ old) =(%skip -.-.-.old))
$(old t.old)
?: =(%m n.g.i.new)
$(new t.new, i +(i), acc (snoc acc i.new))
=/ j=@ud 0
?~ old
acc
?: =(%skip- n.g.i.old)
%= $
old t.old
==
:_ acc
^- json
:- %o
%- my
:~ ['p' [%s 'd']]
['q' [%a (turn old |=(m=manx [%s (getv %key a.g.m)]))]]
==
?: &(?=(^ old) =(%skip- n.g.i.old))
%= $
old t.old
==
?: =(%move- n.g.i.new)
%= $
new t.new
i +(i)
acc
%+ snoc acc
^- json
:- %o
%- my
:~ ['p' [%s 'm']]
['q' [%s (getv %key a.g.i.new)]]
['r' [%n (getv %i a.g.i.new)]]
==
==
=| j=@ud
=/ jold=marl old
=/ nkey=[n=mane k=tape] [n.g.i.new (getv a.g.i.new %key)]
|-
=/ nkey=[n=mane k=@t] [n.g.i.new (getv %key a.g.i.new)]
|- ^- (list json)
?~ new
!!
?~ jold
%= ^$
new t.new
i +(i)
acc %+ snoc acc
;n(id <i>)
;+ i.new
acc
%+ snoc acc
^- json
:- %o
%- my
:~ ['p' [%s 'n']]
['q' [%s pkey]]
['r' [%n (scot %ud i)]]
['s' [%s (crip (en-xml:html i.new))]]
==
==
?~ old
!!
?: =(%skip n.g.i.jold)
$(jold t.jold, j +(j))
?: .=(nkey [n.g.i.jold (getv a.g.i.jold %key)])
?: =(%skip- n.g.i.jold)
%= $
jold t.jold
j +(j)
==
?: =(nkey [n.g.i.jold (getv %key a.g.i.jold)])
?. =(0 j)
=/ n=@ud 0
=| n=@ud
=/ nnew=marl new
=/ okey=[n=mane k=tape] [n.g.i.old (getv a.g.i.old %key)]
|-
=/ okey=[n=mane k=@t] [n.g.i.old (getv %key a.g.i.old)]
|- ^- (list json)
?~ nnew
^^$(old (snoc t.old i.old))
?: =(%m n.g.i.nnew)
$(nnew t.nnew, n +(n))
=/ nnky=[n=mane k=tape] [n.g.i.nnew (getv a.g.i.nnew %key)]
?. .=(okey nnky)
$(nnew t.nnew, n +(n))
?: (gte n j)
=/ aupd=mart (upda a.g.i.old a.g.i.nnew)
?~ aupd
%= ^^$
old c.i.old
new c.i.nnew
i 0
acc
%= ^^$
old t.old
new %^ newm new n
;m(id <(add n i)>, key k.nnky);
==
==
%= ^^$
old c.i.old
new c.i.nnew
i 0
old (snoc t.old i.old)
==
?: =(%move- n.g.i.nnew)
%= $
nnew t.nnew
n +(n)
==
=/ nnky=[n=mane k=@t] [n.g.i.nnew (getv %key a.g.i.nnew)]
?. =(okey nnky)
%= $
nnew t.nnew
n +(n)
==
?: (gte n j)
=/ aupd (upda a.g.i.old a.g.i.nnew)
%= ^^$
old c.i.old
new c.i.nnew
pkey k.nnky
i 0
acc
%= ^^$
old t.old
new %^ newm new n
;m(id <(add n i)>, key k.nnky);
acc :_ acc
[[%c [[%key k.nnky] aupd]] ~]
==
==
=/ aupd=mart (upda a.g.i.jold a.g.i.new)
?~ aupd
%= ^^$
old c.i.jold
new c.i.new
i 0
acc
%= ^^$
old (newm old j ;skip;)
new t.new
i +(i)
acc %+ snoc acc
;m(id <i>, key k.nkey);
new
%^ newm new n
;move-(i (scow %ud (add n i)), key (trip k.nnky));
acc
?: &(?=(~ del.aupd) ?=(~ new.aupd))
acc
:_ acc
^- json
:- %o
%- my
:~ ['p' [%s 'c']]
['q' [%s k.nnky]]
['r' [%a del.aupd]]
['s' [%a new.aupd]]
==
==
==
=/ aupd (upda a.g.i.jold a.g.i.new)
%= ^^$
old c.i.jold
new c.i.new
i 0
old c.i.jold
new c.i.new
pkey k.nkey
i 0
acc
%= ^^$
old (newm old j ;skip;)
old (newm old j ;skip-;)
new t.new
i +(i)
acc :- [[%c [[%key k.nkey] aupd]] ~]
%+ snoc
acc
=. acc
%+ snoc acc
^- json
:- %o
%- my
:~ ['p' [%s 'm']]
['q' [%s k.nkey]]
['r' [%n (scot %ud i)]]
==
?: &(?=(~ del.aupd) ?=(~ new.aupd))
acc
;m(id <i>, key k.nkey);
:_ acc
^- json
:- %o
%- my
:~ ['p' [%s 'c']]
['q' [%s k.nkey]]
['r' [%a del.aupd]]
['s' [%a new.aupd]]
==
==
==
?: =("text" (getv a.g.i.new %mast))
?: =(+.-.+.-.-.+.-.old +.-.+.-.-.+.-.new)
^$(old t.old, new t.new, i +(i))
?: =(%t- n.g.i.new)
?: ?& ?=(^ c.i.old) ?=(^ c.i.new)
?=(^ a.g.i.c.i.old) ?=(^ a.g.i.c.i.new)
=(v.i.a.g.i.c.i.old v.i.a.g.i.c.i.new)
==
%= ^$
old t.old
new t.new
i +(i)
==
=/ txt=@t
?. &(?=(^ c.i.new) ?=(^ a.g.i.c.i.new))
''
(crip v.i.a.g.i.c.i.new)
%= ^$
old t.old
new t.new
i +(i)
acc [i.new acc]
==
=/ aupd=mart (upda a.g.i.old a.g.i.new)
?~ aupd
%= ^$
old c.i.old
new c.i.new
i 0
acc ^$(old t.old, new t.new, i +(i))
acc
:_ acc
^- json
:- %o
%- my
:~ ['p' [%s 't']]
['q' [%s (getv %key a.g.i.new)]]
['r' [%s txt]]
==
==
=/ aupd (upda a.g.i.old a.g.i.new)
%= ^$
old c.i.old
new c.i.new
i 0
old c.i.old
new c.i.new
pkey k.nkey
i 0
acc
%= ^$
old t.old
new t.new
i +(i)
acc :_ acc
[[%c [[%key k.nkey] aupd]] ~]
acc
?: &(?=(~ del.aupd) ?=(~ new.aupd))
acc
:_ acc
^- json
:- %o
%- my
:~ ['p' [%s 'c']]
['q' [%s k.nkey]]
['r' [%a del.aupd]]
['s' [%a new.aupd]]
==
==
==
$(jold t.jold, j +(j))
%= $
jold t.jold
j +(j)
==
::
++ getv
|= [m=mart tag=@tas]
^- tape
?~ m
~
?: =(n.i.m tag)
v.i.m
|= [t=@tas m=mart]
^- @t
?~ m ''
?: =(n.i.m t)
(crip v.i.m)
$(m t.m)
::
++ upda
|= [om=mart nm=mart]
=/ acc=mart ~
|- ^- mart
=| acc=[del=(list json) new=(list json)]
|- ^+ acc
?~ nm
?~ om
acc
:_ acc
:- %rem
=/ omom=mart om
|-
?~ omom
~
=/ nom=tape +:<n.i.omom>
|-
?~ nom
[' ' ^$(omom t.omom)]
[i.nom $(nom t.nom)]
=/ i=@ud 0
%_ acc
del
%+ turn om
|= [n=mane *]
[%s `@t`?>(?=(@ n) n)]
==
=| i=@ud
=/ com=mart om
|-
|- ^+ acc
?~ nm
!!
?~ com
^$(nm t.nm, acc [i.nm acc])
%= ^$
nm t.nm
new.acc
:_ new.acc
:- %a
:~ [%s `@t`?>(?=(@ n.i.nm) n.i.nm)]
[%s (crip v.i.nm)]
==
==
?~ om
!!
?: =(n.i.com n.i.nm)
?: =(v.i.com v.i.nm)
^$(om (oust [i 1] (mart om)), nm t.nm)
%= ^$
om (oust [i 1] (mart om))
nm t.nm
==
%= ^$
om (oust [i 1] (mart om))
nm t.nm
acc [i.nm acc]
om (oust [i 1] (mart om))
nm t.nm
new.acc
:_ new.acc
:- %a
:~ [%s `@t`?>(?=(@ n.i.nm) n.i.nm)]
[%s (crip v.i.nm)]
==
==
$(com t.com, i +(i))
%= $
com t.com
i +(i)
==
::
++ newm
|= [ml=marl i=@ud mx=manx]
=/ j=@ud 0
=| j=@ud
|- ^- marl
?~ ml
~