diff options
| author | Xe Iaso <me@xeiaso.net> | 2024-01-27 07:42:31 -0500 |
|---|---|---|
| committer | Xe Iaso <me@xeiaso.net> | 2024-01-27 07:42:52 -0500 |
| commit | 95d775d4d8e6c3d3204ad6360ea29fb6dff53a2c (patch) | |
| tree | fdbae61742cff14142fd344f45120551befd6112 | |
| parent | b2d1a2eb9b93ddc92938f2a912e01b87b1f65c14 (diff) | |
| download | xesite-95d775d4d8e6c3d3204ad6360ea29fb6dff53a2c.tar.xz xesite-95d775d4d8e6c3d3204ad6360ea29fb6dff53a2c.zip | |
Xeact talk
Signed-off-by: Xe Iaso <me@xeiaso.net>
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | flake.nix | 3 | ||||
| -rw-r--r-- | lume/src/talks/2024/xeact.mdx | 663 | ||||
| -rw-r--r-- | package-lock.json | 204 | ||||
| -rw-r--r-- | package.json | 25 | ||||
| -rwxr-xr-x | scripts/nukestickercache.sh | 12 | ||||
| -rw-r--r-- | scripts/prebake-node.mjs | 56 |
7 files changed, 964 insertions, 0 deletions
@@ -8,3 +8,4 @@ cw.tar /target .patreon.json .direnv +node_modules @@ -192,6 +192,9 @@ zig nodejs + jq + jo + # tools ispell pandoc diff --git a/lume/src/talks/2024/xeact.mdx b/lume/src/talks/2024/xeact.mdx new file mode 100644 index 0000000..0cac616 --- /dev/null +++ b/lume/src/talks/2024/xeact.mdx @@ -0,0 +1,663 @@ +--- +title: "Xeact: The femtoframework you've been waiting for" +date: 2024-01-25 +tags: + - js + - react +series: xeact +image: talks/2024/xeact/001 +--- + +## Warning to readers + +This talk is about [a shitpost](https://github.com/Xe/Xeact) that got way out of hand. Out of respect for the material, this talk is also a shitpost and a work of satire. In order to help make this talk teach you things, I have included technical deep dives into aspects of how and why Xeact works. I hope you enjoy it and you can learn...something useful. + +Please don't repeat any of the absurd acts mentioned here in production. I am not responsible for any damage caused by this talk. You are the one copying and pasting my code samples into production. + +Otherwise, kick back, grab a beverage, and enjoy the ride. + +## Video + +<XeblogVideo path="talks/2024/xeact" /> + +In case the video from XeDN doesn't load, try the [YouTube +version](https://youtu.be/povkpv-mRKw). Please [let me +know](/contact/) with the contents of +[`cdn.xeiaso.net/cgi-cdn/wtf`](https://cdn.xeiaso.net/cgi-cdn/wtf) so +I can diagnose the problem. Hopefully it's not boltdb acting up again. + +## Transcript + +<XeblogSlide name="2024/xeact/001" essential /> + +Hi, I'm Xe. I'm the Philosopher-in-Chief at Techaro. You might know me +from my blog or other hit talks I've given like ["AI, the not-so-good +parts"](/talks/2024/prepare-unforeseen-consequences/), or ["Reaching the Unix philosophy's logical conclusion with WebAssembly"](/talks/unix-philosophy-logical-extreme-wasm/), but today +I'm not going to talk about any of my employers. + +Today I'm talking about Xeact. It's the femtoframework that your +editor has been waiting for. As I mentioned, Xeact is a +femtoframework. It's designed to help you make your websites load +faster, work with the script tag, and overall helps you live your life +with love and light. It is the perfect basis for your projects and +should scale infinitely. + +Asterisk. + +<XeblogSlide name="2024/xeact/003" essential /> + +React is a framework. It gives you all the goodness of working on the +front end, but sometimes it's a bit too big for what you need. So you +reach for Preact. Preact has a lot of the benefits of React, but it's +smaller, which makes it more adaptable and easier to understand. Xeact +is even smaller. It's a femtoframework, which takes ideas from both +React and Preact to get you the smallest possible bundle that can do +what you need. + +Today I'm going to cover the foundations of Xeact, how it works, what +I learned in the process, and then we're going to look into the future +with the help of Techaro. + +So our industry is based heavily on design. Design is the heart of our +products and it's what our users crave. When I started working on +Xeact, I just started working right on the design first and foremost. +Here are the core principles that I used for designing Xeact. + +I wanted the source code to be understandable because let's face it, +when you're debugging things, knowing what's going on means you know +what's going on. Computer programming is complicated. There's a lot of +indirection and access layers and everything that just makes it +difficult to understand. I want the source code of Xeact to fit inside +your mental model so that you don't have to think about it. It's +beautiful. + +Zero compile steps. Two steps is too many. If you have more than a +script tag, you're doing it wrong. That's my hope at least. Less time +spending deploying your product, more time spending disrupting the +burrito delivery industry or whatever. + +I want the source code to fit on a t-shirt because open source +maintainer burnout is real and one of the main reasons why it happens +is because people don't get paid adequately for their work. This way, +by having the source code available on the t-shirt, you open up +merchandising possibilities that help people make up for the lost +income spent working on open source. + +And the entire thing GZipped should fit inside 500 bytes. Egress +bandwidth? Expensive. One gigabyte through managed NAT gateway? Seven +U.S. pennies. That adds up. The less amount of money you spend per +user, the more money you make per user. Xeact saves you time, grief, +your money, and saves your company from bankruptcy. + +So, in the beginning, it started out with a function like this. + +```javascript +const mkNode = (name, data = {}, children = []) => { + let result = Object.assign(document.createElement(name), data); + result.append(...children); + return result; +}; +``` + +In the beginning, the make node function was created. This has made a +lot of people very happy and has been widely regarded as a good move. +In this young state, this function is small, nimble, adaptable, and +with it came syntax that only a Haskeller could love. But that's okay +because I love Haskell. + +```javascript +const blockQuote = (text) => + mkNode( + "blockquote", + { + class: "p-4 border-l-4 border-gray-400 bg-gray-100 text-lg font-semibold", + }, + [ + mkNode( + "p", + { + class: "text-lg font-semibold", + }, + [text] + ), + ] + ); +``` + +HTML is just a tree, right? Why should our code hide this? You can +kind of see it, right? That kind of resembles how a tree of elements +is. And if you're in the back and you can't see it, I just want you to +imagine it because it's about as perfect as you think. + +With all this in mind, I had to rename this function, this make node +function, because that's like, what, six characters and a shift key? +You're going to be typing that all the time. It needs to be short, it +needs to be rememberable, and most importantly, + +It needs to be representative of everything because this is +effectively the one function that gives you anything. It's the +universal source of meaning and meaninglessness in your program. + +<XeblogSlide name="2024/xeact/017" essential /> + +With all this in mind, I had one idea. I looked back into my life, I +thought about everything, and one name stood out. This letter came to +me in a divine vision with eight fantastic sides and eight awesome +angles. This letter is the letter H, and with it came a divine vision +that I will repeat now. + +One day on the road to Nazareth, Jesus Christ met with a group of +theologians. The theologians realized who he was and stood with him. +Jesus looked upon them in confusion and said unto them, "Who do you +say that I am?" + +All at once they replied, "You are the astrological manifestation of +the ground of our being, the kerygma of which we find the ultimate +meaning in our interpersonal relationships. You are the source of love +and life in the world. The foundation, the savior, the alpha, the +omega, the beginning, the end, all and nothing simultaneously, and we +love you for it all." + +Upon hearing this, Jesus was taken back a bit. This was a bit much for +him, and he was confused. After some time, he replied, "What the fuck +are you talking about"? Panic sprung up among the theologians. They +had just confused their savior. They had sullied the thoughts of their +messiah. The silence deafened the field. + +After some time, one of the theologians managed to speak up. +And they spoke. "h". + +Jesus was enlightened. + +```javascript +const blockQuote = (text) => + h( + "blockquote", + { + class: "p-4 border-l-4 border-gray-400 bg-gray-100 text-lg font-semibold", + }, + [ + h( + "p", + { + class: "text-lg font-semibold", + }, + [text] + ), + ] + ); +``` + +This is the name of the function. Now let me paste that code from +earlier, but with the proper name. It just takes the name of a tag, +the list of attributes to apply, and the list of children. And that's +it. That's the entire thing. That's the entire femto framework. +Everything else is just a bunch of helpers to make things more +convenient, like plain text nodes or removing all the children or +grabbing specific things out of the tree or debouncing or onload +handlers. But, you know, that's just standard JavaScript stuff that I +just remade because you can't stop me. + +So, this made everything a lot more easy because I could just assemble +the nodes in the way that I understood, which, because I have back end +brain rot syndrome, I just need to do in functions. + +And this made Xeact a success. + +With this shitpost, I was finally able to understand how to make +frontend UI stuff work. I finally understood how to get an HTTP fetch, +parse the JSON, crap out a bunch of nodes, and then throw it on the +page for people to understand what's going on. And then this basically +unblocked everything else so that I could use everything else +normally. + +However, in the process, there was one small problem. Semantic +satiation. If H is supposed to mean everything and it's everywhere, it +loses its meaning. This cannot stand. + +So I ended up creating a library to help with it and I made the +femtomixin Xeact HTML. If you look over the code of a bunch of all the +popular websites, you'll see that they use like 15 HTML tags. And even +then, you can put them into three categories, like stuff that usually +takes attributes and children, stuff that only takes attributes or +stuff that stands bu itself, like the horizontal rule tag. + +```javascript +const blockQuote = (text) => + blockquote( + { + class: "p-4 border-l-4 border-gray-400 bg-gray-100 text-lg font-semibold", + }, + [p(text)] + ); +``` + +With this knowledge, you can break this down into a list of things, and then you +can create functions for all of them. So here's that same block quote +function, but with you know the function blockquote to create a +blockquote. Wow, so easy! And this is where things really started +making sense because it was a lot easier for me to look at this token +soup and then imagine what it would look like. Press f5. It shows up. I +feel unstoppable. + +It was just a continuous series of golden moments that made me a real +full stack developer: kernel to front end. + +```javascript +console.log(`import { h, t } from "./xeact.js";`); +console.log(`const $tl = (kind) => (text, attrs = {}, children = []) => { + children.unshift(t(text)); + return h(kind, attrs, children); +};`); + +[ + "h1", + "h2", + "h3", + "h4", + "h5", + "h6", + "p", + "b", + "i", + "u", + "dd", + "dt", + "del", + "sub", + "sup", + "strong", + "small", +].forEach((tag) => console.log(`export const ${tag} = $tl("${tag}");`)); +``` + +So in order to make this and not lose whatever shred of sanity I had left, I +made a code generator. This is a JavaScript program that prints JavaScript +code to standard output so that you can include it in your JavaScript code. +It's kind of beautiful. Again, if you're in the back, you can't see it because I'm +very bad at formatting code, just imagine like a bunch of things in a list and then +some small forEach at the bottom with an arrow function to actually generate the +code. It's a lot more beautiful in practice than it looks. + +At this point, I feel like I need to clarify something very important. I'll circle back to Xeact, but just trust me where I'm going with this. I have a plan. + +I'm not an Arch Linux user (by the way), but do use something else that continues to be a source of wisdom. + +I use Emacs rigged to act like Vim. One of the main things about +Emacs that continues to give me inspiration is extensibility in its +own little language called Emacs Lisp. + +If you've never used Lisp before, it is a very unique kind of violence +where lists are the core data type of everything where everything is +your code and your data. Yes, you can represent data and code in the +same way. And this allows you to create new code on the fly with while +making it impossible to make something that won't parse. + +```lisp +ELISP> (+ 3 4) +7 +``` + +So, by default, when you make a list in Lisp, it's considered a code +list. This is something that just immediately gets evaluated. Like, +for example, adding the numbers 3 and 4 and getting 7. + +```lisp +ELISP> '(+ 3 4) +(+ 3 4) +``` + +This is nice and all, but sometimes you need to make data. So they +have this concept of quoting a list to get the data associated with +it. This is so common that it's considered one of the core functions +in Lisp. I think, like, McCarthy has a paper that's, like, 11 +functions that you can use to bootstrap the entire Turing complete +world. It's quite a paper, but it is very old and has some 1970s-isms +in it. + +But if you notice, you either get all code or all data. Sometimes you +need to go halfsies. + +That's why they have this magic thing called quasi-quoting. When +you're assembling complicated things, you will need to mix code and +data together. Quasi-quoting effectively lets you mix the two. Things +normally get quoted, as in you normally have data, but then you can +use a comma to unquote or inject the code value into it. + +```lisp +ELISP> (let ((user-name "Xe") + (user-email "xeact@xeserv.us")) + (json-serialize + `((user . ,user-name) + (email . ,user-email)))) +"{\"user\":\"Xe\",\"email\":\"xeact@xeserv.us\"}" +``` + +So for example, for the sake of argument, I have this associative +list, which is probably known as a hash map in any sensible language. +And I have some variables with let for the user name and user email. +And I build an associative array and I get it back. And why would you +use this? JSON. That's why you would use it. You mix literal names +with variable code. + +So if quasi-quoting lets you mix code and data to tree-like +structures, and we mostly deal with web applications that deal with +elements in a tree, what else could we do with this? + +HTML. HTML is a tree and we often need to mix literal data and +variable data. So what if we put this all, what if we add this all up +and put it together? + +It turns out there's prior art here. I'm not the first person to come +up with the idea of JSX, but JSX is a compiler for JavaScript that +lets you mix HTML literal code and variable JavaScript data, and it +will just transparently compile to all the right JavaScript things +under the hood. It's really nice because it's impossible to create +invalid HTML syntax trees. Well, normally impossible. Otherwise you +found a bug in the JSX compiler, but that's a different story. + +```javascript +export const jsx = (tag, data) => { + let children = data.children; + delete data.children; + const result = h(tag, data, children); + result.classList.value = result.class; + return result; +}; +``` + +So I experimented and in the process, I decided to see what would +happen if I broke that core tenant of zero compile steps. The +efficiency gains that you do this are phenomenal because code and data +mixed together is just such a lovely pattern that I thought was a +waste of time until I started doing it. I was wrong initially because +I thought the extra step would just be another layer of annoyance, but +it worked out pretty great. + +And yeah, what is this? Didn't you just make a big show about not +needing a compile step? + +I never said you need to use JSX with this. It turns out that my H +function is depressingly similar to react createElement function. So +with this five line monster, I'm able to adapt it into the create +element into the JSX signature that it wants. And you know, you're off +to the races. You, if you want, you activate the JSX runtime, you +write your backwards PHP all you want, and you're good to go. Instant +deployment to any cloud, including no cloud. And like I said, don't +want it. Don't turn it on. Do you want it? Do turn it on. It's great. + +Also, if you're deploying with Nix, the idiomatic Xeact deployment +process, by the way, you should be able to just have Nix handle it for +you, and then you don't even have to think about thinking about it. +It's really great. + +It was really easy to get a basic Xeact JSX runtime created because of +that similar function signature, but there was one key thing that it +missed. Components. + +However, components in React are just functions, asterisk. All you +have to do is detect if the HTML tag name argument is a function and +then call it. So I did just that. + +```javascript +const h = (name, data = {}, children = []) => { + const result = + typeof name == "function" + ? name(data) + : Object.assign(document.createElement(name), data); + if (!Array.isArray(children)) { + children = [children]; + } + result.append(...children); + return result; +}; +``` + +And this is the current `h` function in the open source repo. This +allowed me to have, this allowed with everything else, let me have +modern syntax, compiler handrails, and a minimal JavaScript workflow +at the same time. And not to mention, I had compatibility with +React... + +...asterisk. + +At this point, I had a very nice situation going on. I'd reached +version 0.69.71. It was all in a private repo, internal to work. And +the world of front end that had eluded me for so long was finally +within my grasp and I was able to understand what the JavaScript runes +did and bend them to my chaotic-good will. + +In a moment, I knew where this place could be, this new power could be +used for good. I saw a place where it could fit in, and I saw a +feature gap and jumped to fill it. + +It was for an internal tool, as one does, called DAB, data about +business. It was effectively a sidebar for the support UI, so the +support people didn't have to open as many tabs when they were trying +to debug what was going on. It was designed with the kind of UI that +only a terminal hacker could love, yet it was ruthlessly effective +enough that when I deployed it in testing, and then realized that it +showed up for the support people by default, because who would think +about having something that doesn't show up by default for support, +they were like, this is amazing, this has already cut down our ticket +response time in half, so I knew I was onto something, so I just kept +going. + +It was a success thanks to Xeact. + +It was then that I realized that the world needs this power of Xeact +for their single page applications. Sometimes you only need to view +some stuff that requires poking an API, and Xeact fits that goal, +hackery tools that display simple information. + +Xeact remains open source software to this day, where it is used by +thousands of milli-developers. + +However, when I got to a certain scale, I realized that I made another +mistake here. I was missing something very important that made it +impossible to scale beyond those simple hackery tools to view web +forms. I was missing the fact that React components are monads. + +This isn't gonna be a monad tutorial. There's no burritos here. But +the small reason, the reason why I was missing this is because of a +fifth design principle that is a secret and will now be revealed. + +The separation of Church-Turing and state. The idea is that the state +was supposed to be external to your Xeact components. And you know, +the Xeact components were just supposed to render HTML notes. And this +sounds insane, but it does work for very small tools like that. It +just doesn't scale to the levels that I wanted to do something more +complicated, like a form for filling out and creating a server in one +of my other projects. + +I kind of regret this in the long run. So I remade it. I remade things +to make it better. React components are monads because they have +effects and they can leech into each other. And there's a whole bunch +of math that you can talk about here. But the important thing is that +they're just monads. The important part is that what I had was not +monads. I needed to have effects and ways to handle state. + +So one of the main ways that you handle state in React is with this +thing called useState. It's effectively a container for data. You put +the data in on one end, it triggers re-renders on the other, and you +know, it just works sorta. The only thing is that you need to +implement the hook system and I'm crazy, but I'm not crazy enough to +re-implement React's hook system in a weekend. + +```javascript +const useState = (x = undefined) => [() => x, (y) => (x = y)]; +``` + +So I made the Xeact version of useState, which is this golfed +monstrosity. It is a mutable variable that returns a getter and a +setter. This is effectively a burrito around the data. It lets you +change what value X points to so that you can build up state with a +text area and then grab it out when you're submitting it to a fetch +call. It doesn't trigger re-renders because, again, I didn't want to +reinvent React hooks for a very good reason, but the surprising part +is that this works. + +Oh, by the way, fun cursed JavaScript fact for you. The reason that +this works is because function arguments are mutable references. You +can redefine what function arguments are in a function, and that just +works. Try it in production with some people that are more junior and +newer to JavaScript. You'll never expect what happens next. + +At this point, I thought Xeact was basically perfect. It had all the +features I want, none of the features I didn't, and here's just where +I decided to stop working on it, not because I lost interest or anything. +Xeact made my front end tasks as hard as I wanted to make them. I +could go from thought to photon in seconds and there was no madness +unless I felt like it. + +Grug brain make you want dot key work? I added TypeScript types +everywhere, so the dot key worked. Absolutely beautiful. Full +TypeScript for the entire femtoframework. + +It has mature and robust integrations with tools like Nix to automate +your production deployments so you can get back to disrupting the +burrito drone delivery industry. Don't think about minutiae. Go back +to innovation. Xeact is the femtoframework that developers love. Don't +believe us? See the testimonials for yourself. + +<XeblogSlide name="2024/xeact/067" essential /> + +> Our engineering team was blown away. This is versatile, powerful, and +> constantly updated. It's everything we've wanted and more. + +<XeblogSlide name="2024/xeact/068" essential /> + +> This software's cloud backend has only been hacked twice so far this +> year. + +<XeblogSlide name="2024/xeact/069" essential /> + +> It shouldn't crash until the heat death of the universe. + +<XeblogSlide name="2024/xeact/070" essential /> + +> Oh God, where are my hands? Why have you taken my hands away from me? + +Overall, you can see that Xeact is an obvious choice for your front +end projects. Small, fast, and...small. Xeact scales to your needs or +your money back, and you didn't pay me. + +However, Xeact only focuses on the front end. There's a whole other +half of the stack to look at and a whole other half of that stack to +look at. What would Xeact for the backend look like? + +<XeblogPicture path="blog/2023/incredible-xeact-journey/our-incredible-journey" /> + +We think there's room for the Xeact way to be taken to the backend +where it belongs. That's right. At the end of October last year, +Techaro acquired Xeact. All the existing cloud services were shut down +and refunds were issued to all affected customers with only 24 hours +of notice. However, in the process, Xeact has become more and more +popular. + +<XeblogSlide name="2024/xeact/074" essential /> + +In the process, we have a unique opportunity to ideate some more +synergy and really disrupt everything. We're going to revolutionize +the concept of disruption. With Techaro, we are going to make the +Xeact development flow for the backend and the front end at the same +time using PILK, or Putting Individual Lookups in Kubernetes. This +will allow you to make infinitely scalable backend services as easily +as you can make infinitely scalable front end services. + +Legacy frameworks like Next.js make it easy to mix front-end and +back-end code, but they have limitations when it comes to scaling it. +What happens when your search route uses too many resources and blocks +your credit card processing route and you just turned off the money +generator and you can't generate money anymore? + +We can't stand for this. Why do we accept this as an industry? + +<XeblogSlide name="2024/xeact/076" essential /> + +So we are leveraging the power of PILK to automagically put every +server function into its own auto-scaling group with Kubernetes with +its own URL that changes it every single time. Every deploy, so your +backend is also unscrapable. Take that, ArchiveTeam! + +It's infinitely scalable. Everything has its own execution context and +your cloud provider will love you. This makes PILK a win-win-win +scenario for everyone involved. Your front-end logic? Easy. Your +backend logic? Easy. Your SREs, they'll have nothing to do and they'll +be very bored. + +Maybe even so bored, they'll invent a sarcastic JavaScript framework +with a bunch of bad jokes. + +And this allows the Xeact to advance you towards infinity. Looking +back, we saved developers from the despair of Webpack with the power +of the script tag. We covered the amazing might of naming and how +choosing good names makes the Xeact experience what developers crave. +We covered JSX, quasi-quoting, DAB, and the useState monad. And then +finally, we looked towards the future with the sheer glory of PILK. + +It's obvious. + +Xeact is the perfect choice for your server applications. If you want +it to happen on the front-end, use Xeact. If you want it to happen on +the backend tomorrow, use PILK. + +<XeblogSlide name="2024/xeact/081" essential /> + +By the way, a little disclaimer, the entire preceding talk was a work +of satire. All characters, companies, or events referenced in this +talk are products of my imagination and thus fictional. Any synergy +with observable realities is purely coincidental. I was not speaking +for any of my employers' past, present, or future, and ha-ha, gottem. + +<XeblogSlide name="2024/xeact/082" essential /> + +Thanks for having me tonight, and I hope you learned some- + +(thunderous applause) + +Thanks for having me tonight. I hope you learned...something. By the +way, when I was writing this talk, I put at least one joke about the +industry in it. Extra credit if you can tell me what it was. If I +don't get to your questions, email xeact@xeserv.us, and I promise I will reply. +Otherwise, any questions? + +## Q&A + +<BlockQuote> + If having small frameworks means you eventually build up all the code that the + framework has anyways, do you see that happening with Xeact? +</BlockQuote> + +Well, yeah. That's going to happen no matter what you do. That's just +kind of how this industry is. And the best way to handle that is to, +like, just find something that you can be at peace with and then cry. +Or laugh. I think laughing is more healthy than crying. I think that's +what my therapist said. Not entirely sure. It was a while ago. + +Any more questions? + +<BlockQuote>How does it handle "rage clicks"?</BlockQuote> + +<XeblogConv name="Mara" mood="hacker"> + Context: one of the talks talked about how you measure "rage clicks", or + repeated clicks to get the UI to do something when things are slow by + frustrated users. +</XeblogConv> + +It handles rage clicks thanks to the debounce timer built into the +Xeact standard library. And if you forget to debounce it, then you +have problems. So don't forget. + +<BlockQuote>Where is the documentation?</BlockQuote> + +The documentation for Xeact is at +[github.com/Xe/Xeact](https://github.com/Xe/Xeact). And if you are in +doubt, read the source code. Because the source code is designed to be +readable. Asterisk. + +<BlockQuote>Did you actually make the Xeact source code T-shirt?</BlockQuote> + +Oh, the T-shirt, right? I was actually going to get a T-shirt as a +bit. But I thought about that idea after the logistics wouldn't work +out. diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..dd57863 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,204 @@ +{ + "name": "@xeserv/xesite", + "version": "4.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "@xeserv/xesite", + "version": "4.0.0", + "license": "ISC", + "dependencies": { + "execa": "^8.0.1" + } + }, + "node_modules/cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dependencies": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + }, + "engines": { + "node": ">= 8" + } + }, + "node_modules/execa": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" + }, + "engines": { + "node": ">=16.17" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/human-signals": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", + "engines": { + "node": ">=16.17.0" + } + }, + "node_modules/is-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==" + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/mimic-fn": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.2.0.tgz", + "integrity": "sha512-W4/tgAXFqFA0iL7fk0+uQ3g7wkL8xJmx3XdK0VGb4cHW//eZTtKGvFBBoRKVTpY7n6ze4NL9ly7rgXcHufqXKg==", + "dependencies": { + "path-key": "^4.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/onetime": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", + "dependencies": { + "mimic-fn": "^4.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dependencies": { + "shebang-regex": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "engines": { + "node": ">=8" + } + }, + "node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/strip-f |
