var lesson = {
	files: [
		{
			name: "main",
			content: "// @ts-nocheck\nimport { render } from \"solid-js/web\";\nimport { For } from \"solid-js\";\n\nimport useRedux from \"./useRedux\";\nimport reduxStore from \"./store\";\nimport actions from \"./actions\";\n\nconst App = () => {\n  const [store, { addTodo, toggleTodo }] = useRedux(\n    reduxStore,\n    actions\n  );\n  let input;\n  return (\n    <>\n      <div>\n        <input ref={input} />\n        <button\n          onClick={(e) => {\n            if (!input.value.trim()) return;\n            addTodo(input.value);\n            input.value = \"\";\n          }}\n        >\n          Add Todo\n        </button>\n      </div>\n      <For each={store.todos}>\n        {(todo) => {\n          const { id, text } = todo;\n          console.log(\"Create\", text)\n          return <div>\n            <input\n              type=\"checkbox\"\n              checked={todo.completed}\n              onchange={[toggleTodo, id]}\n            />\n            <span\n              style={{ \"text-decoration\": todo.completed ? \"line-through\" : \"none\"}}\n            >{text}</span>\n          </div>\n        }}\n      </For>\n    </>\n  );\n};\n\nrender(App, document.getElementById(\"app\"));\n"
		},
		{
			name: "useRedux",
			content: "import { onCleanup } from \"solid-js\";\nimport { createStore, reconcile } from \"solid-js/store\";\n\nexport default function useRedux(store, actions) {\n  const [state, setState] = createStore(store.getState());\n  const unsubscribe = store.subscribe(\n    () => setState(store.getState())\n  );\n  onCleanup(() => unsubscribe());\n  return [\n    state,\n    mapActions(store, actions)\n  ];\n};\n\nfunction mapActions(store, actions) {\n  const mapped = {};\n  for (const key in actions) {\n    mapped[key] = (...args) => store.dispatch(actions[key](...args));\n  }\n  return mapped;\n}\n"
		},
		{
			name: "actions",
			content: "let nextTodoId = 0;\nexport default {\n  addTodo: text => ({ type: \"ADD_TODO\", id: ++nextTodoId, text }),\n  toggleTodo: id => ({ type: \"TOGGLE_TODO\", id })\n};\n"
		},
		{
			name: "store",
			content: "// @ts-nocheck\nimport { createStore } from 'redux';\n\n// todos reducer\nconst todos = (state = { todos: [] }, action) => {\n  switch (action.type) {\n    case \"ADD_TODO\":\n      return { todos: [\n        ...state.todos,\n        {\n          id: action.id,\n          text: action.text,\n          completed: false\n        }\n      ]};\n    case \"TOGGLE_TODO\":\n      return { todos: state.todos.map(todo => \n        todo.id === action.id ? { ...todo, completed: !todo.completed } : todo\n      )};\n    default:\n      return state;\n  }\n};\n\nexport default createStore(todos);\n"
		}
	]
};
var solved = {
	files: [
		{
			name: "main",
			content: "// @ts-nocheck\nimport { render } from \"solid-js/web\";\nimport { For } from \"solid-js\";\n\nimport useRedux from \"./useRedux\";\nimport reduxStore from \"./store\";\nimport actions from \"./actions\";\n\nconst App = () => {\n  const [store, { addTodo, toggleTodo }] = useRedux(\n    reduxStore,\n    actions\n  );\n  let input;\n  return (\n    <>\n      <div>\n        <input ref={input} />\n        <button\n          onClick={(e) => {\n            if (!input.value.trim()) return;\n            addTodo(input.value);\n            input.value = \"\";\n          }}\n        >\n          Add Todo\n        </button>\n      </div>\n      <For each={store.todos}>\n        {(todo) => {\n          const { id, text } = todo;\n          console.log(\"Create\", text)\n          return <div>\n            <input\n              type=\"checkbox\"\n              checked={todo.completed}\n              onchange={[toggleTodo, id]}\n            />\n            <span\n              style={{ \"text-decoration\": todo.completed ? \"line-through\" : \"none\"}}\n            >{text}</span>\n          </div>\n        }}\n      </For>\n    </>\n  );\n};\n\nrender(App, document.getElementById(\"app\"));\n"
		},
		{
			name: "useRedux",
			content: "import { onCleanup } from \"solid-js\";\nimport { createStore, reconcile } from \"solid-js/store\";\n\nexport default function useRedux(store, actions) {\n  const [state, setState] = createStore(store.getState());\n  const unsubscribe = store.subscribe(\n    () => setState(reconcile(store.getState()))\n  );\n  onCleanup(() => unsubscribe());\n  return [\n    state,\n    mapActions(store, actions)\n  ];\n};\n\nfunction mapActions(store, actions) {\n  const mapped = {};\n  for (const key in actions) {\n    mapped[key] = (...args) => store.dispatch(actions[key](...args));\n  }\n  return mapped;\n}\n"
		},
		{
			name: "actions",
			content: "let nextTodoId = 0;\nexport default {\n  addTodo: text => ({ type: \"ADD_TODO\", id: ++nextTodoId, text }),\n  toggleTodo: id => ({ type: \"TOGGLE_TODO\", id })\n};\n"
		},
		{
			name: "store",
			content: "// @ts-nocheck\nimport { createStore } from 'redux';\n\n// todos reducer\nconst todos = (state = { todos: [] }, action) => {\n  switch (action.type) {\n    case \"ADD_TODO\":\n      return { todos: [\n        ...state.todos,\n        {\n          id: action.id,\n          text: action.text,\n          completed: false\n        }\n      ]};\n    case \"TOGGLE_TODO\":\n      return { todos: state.todos.map(todo => \n        todo.id === action.id ? { ...todo, completed: !todo.completed } : todo\n      )};\n    default:\n      return state;\n  }\n};\n\nexport default createStore(todos);\n"
		}
	]
};
var markdown = "ストアは多くの場合、Solid のストアプロキシを使用して Solid で作成されます。時には、Redux、Apollo、XState などのイミュータブルなライブラリとインターフェイスでつなぎ、これらに対して粒度の高い更新を行う必要があります。\n\nこの例では、Redux のシンプルなラッパーを用意しています。その実装は `useRedux.tsx` で見ることができます。ストアの定義とアクションは残りのファイルにあります。\n\n中心となる動作は、Store オブジェクトを作成し、Redux のストアを購読して、更新時に状態を更新するというものです。\n\n```js\nconst [state, setState] = createStore(store.getState());\nconst unsubscribe = store.subscribe(\n  () => setState(store.getState())\n);\n```\nデモをクリックしてアイテムを追加したり、チェックしたりすると、かなりうまくいっているように見えます。しかし、明白でないのは、レンダリングが非効率的であるということです。作成時だけでなく、ボックスをチェックするたびに console.log が表示されていることに注目してください。\n\nその理由は、Solid はデフォルトでは差分を取らないためです。新しいアイテムを新しいものとみなして置き換えてしまうのです。データが細かく変化する場合は、差分を取る必要はありません。しかし、もしやる場合は？\n\nSolid は差分を取るためのメソッド `reconcile` を提供しています。これは `setStore` の呼び出しを強化するもので、イミュータブルなソースからのデータを差分して、細かい更新のみを通知できます。\n\nでは、このコードを次のように更新してみましょう:\n```js\nconst [state, setState] = createStore(store.getState());\nconst unsubscribe = store.subscribe(\n  () => setState(reconcile(store.getState()))\n);\n```\nこれで、この例では、create のコードを作成時にだけ実行するという、期待通りの動作になりました。この問題を解決する唯一の方法ではなく、一部のフレームワークでテンプレートループフローに `key` プロパティがあるのを見たことがあるでしょう。\n\n問題は、それをテンプレートのデフォルト部分にすることにより、コンパイル済みのフレームワークであっても、リストの一致を常に実行する必要があり、潜在的な変更のためにすべての子の差分を常に取る必要があることです。データ中心のアプローチでは、テンプレートの外でもこれを適用できるだけでなく、オプトインもできます。内部の状態管理にはこれが必要ないことを考える場合、デフォルトで最高のパフォーマンスが得られることになります。\n\nもちろん、必要に応じて `reconcile` を使うことは問題ありません。シンプルな reducer がデータの更新を整理するのに最適な方法であることもあります。`reconcile` は、独自の `useReducer` プリミティブを作ることで、ここで威力を発揮します:\n\n```js\nconst useReducer = (reducer, state) => {\n  const [store, setStore] = createStore(state);\n  const dispatch = (action) => {\n    state = reducer(state, action);\n    setStore(reconcile(state));\n  }\n  return [store, dispatch];\n};\n```\n\n`reconcile` の動作は設定可能です。カスタムの `key` を設定ができ、構造的に複製することを無視して葉ノードのみを差分する `merge` オプションもあります。\n";
var stores_immutable = {
	lesson: lesson,
	solved: solved,
	markdown: markdown
};

export { stores_immutable as default, lesson, markdown, solved };
