Skip to content

Instantly share code, notes, and snippets.

View hanakla's full-sized avatar
🏙️
Bless of type

Hanakla hanakla

🏙️
Bless of type
View GitHub Profile
@hanakla
hanakla / mod.ts
Created March 28, 2026 11:06
GitButler CLI MCP (Deno)
#!/usr/bin/env -S deno run -A
//
// GitButler CLI MCP Server
//
// Usage:
// deno run -A gitbutler-cmd.ts # start MCP server
// deno run -A gitbutler-cmd.ts --allow-reset # enable destructive commands (undo, oplog restore)
// deno run -A gitbutler-cmd.ts --test # run smoke test
//
@hanakla
hanakla / styled-tailwind.ts
Last active October 24, 2025 12:52
styled-tailwind.ts
import { ComponentProps, ComponentType, createElement, memo, MemoExoticComponent, ReactElement } from 'react'
import { twMerge } from 'tailwind-merge'
type Substitutions<Props> = string | ((props: Props) => string | false | undefined | null)
type StyledFactory = {
[Tag in keyof JSX.IntrinsicElements]: <Props>(
template: { raw: ReadonlyArray<string> | ArrayLike<string> },
...substitutions: Array<Substitutions<Props>>
) => MemoExoticComponent<(props: ComponentProps<Tag> & Props) => ReactElement>
@hanakla
hanakla / rescue.ts
Created April 18, 2024 06:49
rescue.ts - Single function for safety error handling for TypeScript
// MIT License
//
// Copyright 2024 Hanakla (https://x.com/hanak1a_)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
// documentation files (the “Software”), to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial
@hanakla
hanakla / i18n.ts
Last active April 18, 2024 06:47
Minimal I18n lib for React
// MIT License
//
// Copyright 2024 Hanakla (https://x.com/hanak1a_)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
// documentation files (the “Software”), to deal in the Software without restriction, including without limitation
// the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
// and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial
@hanakla
hanakla / usage.ts
Last active November 13, 2019 06:54
React Hooks onChangedEffect
import { useChangedEffect } from './useChangedEffect'
const SomeComponent = ({ lastUpdate }: { lastUpdate: number }) => {
useChangedEffect(() => {
// Do something when `lastUpdate` changed
}, [ lastUpdate ]);
return null
};
import Fleur from '@fleur/fleur'
import { FleurContext } from '@fleur/fleur-react'
import React from 'react'
import ReactDOM from 'react-dom'
import AppRoot from './App'
import { CountStore } from './store'
const app = new Fleur({
stores: [ CountStore ]
import React, { useCallback } from 'react'
import { useFleurContext, useStore } from '@fleur/fleur-react'
import { CounterOps } from './operations'
import { CountStore } from './store'
export const App = () => {
const { executeOperation } = useFleurContext()
const { count } = useStore([CountStore], getStore => ({
count: getStore(CountStore).getCount(),
import { operations } from '@fleur/fleur'
import { CounterActions } from './actions.ts'
export const CounterOps = operations({
async increase(context, amount: number) {
context.dispatch(CounterActions.increase, { amount })
},
async decrease(context, amount: number) {
context.dispatch(CounterActions.decrease, { amount })
import { listen, Store } from '@fleur/fleur'
import { CounterActions } from './actions.ts'
type State = {
count: number
}
export class CountStore extends Store<State> {
public state: State = { count: 0 }
// Actionの型定義 (actions.ts)
import { action } from '@fleur/fleur'
export const CounterActions = actions('CounterAction', {
increase: action<{ amount: number }>(),
decrease: action<{ amount: number }>(),
})