open-index/open-npm huggingface dataset:
npm package: @naporin0624/flat-shop-ui
Description: ## セットアップ
Author: naporin0624
Latest version: 3.5.5

# UI 開発基盤

## セットアップ

```shell
git@github.com:naporin0624/flat-kobo-makeshop-design.git
cd flat-kobo-makeshop-design/
docker-compose up -d
npm install
npm run dev # <-- これで javascript の開発できるようになる
```

localhost:8080 でアクセス

### 一部 Linux 環境で Permission Error が発生する件

一部の Linux 環境ではコンテナ内の Apache 実行ユーザーをコンテナ実行ユーザーに合わせる必要があります。

```bash
id
> uid=xxxx(user) gid=xxxx(user)
```

この uid と gid を .env に記述

```shell
UID=xxxx
GID=xxxx
```

## ディレクトリ構成

`html/theme/data/`以下にデータファイル(.json)、`html/theme/templates/`以下にテンプレートファイル(.tpl)を配置します。

- html/ : Apache document root
  - **theme/**
    - **data/** : テンプレートから呼び出すデータ
      - data1.json
      - data2.json
      - data3.json
      - ...
    - **templates/** : テンプレートファイル
      - module/ : モジュール (テンプレートから`{$module.header}`等で呼び出し)
        - header.tpl
        - footer.tpl
        - side_bar.tpl
        - ...
      - page1.tpl
      - page2.tpl
      - page2.tpl
      - ...

`theme/`以下のファイルには`/`以下でアクセス可能です。(例: `theme/assets/style.css` -> `/assets/style.css`)

## サンプル

### データファイル (html/theme/data/data.json)

```json
{
  "page": {
    "title": "デザインテンプレート開発環境",
    "css": "/assets/style.css"
  },
  "shop": {
    "name": "ショップ名"
  }
}
```

上記 page と shop は別ファイルに分割することも出来ます。

#### data1.json

```json
{
  "page": {
    "title": "デザインテンプレート開発環境",
    "css": "/assets/style.css"
  }
}
```

#### data2.json

```json
{
  "shop": {
    "name": "ショップ名"
  }
}
```

### テンプレート (html/theme/templates/top.tpl)

```html
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title><{$page.title}></title>
    <meta name="viewport" content="width=device-width,initial-scale=1" />
    <link rel="stylesheet" href="<{$page.css}>" />
  </head>
  <body>
    <{$module.header}>
  </body>
</html>
```

### テンプレートモジュール (html/theme/templates/module/header.tpl)

```html
<h1><{$shop.name}></h1>
```

## License

MIT License

## release

機能修正・追加ごとに以下のコマンドを実行してください。

```shell
npx changeset add
```

それぞれの変更に対して、以下のように変更の種類を選択してください。

- patch
  - バグ修正
- minor
  - 機能追加
- major
  - 破壊的変更
  - 特大リリース

変更の種類を選択すると、CHANGELOG.md に記載される変更内容の入力が求められるので、変更内容を記載してください。
npm package: @naporin0624/react-flow
Description: > TODO: description
Author: naporin0624
Latest version: 1.0.7

# `react-flow`

A library that connects rxjs to React.

Observables registered with the same key are subscribed only once in total.

[![Image from Gyazo](https://i.gyazo.com/0b5f38a4c3e943eff75ebdfc8a6ba16e.gif)](https://gyazo.com/0b5f38a4c3e943eff75ebdfc8a6ba16e)

## Usage

```jsx
import ReactDOM from "react-dom";
import { Subject, scan } from "rxjs";
import { Provider, useFlow } from "@naporin0624/react-flow";

const root = new Subject<number>();
const counter$ = root.pipe(
  scan<number, number>((acc, value) => acc + value, 0)
);
const increment = () => root.next(1);
const decrement = () => root.next(-1);

const Counter = () => {
  const counter = useFlow("counter", counter$) ?? 0;

  return (
    <div>
      <p>counter: {counter}</p>
      <div>
        <button onClick={increment}>+</button>
        <button onClick={decrement}>-</button>
      </div>
    </div>
  );
};

// The counter subscribe is called only once.
const App = () => {
  return (
    <Provider>
      <div>
        <p>counter1</p>
        <Counter />
      </div>
      <div>
        <p>counter2</p>
        <Counter />
      </div>
    </Provider>
  );
};

ReactDOM.render(<App />, document.getElementById("root"));
```

## LICENSE

MIT
npm package: @naporin0624/react-flowder
Description: data loader for react
Author: naporin0624
Latest version: 3.3.0

# `react-flowder`

A library that connects rxjs to React and uses suspense to load data on the first subscribe.

![505d0082dcff533299cb631f616f1cd5](https://user-images.githubusercontent.com/32933709/145654002-6ae8b5ee-ebce-45ab-9af7-3894e4450f10.gif)

## Usage

- [example-page](https://packages-sigma.vercel.app/)
- [blog](https://naporitan.hatenablog.com/entry/2022/03/23/194002)

```jsx
import React, { Suspense } from "react";
import { render } from "react-dom";
import { interval } from "rxjs";
import { datasource, useReadData, Provider } from "@naporin0624/react-flowder";

const timer = datasource(() => interval(1000));

const Timer = () => {
  const time = useReadData(timer());

  return (
    <div>
      <p>time: {time}</p>
    </div>
  );
};

const App = () => (
  <Provider>
    <Suspense fallback={<p>loading</p>}>
      <Timer />
    </Suspense>
  </Provider>
);

export default App;
```

## LICENSE

MIT
npm package: @naporin0624/react-loader
Description: data loader for React
Author: naporin0624
Latest version: 1.0.7

# `react-loader`

Simple data loader hooks that use Suspense.

[![Image from Gyazo](https://i.gyazo.com/4bac571679807edb0a6ef722aa1a08d8.gif)](https://gyazo.com/4bac571679807edb0a6ef722aa1a08d8)

## Usage

```jsx
import { render } from "react-dom";
import { Suspense, useEffect, useState } from "react";
import { Cache, useLoader } from "@naporin0624/react-loader";

import Nprogress from "nprogress";
import "nprogress/nprogress.css";

const timeout = (ms: number) => {
  return new Promise() < number > ((resolve) => setTimeout(() => resolve(ms), ms));
};

const App = () => {
  const [count, setCount] = useState(100);
  const data = useLoader(`timeout_${count}`, () => timeout(count));

  return (
    <div>
      <input type="number" value={count} onChange={(e) => setCount(parseInt(e.target.value, 10))} step={100} min={0} />

      <p>result: {data}</p>
    </div>
  );
};

const Fallback = () => {
  useEffect(() => {
    Nprogress.start();
    return () => {
      Nprogress.done();
    };
  }, []);
  return null;
};

render(
  <Cache>
    <Suspense fallback={<Fallback />}>
      <Cache>
        <App />
      </Cache>
    </Suspense>
  </Cache>,
  document.getElementById("root")
);
```

## LICENSE

MIT
npm package: @naporin0624/simple-store
Description: A simple store using map
Author: naporin0624
Latest version: 0.1.4

# `simple-store`

Simple state management using Set objects.

[![Image from Gyazo](https://i.gyazo.com/8601ece7cc54d0439551cd306e586a0f.gif)](https://gyazo.com/8601ece7cc54d0439551cd306e586a0f)

## Usage

```typescript
import { createStore } from "@naporin0624/simple-store";

const store = createStore<string, number>();
const counter = document.createElement("p");
counter.innerText = `count: ${0}`;

store.subscribe(() => {
  const count = store.get("count") ?? 0;
  counter.innerText = `count: ${count}`;
});

const increment = document.createElement("button");
increment.onclick = () => {
  const count = store.get("count") ?? 0;
  store.set("count", count + 1);
};
increment.innerText = "increment";

const decrement = document.createElement("button");
decrement.onclick = () => {
  const count = store.get("count") ?? 0;
  store.set("count", count - 1);
};
decrement.innerText = "decrement";

const app = document.getElementById("app");
if (!app) throw new Error();

app.innerHTML = `
  <h1>Hello Simple Store</h1>
`;
app.appendChild(counter);
app.appendChild(increment);
app.appendChild(decrement);
```