RangerMauve / webrun

Run Web-first ESM modules outside of the browser
https://webrun-presentation.hashbase.io/
MIT License
76 stars 4 forks source link

How to pass parameters to a webrun script? #1

Closed tswast closed 6 years ago

tswast commented 6 years ago

I feel like the browser JavaScript way to pass parameters to a script is via the anchor tags portion of the location URL. When self.location support is added will it be possible to add anchor tags when running a script from the command-line?

Or is there a better way to pass parameters? Perhaps I can "fetch" a local file relative to the script location?

tswast commented 6 years ago

~Maybe readline? https://stackoverflow.com/a/38473848/101923~

Edit: prompt() seems more the equivalent to readline in browsers. https://developer.mozilla.org/en-US/docs/Web/API/Window/prompt

RangerMauve commented 6 years ago

I'm not sure yet, to be honest. At the moment I've been using the search parameters in the URL.

You can see an example of that in follow-seeder.

When running follow-seeder with webrun, I pass in the URL that should be seeded as a querystring parameter.

webrun "dat://follow-seeder.hashbase.io/run.js?url=dat://fritter-rangermauve.hashbase.io"

Within the module, the URL is available as a string under import.meta.url. I use that to parse the URL using the URL API here.

Then you can access whatever parameters you want with url.searchParams.get("whatever") to get the specific params you want.

I think this will be useful going forwards for starting scripts with webrun, but I'm not sure if it's really the best approach. I'm totally open to suggestions for alternatives that'd play nicely with the web.

Regarding input through STDIN and output through STDOUT, I provide self.onmessage and self.postMessage which are APIs that are available in the browser.

You can listen on input through STDIN with this:

self.onmessage = function (data){
  console.log(data);
}
tswast commented 6 years ago

I don't know what would happen if I tried to use URL parameters to webrun a GitHub URL, for example. I think it's a little to risky to hope that the server doesn't change the content based on the URL parameters I pass in.

I think the hash might be a little bit more what I'd do on the web. For dat-pin-box, I think I'll do something like

const url = new URL(import.meta.url)
const pinUrl = url.hash.substring(1)
RangerMauve commented 6 years ago

Yeah, that works too. 😁

Maybe I should add something like console.argv so you can get CLI inputs? Though that would break running it on the web.

Theoretically, you should be able to run the exact same command by using:

<script type="module" src="dat://follow-seeder.hashbase.io/run.js?url=dat://fritter-rangermauve.hashbase.io"></script>

And if we used command line args with a webrun-specific variable, that'd break the ability to do that.

tswast commented 6 years ago

Yeah, console.argv seems counter to the goals of webrun. If single-page JavaScript apps have gotten this far by hacking the URL for client-side logic, I think we can do the same for modules.

🤔 I wonder if there's some routing logic for single-page JS apps that could make a good canonical example for this.

RangerMauve commented 6 years ago

For SPAs these days you'd probably have data in your URL and use the history.pushState() API combined with a 404 page that loads your SPA on all URLs.

E.g.

<Route path="/foo/:user/bar">{(user) => "Whatever"}</Route>

https://example.com/foo/bob/bar => loads the SPA and gets caught by the router

I don't think hash routing is as popular anymore.

RangerMauve commented 6 years ago

One idea I had was automatically turning CLI args into searchParams through something like minimist.

ie: webrun "https://example.com" --spaghetti=meatballs => https://example.com?spaghetti=meatballs

allain commented 6 years ago

Might be relevant: the hash at the end of a url isn't supposed to be passed to the server from the browser, so it would reduce the risk of the server tweaking the result based on the query params.

webrun "https://example.com#spaghetti=meatballs"

RangerMauve commented 6 years ago

Also, I'm not sure if I'm really against servers doing weird logic with the query params. If you're hosting a script somewhere, it should be fine to return different content based on parameters if that's part of the thing you're making. E.g., a polyfill service that takes the list of APIs you want as params and returns just the stuff you need.

tswast commented 6 years ago

I just tried the query params method out with a GitHub raw content URL. It worked great.

webrun 'https://raw.githubusercontent.com/tswast/dat-pin-box/master/index.js?pin=dat://464b000900de29e2f02e1c304abb70de0a94266cae55a5ca94bf1abae78839b6/'

ie: webrun "https://example.com" --spaghetti=meatballs => https://example.com?spaghetti=meatballs

I like this idea a lot. When I add URL parameters to webrun a local file it feels weird and somewhat ambiguous because theoretically I could have a filename with a ? character in it (though that's probably not recommended).

RangerMauve commented 6 years ago

Yeah, I'm not sure what to do about files that don't translate to URLs easily. 😅