npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@enhance/types

v0.7.0

Published

Type definitions for Enhance.dev

Downloads

327

Readme

@enhance/types

Type definitions for Enhance

Required reading: Enhance with TypeScript

Installation

npm i -D @enhance/types

JS/TS Examples

💁 The TypeScript examples are intentionally "over-typed" to demonstrate different uses. No need to declare a function's type and its call signature + return type.

API Handler

Read more about Enhance API Routes, their request object, and the expected response to understand each interface's properties.

With JSDoc comments in .mjs

The simplest way to type an API middleware function is to use JSDoc's @type and import "@enhance/types". Typically, the API handler functions should be marked aasync.

You can also import the arugment (EnhanceApiReq) and response (EnhanceApiRes) types.

/**
 * @type {import('@enhance/types').EnhanceApiFn}
 */
export async function get(request) {
  console.log(`Handling ${request.path}...`);

  const todos = [
    { title: "todo 1", completed: false },
    { title: "todo 2", completed: true },
    { title: "todo 3" },
  ];

  const response = {
    json: { todos },
  };

  return response;
}

With .ts

Enhance API middlewares for named get and post functions are passed an EnhanceApiReq object and expected to return a Promise that resolves with an EnhanceApiRes payload.

These types can be used independenty, or by simply typing each handler with EnhanceApiFn.

import type {
  EnhanceApiFn,
  EnhanceApiReq,
  EnhanceApiRes,
} from "@enhance/types";

type Todo = {
  title: string;
  completed?: boolean;
};

export const get: EnhanceApiFn = async function (
  request: EnhanceApiReq,
): Promise<EnhanceApiRes> {
  console.log(`Handling ${request.path}...`);

  const todos: Todo[] = [
    { title: "todo 1", completed: false },
    { title: "todo 2", completed: true },
    { title: "todo 3" },
  ];

  const response: EnhanceApiRes = {
    json: { todos },
  };

  return response;
};

Custom Element

Single file components are the core of the Enhance developer experience.

With JSDoc comments in .mjs

Server rendered custom element functions receive EnhanceElemArg with 2 keys:

  1. html: EnhanceHtmlFn to render HTML strings
  2. state: {attrs: object, store: object} a record of the state used by Enhance
/**
 * @type {import('@enhance/types').EnhanceElemFn}
 */
export default function TodoItem({
  html,
  state: { attrs }
}) {
  const todoId = attrs["todo-id"];
  const completed = typeof attrs.completed === "string";

  return html`
    <div class="flex gap-2 mb-1">
      <input
        type="checkbox"
        name="completed"
        ${completed ? "checked" : ""}
      />
      <slot></slot>
    </div>
  `;
}

With .ts

Several type definitions are available for SSR custom elements. The simplest is to type your default export function as EnhanceElemFn.

You probably shouldn't make a copy of html() -- but its type, EnhanceHtmlFn, is available if needed.

import type {
  EnhanceElemArg,
  EnhanceElemFn,
  EnhanceHtmlFn,
  EnhanceElemResult,
} from "@enhance/types";

const TodoItem: EnhanceElemFn = function ({
  html,
  state: { attrs },
}: EnhanceElemArg): EnhanceElemResult {
  const todoId = attrs["todo-id"];
  const completed = typeof attrs.completed === "string";
  const myHtml: EnhanceHtmlFn = html;

  return html`
    <div class="flex gap-2 mb-1">
      <input
        type="checkbox"
        name="completed"
        ${completed ? "checked" : ""}
      />
      <slot></slot>
    </div>
  `;
};

export default TodoItem;

Head Function

Customize your Enhance app by providing a Head function.

With JSDoc comments in .mjs

Utilize the EnhanceHeadFn type to annotate your app/head.mjs file.

The function takes a EnhanceApiReq object for access to things like the request path and session.

Return a standard EnhanceElemResult (aka a string of HTML).

/**
 * @type {import('@enhance/types').EnhanceHeadFn}
 */
export default function Head(request) {
  const { path } = request;
  const title = `Todos — ${path}`;
  
  return `
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>${title}</title>
  <link rel="stylesheet" href="/_static/styles.css">
</head>
  `;
}

With .ts

The EnhanceHeadFn is similar to an API handler but returns a string of HTML as EnhanceElemResult.

import type {
  EnhanceApiReq,
  EnhanceElemResult,
  EnhanceHeadFn,
} from "@enhance/types";

const Head: EnhanceHeadFn = function (
  request: EnhanceApiReq,
): EnhanceElemResult {
  const { path } = request;
  const title = `Todos — ${path}`;

  return `
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>${title}</title>
  <link rel="stylesheet" href="/_static/styles.css">
</head>
  `;
};

export default Head;