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 🙏

© 2026 – Pkg Stats / Ryan Hefner

hyperapp-is

v0.2.2

Published

hyperapp 用ユーティリティ集

Readme

hyperapp-is

hyperapp 用ユーティリティ集

ライブラリ名の is は、is4416 の is です
自分用に作成しているユーティリティをまとめたライブラリです


ファイル構成

index.ts: エクスポートの一覧

[core]
  ├ state.ts    : state 操作に関するもの
  ├ component.ts: VNode の作成に関するもの
  └ effects.ts  : Effectに関するもの

[dom]
  ├ utils.ts : DOM 操作に関するユーティリティ
  └ dialog.ts: DOM を利用したダイアログ

[animation]
  ├ raf.ts       : requestAnimationFrame を state と連携する仕組み
  ├ easing.ts    : イージング関数集
  └ properties.ts: raf.tsを利用した CSS アニメーション

[services]
  └ google.ts: Google 認証ユーティリティ

関数一覧 (interfaceは省略)

core

  • state : getValue, setValue, getLocalState, setLocalState, createLocalKey
  • component: el, concatAction, getClassList, deleteKeys
  • effects : effect_toast

dom

  • utils : d, css, getScrollMargin
  • dialog: withLoadingDialog

animation

  • raf : RAFTask, subscription_RAFManager
  • easing : progress_easing
  • properties: createRAFProperties, effect_RAFProperties

services

  • google: getAccessToken, GoogleAuth

使い方

core

  • getValue, setValue: keyNames には、取得・設定したい値までのパス

ステートの構造に依存せずに目的の値が取得・設定できます
汎用コンポーネントの作成に利用できます

const state = {
	title: "ユーザー情報",
	user: {
		name: "青年",
		age : 20
	}
}

const title = getValue(state, ["title"], "タイトル情報")  // res: ユーザー情報
const name  = getValue(state, ["user", "name"], "名無し") // res: 青年
const age   = getValue(state, ["user", "age"], 0)         // res: 20

  • getLocalState, setLocalState: ローカルステートのように値を取得・設定できます
  • createLocalKey は、基本的には内部で使うための関数ですが、外部からも利用可能です

setLocalState は、メインステートに追加ツリーを追加します
ユーザーはメインステートの改変を意識することなく、ローカルステートのように値を取得・設定できます
汎用コンポーネントの作成で、ローカルステートが欲しいときに利用できます

interface LocalState {
	color?: string
	size ?: number
}

const localState = getLocalState(state, name, {
	color: "red"
}) // res: { color: "red" }

const newState = setLocalState(state, name, {
	color: "blue"
	size : 180
})

/* res:
	{
		title: "ユーザ情報",
		user : {
			name: "青年",
			age : 20
		},
		local_key_青年: {
			color : "blue",
			size  : 180
		}
	}
*/

  • el: hyperapp の h 関数のラッパーです

text関数の省略や、配列の省略などが可能です
JSXを使用する場合は、出番がありません

const body = el("body")
const div  = el("div")

const vnode = body({},
	div({}, "タイトル行"),
	div({}, "メイン")
)

  • deleteKeys : props から指定したキーを削除します
  • getClassList: props からクラスリストを取得します
  • concatAction: アクションを結合します

汎用コンポーネントを作成する場合などに使用できます

const button = el("button")

const MyButton = function <S> (
	props: {
		state: S
		onclick?: (state: S, e: Event) => S | [S, Effect<S>],
		keyNames: string[] // number までのパス
		[key: string]: any
	},
	child: any
): VNode<S> {
	const { state, onclick, keyNames } = props
	const classList = getClassList(props)

	// action
	const action_click = (state: S, e: Event) => {
		const count = getValue(state, keyNames, 0)
		const newState = setValue(state, keyNames, count + 1)

		// ユーザーが指定したアクションとの結合
		return concatAction(onclick, newState, e)
	}

	// vnode
	return button({
		type: "button",
		...deleteKeys(props, "state", "keyNames"),       // DOM に設定しない値を削除
		class  : classList.concat("MyButton").join(" "), // 取得したクラス名に MyButton を追加
		onclick: action_click
	}, child)
}

  • effect_toast: 設定した値を、一定時間経過後に元に戻します

const action = (state: S) => {
	return [
		{
			...state,
			message: "ready"
		},
		effect_toast({
			keyNames: ["message"],
			value   : "toast message",
			duration: 1000
		})
	]
}

message に 1秒間 "toast message" と表示された後
"ready" という値に戻ります


dom

  • d: DOM 作成用のラッパー

HTMLElement を作成し、プロパティの設定・子ノードの追加・親ノードへの追加をまとめて行います

引数

  • parent : 親ノードを指定した場合、作成した要素を追加します
  • tag : タグ名
  • properties: プロパティ
  • children : 子ノードまたは文字列等

  • css: DOM へ CSS を設定するラッパー

要素に複数の CSS スタイルをまとめて設定します

例: d, css

// create dom tree
const header = d(null, "header", {}, "ヘッダー")
const div    = d(null, "div", {}, "body", "コンテンツ")
const dialog = d(document.body, "dialog", { id: "dialogWindow" },
	header,
	div
)

// set style
css(dialog, {
	margin      : "auto auto",
	maxWidth    : "90vw",
	borderRadius: "1rem"
})
css(header, {
	position: "sticky",
	top     : "0"
})
css(div, {
	overflow: "auto"
})

// dialog 表示
dialog.showModal()

  • getScrollMargin: スクロール状態を取得

無限スクロールなどに利用できます

例:

const action = (state: S, e: Event) => {
	const scrollMargin = getScrollMargin(e)

	if (scrollMargin.bottom < 100) {
		// 残り 100px で、アイテムの追加処理などを実行
		const newState = {
			...state,
			count: count + 10
		}
		return newState
	}

	return state
}

  • withLoadingDialog: task 実行中、ローディングダイアログを表示します

onCancel を指定した場合は、Esc キーで onCancel が呼び出されます

const json = await withLoadingDialog(async () => {
	const res = await fetch("/api/hoge")
	if (!res.ok) throw new Error("error: task")
	return res.json()
})

animation

  • subscription_RAFManager: RAFTask 配列の実行を管理するサブスクリプション

ステートに RAFTask[] の配列を用意します
RAFTask が追加されると、自動的にタスクの実行管理を開始します
タスクが完了すると、自動的に RAFTask[] から削除されます

例:

app({
	node,
	init: [
		{
			tasks  : [] as RAFTask[],
			message: ""
		},
		(dispatch: S) => {
			const newTask = new RAFTask({
				id      : "uniqueID",
				duration: 2000,
				action  : (state: S, task: RAFTask<S>) => {
					return {
						...state,
						message: `progress = ${ task.progress }`
					}
				}
			})
		}
	],
	view,
	subscription: (state: S) => [
		subscription_RAFManager(state, ["tasks"])
	]
})

RAFTask クラスの作成には、最低限次の項目を設定する必要があります

  • id: タスク管理用のユニークIDを設定してください。DOMのIDとは関係ありません
  • duration: 実行時間をミリ秒で指定してください
  • action: 1フレームごとの処理内容を指定します。進捗状況は RAFTask.progress から取得できます

  • effect_RAFProperties: RAFTask を利用して CSS プロパティをアニメーションする Effect

CSSProperty により、複数の CSS アニメーションを同時処理することが可能です

例:

	const action = (state: S) => {
		const property: CSSProperty = {
			"button": {
				"fontSize": (progress: number) => `${ 1 + 1 * progress }rem`,
				"color"   : (progress: number) => `rgb(${ 255 * progress }, 0, 0)`
			}
		}

		return [state, effect_RAFProperties({
			id        : "uniqueID",
			duration  : 1000,
			properties: [ property ]
		})]
	}

すべてのボタンに対して、1秒かけて文字サイズを拡大し、文字色を赤へ変化させるアニメーションのサンプルです


services

  • GoogleAuth: Google Identity Services を利用した Google 認証クラス

ログインボタンを作成しない場合は、new GoogleAuth({ clientId: "hoge" }) だけで利用できます
インスタンス作成後、initialize を実行すると認証処理を開始します

const config: GoogleAuthConfig = {
	clientId: "your google api key"
}

const option: GoogleButtonOption = {
	renderButton: document.querySelector("article")
}

const auth = new GoogleAuth(config, option)

auth.initialize().then((res: GoogleAuthResult) => {
	const idToken = res.idToken
	const user = res.user

	alert("ログイン成功")
})