maxm avatar
maxm
forwarder
Email
Forked from stevekrouse/forwarder
0
lho avatar
lho
VALLE
HTTP
Forked from janpaul123/VALLE
0
postpostscript avatar
postpostscript
ReloadScript
Script
Forked from stevekrouse/ReloadScript
0
maxm avatar
maxm
actuallyGoodEmojiSearch
HTTP
Forked from maxm/simpleWikipediaInstantSearch
2
nbbaier avatar
nbbaier
vtIdeaList
HTTP
Vals I Want to Build A running list of things I want to build on Val Town, hosted in a Val Town readme . [ ] A bare bones CMS to edit markdown files hosted on a github (or val town readmes eventually) [ ] A set of Vals for interacting with github repos via Octokit (useful for the above CMS idea) [ ] A full json-server like implementation for quickly generating stub APIs based on json/valtown blob data ( begun ) [ ] An implementation of Convert bookmarklet to Chrome extension [ ] A tool for generating an NPM package from a Val or set of Vals (something like [dnt]- [ ] (https://github.com/denoland/dnt/)) [ ] An email handler for forwarding emails to Tana [ ] A component library (this would be a wild swing for me) [ ] A val to get a dependency graph of a val(s) ( started here by rlesser ) [ ] A single val that wraps a FeTS client to the API for saving a couple of lines of boilerplate [ ] A val for generating OpenAPI specs from jsdoc comments within vals (sort of like this npm package ) [ ] Conways game of life pst, if you want to see stuff I would love to see built right into Val Town, here you go
1
stevekrouse avatar
stevekrouse
usageAlert
Script
HTTP Val Usage Alert As of Oct 29, 2024, HTTP vals can comfortably run 2k times per minute. If you want to get alerted if you val is getting close to those limits, you can wrap your HTTP handler in this middleware: import { usageAlert } from "https://esm.town/v/stevekrouse/usageAlert" async function sampleHandler(req: Request): Promise<Response> { return new Response("Hello, World!"); } export default usageAlert(sampleHandler); It keeps a sliding window count of requests in memory (which is perfect for this sittuation) and will send you an email using @std/email if you go over 1k req / min.
0
maxm avatar
maxm
asciiNycCameras
HTTP
ASCII NYC Traffic Cameras All of NYC's traffic cameras available as streaming ASCII images: https://maxm-asciinyccameras.web.val.run/ NYC has a bunch of traffic cameras and makes them available through static images like this one . If you refresh the page you'll see the image update every 2 seconds or so. I thought it might be fun to make these cameras viewable as an ASCII art video feed. I made a small library that takes most of its logic from this repo . You can see a basic example of how to convert any image to ASCII here . I pull in NYC GeoJSON from here and then hook up a Server-Sent Events endpoint to stream the ASCII updates to the browser. (Polling would work just as well, I've just been on a bit of a SSE kick lately.) Hilariously (and expectedly) The ASCII representation is about 4x the size of the the source jpeg and harder to see, but it has a retro-nostalgia look to it that is cool to me :)
4
postpostscript avatar
postpostscript
blogSqliteUniverse
HTTP
sqliteUniverse: Make SQLite Queries Against Multiple Endpoints in Deno (Val Town) (Part 1) Prerequisite Knowledge Val Town-Hosted SQLite Val Town hosts SQLite as part of its standard library ( @std/sqlite ). This makes a fetch request against their closed-source API (using your API token) which returns results in a consistent format. This is great because you can host your own endpoints that work similarly, and reuse code that was only designed in mind for that original hosted interface The standard format (abridged to important fields): POST /execute { "statement": { "sql": "SELECT * FROM some_table", "args": [] } } Output: { "rows": [[1, "first", 1709942400], [2, "second", 1709942401]], "columns": ["id", "name", "lastModified"] } POST /batch { "statements": [ { "sql": "INSERT INTO some_table VALUES (?, ?, ?)", "args": [3, "third", 1709942402] }, { "sql": "SELECT * FROM some_table", "args": [] } ] } Output: [ { "rows": [], "columns": ["id", "name", "lastModified"] }, { "rows": [[1, "first", 1709942400], [2, "second", 1709942401], [3, "third", 1709942402]], "columns": ["id", "name", "lastModified"] }, ] SQLite in Wasm There is a deno package (sqlite) which lets you (among other things) create SQLite databases in-memory using WebAssembly. I've created a Val which wraps this to enable it to be a drop-in replacement for @std/sqlite: @postpostscript/sqliteWasm Example import { createSqlite } from "https://esm.town/v/postpostscript/sqliteWasm"; import { Statement } from "https://esm.town/v/postpostscript/sqliteBuilder"; const sqlite = createSqlite(); console.log(sqlite.batch([ Statement` CREATE TABLE test ( id TEXT PRIMARY KEY, value TEXT ) `, Statement` INSERT INTO test VALUES ( ${"some-id"}, ${"some-value"} ) `, Statement` SELECT * FROM test `, ])) Result: [ { rows: [], rowsAffected: 0, columns: [] }, { rows: [], rowsAffected: 1, columns: [] }, { rows: [ [ "some-id", "some-value" ] ], rowsAffected: 0, columns: [ "id", "value" ] } ] Dump Tool I have modified @nbbaier's great work at @postpostscript/sqliteDump to support dumping from any sqlite interface, whether the standard library's version, over HTTP, or through the above Wasm implementation Putting it All Together All of the above enables: Serving a subset of your private data publicly for others to query (Example: @postpostscript/sqlitePublic ) Backing up your database and querying against that backup (via @postpostscript/sqliteBackup's sqliteFromBlob and sqliteToBlob ) But we can do more..! What if we could query from multiple of these data sources.. at the same time! 😱 sqliteUniverse sqliteUniverse is an @std/sqlite compatible interface that determines where a table should route to based on different patterns Table Name Patterns The actual table name will always come after a "/", with the exception of tables without any endpoint, for example users . Everything before the last "/" is the endpoint name. Endpoint interfaces will be chosen in the following order: Exact match in options.interfaces.exact e.g. @std/sqlite/someTable would match options.interfaces.exact["@std/sqlite"] Each pattern in options.interfaces.patterns options.interfaces.fallback will be called An error is thrown if none of the above matches AND returns an sqlite interface. If there is a match but the handler returns nothing, it will continue down the list Default options.interfaces.patterns : patterns.https - /^https:\/\// ( https://example.com/somePath/tableName ): fetch from https://example.com/somePath/batch patterns.val - /^@/ ( @author/name/somePath/tableName ): fetch from the val's endpoint, https://author-name.web.val.run/somePath/batch Other Available Patterns: The following patterns are accessible through import { patterns } from "https://esm.town/v/postpostscript/sqliteUniverse" : patterns.blob - /^blob:\/\// ( blob://backup:sqlite:1709960402936 ) - import the database from private blob backup:sqlite:1709960402936 Overriding Default Options The sqliteUniverse export contains defaults insuring no private data will be leaked. If you want to reduce or extend these options, use the sqliteUniverseWithOptions export and pass a modified interfaces option in the first argument: Examples of how to set options.interfaces.exact , options.interfaces.patterns , and options.interfaces.fallback : import { sqliteUniverseWithOptions, patterns, defaultPatterns } from "https://esm.town/v/postpostscript/sqliteUniverse"; import { createSqlite } from "https://esm.town/v/postpostscript/sqliteWasm"; import { sqliteFromAPI } from "https://esm.town/v/postpostscript/sqliteFromAPI"; import { Statement } from "https://esm.town/v/postpostscript/sqliteBuilder"; const sqlite = sqliteUniverseWithOptions({ interfaces: { exact: { // `SELECT * FROM "some-endpoint/someTable"` will match // `SELECT * FROM "some-endpoint/somePath/someTable"` will NOT match "some-endpoint": ({ endpoint, tables }) => { const sqlite = createSqlite() sqlite.batch([ Statement`CREATE TABLE someTable (someField TEXT PRIMARY KEY)`, Statement`INSERT INTO someTable VALUES (${"some-field"})` ]) return sqlite }, }, patterns: [ ...defaultPatterns, [ // shorthand e.g. ~/sqlitePublic -> @postpostscript/sqlitePublic /^~\/(\w+)/, ({ endpoint, tables, match }) => { return sqliteFromAPI(`@postpostscript/${match[1]}`) }, ] ], fallback({ endpoint, tables }) { // if an endpoint is not found, this will be called return sqliteFromAPI(`@postpostscript/sqlitePublic`) }, }, }) console.log(await Statement` SELECT * FROM "some-endpoint/someTable" JOIN "~/sqliteVals/vals" JOIN authIdExampleComments_comment LIMIT 1 `.execute({ sqlite })) Output: [ { someField: "some-field", id: "aeb70bbb-05fc-403b-8d6a-130c423ecb53", name: "discordWelcomedMembers", code: "// set at Sun Mar 10 2024 00:32:48 GMT+0000 (Coordinated Universal Time)\n" + "export let discordWelcomedM"... 8289 more characters, version: 234771, privacy: "public", public: 1, run_start_at: "2024-03-10T00:32:48.978Z", run_end_at: "2024-03-10T00:32:48.978Z", created_at: "2024-03-10T00:32:48.978Z", author_id: "a0bf3b31-15a5-4d5c-880e-4b1e22c9bc18", author_username: "stevekrouse", username: "postpostscript", comment: "test", date_added: 1709776325.857 } ] Part 2 Since Val Town currently has a character limit for val readmes, this will have to continue in Part 2 !
1
nicosql avatar
nicosql
forwarder
Email
Forked from stevekrouse/forwarder
0
mrblanchard avatar
mrblanchard
VALLE
HTTP
Forked from janpaul123/VALLE
0
stevekrouse avatar
stevekrouse
hono_react_ssr
Script
Forked from stevekrouse/ssr_react_mini
0
vawogbemi avatar
vawogbemi
wide
HTTP
Forked from maxm/wide
0
maxm avatar
maxm
wasmBlobHost
HTTP
WASM Binary Host https://maxm-wasmblobhost.web.val.run/ Where should you host your WASM blobs to use in vals? Host them here! Upload with curl: curl -X POST -H "Content-Type: application/wasm" \ --data-binary @main.wasm https://maxm-wasmBlobHost.web.val.run
3
kylem avatar
kylem
gitReleaseNotes
HTTP
Github Release Notes from package.json Enter a raw github URL to a package.json, https://raw.githubusercontent.com/username/repo/branch/package.json and get a response of all release notes for all packages from current to latest. Roadmap [ ] GenAI summary [ ] Weekly cron email reports [ ] Send update PRs [ ] Other package managers like PyPi [ ] Formatting/styling [ ] Loading spinner
7
nbbaier avatar
nbbaier
vtIdeaAggregator
HTTP
Forked from pomdtr/blog
2
pomdtr avatar
pomdtr
lowdb_example
Script
Lowdb Example This val demonstrates the integration between valtown and lowdb . Read the Lodash section if you want to give superpowers to your DB.
4
Updated: January 8, 2025