dys πŸ™
dys πŸ™
KPCKevin Powell - Community
Created by dys πŸ™ on 11/12/2024 in #back-end
Creating an IPFS UnixFS File System By Hand
I am contemplating a collaborative file system based on IPFS. Users will publish the root of a directory tree & a service worker will copy that tree into a Neo4j instance running in Docker with a model of a versioned repository in it. The frontend, then, will talk to Neo4j (which is a graph database) to allow more complex views of the data than a simple tree view. I'm particularly interested in incorporating ordered lists where users rank content. Say I could get 50 people's opinions of the top 20 funniest memes ever, & generate a composite list from those. To avoid having to upload a ton of information for every update, I want to reuse the unchanged parts of the previous iteration that are already in IPFS rather than reupload. To do this, I need to manually construct the directory tree. I had it working with a CBOR-DAG, but the ipfs dag commands are only available on instances where you have API access. So, I want to switch to UnixFS to store stuff. I've tried to get Claude, V0, Co-Pilot, & Bolt to help me, and this is where we're at currently:
#!/usr/bin/env node

import { create as ipfsClient } from 'kubo-rpc-client'
import { prepare, encode } from '@ipld/dag-pb'
import { UnixFS } from 'ipfs-unixfs'

const ipfs = ipfsClient('http://localhost:5001')

try {
const content = 'Β‘Hello, World!'
const file = new UnixFS({
type: 'file',
data: (
typeof content === 'string' ? (new TextEncoder().encode(content)) : (content)
),
})
const fileNode = prepare({ Data: file.marshal(), Links: [] })
const fileBytes = encode(fileNode)
const start = await ipfs.add(fileBytes, { layout: 'dag-pb' })
console.info(`Start CID: ${start.cid.toString()}`)

const dir = new UnixFS({ type: 'directory' })
const dirNode = (
prepare({
Data: dir.marshal(),
Links: [{ Hash: start.cid, Name: 'hello.txt', Tsize: file.fileSize() }],
})
)
const dirBytes = encode(dirNode)
const final = await ipfs.add(dirBytes, { layout: 'dag-pb' })
console.info(`Final CID: ${final.cid.toString()}`)
} catch(error) {
console.error(`Error: ${error.message}`)
console.error(error.stack)
}
#!/usr/bin/env node

import { create as ipfsClient } from 'kubo-rpc-client'
import { prepare, encode } from '@ipld/dag-pb'
import { UnixFS } from 'ipfs-unixfs'

const ipfs = ipfsClient('http://localhost:5001')

try {
const content = 'Β‘Hello, World!'
const file = new UnixFS({
type: 'file',
data: (
typeof content === 'string' ? (new TextEncoder().encode(content)) : (content)
),
})
const fileNode = prepare({ Data: file.marshal(), Links: [] })
const fileBytes = encode(fileNode)
const start = await ipfs.add(fileBytes, { layout: 'dag-pb' })
console.info(`Start CID: ${start.cid.toString()}`)

const dir = new UnixFS({ type: 'directory' })
const dirNode = (
prepare({
Data: dir.marshal(),
Links: [{ Hash: start.cid, Name: 'hello.txt', Tsize: file.fileSize() }],
})
)
const dirBytes = encode(dirNode)
const final = await ipfs.add(dirBytes, { layout: 'dag-pb' })
console.info(`Final CID: ${final.cid.toString()}`)
} catch(error) {
console.error(`Error: ${error.message}`)
console.error(error.stack)
}
The output I get from that is:
Start CID: Qmc4KqktSNtJimrTJB5aKujCD27P7sV2AH48CeUbJZ4yJm
Final CID: QmcZA3Zohp3UtsPafQfSg4kPPpxZtGWMeQJvW7dW9WbyLx
❯ ipfs dag get Qmc4KqktSNtJimrTJB5aKujCD27P7sV2AH48CeUbJZ4yJm
{"Data":{"/":{"bytes":"CAISFwoVCAISD8KhSGVsbG8sIFdvcmxkIRgPGBc"}},"Links":[]}
❯ ipfs dag get QmcZA3Zohp3UtsPafQfSg4kPPpxZtGWMeQJvW7dW9WbyLx
{"Data":{"/":{"bytes":"CAISNRIvCiISIMvU/WQImfeyfmFxszzo6JKoCnjTRTSoY4rD1esrAmr+EgloZWxsby50eHQKAggBGDU"}},"Links":[]}
❯ ipfs cat Qmc4KqktSNtJimrTJB5aKujCD27P7sV2AH48CeUbJZ4yJm | cat -A
$
^U^H^B^R^OM-BM-!Hello, World!^X^O
❯ ipfs cat QmcZA3Zohp3UtsPafQfSg4kPPpxZtGWMeQJvW7dW9WbyLx | cat -A
^R/$
"^R M-KM-TM-}d^HM-^YM-wM-2~aqM-3<M-hM-hM-^RM-($
xM-SE4M-(cM-^JM-CM-UM-k+^BjM-~^R^Ihello.txt$
^B^H^A
Start CID: Qmc4KqktSNtJimrTJB5aKujCD27P7sV2AH48CeUbJZ4yJm
Final CID: QmcZA3Zohp3UtsPafQfSg4kPPpxZtGWMeQJvW7dW9WbyLx
❯ ipfs dag get Qmc4KqktSNtJimrTJB5aKujCD27P7sV2AH48CeUbJZ4yJm
{"Data":{"/":{"bytes":"CAISFwoVCAISD8KhSGVsbG8sIFdvcmxkIRgPGBc"}},"Links":[]}
❯ ipfs dag get QmcZA3Zohp3UtsPafQfSg4kPPpxZtGWMeQJvW7dW9WbyLx
{"Data":{"/":{"bytes":"CAISNRIvCiISIMvU/WQImfeyfmFxszzo6JKoCnjTRTSoY4rD1esrAmr+EgloZWxsby50eHQKAggBGDU"}},"Links":[]}
❯ ipfs cat Qmc4KqktSNtJimrTJB5aKujCD27P7sV2AH48CeUbJZ4yJm | cat -A
$
^U^H^B^R^OM-BM-!Hello, World!^X^O
❯ ipfs cat QmcZA3Zohp3UtsPafQfSg4kPPpxZtGWMeQJvW7dW9WbyLx | cat -A
^R/$
"^R M-KM-TM-}d^HM-^YM-wM-2~aqM-3<M-hM-hM-^RM-($
xM-SE4M-(cM-^JM-CM-UM-k+^BjM-~^R^Ihello.txt$
^B^H^A
So, my file attempt has a bunch of random crap in with the data, & my directory doesn't have any children. When I open either up in the IPFS Desktop it says they're not browsable.
1 replies
KPCKevin Powell - Community
Created by dys πŸ™ on 10/30/2024 in #front-end
How to link to an external CSS style in SVG?
I have a Codepen where I try three different methods of importing an extrenal stylesheet into an SVG. I'm working from the specification which says:
An HTML β€˜link’ element in an SVG document (that is, an element in the HTML namespace with local name "link") with its β€˜rel’ attribute set to 'stylesheet' must be processed as defined in the HTML specification and cause external style sheets to be loaded and applied to the document.
I tried: ● A <link/> tag in the <defs/> section with an xmlns="http://www.w3.org/1999/xhtml". ● A <svg> with a xmlns:html="http://www.w3.org/1999/xhtml" & containing a <html:link/> tag. ● A <style> tag with an @import url() directive. Only the last one works, and when I select either of the <link/>s in the Inspector and console.debug($0.namespaceURI), I get http://www.w3.org/2000/svg. How do I create a HTML <link/> tag within a SVG document short of JavaScript?
7 replies
KPCKevin Powell - Community
Created by dys πŸ™ on 9/20/2024 in #front-end
How to target a tag that has no parents?
I am playing with userContent.css in Firefox which allows me to inject a stylesheet into every page. I have several SVGs that include a @media (prefers-color-scheme: dark) rule to display differently on dark monitors. My issue is the default background for a SVG opened by itself is "transparent", but is effectively white. I tried adding a @media (prefers-color-scheme: dark) { svg { background-color: #0008 } } style, which worked, but it affects every SVG on every page, & generally makes the browser look crappy. I want to just target the background of SVGs when they are the root of the DOM. I tried :root > svg, but that doesn't work. ΒΏAnyone got a clue❔
5 replies
KPCKevin Powell - Community
Created by dys πŸ™ on 7/2/2024 in #front-end
What are the dangers of allowing a user to specify a stylesheet?
I've got a NFT site & I'm considering allowing users to specify custom page styles as an element of the NFT's metadata. The style will be an emotionesque CSS-in-JS encoding like:
const color = 'blue'
const style = {
padding: '32px',
backgroundColor: 'hotpink',
fontSize: '24px',
borderRadius: '4px',
'&:hover': { color },
}
const color = 'blue'
const style = {
padding: '32px',
backgroundColor: 'hotpink',
fontSize: '24px',
borderRadius: '4px',
'&:hover': { color },
}
What are the security considerations here? I can easily disallow @import directives.
5 replies
KPCKevin Powell - Community
Created by dys πŸ™ on 4/4/2024 in #front-end
How to color text so it is visible against any background color?
No description
35 replies
KPCKevin Powell - Community
Created by dys πŸ™ on 2/12/2024 in #back-end
Cookie Confusion
I'm using iron-session to store the information necessary for ConnectKit's Sign-In With Ethereum (SIWE) to work on a GitHub pages hosted site backed by Supabase edge functions. (ConnectKit expects to have access to a /session endpoint that returns the authenticated user's Ethereum address.) iron-session stores session information as an encrypted string sent back and forth as a cookie. The problem I'm having is if SameSite is set to Lax or Strict, I get an error:
This attempt to set a cookie via a set-cookie header was blocked because it had a SameSite="Lax" attribute but came from a cross-site response which was not a response to a top-level navigation.
This is because the Supabase edge functions run on a randomuid.supabase.co host. If I set SameSite to None, I can get the cookie to go through, but I know browsers are increasingly restricting third-party cookies. Anyone have a suggestion as to how I should restructure my code? The obvious solution would be to use Supabase's session, but because I'm using SIWE, I don't think I have access to it. The Google page on deprecation of third-party cookies lists a few technological alternatives, probably using partitioned cookies is the way to go.
1 replies
KPCKevin Powell - Community
Created by dys πŸ™ on 1/18/2024 in #back-end
My Svelte app compiles, but dies on loading. ⸘Whyβ€½
I'm working on my first Svelte app, & it dies in the browser with:
Uncaught Error: No element `#globe` found.
at instance (App.svelte:5:7)
at init (Component.js:135:5)
at new App (App.svelte:32:31)
at createProxiedComponent (svelte-hooks.js:341:9)
at new ProxyComponent (proxy.js:242:7)
at new Proxy<App> (proxy.js:349:11)
at main.ts:4:13
Uncaught Error: No element `#globe` found.
at instance (App.svelte:5:7)
at init (Component.js:135:5)
at new App (App.svelte:32:31)
at createProxiedComponent (svelte-hooks.js:341:9)
at new ProxyComponent (proxy.js:242:7)
at new Proxy<App> (proxy.js:349:11)
at main.ts:4:13
I've defined a <article id="globe"> in the Svelte app where this script is running.
5 replies
KPCKevin Powell - Community
Created by dys πŸ™ on 9/10/2023 in #front-end
How to get an element to fit within its parent?
I'm working on a simple layout: https://codepen.io/u3b4/pen/gOZmKmw The basic structure is something like:
<main>
<section class="top">
<menu>…</menu>
<video/>
</section>
<section class="bottom">
<div class="bar"/>
</section>
</main>
<main>
<section class="top">
<menu>…</menu>
<video/>
</section>
<section class="bottom">
<div class="bar"/>
</section>
</main>
What I want to do is put a max-width: 100svw & max-height: 100svh on the main element, and then have the children resize to fit within a single screen. I'm using a columnar flexbox on main and a regular flexbox on .top. Currently the video is way too big. I've tried object-fit: contain, but that was no good. Can someone point me in the right direction?
5 replies
KPCKevin Powell - Community
Created by dys πŸ™ on 7/25/2023 in #os-and-tools
Is this a bug in Chrome *(`@supports (animation)` for a SVG favicon)*?
I have the following SVG as my favicon on https://bafybeihfwqwlluejiuskhmgdcq7sme54m4ewtzfluodr2duj3yokjzyehe.ipfs.dweb.link/
<svg version="1.1" viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
@font-face {
font-family: 'Battle Skill';
/* `url()` pointing to a external file doesn't work in Firefox favicon. */
src: url('data:font/woff2;base64,…'); /* omitted b/c it's 300KiB */
}

text {
fill: #e4711b;
font-family: 'Battle Skill';
font-size: 415px;
paint-order: stroke fill markers;
stroke-width: 10;
stroke: #00ff19;
animation: scroll 5s ease-in 0s infinite;
}

@keyframes scroll {
0% { transform: translateX(0px) }
10% { transform: translateX(0px) }
20% { transform: translateX(-200px) }
30% { transform: translateX(-200px) }
45% { transform: translateX(-425px) }
55% { transform: translateX(-425px) }
70% { transform: translateX(-575px) }
80% { transform: translateX(-575px) }
100% { transform: translateX(0px) }
}

rect { fill: green }

@supports (not(animation: scroll)) {
text { animation: none }
rect { fill: red }
}
</style>
</defs>
<title>MBTI Ligature</title>
<rect width="300" height="300"/>
<text x="-3.172616" y="280.16232">MBTI</text>
</svg>
<svg version="1.1" viewBox="0 0 300 300" xmlns="http://www.w3.org/2000/svg">
<defs>
<style>
@font-face {
font-family: 'Battle Skill';
/* `url()` pointing to a external file doesn't work in Firefox favicon. */
src: url('data:font/woff2;base64,…'); /* omitted b/c it's 300KiB */
}

text {
fill: #e4711b;
font-family: 'Battle Skill';
font-size: 415px;
paint-order: stroke fill markers;
stroke-width: 10;
stroke: #00ff19;
animation: scroll 5s ease-in 0s infinite;
}

@keyframes scroll {
0% { transform: translateX(0px) }
10% { transform: translateX(0px) }
20% { transform: translateX(-200px) }
30% { transform: translateX(-200px) }
45% { transform: translateX(-425px) }
55% { transform: translateX(-425px) }
70% { transform: translateX(-575px) }
80% { transform: translateX(-575px) }
100% { transform: translateX(0px) }
}

rect { fill: green }

@supports (not(animation: scroll)) {
text { animation: none }
rect { fill: red }
}
</style>
</defs>
<title>MBTI Ligature</title>
<rect width="300" height="300"/>
<text x="-3.172616" y="280.16232">MBTI</text>
</svg>
In Firefox, I get an animated favicon. In Chrome, I get just the first letter, on a green background, no animation. In Brave, I just get a green square, no letters. I'm using @supports (not(animation: scroll)) to try and identify environments that don't support @keyframes, but it doesn't match any of the browsers. Shouldn't it?
2 replies
KPCKevin Powell - Community
Created by dys πŸ™ on 7/19/2023 in #front-end
TypeScript `|` Combinator
I have the following code:
ceramic.did = new DID({
provider: threeID.getDidProvider(),
resolver: {
...get3IDResolver(ceramic), // returns a ResolverRegistry
...getKeyResolver(), // returns a ResolverRegistry
} as ResolverRegistry,
});
ceramic.did = new DID({
provider: threeID.getDidProvider(),
resolver: {
...get3IDResolver(ceramic), // returns a ResolverRegistry
...getKeyResolver(), // returns a ResolverRegistry
} as ResolverRegistry,
});
And, TypeScript is giving me the following error:
Type 'ResolverRegistry' is not assignable to type 'Resolver | ResolverRegistry | undefined'.
Type 'ResolverRegistry' is missing the following properties from type 'Resolver': registry, cache, resolvets(2322)
(property) resolver?: Resolver | ResolverRegistry | undefined
Type 'ResolverRegistry' is not assignable to type 'Resolver | ResolverRegistry | undefined'.
Type 'ResolverRegistry' is missing the following properties from type 'Resolver': registry, cache, resolvets(2322)
(property) resolver?: Resolver | ResolverRegistry | undefined
I thought that let pet: Cat | Dog means I can assign either a Cat or Dog to it. Is that not right?
2 replies
KPCKevin Powell - Community
Created by dys πŸ™ on 7/18/2023 in #front-end
Why is the height of my body 0px?
I'm playing around with a personality type scoring interface. For some reason, the <body> and #root (it's a Next.js app) have a calculated height of 0px. https://bafybeigigh6p2fcpfqmck32vkpi3i3akknmh5sbabtvupbiknfzqrkw4ha.ipfs.w3s.link/ Anyone have any suggestions?
5 replies
KPCKevin Powell - Community
Created by dys πŸ™ on 6/13/2023 in #front-end
Horizontal Accordion of Links
10 replies
KPCKevin Powell - Community
Created by dys πŸ™ on 4/4/2023 in #os-and-tools
Virtual PulseAudio device that will run all my speakers simultaneously doesn't work. 🦠
1 replies
KPCKevin Powell - Community
Created by dys πŸ™ on 3/1/2023 in #front-end
How to theme when using CSS modules?
So, I'm currently working on a pitch to dig deep into the guts of https://metagame.wtf and tear out all the Chakra UI. Replace it instead with semantic HTML & class and id-based matched CSS modules as parsed by whatever. The visual appearance of the page is contained solely in external CSS files, the structural appearance in the markup. So, a pair of programmers picks some set of issues to forward. They begin their session with a 30-minute overlap with the previous pair where they hand-off development tasks. And it just hands team to team in a single line through history. The problem is I would like to store styles as metadata in NFTs. Just JS-in-CSS style JSON-formatted styles. I want to insert the contents of that file into the CSS cascade giving it as much descriptive power as possible. So you can redraw your site to your liking. How would that work with CSS modules? You're not generating semantic tag classes & ids, you're creating something to get munged to get the program to work like we want. It is a hack. However, when combined with nested selectors and semantic matching, it is a really powerful way to target styles only to specific portions of the page. What I really need, I guess is that when I create a classes entry for a CSS module I need both the generated classname to pull in the files I've defined, but also the unaltered semantic name so that the user stylesheet can match on it (which is, again, stored in the NFT's metadata).
2 replies