24 * By convention, we only use string and number values. Complex values are serialized.
25 */
26export async function transformExport(
27 tracesData: IExportTraceServiceRequest,
28): Promise<Array<OtelSpan>> {
107 | Record<string, AttributeValuePrimitive>;
108
109async function mapAttributeValue(value: IAnyValue): Promise<AttributeValue> {
110 if (!value) {
111 return null;
137}
138
139async function mapAttributes(
140 attributes: IKeyValue[],
141): Promise<Record<string, AttributeValue>> {
158}
159
160async function mapEvent(event: IEvent) {
161 return {
162 name: event.name,
166}
167
168async function mapLink(link: ILink) {
169 return {
170 trace_id: stringOrUintToString(link.traceId),
175}
176
177function stringOrUintToString(id: string | Uint8Array) {
178 return id instanceof Uint8Array
179 ? Buffer.from(id).toString("hex")
181}
182
183function mapStatus(status: IStatus) {
184 return {
185 code: status.code,
188}
189
190function statusCodeToString(statusCode: EStatusCode) {
191 switch (statusCode) {
192 case 0:
201}
202
203// Function to convert ESpanKind to SpanKind
204function convertToSpanKind(spanKind: ESpanKind): string {
205 switch (spanKind) {
206 case 1:
47
48/**
49 * Export a function that wraps the incoming request,
50 * then injects the Deno env vars into the Hono app befoe
51 * executing the api entrypoint (`app.fetch`)
52 */
53export default async function(req: Request): Promise<Response> {
54 const env = Deno.env.toObject();
55 // NOTE - Adding the entire env object will also expose the following values to your api handlers:
3 * with a better experience
4 */
5export function getOpenAPISpec() {
6 return {
7 openapi: "3.0.0",
8 * @TODO - Need to implement `end_time` column for this query to work
9 */
10export function findTraces(db: DBType) {
11 const REFERENCE QUERY = `
12SELECT trace_id, MAX(end_time) as end_time
30};
31
32function InstructionsModal({ onClose }) {
33 return (
34 <div className="modal-overlay">
50}
51
52function GameOverModal({ elapsedTime, onPlayAgain }) {
53 return (
54 <div className="modal-overlay">
62}
63
64function App() {
65 const [wordlist, setWordlist] = useState([]);
66 const [currentWordIndex, setCurrentWordIndex] = useState(0);
358}
359
360function client() {
361 createRoot(document.getElementById("root")).render(<App />);
362}
366}
367
368export default async function server(request: Request): Promise<Response> {
369 const { sqlite } = await import("https://esm.town/v/stevekrouse/sqlite");
370
16In a normal server environment, you would likely use a middleware [like this one](https://hono.dev/docs/getting-started/nodejs#serve-static-files) to serve static files. Some frameworks or deployment platforms automatically make any content inside a `public/` folder public.
17
18However in Val Town you need to handle this yourself, and it can be suprisingly difficult to read and serve files in a Val Town Project. This template uses helper functions from [stevekrouse/utils/serve-public](https://www.val.town/x/stevekrouse/utils/branch/main/code/serve-public/README.md), which handle reading project files in a way that will work across branches and forks, automatically transpiles typescript to javascript, and assigns content-types based on the file's extension.
19
20### `index.html`
26## CRUD API Routes
27
28This app has two CRUD API routes: for reading and inserting into the messages table. They both speak JSON, which is standard. They import their functions from `/backend/database/queries.ts`. These routes are called from the React app to refresh and update data.
29
30## Errors
4
5* `migrations.ts` - code to set up the database tables the app needs
6* `queries.ts` - functions to run queries against those tables, which are imported and used in the main Hono server in `/backend/index.ts`
7
8## Migrations
18The queries file is where running the migrations happen in this app. It'd also be reasonable for that to happen in index.ts, or as is said above, for that line to be commented out, and only run when actual changes are made to your database schema.
19
20The queries file exports functions to get and write data. It relies on shared types and data imported from the `/shared` directory.
10await createTables();
11
12export async function getMessages(limit = MESSAGE_LIMIT): Promise<Message[]> {
13 const messages = await sqlite.execute(
14 `SELECT * FROM ${tableName}
20}
21
22export async function insertMessage(content: string) {
23 await sqlite.execute(
24 `INSERT INTO ${tableName} (content)
3import type { Message } from "../shared/types.ts";
4
5export function MessageInput({ onSubmit }: { onSubmit: () => void }) {
6 const [message, setMessage] = React.useState("");
7
4import { MessageInput } from "./MessageInput.tsx";
5
6export function App(
7 { initialMessages = [], thisProjectURL }: { initialMessages?: Message[]; thisProjectURL?: string },
8) {
41}
42
43function MessageList({ messages }: { messages: Message[] }) {
44 const displayedMessages = messages.slice(0, MESSAGE_LIMIT);
45 return (
50}
51
52function MessageItem({ message }) {
53 const formattedDate = new Date(message.timestamp).toLocaleString();
54