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 = "Stores werden in Solid meistens durch Solids Store-Proxies erstellt. Manchmal wünschen wir uns eine Schnittstelle zu auf Unveränderlichkeit basierenden Libraries wie Redux, Apollo oder XState und müssen granulare Aktualisierungen gegen diese durchführen.\n\nIn unserem Beispiel haben wir einen einfachen Wrapper um Redux. Die Implementation kann man in `useRedux.tsx` sehen. Die Definition vom Store und den Aktionen sind in den anderen Dateien.\n\nDas wesentliche Verhalten ist, dass wir ein Store-Objekt erzeugt haben und nun den Redux-Store darin einschreiben, um den Zustand bei Aktualisierungen anzugleichen.\n\n```js\nconst [state, setState] = createStore(store.getState());\nconst unsubscribe = store.subscribe(\n  () => setState(store.getState())\n);\n```\nWenn du in der Demo herumklickst, neue Einträge hinzufügst und sie abhakst, scheint es recht gut zu funktionieren. Was allerdings nicht offensichtlich ist, ist, dass das Rendering ineffizient ist. Man beachte die Log-Ausgabe nicht nur beim Hinzufügen, sondern auch jedes Mal, dass die Box geklickt wird.\n\nDer Grund dafür ist, dass Solid die Änderungen nicht standardmäßig selbstständig abgleicht. Es nimmt an, dass der Eintrag neu ist und ersetzt ihn. Wenn sich die Daten granular ändern, muss man nicht abgleichen - aber was, wenn man es doch tun muss?\n\nSolid stellt dafür eine Ableich-Methode `reconcile` bereit, die den `setStore`-Aufruf verbessert und uns ermöglicht, die Daten von unveränderlichen Quellen abzugleichen und nur für die granularen Änderungen benachrichtigt.\n\nÄndern wir unseren Code wie folgt:\n```js\nconst [state, setState] = createStore(store.getState());\nconst unsubscribe = store.subscribe(\n  () => setState(reconcile(store.getState()))\n);\n```\nJetzt funktioniert das Beispiel wie erwartet und erzeugt nur noch Einträge, wenn diese auch erzeugt werden sollen.\n\nDas ist nicht der einzige Weg, dieses Problem zu lösen und Du hast sicher schon gesehen, dass manche Frameworks eine `key`-Eigenschaft in ihren Template-Schleifen-Helfern verwenden. Das Problem ist, indem man dies zu einem standardmäßigen Teil des Templating macht, muss man alle Listen immer abgleichen und immer alle Kind-Elemente auf potentielle Änderungen prüfen, selbst in kompilierten Frameworks. Eine Daten-zentrische Herangehensweise macht das nicht nur außerhalb des Templatings ohne Abgleich nutzbar, sondern auch beliebig einsetzbar. Wenn man bedenkt, dass die interne Zustandsverwaltung dies gar nicht benötigt, bedeutet das, dass wir grundsätzlich auf den performantesten Ansatz setzen.\n\nNatürlich gibt es kein Problem damit, `reconcile` bei Bedarf zu verwenden. Manchmal ist ein einfacher Reducer ein guter Weg, um Datenveränderungen zu organisieren. `reconcile` kann hier glänzen, etwa als Teil einer eigenen `useReducer`-Primitive:\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\nDAs Verhalten von `reconcile` ist konfigurierbar. Ein benutzerdefinierter `key` kann vorgegeben werden und es gibt eine `merge`-Option, die strukturelles Klonen ignoriert und nur die obersten Zweige abgleicht.";
var stores_immutable = {
	lesson: lesson,
	solved: solved,
	markdown: markdown
};

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