diff --git a/pkg/arvo/app/neo.hoon b/pkg/arvo/app/neo.hoon index 0230f1331cf..7204abd7ce6 100644 --- a/pkg/arvo/app/neo.hoon +++ b/pkg/arvo/app/neo.hoon @@ -257,6 +257,7 @@ %noun (on-noun q.vase) %neo-raw-poke (on-move (poke:harden !<(raw-poke:neo vase))) %handle-http-request (handle-http-request:sttp !<([@ta inbound-request:eyre] vase)) + %json (handle-eyre-chan-request:sttp !<(json vase)) == ++ on-noun |= non=* @@ -322,6 +323,7 @@ [%sync rest=*] (on-peer-sync (pave:neo rest.pole) stop) [%fetch rest=*] ?:(stop run (on-peer-fetch (pave:neo rest.pole))) [%http-response *] run + [%eyre-chan *] run == :: ++ on-peer-fetch @@ -2312,10 +2314,11 @@ ++ call |= [src=pith:neo dst=pith:neo =note:neo] ?> ?=(%poke -.note) :: XX: all shanes should be virtualised and hand deliver acks - ?+ p.pail.note ~|(bad-eyre-call/p.pail.note !!) - %ack run - %eyre-req (on-eyre-req !<(req:eyre:neo q.pail.note)) - %eyre-sign (on-eyre-sign src !<(sign:eyre:neo q.pail.note)) + ?+ p.pail.note ~|(bad-eyre-call/p.pail.note !!) + %ack run + %eyre-req (on-eyre-req !<(req:eyre:neo q.pail.note)) + %eyre-sign (on-eyre-sign src !<(sign:eyre:neo q.pail.note)) + %eyre-chan-gift (on-eyre-chan-gift !<(chan-gift:eyre:neo q.pail.note)) == +$ request-line $: [ext=(unit @ta) site=(list @t)] @@ -2348,6 +2351,13 @@ %data `http-response-data/!>(dat.gift) %done ~ == + :: + ++ on-eyre-chan-gift + |= [sub=path dat=json] + ^+ run + =/ cag=cage [%json !>(dat)] + (give %fact ~[sub] cag) + :: ++ match-binding =| test=(list @t) |= site=(list @t) @@ -2370,6 +2380,35 @@ =/ =card:neo [u.bin %poke eyre-task/!>(`task:eyre:neo`[eyre-id req])] =/ =move:neo [#/[p/our.bowl]/$/eyre card] (emit (do-move move)) + :: + ++ handle-eyre-chan-request + |= jon=json + ^+ run + =/ dst=(unit pith:neo) + ?. &(?=(^ jon) ?=(%o -.jon)) + ~ + =/ str=(unit json) (~(get by p.jon) 'pith') + ?. &(?=(^ str) ?=(^ u.str) ?=(%s -.u.str)) + ~ + :- ~ + %+ turn (stab p.u.str) + |= i=@ta + %- iota + =+ v=(slay i) + ?> &(?=(^ v) ?=(%$ -.u.v)) + ?: =(~.tas p.p.u.v) + q.p.u.v + p.u.v + ?~ dst ~|(eyre-channel-req-missing-pith/jon !!) + =. jon + ?. &(?=(^ jon) ?=(%o -.jon)) + ~ + =/ dat=(unit json) (~(get by p.jon) 'data') + ?~ dat ~ + u.dat + =/ =card:neo [u.dst %poke eyre-chan-task/!>(`chan-task:eyre:neo`jon)] + =/ =move:neo [#/[p/our.bowl]/$/eyre card] + (emit (do-move move)) -- ++ cttp diff --git a/pkg/arvo/neo/cod/std/src/fil/mast-js.js b/pkg/arvo/neo/cod/std/src/fil/mast-js.js new file mode 100644 index 00000000000..d5951b6e64a --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/fil/mast-js.js @@ -0,0 +1,222 @@ +let pith; +let path; +let ship; +let app; +let channelMessageId = 0; +let eventSource; +const channelId = `${Date.now()}${Math.floor(Math.random() * 100)}`; +const channelPath = `${window.location.origin}/~/channel/${channelId}`; +addEventListener('DOMContentLoaded', async () => { + pith = document.documentElement.getAttribute('pith'); + path = document.documentElement.getAttribute('path'); + ship = document.documentElement.getAttribute('ship'); + app = document.documentElement.getAttribute('app'); + await connectToShip(); + let eventElements = document.querySelectorAll('[event]'); + eventElements.forEach(el => setEventListeners(el)); +}); +function setEventListeners(el) { + const eventTags = el.getAttribute('event'); + const returnTags = el.getAttribute('return'); + eventTags.split(/\s+/).forEach(eventStr => { + const eventType = eventStr.split('/', 2)[1]; + el[`on${eventType}`] = (e) => pokeShip(e, eventStr, returnTags); + }); +}; +async function connectToShip() { + try { + const storageKey = `${ship}${app}${path}`; + let storedId = localStorage.getItem(storageKey); + localStorage.setItem(storageKey, channelId); + if (storedId) { + const delPath = `${window.location.origin}/~/channel/${storedId}`; + await fetch(delPath, { + method: 'PUT', + body: JSON.stringify([{ + id: channelMessageId, + action: 'delete' + }]) + }); + }; + const body = JSON.stringify(makeSubscribeBody()); + await fetch(channelPath, { + method: 'PUT', + body + }); + eventSource = new EventSource(channelPath); + eventSource.addEventListener('message', handleChannelStream); + } catch (error) { + console.error(error); + }; +}; +function pokeShip(event, tagString, dataString) { + try { + let data = {}; + if (dataString) { + const dataToReturn = dataString.split(/\s+/); + dataToReturn.forEach(dataTag => { + let splitDataTag = dataTag.split('/'); + if (splitDataTag[0] === '') splitDataTag.shift(); + const kind = splitDataTag[0]; + const key = splitDataTag.pop(); + if (kind === 'event') { + if (!(key in event)) { + console.error(`Property: ${key} does not exist on the event object`); + return; + }; + data[dataTag] = String(event[key]); + } else if (kind === 'target') { + if (!(key in event.currentTarget)) { + console.error(`Property: ${key} does not exist on the target object`); + return; + }; + data[dataTag] = String(event.currentTarget[key]); + } else { + const elementId = splitDataTag.join('/'); + const linkedEl = document.getElementById(elementId); + if (!linkedEl) { + console.error(`No element found for id: ${kind}`); + return; + }; + if (!(key in linkedEl)) { + console.error(`Property: ${key} does not exist on the object with id: ${elementId}`); + return; + }; + data[dataTag] = String(linkedEl[key]); + }; + }); + }; + fetch(channelPath, { + method: 'PUT', + body: JSON.stringify(makePokeBody({ + path: tagString, + data + })) + }); + } catch (error) { + console.error(error); + }; +}; +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; + 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); + }); + 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); + }; + }; + 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); + }; + if (replacedNode.childElementCount > 0) { + let needingListeners = replacedNode.querySelectorAll('[event]'); + needingListeners.forEach(child => setEventListeners(child)); + }; + }; + }; + } catch (error) { + console.error(error); + }; +}; +function makeSubscribeBody() { + channelMessageId++; + return [{ + id: channelMessageId, + action: 'subscribe', + ship: ship, + app: app, + path: path + }]; +}; +function makePokeBody(jsonData) { + channelMessageId++; + return [{ + id: channelMessageId, + action: 'poke', + ship: ship, + app: app, + mark: 'json', + json: { pith: pith, data: jsonData } + }]; +}; +function makeAck(eventId) { + channelMessageId++; + return [{ + id: channelMessageId, + action: 'ack', + "event-id": eventId + }]; +}; diff --git a/pkg/arvo/neo/cod/std/src/imp/food.hoon b/pkg/arvo/neo/cod/std/src/imp/food.hoon new file mode 100644 index 00000000000..54bcf304652 --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/imp/food.hoon @@ -0,0 +1 @@ +~ diff --git a/pkg/arvo/neo/cod/std/src/imp/foods.hoon b/pkg/arvo/neo/cod/std/src/imp/foods.hoon new file mode 100644 index 00000000000..5e09d714034 --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/imp/foods.hoon @@ -0,0 +1,46 @@ +/@ food +/@ foods-diff +:: +^- kook:neo +|% + ++ state pro/%sig + ++ poke (sy %foods-diff %food ~) + ++ kids + :+ ~ %y + %- ~(gas by *lads:neo) + :~ :- [|/%ux |] [pro/%food ~] + == + ++ deps *deps:neo + ++ form + ^- form:neo + |_ [=bowl:neo =aeon:neo state=pail:neo] + ++ init + |= old=(unit pail:neo) + ^- (quip card:neo pail:neo) + :- ~ sig/!>(~) + ++ poke + |= [=stud:neo vax=vase] + ^- (quip card:neo pail:neo) + :_ sig/!>(~) :: There is no state + :~ ?+ stud !! + %food + :- (snoc here.bowl [%ux (mod eny.bowl (pow 16 16))]) + [%make %food `food/vax ~] + %foods-diff + =/ poke !<(foods-diff vax) + ?> =(our.bowl ship.src.bowl) + ?- -.poke + %new-food + :- (snoc here.bowl [%ux (mod eny.bowl (pow 16 16))]) + [%make %food `food/!>(food.poke) ~] + %put-food + :- (snoc here.bowl [%ux id.poke]) + [%make %food `food/!>(food.poke) ~] + %del-food !! + :: :- (snoc here.bowl [%ux id.poke]) + :: [%tomb %food ~] + == + == + == + -- +-- diff --git a/pkg/arvo/neo/cod/std/src/imp/manx.hoon b/pkg/arvo/neo/cod/std/src/imp/manx.hoon new file mode 100644 index 00000000000..54bcf304652 --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/imp/manx.hoon @@ -0,0 +1 @@ +~ diff --git a/pkg/arvo/neo/cod/std/src/imp/mast-diary-ui.hoon b/pkg/arvo/neo/cod/std/src/imp/mast-diary-ui.hoon new file mode 100644 index 00000000000..4f8f0948a99 --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/imp/mast-diary-ui.hoon @@ -0,0 +1,166 @@ +/@ ui-event +/@ txt +/@ diary-diff +^- kook:neo +=< +|% +++ state pro/%manx +++ poke (sy %ui-event %rely %gift ~) +++ kids + *kids:neo + :: ^- kids:neo + :: :+ ~ %y + :: %- my + :: :~ [[&/%selection |] pro/%sig ~] + :: == +++ deps + ^- deps:neo + %- my + :~ :^ %diary & [pro/%diary (sy %diary-diff ~)] + :+ ~ %y + %- my + :~ [[|/%da |] only/%txt ~] + == + == +++ form + ^- form:neo + |_ [=bowl:neo =aeon:neo =pail:neo] + :: + ++ init + |= pal=(unit pail:neo) + ^- (quip card:neo pail:neo) + =/ diary-entries + (get-diary-entries deps.bowl) + :- ~ + manx/!>((render [diary-entries ~])) + :: + ++ poke + |= [sud=stud:neo vaz=vase] + ^- (quip card:neo pail:neo) + ?+ sud ~|(bad-stud/sud !!) + :: + %ui-event + =/ eve !<(ui-event vaz) + ?+ path.eve ~|(missing-event-handler-for/path.eve !!) + :: + [%click %submit ~] + =/ dat=(unit @t) + (~(get by data.eve) '/diary-input/value') + ?~ dat + ~|(%diary-input-fail !!) + =/ dif=diary-diff + [%put-entry now.bowl u.dat] + =/ dst=pith:neo + p:(~(got by deps.bowl) %diary) + :_ pail + :~ [dst %poke diary-diff/!>(dif)] + == + :: + [%click %delete @ta ~] + =/ key=@da + (slav %da i.t.t.path.eve) + =/ dif=diary-diff + [%del-entry key] + =/ dst=pith:neo + p:(~(got by deps.bowl) %diary) + :_ pail + :~ [dst %poke diary-diff/!>(dif)] + == + :: + == + :: + %rely + =/ diary-entries + (get-diary-entries deps.bowl) + `manx/!>((render [diary-entries ~])) + :: + == + :: + -- +-- +:: +|% +:: +++ render + |_ $: diary-entries=(list [date=@da =txt]) + selection=(unit @da) + == + ++ $ + ^- manx + ;html + ;head + ;meta(charset "utf-8"); + == + ;body + =style "margin: 0; width: 100%; display: grid; place-items: center;" + ;main + ;h1: Diary + ;+ diary-form + ;+ diary-items + == + == + == + :: + ++ diary-form + ^- manx + ;div + ;textarea(id "diary-input", style "height: 10rem; width: 25rem; margin-block: 1rem;"); + ;button + =event "/click/submit" + =return "/diary-input/value" + ;+ ;/ "Enter" + == + == + :: + ++ diary-items + ^- manx + ;div + ;* %+ turn diary-entries + |= [date=@da =txt] + =/ key=tape + ;div + =key key + ;p: {(pretty-date date)} + ;p: {(trip txt)} + ;button + =event "/click/delete/{key}" + ;+ ;/ "✖" + == + == + == + :: + -- +:: :: :: :: :: :: :: :: :: :: +++ get-diary-entries + |= sam=(map term (pair pith:neo lore:neo)) + ^- (list [date=@da =txt]) + =/ dat=(unit (pair pith:neo lore:neo)) + (~(get by sam) %diary) + ?~ dat + ~|(%no-diary !!) + =/ pod=(list [date=@da =txt]) + %+ turn ~(tap by kid.q.u.dat) + |= (pair iota:neo (axal:neo idea:neo)) + ?> &(?=(^ p) ?=(%da -.p)) + ?> ?=(^ fil.q) + [+.p !<(txt q.pail.u.fil.q)] + %+ sort pod + |= (pair [date=@da =txt] [date=@da =txt]) + (gth date.p date.q) +:: +++ get-selection + |= sam=(axal:neo idea:neo) + ^- (unit @da) + =/ dat=(unit (axal:neo idea:neo)) + (~(get by kid.sam) %selection) + ?~ dat ~ + ?~ fil.u.dat ~ + [~ !<(@da q.pail.u.fil.u.dat)] +:: +++ pretty-date :: from diary-htmx + |= date=@da + ^- tape + =/ d (yore date) + "{(y-co:co y:d)}-{(y-co:co m:d)}-{(y-co:co d:t:d)}" +:: +-- diff --git a/pkg/arvo/neo/cod/std/src/imp/mast-food-ui.hoon b/pkg/arvo/neo/cod/std/src/imp/mast-food-ui.hoon new file mode 100644 index 00000000000..378750640df --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/imp/mast-food-ui.hoon @@ -0,0 +1,169 @@ +/@ ui-event +/@ food +:: +^- kook:neo +=< +|% + ++ state pro/%manx + ++ poke (sy %ui-event %rely %gift ~) + ++ kids *kids:neo + ++ deps + ^- deps:neo + %- ~(gas by *deps:neo) + :~ [%src | [pro/%food (sy %food ~)] ~] + == + ::%- my + :::~ :^ %the-food | [pro/food (sy %food ~)] + + :: :::+ ~ %y + :: ::%- ~(gas by *lads:neo) + :: :::~ :- [|/%ux |] [pro/%food ~] + :: ::== + ::== + ++ form + ^- form:neo + |_ [=bowl:neo =aeon:neo =pail:neo] + :: + ++ init + |= pal=(unit pail:neo) + ^- (quip card:neo pail:neo) + =/ the-food (get-food bowl) + :- ~ :: no cards + manx/!>((render the-food)) + :: + ++ poke + |= [std=stud:neo vaz=vase] + ^- (quip card:neo pail:neo) + ?+ std ~|(bad-stud/std !!) + :: + %ui-event + =/ eve !<(ui-event vaz) + ?+ path.eve !! + [%click %submit ~] + !! + ::=/ name (~(got by data.eve) '/name-input/value') + ::=/ calories (slav %rs (~(got by data.eve) '/calories-input/value')) + ::=/ carbs (slav %rs (~(got by data.eve) '/carbs-input/value')) + ::=/ protein (slav %rs (~(got by data.eve) '/protein-input/value')) + ::=/ the-diff=foods-diff + :: [%new-food %*(. *food name name, calories calories, carbs carbs, protein protein)] + ::=/ dst=pith:neo p:(~(got by deps.bowl) %src) + :::_ pail + :::~ [dst %poke foods-diff/!>(the-diff)] + ::== + == + :: + %rely + =/ the-food (get-food bowl) + :- ~ + manx/!>((render the-food)) + :: + :: ::?+ path.eve ~|(missing-event-handler-for/path.eve !!) + :: :: :: + :: :: [%click %submit ~] + :: :: =/ dat=(unit @t) + :: :: (~(get by data.eve) '/diary-input/value') + :: :: ?~ dat + :: :: ~|(%diary-input-fail !!) + :: :: =/ dif=diary-diff + :: :: [%put-entry now.bowl u.dat] + :: :: =/ dst=pith:neo + :: :: p:(~(got by deps.bowl) %diary) + :: :: :_ pail + :: :: :~ [dst %poke diary-diff/!>(dif)] + :: :: == + :: :: :: + :: :: [%click %delete @ta ~] + :: :: =/ key=@da + :: :: (slav %da i.t.t.path.eve) + :: :: =/ dif=diary-diff + :: :: [%del-entry key] + :: :: =/ dst=pith:neo + :: :: p:(~(got by deps.bowl) %diary) + :: :: :_ pail + :: :: :~ [dst %poke diary-diff/!>(dif)] + :: :: == + :: :: :: + :: ::== + :: :: + == + :: + -- +-- +:: +|% + :: + ++ render + |= [the-food=food] + ::|^ + ^- manx + ;html + ;head + ;meta(charset "utf-8"); + == + ;body + =style "margin: 0; width: 100%; display: grid; place-items: center;" + ;main + ;h1: {(trip name.the-food)} + ;div + ;label: Calories + ;span: {} + == + ::;+ food-form + ::;+ food-items + == + == + == + :: + ::++ food-items + :: ^- manx + :: ;div + :: ;* %+ turn ~(val by the-foods) + :: |= [=food] + :: ;div + :: ;a(href "mast/mast-food-ui/~met/foods/{}"): {(trip name.food)} + :: == + :: == + :::: + ::++ food-form + :: ^- manx + :: ;div + :: ;div + :: ;label: Name: + :: ;input(id "name-input", name "name", type "text"); + :: == + :: ;div + :: ;label: Calories: + :: ;input(id "calories-input", name "calories", type "text"); + :: == + :: ;div + :: ;label: Carbs: + :: ;input(id "carbs-input", name "carbs", type "text"); + :: == + :: ;div + :: ;label: Protein: + :: ;input(id "protein-input", name "protein", type "text"); + :: == + :: ;button + :: =event "/click/submit" + :: =return + :: """ + :: /name-input/value + :: /calories-input/value + :: /carbs-input/value + :: /protein-input/value + :: """ + :: ; Enter + :: == + :: == + ::-- + :: :: :: :: :: :: :: :: :: :: + ++ get-food + |= =bowl:neo + ^- food + ~& ~(key by deps.bowl) + =/ =lore:neo q:(~(got by deps.bowl) %src) :: lore is any tree + ~& lore + =/ =idea:neo (~(got of:neo lore) /) :: idea is an tree node + !<(food q.pail.idea) +-- diff --git a/pkg/arvo/neo/cod/std/src/imp/mast-foods-ui.hoon b/pkg/arvo/neo/cod/std/src/imp/mast-foods-ui.hoon new file mode 100644 index 00000000000..13f4c044e37 --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/imp/mast-foods-ui.hoon @@ -0,0 +1,166 @@ +/@ ui-event +/@ food +::/@ txt +/@ foods-diff +:: +^- kook:neo +=< +|% + ++ state pro/%manx + ++ poke (sy %ui-event %rely %gift ~) + ++ kids *kids:neo + ++ deps + ^- deps:neo + %- my + :~ :^ %src & [pro/%sig (sy %foods-diff %food ~)] + :+ ~ %y + %- ~(gas by *lads:neo) + :~ :- [|/%ux |] [pro/%food ~] + == + == + ++ form + ^- form:neo + |_ [=bowl:neo =aeon:neo =pail:neo] + :: + ++ init + |= pal=(unit pail:neo) + ^- (quip card:neo pail:neo) + =/ the-foods (food-map bowl) + :- ~ + manx/!>((render the-foods)) + :: + ++ poke + |= [std=stud:neo vaz=vase] + ^- (quip card:neo pail:neo) + ?+ std ~|(bad-stud/std !!) + :: + %ui-event + =/ eve !<(ui-event vaz) + ?+ path.eve !! + [%click %submit ~] + =/ name (~(got by data.eve) '/name-input/value') + =/ calories (slav %rs (~(got by data.eve) '/calories-input/value')) + =/ carbs (slav %rs (~(got by data.eve) '/carbs-input/value')) + =/ protein (slav %rs (~(got by data.eve) '/protein-input/value')) + =/ the-diff=foods-diff + [%new-food %*(. *food name name, calories calories, carbs carbs, protein protein)] + =/ dst=pith:neo p:(~(got by deps.bowl) %src) + :_ pail + :~ [dst %poke foods-diff/!>(the-diff)] + == + == + :: + %rely + =/ the-foods (food-map bowl) + :- ~ + manx/!>((render the-foods)) + :: + :: ::?+ path.eve ~|(missing-event-handler-for/path.eve !!) + :: :: :: + :: :: [%click %submit ~] + :: :: =/ dat=(unit @t) + :: :: (~(get by data.eve) '/diary-input/value') + :: :: ?~ dat + :: :: ~|(%diary-input-fail !!) + :: :: =/ dif=diary-diff + :: :: [%put-entry now.bowl u.dat] + :: :: =/ dst=pith:neo + :: :: p:(~(got by deps.bowl) %diary) + :: :: :_ pail + :: :: :~ [dst %poke diary-diff/!>(dif)] + :: :: == + :: :: :: + :: :: [%click %delete @ta ~] + :: :: =/ key=@da + :: :: (slav %da i.t.t.path.eve) + :: :: =/ dif=diary-diff + :: :: [%del-entry key] + :: :: =/ dst=pith:neo + :: :: p:(~(got by deps.bowl) %diary) + :: :: :_ pail + :: :: :~ [dst %poke diary-diff/!>(dif)] + :: :: == + :: :: :: + :: ::== + :: :: + == + :: + -- +-- +:: +|% + :: + ++ render + |= [the-foods=(map pith food)] + |^ ^- manx + ;html + ;head + ;meta(charset "utf-8"); + == + ;body + =style "margin: 0; width: 100%; display: grid; place-items: center;" + ;main + ;h1: Foods database + ;+ food-form + ;+ food-items + == + == + == + :: + ++ food-items + ^- manx + ;div + ;* %+ turn ~(val by the-foods) + |= [=food] + ;div + ;a(href "/mast/mast-food-ui/~met/foods/{}"): {(trip name.food)} + == + == + :: + ++ food-form + ^- manx + ;div + ;div + ;label: Name: + ;input(id "name-input", name "name", type "text"); + == + ;div + ;label: Calories: + ;input(id "calories-input", name "calories", type "text"); + == + ;div + ;label: Carbs: + ;input(id "carbs-input", name "carbs", type "text"); + == + ;div + ;label: Protein: + ;input(id "protein-input", name "protein", type "text"); + == + ;button + =event "/click/submit" + =return + """ + /name-input/value + /calories-input/value + /carbs-input/value + /protein-input/value + """ + ; Enter + == + == + -- + :: :: :: :: :: :: :: :: :: :: + ++ food-map + |= =bowl:neo + ^- (map pith food) + %- malt + %+ turn + %~ tap + of:neo + %- %~ del of:neo + q:(~(got by deps.bowl) %src) + / + |= [=pith =idea:neo] + :- pith + !<(food q.pail.idea) +-- diff --git a/pkg/arvo/neo/cod/std/src/imp/mast-recipe-ui.hoon b/pkg/arvo/neo/cod/std/src/imp/mast-recipe-ui.hoon new file mode 100644 index 00000000000..bbb9c4b7c44 --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/imp/mast-recipe-ui.hoon @@ -0,0 +1,164 @@ +/@ ui-event +/@ food +::/@ txt +/@ foods-diff +:: +^- kook:neo +=< +|% + ++ state pro/%manx + ++ poke (sy %ui-event %rely %gift ~) + ++ kids *kids:neo + ++ deps + ^- deps:neo + %- my + :~ :^ %src & [pro/%sig (sy %foods-diff %food ~)] + :+ ~ %y + %- ~(gas by *lads:neo) + :~ :- [|/%ux |] [pro/%food ~] + == + == + ++ form + ^- form:neo + |_ [=bowl:neo =aeon:neo =pail:neo] + :: + ++ init + |= pal=(unit pail:neo) + ^- (quip card:neo pail:neo) + =/ the-foods (food-map bowl) + :- ~ + manx/!>((render the-foods)) + :: + ++ poke + |= [std=stud:neo vaz=vase] + ^- (quip card:neo pail:neo) + ?+ std ~|(bad-stud/std !!) + :: + %ui-event + =/ eve !<(ui-event vaz) + ?+ path.eve !! + [%click %submit ~] + =/ name (~(got by data.eve) '/name-input/value') + =/ calories (slav %rs (~(got by data.eve) '/calories-input/value')) + =/ carbs (slav %rs (~(got by data.eve) '/carbs-input/value')) + =/ protein (slav %rs (~(got by data.eve) '/protein-input/value')) + =/ the-diff=foods-diff + [%new-food %*(. *food name name, calories calories, carbs carbs, protein protein)] + =/ dst=pith:neo p:(~(got by deps.bowl) %src) + :_ pail + :~ [dst %poke foods-diff/!>(the-diff)] + == + == + :: + %rely + =/ the-foods (food-map bowl) + :- ~ + manx/!>((render the-foods)) + :: + :: ::?+ path.eve ~|(missing-event-handler-for/path.eve !!) + :: :: :: + :: :: [%click %submit ~] + :: :: =/ dat=(unit @t) + :: :: (~(get by data.eve) '/diary-input/value') + :: :: ?~ dat + :: :: ~|(%diary-input-fail !!) + :: :: =/ dif=diary-diff + :: :: [%put-entry now.bowl u.dat] + :: :: =/ dst=pith:neo + :: :: p:(~(got by deps.bowl) %diary) + :: :: :_ pail + :: :: :~ [dst %poke diary-diff/!>(dif)] + :: :: == + :: :: :: + :: :: [%click %delete @ta ~] + :: :: =/ key=@da + :: :: (slav %da i.t.t.path.eve) + :: :: =/ dif=diary-diff + :: :: [%del-entry key] + :: :: =/ dst=pith:neo + :: :: p:(~(got by deps.bowl) %diary) + :: :: :_ pail + :: :: :~ [dst %poke diary-diff/!>(dif)] + :: :: == + :: :: :: + :: ::== + :: :: + == + :: + -- +-- +:: +|% + :: + ++ render + |= [the-foods=(map pith food)] + |^ ^- manx + ;html + ;head + ;meta(charset "utf-8"); + == + ;body + =style "margin: 0; width: 100%; display: grid; place-items: center;" + ;main + ;h1: Foods database + ;+ food-form + ;+ food-items + == + == + == + :: + ++ food-items + ^- manx + ;div + ;* %+ turn ~(val by the-foods) + |= [=food] + ;div: {(trip name.food)} + == + :: + ++ food-form + ^- manx + ;div + ;div + ;label: Name: + ;input(id "name-input", name "name", type "text"); + == + ;div + ;label: Calories: + ;input(id "calories-input", name "calories", type "text"); + == + ;div + ;label: Carbs: + ;input(id "carbs-input", name "carbs", type "text"); + == + ;div + ;label: Protein: + ;input(id "protein-input", name "protein", type "text"); + == + ;button + =event "/click/submit" + =return + """ + /name-input/value + /calories-input/value + /carbs-input/value + /protein-input/value + """ + ; Enter + == + == + -- + :: :: :: :: :: :: :: :: :: :: + ++ food-map + |= =bowl:neo + ^- (map pith food) + %- malt + %+ turn + %~ tap + of:neo + %- %~ del of:neo + q:(~(got by deps.bowl) %src) + / + |= [=pith =idea:neo] + :- pith + !<(food q.pail.idea) +-- diff --git a/pkg/arvo/neo/cod/std/src/imp/mast-task-ui.hoon b/pkg/arvo/neo/cod/std/src/imp/mast-task-ui.hoon new file mode 100644 index 00000000000..990bbd1a83e --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/imp/mast-task-ui.hoon @@ -0,0 +1,134 @@ +/@ ui-event +/@ task +/@ task-diff +^- kook:neo +=< +|% +++ state pro/%manx +++ poke (sy %ui-event %rely %gift ~) +++ kids + *kids:neo +++ deps + ^- deps:neo + %- my + :~ :- %src + :- req=& + :- [pro/%task (sy %task-diff %gift ~)] + :+ ~ %y + %- my + :~ [[|/%ud |] pro/%task (sy %task-diff %gift ~)] + == + == +++ form + ^- form:neo + |_ [=bowl:neo =aeon:neo =pail:neo] + :: + ++ init + |= pal=(unit pail:neo) + ^- (quip card:neo pail:neo) + :- ~ + manx/!>((render (task-map bowl))) + :: + ++ poke + |= [=stud:neo =vase] + ^- (quip card:neo pail:neo) + ?+ stud ~|(bad-stud/stud !!) + :: + %ui-event + =/ event !<(ui-event vase) + ?+ path.event + ~|(missing-event-handler-for/path.event !!) + :: + [%click %new ~] + =/ text=@t + (~(got by data.event) '/task-input/value') + :_ pail + :~ :- p:(~(got by deps.bowl) %src) + :+ %poke + %task-diff + !>([%new [text %.y %.y ~] %.y]) + == + :: + [%click %checkbox ~] + =/ t=pith #/placeholder + ::(~(got by data.event) '/task-input/value') :: XX encode this + :_ pail + :~ :- t + :+ %poke + %task-diff + !>([%edit 'placeholder' %.y]) :: XX get text from issue + == + == + :: + %rely + :- ~ + manx/!>((render (task-map bowl))) + == + -- +-- +:: +|% +++ render + |_ tasks=(map pith task) + ++ $ + ^- manx + ;html + ;head + ;meta(charset "utf-8"); + == + ;body + =style "margin: 0; width: 100%; display: grid; place-items: center;" + ;main + ;h1: Tasks + ;div + ;p: {(trip text:(~(got by tasks) /))} + == + ;+ task-form + ;+ subtasks + == + == + == + :: + ++ task-form + ^- manx + ;div + ;textarea(id "task-input", style "height: 10rem; width: 25rem; margin-block: 1rem;"); + ;button + =event "/click/new" + =return "/task-input/value" + ;+ ;/ "Enter" + == + == + :: + ++ subtasks + ^- manx + ;div + ;* %+ turn + %~ tap by + (~(del by tasks) /) + |= [=pith =task] + ;div + ;p: {(trip text.task)} + :: ;input + :: =type "checkbox" + :: =name "done" + :: =event "/click/checkbox" + :: =return :: XX what to return here? + :: ; + :: == + == + == + -- +:: +++ task-map + |= =bowl:neo + ^- (map pith task) + %- malt + %+ turn + %~ tap + of:neo + q:(~(got by deps.bowl) %src) + |= [=pith =idea:neo] + :- pith + !<(task q.pail.idea) +-- diff --git a/pkg/arvo/neo/cod/std/src/imp/mast.hoon b/pkg/arvo/neo/cod/std/src/imp/mast.hoon new file mode 100644 index 00000000000..a295b3fa677 --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/imp/mast.hoon @@ -0,0 +1,497 @@ +/- mast +/* mast-js +=< +^- kook:neo +|% +++ state [%pro %sig] +++ poke (sy %eyre-task %eyre-chan-task %gift ~) +++ kids + :+ ~ %y + %- my + :~ [[|/%p |] [%pro %manx] (sy %sig ~)] :: fix + [[&/%aft |/%p |] [%pro %manx] ~] + == +++ deps *deps:neo +++ form + ^- form:neo + |_ [=bowl:neo =aeon:neo =pail:neo] + :: + ++ init + |= pal=(unit pail:neo) + ^- (quip card:neo pail:neo) + ?> ?=(^ pal) + =+ !<(prow:mast q.u.pal) + =/ =pith:neo #/[p/our.bowl]/$/eyre + =/ =binding:eyre [~ url] + =/ =req:eyre:neo [%connect binding here.bowl] + =/ =rig:mast + :* urth + made + /eyre-chan/mast/(scot %ud ^-(@ud (mug here.bowl))) + ~ + == + :_ sig/!>(rig) + :~ [pith %poke eyre-req/!>(req)] + [(snoc here.bowl p/ship.src.bowl) %make made.rig] + == + :: + ++ poke + |= [sud=stud:neo vaz=vase] + ^- (quip card:neo pail:neo) + :: ~& mast-poke/sud + =+ !<(=rig:mast q.pail) + ?+ sud ~|(bad-stud/sud !!) + :: + %eyre-task + =+ !<([rid=@ta req=inbound-request:eyre] vaz) + ?. authenticated.req + :_ pail + (~(make-auth-redirect res bowl) rid) + ?+ method.request.req + [(~(make-400 res bowl) rid) pail] + :: + %'GET' + ?. |(urth:rig =(our.bowl ship.src.bowl)) + :_ pail + (~(make-403 res bowl) rid) + =/ jig=(unit idea:neo) + =/ g (~(get by kid.kids.bowl) p/ship.src.bowl) + ?~ g ~ + fil.u.g + ?~ jig + =. open-http.rig + (~(put by open-http.rig) ship.src.bowl rid) + ~& open-http/rid + :_ sig/!>(rig) + :~ [(snoc here.bowl p/ship.src.bowl) %make made.rig] + == + =/ sail=manx + (hoist !<(manx q.pail.u.jig)) + :_ pail + (~(gale res bowl) rid sail rig) + :: + == + :: + %gift + =/ rum=(list [=pith:neo =loot:neo]) + ~(tap of:neo !<(gift:neo vaz)) + =^ cards rig + =| cards=(list card:neo) + |- ^- (quip card:neo rig:mast) + ?~ rum + [cards rig] + ?: ?=([%aft *] pith.i.rum) + $(rum t.rum) + =/ jig=(unit idea:neo) + (~(get of:neo kids.bowl) pith.i.rum) + ?~ jig + $(rum t.rum) + =/ sail=manx + (hoist !<(manx q.pail.u.jig)) + =/ boat=@p + =/ p (rear pith.i.rum) + ?> &(?=(^ p) ?=(%p -.p)) + +.p + =/ rid=(unit @ta) + (~(get by open-http.rig) boat) + ?^ rid + ~& close-http/u.rid + %= $ + open-http.rig (~(del by open-http.rig) boat) + rum t.rum + cards + %+ weld + cards + %+ snoc + (~(gale res bowl) u.rid sail rig) + (new-aft-sail sail boat here.bowl) + == + ?+ mode.loot.i.rum + $(rum t.rum) + :: + %add + %= $ + rum t.rum + cards (snoc cards (new-aft-sail sail boat here.bowl)) + == + :: + %dif + =/ aft=manx + =/ ide=(unit idea:neo) + (~(get of:neo kids.bowl) #/aft/[p/boat]) + ?~ ide + ~& >>> missing-aft-sail/[here.bowl aft/boat] + (hoist [[%html ~] [[%head ~] ~] [[%body ~] ~] ~]) + !<(manx q.pail.u.ide) + %= $ + rum t.rum + cards + %+ weld + cards + %+ snoc + (~(gust res bowl) rig aft sail) + (new-aft-sail sail boat here.bowl) + == + :: + == + [cards sig/!>(rig)] + :: + %eyre-chan-task + =+ !<(jon=json vaz) + =/ dat + (parse-channel-data jon) + :_ pail + :~ [(snoc here.bowl p/ship.src.bowl) %poke ui-event/!>(dat)] + == + :: + == + :: + -- +-- +:: +|% +:: +++ res + |_ =bowl:neo + :: + ++ gale + |= [rid=@ta sail=manx =rig:mast] + ^- (list card:neo) + ?> ?=(^ c.sail) + %^ make-direct-http-cards + rid + [200 ['Content-Type' 'text/html'] ~] + :- ~ + ^- octs + %- as-octt:mimes:html + %- en-xml:html + %_ sail + a.g + ^- mart + :* [%pith <^-(path (pout:neo here.bowl))>] :: destination path to shrub from neo + [%path <^-(path (snoc base-sub.rig (scot %p ship.src.bowl)))>] :: sub path, shrub to eyre + [%ship +:(scow %p our.bowl)] + [%app "neo"] + a.g.sail + == + c.i.c + (marl [script-node c.i.c.sail]) + == + :: + ++ gust + |= [=rig:mast old=manx new=manx] + ^- (list card:neo) + ?~ c.old !! + ?~ c.new !! + ?~ t.c.old !! :: fix + ?~ t.c.new !! + ?~ a.g.new !! + :_ ~ + :- #/[p/our.bowl]/$/eyre + :- %poke + :- %eyre-chan-gift + !> + ^- chan-gift:eyre:neo + :- (snoc base-sub.rig (scot %p ship.src.bowl)) + %- 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 + == + :: + ++ make-400 + |= rid=@ta + ^- (list card:neo) + %^ make-direct-http-cards + rid + [400 ~] + ~ + :: + ++ make-403 + |= rid=@ta + ^- (list card:neo) + %^ make-direct-http-cards + rid + [403 ~] + ~ + :: + ++ make-auth-redirect + |= rid=@ta + ^- (list card:neo) + %^ make-direct-http-cards + rid + [307 ['Location' '/~/login?redirect='] ~] + ~ + :: + ++ make-direct-http-cards + |= [rid=@ta hed=response-header:http dat=(unit octs)] + ^- (list card:neo) + =/ eyre=pith:neo #/[p/our.bowl]/$/eyre + =/ head=sign:eyre:neo [rid %head hed] + =/ data=sign:eyre:neo [rid %data dat] + =/ done=sign:eyre:neo [rid %done ~] + :~ [eyre %poke eyre-sign/!>(head)] + [eyre %poke eyre-sign/!>(data)] + [eyre %poke eyre-sign/!>(done)] + == + :: + -- +:: +++ new-aft-sail + |= [sail=manx boat=@p base=pith:neo] + ^- card:neo + [(welp base #/aft/[p/boat]) %make [%manx [~ manx/!>(sail)] ~]] +:: +++ parse-channel-data + |= jon=json + ^- crow:mast + ((ot ~[path+pa data+(om so)]):dejs:format jon) +:: +++ script-node + ^- manx + ;script: {(trip mast-js)} +:: +++ 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) + ?: =(%$ n.g.m) + ;span + =mast "text" + =key nkey + =pkey pkey + ;+ 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 + ++ tarl + |= [m=marl key=tape] + =/ i=@ud 0 + |- ^- marl + ?~ m + ~ + :- %^ tanx + (manx i.m) + (weld (scow %ud i) (weld "-" key)) + key + $(m t.m, i +(i)) + -- +:: +++ algo + |= [old=marl new=marl] + ^- marl + =/ i=@ud 0 + =/ acc=marl ~ + |- + ?~ new + ?. =(~ old) + ?: =(%skip -.-.-.old) + $(old +.old) + :_ acc + :_ ~ + :- %d + =/ c=@ud 0 + |- ^- mart + ?~ old + ~ + :- :- (crip (weld "d" )) + (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 + =/ jold=marl old + =/ nkey=[n=mane k=tape] [n.g.i.new (getv a.g.i.new %key)] + |- + ?~ new + !! + ?~ jold + %= ^$ + new t.new + i +(i) + acc %+ snoc acc + ;n(id ) + ;+ i.new + == + == + ?~ old + !! + ?: =(%skip n.g.i.jold) + $(jold t.jold, j +(j)) + ?: .=(nkey [n.g.i.jold (getv a.g.i.jold %key)]) + ?. =(0 j) + =/ n=@ud 0 + =/ nnew=marl new + =/ okey=[n=mane k=tape] [n.g.i.old (getv a.g.i.old %key)] + |- + ?~ 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 + 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 , key k.nkey); + == + == + %= ^^$ + old c.i.jold + new c.i.new + i 0 + acc + %= ^^$ + old (newm old j ;skip;) + new t.new + i +(i) + acc :- [[%c [[%key k.nkey] aupd]] ~] + %+ snoc + acc + ;m(id , key k.nkey); + == + == + ?: =("text" (getv a.g.i.new %mast)) + ?: =(+.-.+.-.-.+.-.old +.-.+.-.-.+.-.new) + ^$(old t.old, new t.new, i +(i)) + %= ^$ + 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)) + == + %= ^$ + old c.i.old + new c.i.new + i 0 + acc + %= ^$ + old t.old + new t.new + i +(i) + acc :_ acc + [[%c [[%key k.nkey] aupd]] ~] + == + == + $(jold t.jold, j +(j)) +:: +++ getv + |= [m=mart tag=@tas] + ^- tape + ?~ m + ~ + ?: =(n.i.m tag) + v.i.m + $(m t.m) +:: +++ upda + |= [om=mart nm=mart] + =/ acc=mart ~ + |- ^- mart + ?~ nm + ?~ om + acc + :_ acc + :- %rem + =/ omom=mart om + |- + ?~ omom + ~ + =/ nom=tape +: + |- + ?~ nom + [' ' ^$(omom t.omom)] + [i.nom $(nom t.nom)] + =/ i=@ud 0 + =/ com=mart om + |- + ?~ nm + !! + ?~ com + ^$(nm t.nm, acc [i.nm acc]) + ?~ 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 + acc [i.nm acc] + == + $(com t.com, i +(i)) +:: +++ newm + |= [ml=marl i=@ud mx=manx] + =/ j=@ud 0 + |- ^- marl + ?~ ml + ~ + :- ?: =(i j) + mx + i.ml + $(ml t.ml, j +(j)) +:: +-- diff --git a/pkg/arvo/neo/cod/std/src/imp/recipe-book.hoon b/pkg/arvo/neo/cod/std/src/imp/recipe-book.hoon new file mode 100644 index 00000000000..62a4b8d7a55 --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/imp/recipe-book.hoon @@ -0,0 +1,50 @@ +/@ recipe +/@ recipes-diff +:: +^- kook:neo +|% + ++ state pro/%pith :: absolute path to the food database + ++ poke (sy %recipes-diff ~) + ++ kids + :+ ~ %y + %- ~(gas by *lads:neo) + :~ :- [|/%ux |] [pro/%recipe ~] + == + ++ deps *deps:neo + ++ form + ^- form:neo + |_ [=bowl:neo =aeon:neo state-pail=pail:neo] + ++ init + |= old=(unit pail:neo) + ^- (quip card:neo pail:neo) + ?~ old !! + =/ the-pail (need old) + ?> =(%pith p.the-pail) + :- ~ the-pail + ++ poke + |= [=stud:neo vax=vase] + ^- (quip card:neo pail:neo) + :::_ sig/!>(~) :: There is no state + :_ state-pail + :~ ?+ stud !! + %recipes-diff + =/ poke !<(recipes-diff vax) + ?> =(our.bowl ship.src.bowl) + ?+ -.poke !! + %new-recipe + =/ the-recipe %*(. *recipe name name.poke) + :- (snoc here.bowl [%ux (mod eny.bowl (pow 16 16))]) + :* %make %recipe `recipe/!>(the-recipe) + %- molt ~[[%src !<(pith q.state-pail)]] + == + ::%put-food + :: :- (snoc here.bowl [%ux id.poke]) + :: [%make %food `food/!>(food.poke) ~] + ::%del-food !! + :: :- (snoc here.bowl [%ux id.poke]) + :: [%tomb %food ~] + == + == + == + -- +-- diff --git a/pkg/arvo/neo/cod/std/src/imp/recipe.hoon b/pkg/arvo/neo/cod/std/src/imp/recipe.hoon new file mode 100644 index 00000000000..36df76dc6df --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/imp/recipe.hoon @@ -0,0 +1,68 @@ +/@ recipe +/@ recipe-diff +/@ ingredient +:: +^- kook:neo +|% + ++ state pro/%recipe + ++ poke (sy %recipe-diff ~) + ++ kids *kids:neo + :::+ ~ %y + ::%- ~(gas by *lads:neo) + :::~ :- [|/%ux |] [pro/%recipes ~] + ::== + ++ deps + ^- deps:neo + %- my + :~ :^ %src & [pro/%sig (sy %foods-diff %food ~)] + :+ ~ %y + %- ~(gas by *lads:neo) + :~ :- [|/%ux |] [pro/%food ~] + == + == + ++ form + ^- form:neo + |_ [=bowl:neo =aeon:neo state-pail=pail:neo] + ++ init + |= old=(unit pail:neo) + ^- (quip card:neo pail:neo) + :- ~ (need old) + ++ poke + |= [poke-stud=stud:neo poke-vase=vase] + ^- (quip card:neo pail:neo) + ?> =(poke-stud %recipe-diff) + =/ the-recipe !<(recipe q.state-pail) + =/ poke !<(recipe-diff poke-vase) + ?> =(our.bowl ship.src.bowl) + :- ~ :: No cards + :: + ?+ -.poke !! + %rename + :- %recipe + !> %_ the-recipe + name name.poke + == + :: + %add-ingredient + :- %recipe + !> %_ the-recipe + ingredients (snoc ingredients.the-recipe ingredient.poke) + == + :: + %add-instruction + :- %recipe + !> %_ the-recipe + instructions (snoc instructions.the-recipe text.poke) + == + ::%new-recipe + :: :- (snoc here.bowl [%ux (mod eny.bowl (pow 16 16))]) + :: [%make %recipe `recipe/!>(recipe.poke) ~] + ::%put-recipe + :: :- (snoc here.bowl [%ux id.poke]) + :: [%make %recipe `recipe/!>(recipe.poke) ~] + ::%del-recipe !! + :: :- (snoc here.bowl [%ux id.poke]) + :: [%tomb %recipe ~] + == + -- +-- diff --git a/pkg/arvo/neo/cod/std/src/lib/mast.hoon b/pkg/arvo/neo/cod/std/src/lib/mast.hoon new file mode 100644 index 00000000000..3708b6bc718 --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/lib/mast.hoon @@ -0,0 +1,19 @@ +|% +:: ++$ crow :: :: :: mast event poke data + [=path data=(map @t @t)] +:: ++$ prow :: :: :: mast init data + $: urth=? :: > are you serving to earth? + url=path :: > the base url that mast will bind with eyre + =made:neo :: > the +$made mast uses to spawn your ui shrubs + == +:: ++$ rig :: :: :: mast state + $: urth=? + =made:neo + base-sub=path + open-http=(map @p @ta) :: eyre ids of http requests pending session creation + == +:: +-- diff --git a/pkg/arvo/neo/cod/std/src/pro/food.hoon b/pkg/arvo/neo/cod/std/src/pro/food.hoon new file mode 100644 index 00000000000..294f9a8202c --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/pro/food.hoon @@ -0,0 +1,25 @@ +=> |% + +$ id @ux + -- +$+ food-type +$: id=id + name=@t + calories=@rs + carbs=@rs + protein=@rs + fat=@rs + sugar=@rs + alcohol=@rs + water=@rs + potassium=@rs + sodium=@rs + calcium=@rs + magnesium=@rs + phosphorus=@rs + iron=@rs + zinc=@rs + mass=@rs + density=(unit @rs) + price=@rs + cook-ratio=@rs +== diff --git a/pkg/arvo/neo/cod/std/src/pro/foods-diff.hoon b/pkg/arvo/neo/cod/std/src/pro/foods-diff.hoon new file mode 100644 index 00000000000..28a6dd51718 --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/pro/foods-diff.hoon @@ -0,0 +1,6 @@ +/@ food +:: +$% [%new-food =food] + [%put-food =id:food =food] + [%del-food =id:food] +== diff --git a/pkg/arvo/neo/cod/std/src/pro/ingredient.hoon b/pkg/arvo/neo/cod/std/src/pro/ingredient.hoon new file mode 100644 index 00000000000..9d3cf947d6f --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/pro/ingredient.hoon @@ -0,0 +1,7 @@ +/@ measure +:: +:: An `ingredient` is an amount of a food. +$+ ingredient-type +$: food-id=@ + amount=[=@rs =measure] :: e.g., [100 %g] => 100 grams; [3 %ct] => three of them +== diff --git a/pkg/arvo/neo/cod/std/src/pro/json.hoon b/pkg/arvo/neo/cod/std/src/pro/json.hoon new file mode 100644 index 00000000000..3c840093b75 --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/pro/json.hoon @@ -0,0 +1 @@ +json diff --git a/pkg/arvo/neo/cod/std/src/pro/manx.hoon b/pkg/arvo/neo/cod/std/src/pro/manx.hoon new file mode 100644 index 00000000000..387ae5ca69e --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/pro/manx.hoon @@ -0,0 +1 @@ +manx diff --git a/pkg/arvo/neo/cod/std/src/pro/measure.hoon b/pkg/arvo/neo/cod/std/src/pro/measure.hoon new file mode 100644 index 00000000000..1e3948db3d0 --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/pro/measure.hoon @@ -0,0 +1,15 @@ +$+ measure +$? %ct :: servings / item count (e.g., "3 bananas") + :: + :: Mass + %g :: grams + %lbs :: pounds + %oz :: ounces + :: + :: Volume + %ml :: milliliters + %cups :: cups + %tsp :: teaspoons + %tbsp :: tablespoons + %fl-oz :: fluid ounces +== diff --git a/pkg/arvo/neo/cod/std/src/pro/recipe-diff.hoon b/pkg/arvo/neo/cod/std/src/pro/recipe-diff.hoon new file mode 100644 index 00000000000..787cdac3ac9 --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/pro/recipe-diff.hoon @@ -0,0 +1,10 @@ +/@ recipe +/@ ingredient +:: +$% [%add-instruction text=@t] + [%move-instruction from=@ to=@] + [%delete-instruction from=@] + [%add-ingredient =ingredient] + [%delete-ingredient from=@] + [%rename name=@t] +== diff --git a/pkg/arvo/neo/cod/std/src/pro/recipe.hoon b/pkg/arvo/neo/cod/std/src/pro/recipe.hoon new file mode 100644 index 00000000000..4497f1e596d --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/pro/recipe.hoon @@ -0,0 +1,16 @@ +/@ ingredient +:: +=> |% + +$ id @ + -- +$+ recipe-type +$: id=id + name=@ta + created-at=@da + last-modified-at=(unit @da) + ingredients=(list ingredient) + blurb=@t + instructions=(list @t) + provenance=(unit $:(author=@p =id)) + comments=(list [author=@p posted-at=@da txt=@t]) +== diff --git a/pkg/arvo/neo/cod/std/src/pro/recipes-diff.hoon b/pkg/arvo/neo/cod/std/src/pro/recipes-diff.hoon new file mode 100644 index 00000000000..f514047eb22 --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/pro/recipes-diff.hoon @@ -0,0 +1,6 @@ +/@ recipe +:: +$% [%new-recipe name=@t] + [%put-recipe =id:recipe =recipe] + [%del-recipe =id:recipe] +== diff --git a/pkg/arvo/neo/cod/std/src/pro/ui-event.hoon b/pkg/arvo/neo/cod/std/src/pro/ui-event.hoon new file mode 100644 index 00000000000..a23f07ffdd2 --- /dev/null +++ b/pkg/arvo/neo/cod/std/src/pro/ui-event.hoon @@ -0,0 +1,3 @@ +$: =path + data=(map @t @t) +== diff --git a/pkg/arvo/sur/neo.hoon b/pkg/arvo/sur/neo.hoon index 5ae2dfb535b..9c7b16a2f60 100644 --- a/pkg/arvo/sur/neo.hoon +++ b/pkg/arvo/sur/neo.hoon @@ -1287,6 +1287,10 @@ == +$ task (pair @ta inbound-request:^eyre) + +$ chan-task + json + +$ chan-gift + [sub=path dat=json] -- :: +clay: Filesystem overlay ::