mynewprojectjxnrss1 match
23// import data from "https://blog.jxnblk.com/api/all.json" with { type: "json" };
4import type { Middleware } from "https://esm.town/v/jxnblk/ReactStream";
56function generateRSSFeed(posts) {
mynewprojectjxnredirects2 matches
1import { match, parse, pathToRegexp } from "https://esm.sh/path-to-regexp@7.2.0";
2import { DataRequest } from "./ReactStream";
34const redirects = new Map();
5redirects.set("/hello-color", "https://jxnblk.io/hello-color");
6redirects.set("/react-icons", "https://jxnblk.io/react-icons/");
78redirects.set("/colorable", "https://colorable.jxnblk.com");
mynewprojectjxnReactStream16 matches
1/** @jsxImportSource https://esm.sh/react@18.3.1 */
2import { hydrateRoot } from "https://esm.sh/react-dom@18.3.1/client";
3import * as React from "https://esm.sh/react@18.3.1";
45export { React };
67export type RequestHandler = (request: Request) => Promise<Response>;
13export type Middleware = (req: DataRequest, res: Response, callback: NextCallback) => Promise<Response>;
1415export interface ReactStreamProps {
16url: URL;
17pathname: string;
2324export function render<T>(
25/** Root-level React component that renders an entire <html> element
26* including the head and body tags.
27*/
28Component: React.ComponentType<ReactStreamProps>,
29/** On Val Town, use `import.meta.url` for client-side hydration */
30module: string | false,
31/** Optional middleware */
32opts: ReactStreamOptions | Middleware[] = [],
33) {
34const useMiddleware = Array.isArray(opts); // for backwards compat
35const options: ReactStreamOptions = !Array.isArray(opts) ? opts : {};
36const { api, getInitialProps } = options;
374243return async function handler(request: Request): Promise<Response> {
44const main = reactStream(Component, module);
45const middleware: Middleware[] = [
46parseURL,
71export default render;
7273// main react response handler
74const reactStream = (
75Component: React.ComponentType<ReactStreamProps>,
76module: string | false,
77): Middleware =>
78async function(req: DataRequest, res: Response): Promise<Response> {
79const { renderToReadableStream } = await import("https://esm.sh/react-dom@18.3.1/server");
8081const stream = await renderToReadableStream(
91headers.set("Content-Type", "text/html");
9293console.log("react", res.status);
94return new Response(stream, {
95headers,
139};
140/** DEPRECATED: Use middleware instead */
141export interface ReactStreamOptions {
142/** DEPRECATED: Optional text response for robots.txt */
143robots?: string;
OpenTowniesystem_prompt.txt9 matches
107- **Storage Strategy:** Only use backend storage if explicitly required; prefer simple static client-side sites
108- For persistence, use Val Town SQLite or Blob storage with `import.meta.url` for keys/table names
109- **React Configuration:** When using React libraries, pin versions with `?deps=react@18.2.0,react-dom@18.2.0` and include the `@jsxImportSource` pragma
110- When facing client-side render issues, check if all React dependencies are pinned to the same version
111- **Styling:** Default to using TailwindCSS via `<script src="https://cdn.twind.style" crossorigin></script>` unless otherwise specified
112220221### Frontend Best Practices
222- Structure as a standard client-side React app
223- Use SVG for favicons (Val Town only supports text files)
224- Separate components into individual files
225- Access bootstrapped data from `window.__INITIAL_DATA__`
226- Use React 18.2.0 consistently in all imports and the `@jsxImportSource` pragma
227- Follow the React component pattern from the example project
228- Handle API calls properly with proper error catching
229247- Always run table creation before querying
2482493. **React Configuration:**
250- All React dependencies must be pinned to 18.2.0
251- Always include `@jsxImportSource https://esm.sh/react@18.2.0` at the top of React files
252- Rendering issues often come from mismatched React versions
2532544. **File Handling:**
OpenTownieREADME.md1 match
89- [ ] Give it all the code (except maybe .txt files) as initial context (like cursor sonnet max)
10- [ ] Rebuild as React Router?
11- [ ] Persistent threads?
12- [ ] opentownie as a pr bot
OpenTownieindex.tsx2 matches
1/** @jsxImportSource https://esm.sh/react@18.2.0?dev */
2import { createRoot } from "https://esm.sh/react-dom@18.2.0/client?dev";
3import { App } from "./components/App.tsx";
4
OpenTownieImageUpload.tsx7 matches
1/** @jsxImportSource https://esm.sh/react@18.2.0?dev */
2import React, { useRef, useState } from "https://esm.sh/react@18.2.0?dev";
34// Maximum number of images that can be uploaded
1516// Handle file selection
17const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
18if (e.target.files) {
19processFiles(Array.from(e.target.files));
6667// Handle drag events
68const handleDragEnter = (e: React.DragEvent) => {
69e.preventDefault();
70e.stopPropagation();
72};
7374const handleDragLeave = (e: React.DragEvent) => {
75e.preventDefault();
76e.stopPropagation();
78};
7980const handleDragOver = (e: React.DragEvent) => {
81e.preventDefault();
82e.stopPropagation();
83};
8485const handleDrop = (e: React.DragEvent) => {
86e.preventDefault();
87e.stopPropagation();
OpenTownieCreateBranch.tsx3 matches
1/** @jsxImportSource https://esm.sh/react@18.2.0?dev */
2import React, { useState } from "https://esm.sh/react@18.2.0?dev";
34interface CreateBranchProps {
25};
2627const handleSubmit = async (e: React.FormEvent) => {
28e.preventDefault();
29
OpenTownieBranchControl.tsx3 matches
1/** @jsxImportSource https://esm.sh/react@18.2.0?dev */
2import React, { useEffect, useState } from "https://esm.sh/react@18.2.0?dev";
3import { CreateBranch } from "./CreateBranch.tsx";
48485// Handle branch selection change
86const handleBranchChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
87const newBranchId = e.target.value;
88setBranchId(newBranchId);