Friday 28 April 2023

Svelte!

quite nice - close to html

But I had this Con component that was recursive:

...
{#if say} <span style="color:darkcyan"> {say} </span>{/if}
{#if nodules.length}
<nodules transition:scale style=...>
{#each nodules as n}
<nodule transition:scale style="display:block">
<svelte:self {...n} />
</nodule>
{/each}
</nodules>
{/if}

Where nodules describe each item of the hash|array we are looking at, or for string|number it simply says it, etc.

The data this is inflating from is changing, but we're not re-rendering the changes. How would it know? It would have to rerun segments of the action: just where Con pulls the many out of the current one. Letting a process make its core awareness available to an other-time (eg when deciding to re-Con) would be a great programming - the thinning of code for re-use...

So we can easily de-memo the whole thing at the top Con by simply conver++ when data might have changed:

{#key conver}
<p> <Con .../> </p>
{/key}

But that's recreating a lot of things.

We need to isolate reactivity to only some of the components.

dispatch to getContext

I group the data-discovery process (so that Con becomes merely templating a few variables), which generates a tree of C atoms that Con will then impersonate.

They have C.c.ip addressing them in the pile, which we shall use almost like NOTIFY channels to version bump.

Before all the challenge of version controlling a pile of data, lets test that the above is going to deliver the goods.

Con.svelte:

<script lang="ts">
import {getContext} from 'svelte'
    ...
let sip = C.c.ip.join('.')
let update
$: update = getContext(sip)
    ...
</script>
...
{#if update} <span style=...>{update}</span>{/if}
...

Code.svelte:

$: refresh, setContext('1.2.1.2.2',refresh);

We test with one we know is changing. That should be it. When refresh increases by 1 when we change data, this line happens. It might be because:

  • it starts with a $:
  • because it involves refresh
  • or because of the extra refresh in void context (list expressions like this return the last item only)
That's Svelte magic. I'm not sure whether the line happens on its own or inside a (partial?) recreation of Code. This is an elegant design for the web of dependencies behind the templating phase (or more dependencies). Again, I'm not sure, but my foots just in the door... Clarity sooner or later perhaps.

Anyway, it manages to set|send at this end, but Con never receives it.

Context is not inherently reactive. If you need reactive values in context then you can pass a store into context, which will be reactive.

as a swarm of writable stores and getContext

works once, usually

Code.svelte:

// set up stores to update them all (con.c.visit[Con+])
for (let C of con.c.visit) {
let sip = C.c.ip.join('.')
if (sips[sip]) continue
newsips[sip] = C
}
    ...
for (let [sip, C] of Object.entries(newsips)) {
let wire = sips[sip] = writable(0)
// allow **-Con to find their wires
setContext(sip, wire)
}
    ...
$: refresh, console.log("Was: "+refresh), sips['1.2.1.2.2']?.set(refresh);

So for each address, a version: starting at 0.

Con.svelte:

...
import Cont from '$lib/pi/Cont.svelte';
import Conz from '$lib/pi/Conz.svelte';
let pis = {Cont, Conz}
    ...
    export let C
let sip = C.c.ip.join('.');
let wire
let update:number
let unsubscribe:Function

wire = getContext(sip)
unsubscribe = wire.subscribe((v) => {
if (!v) return
console.log("Got: "+v)
update = v
});

onDestroy(() => {
unsubscribe();
});
    ...
</script>
...
<small> {sip}</small>
{#if update} <span style=...>{update}</span>{/if}

{#key update}
{#each bits as n}
<span style=...>
<svelte:component this={pis[n.c.pi]} C={n}/>
</span>
{/each}
{/key}

waffle

The nodules are now called bits and there's a namespace of components they choose to be their vessel. There are only two here (imported and put into the pis dispatch table) but this is where a networked consciousness dictionary comes in.

The store subscription syntax could perhaps have been:

$: if (wire) {
console.log("Got:"+wire)
update = wire
}

Or perhaps when (wire). Feels like people would have expected this in the 50s from the 70s.

basically

This works only once. Sometimes not even once.

I might report my program for gross weirdness.

When it works once and {update} there shows 1, as expected. However:

  • Only once
  • The {#key update} doesn't seem to work here, so we don't get fresh innards when we want them. It's not just because it starts undefined.

Box of first principals

I imagine we could pass a version to each Con, bumping every enclosing Con until it stabilises, and the rest of that branch of the tree goes to sleep.
Then I focus on wire...

Code.svelte:

...
let wire = writable(0)
setContext('ooh', wire)
let wirvir = 1
$: console.log('hi-wire:'+wirvir), wire.set('hi'+(wirvir))
...
<button on:click={() => wirvir++} > Box-hi </button>
<Box />

Aside: pretty sweet connection of wirvir++ -> wire.set(...wirvir...). This is where you want the $:.

Box.svelte:

<script lang="ts">
import {onMount, onDestroy, getContext} from 'svelte'
import Box from '$lib/pi/Box.svelte';
let varieties = {Box}
export let n = [1,2,3,4,5,6,7,8,9,10,11,12]
let num = n[0]
let rest = n.slice(1)


let wire
let update:number
let unsubscribe:Function

wire = getContext('ooh')

unsubscribe = wire.subscribe((v) => {
if (!v) return
console.log("Got:"+v)
update = v
});

onDestroy(() => {
unsubscribe();
});

</script>

<div style="margin-left:0.4em">
<small> [{num}]{$wire}</small>

{#if update} <span style="color:darkcyan; text-decoration:underline">{update}</span>{/if}

{#if rest.length} <svelte:component this={varieties['Box']} n={rest} /> {/if}
</div>

Note the realistic svelte:component, unrealistic writable in the main bit of Code rather than in an event handler (or reactive bit of Code thence?)... what happens there again?

Then I see it

for (let [sip, C] of Object.entries(newsips)) {
let wire = sips[sip] = writable(0)
// allow **-Con to find their wires
setContext(sip, wire)
}
newsips = {}

Empty the queue! Simply forgot a line.
That last line avoids recreating stores once they're floating around in sips, which apparently lasts as long as the components listening to them do?

Huuray!

All my bugs. Svelte remains unscathed, as does Javascrpt.

back down the hill

Any out of date **Con are now (as of letz.git 49451ea2b02e) sent updated C to replace the one originally place via prop from its parent.

In 4535955eb7f8, toCon's C** traversal takes a moment for each Con//Con to do 32b358bf3 DCresolve, which decides which things continue the existence of which things from before, over time. The inner Con has /Cont with various traces of id and is about to create /Conz/Con+.
This process results in knowing if things continue, come or go.

Then 358b75b82, DCdiffer decides what changes, given a past self: C and C.y.D

This ended up being easy.

In eg Cont.svelte, we allow remote assignment to C and make this efficient bunch of connections in-sphere to out-sphere with reactivity from the C:
export let C
sip_wiree(C, v => {
C = v
})
let sym,Ct,say
function upto() {
({sym,Ct,say} = C.sc)
}
$: upto(C)

Now, you can see some random problems: deleting mind (1.2.2) keeps its label


The transitions give away some irregularity, also the labels are staying off-by-one...
    looking at it do transitions we are mutating the goner


   {#each} can have a key, items in a changing list remain themselves
        this is Svelte's sense of resolve, which we shall extend some day to go by look and feel...
            I bet weird things will happen when we want to have things swap names...
    goners going, next item slides up

Now we have holes being left, sip wires not being ready when the client component looks for them, ips not changing when the list rearranges:
Lets try moving sip pluck to the core of Con.svelte:
function upto() {
t = C.t
quee = update || '='
sip = C.c.ip.join('.')
}
And now the ips change!
    C.c.ip can be kept in sync without dispatch if put in upto()
        svelte seems to be running all these upto() functions every time
        luckily they are just assigning a few strings...


    old sip is updating as it fades out
      its size|content becomes that other
      and doesnt get removed after transition (usually)

      subscription dupe from the C now assigned its ip

I refactor sip_dispatch.setN so we simply remove old wires - instead of sending a new C that isn't in continuity (C.y.D to the old C on that wire) quite anomalously.


And style good:

Now if we put some electrodes here in Conz.svelte:
let nodules
console.log("mozwales",C.c.sip)
function upto() {
console.log("anbup",C.c.sip)
nodules = o_(C)
}
$: upto(C)
We can see:

And this continues to look good even while I disable most of what I thought was essential:
sip_wiree, sipd.setN(con.c.visit) etc, for (let n of con.c.wake) { sipd.o(n) }
It can all be disabled without stopping reactivity.

Huh?

    every upto() is running (anbup)
    an intelligent minimum of hard work (mozwales)
    even if the C remains the same (no tocon())
     ie not '==', perhaps because object
      defers to the process it does not know how to sleep


   perf of clicking bloop()
    toCon() 1.6ms
    setN() 2.2ms
     it is all console.log! fixed.
    layout etc 60ms
     then without transition 10ms

So
  • {#each nodules as n (n.t)} makes it all work good
    • this is called 'resolve $n', here we use n.t to distinguish individuals
    • this distributes new C** everywhere very quickly when we bloop()
  • we're not saving any time by figuring out where in C** we want to dispatch
  • there's little time to save anyway
  • with hundreds of Cons:
    • bleep() (mozwales) takes a second
    • yet bloop() (anbup) is perfectly fast

Careful

    to not click away the modal error message in the webapp,
    whence it will have failed to reload.

    sometimes you have to watch vite via terminal for the errors, once the webapp shuts itself out.


   wrong:
    in Code.svelte:
     import { Diring } from "$lib/Diring.svelte"
    vite will say:
     Error: <Diring> is not a valid SSR component. ...
   right:
    import Diring from "$lib/Diring.svelte"

   also random undefined variables in templates:
    {#each peek as f, i}
        ...
    at the end of Diring, causes the same "not a valid SSR component"
     along with an earlier: /src/lib/Diring.svelte:69:7 'peek' is not defined

this will make no warning:
let junk = [1,3,5,[6,[6,[6[[6,[2]]]]]]]
ends up with only two sixes in it.

a glance at the todolist


   < get Babz 'expr and block', each, '#' comments, &arg{...} in here...
   < branch layout:
      turtle moves in letter shapes for compute carpentry vocab
      tunneling|folding away, open causing closes
   < overall layout: screen splitting
   < build Le interfacible, like boost
   < reset_tocon to become a disassociation of rowing
     sipd need not reset since .setN() goes goners
      in io parlance,
         sipd could be cascaded to since it looks at history
          as opposed to holding history (3d vs 2d view)
          alluding to a slant, viewing-angle perceptex
   
   
   < loosen the input to Con... drag other items into it?
   
   < permanent sips, where earlier positions are inserted to via 0
     
   < tocon makes a datadump C**
      then generate lv for changes
      over time, as various t are increased
      thus making Story
   
   < pull out all dispatch mannequa?
   < Cont / onMount / getBoundingClientRect
     might help draw fibers of:
   < Eref noticing when objects are the same
     do we need an E for every C?
      follow its C.y.D when it turns up?
     try using WeakMap
   < $page.url.searchParams from '$app/stores' sounds nice
     Storing state in the URL!
     cant quite work out how tho
     accessible from +page server only?

Yay

Good luck to all solving problems with Svelte! Thanks!

“All nations sold out by liars and cowards. Liars who want time for the future negatives to develop stall you with more lying offers while hot crab people mass war to extermination with the film in Rome. These reports reek of nova, sold out job, shit birth and death. Your planet has been invaded. You are dogs on all tape. The entire planet is being developed into terminal identity and complete surrender.” William S. Burroughs - Nova Express

Thursday 27 April 2023

compressor effect on all the audio in linux

install and run:

sudo apt install pulseeffects

then in there:

  • enable "Auto Gain"
    • set its Target to -25dB
for explosions and dialogue at the same level!

Monday 17 April 2023

javascript!

this

In a given function, this refers to the object that function is invoked from.

// handles creating C** once told the scheme
d.partor ||= DCpartor(d,'Con')
Inside DCparator:
// arrow functions don't provide their own this binding
whereas an arrow function retains the this value of the enclosing lexical context
return function (t,pi,c) {
// compat: this is the current d where this function is called
let d = this
            ...
We go on to clone d to recursions, d.partor uses its current d.

just variables

In javascript, class names are just variables, so you'd better call it something other than what you usually call it:
class TheC {}
class TheA extends TheC {}
Then we can do:
let C = new TheC()
ex(C,{t,y,c,sc})
Or:
let A = new TheA()
ex(A, C_(t))
Making a type-of-thing label for us to see amongst piles of objects in computer memory which get tossed, scanned, squished, swept etc around the surrealist office space of our demands.

Once noticed to be A or C, various other knowledge graphs (or assumptions) can apply.

Here we use the classes for nothing but their ability to label types of objects, out of band (separately) to the content of the objects (properties we iterate, etc).
We could alternatively apply a schema to the objects, or simply put the type label in our data model.
Putting the type label in an "unreachable" place (not iterable content of the object) makes a superficial distinction between "conscious" memory and that which lies on the page.
We are working on a new subject-to-object dialectic, so a language-agnostic functional firmament should allow more translation later. It is interesting that we can get lost and then try to recover sense systematically. I imagine this whole area will be wired for sound pretty soon, using misunderstandings and reinterpretations for creativity.
The low-levels of typology smoothly paved over.

post-hoc classimilation not advised

let A = C_(t)
Object.setPrototypeOf(A, TheA.prototype)
This blesses the A hash into TheA-dom.
If you look at TheA.prototype it is instanceof TheC!
with a .constructor = Function, which (in DevTools): 
(magic here?) identifies its source: class TheA extends TheC {} as its source,
and is also the value of TheA (without .prototype).

There's probably a simple explanation. Anyway,

Warning: Changing the [[Prototype]] of an object is, by the nature of how modern JavaScript engines optimize property accesses, currently a very slow operation in every browser and JavaScript engine. 

for in or for of

Arrays are a type of Object. This will print all the keys:

    let thi = [1,2,3]
thi.foo = 'fab'
for (let i in thi) {
console.log(i)
}

but for (let i of thi) { will:

  • avoid foo, because it uses an iterator from Array, which apparently only does array indices
  • iterate values, not keys

So given N=[C+] you can 

for (let C of N) {

And destructure given N=[{thing,act}+]

for (let {thing,act} of o_path(mind,['mind','thing','act'])) {

And to get key and value (iterating array or hash) at the same time:

for (let [k,v] of Object.entries(thi)) {

iterating anyway

In stylehouse, I usually write:

each iv N {

or

each nk,gk,v q {

which compile into for in loops iterating N.$i = v and q.$nk.$gk = v respectively.

They iterate keys then pluck out the value on an extra line, so it works on array or hash.

it's a beautiful world out there

conclusion

onward!