{"id":485770,"date":"2026-07-01T08:44:10","date_gmt":"2026-07-01T08:44:10","guid":{"rendered":"https:\/\/savepearlharbor.com\/?p=485770"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=485770","title":{"rendered":"Point0 \u2014 \u0444\u0443\u043b\u0441\u0442\u0435\u043a TypeScript-\u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u043d\u0430 Bun \u0438 React, \u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u044f \u043c\u0435\u0447\u0442\u0430\u043b"},"content":{"rendered":"<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p>\u0425\u043e\u0447\u0443 \u0430\u043d\u043e\u043d\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a Point0. \u042d\u0442\u043e \u043f\u0435\u0440\u0432\u044b\u0439 Bun FullStack \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043c\u044b\u0439 \u043f\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0443 \u0441 Next.js \u0438 TanStack Start. \u041e\u0434\u043d\u0430\u043a\u043e, \u0438\u043c\u0435\u0435\u0442 \u043a\u0430\u0440\u0434\u0438\u043d\u0430\u043b\u044c\u043d\u043e \u0434\u0440\u0443\u0433\u043e\u0439 DX, \u0440\u0430\u0434\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0438 \u0431\u044b\u043b \u0441\u043e\u0437\u0434\u0430\u043d.<\/p>\n<p>\u041c\u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u043b\u0438\u0441\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e Next.js \u0438 Remix (React Router). \u041d\u043e \u044f \u0434\u0443\u043c\u0430\u043b, \u0447\u0442\u043e, \u0432\u0438\u0434\u0438\u043c\u043e, \u043f\u043e-\u0434\u0440\u0443\u0433\u043e\u043c\u0443 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u044e\u0442\u0441\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438 \u043d\u0435 \u0434\u0435\u043b\u0430\u044e\u0442. \u0410 \u0433\u0440\u043e\u043c\u043e\u0437\u0434\u043a\u043e\u0441\u0442\u044c, \u0447\u0443\u0436\u0438\u0435 \u0441\u0442\u0440\u043e\u0433\u0438\u0435 \u0441\u043e\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u044f, \u043d\u0435\u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043b\u0438\u0432\u043e\u0441\u0442\u044c \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b, \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0437\u043b\u043e, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u044f \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043c\u0438\u0440\u0438\u0442\u044c\u0441\u044f.<\/p>\n<p>\u0412 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u043e \u043c\u043d\u0435 \u043d\u0430\u043a\u043e\u043f\u0438\u043b\u043e\u0441\u044c \u043a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043e\u0449\u0443\u0449\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0432\u0441\u0451 \u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043f\u043e-\u0434\u0440\u0443\u0433\u043e\u043c\u0443. \u0418 \u044f \u043f\u043e\u0434\u0443\u043c\u0430\u043b, \u0430 \u043d\u0430\u043f\u0438\u0448\u0443-\u043a\u0430 \u044f \u043f\u0441\u0435\u0432\u0434\u043e\u043a\u043e\u0434 \u043d\u0430 \u0432\u043e\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u043e\u043c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u044b \u043c\u0435\u043d\u044f \u0443\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u043b, \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0432\u0437\u0438\u0440\u0430\u044f \u043d\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u041f\u0440\u043e\u0441\u0442\u043e \u0431\u0443\u0434\u0443 \u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442, \u0431\u0443\u0434\u0442\u043e \u0431\u044b \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.<\/p>\n<p>\u0418 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0442\u0430\u043a \u0437\u0434\u043e\u0440\u043e\u0432\u043e, \u0447\u0442\u043e \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u0431\u044b\u043b \u043e\u0431\u043e \u0432\u0441\u0451\u043c \u043d\u0430 \u0441\u0432\u0435\u0442\u0435 \u0438 10 \u043c\u0435\u0441\u044f\u0446\u0435\u0432 \u043f\u0438\u043b\u0438\u043b \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u044d\u0442\u043e\u0433\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430, \u0430 3 \u043c\u0435\u0441\u044f\u0446\u0430 \u043d\u0430\u0437\u0430\u0434 \u0434\u0430\u0436\u0435 \u0443\u0432\u043e\u043b\u0438\u043b\u0441\u044f \u0441 \u0440\u0430\u0431\u043e\u0442\u044b, \u0447\u0442\u043e\u0431\u044b \u0443\u0436\u0435 \u0441\u043a\u043e\u0440\u0435\u0435 \u0435\u0433\u043e \u0434\u043e\u0431\u0438\u0442\u044c. \u0418 \u0432\u043e\u0442 \u0434\u043e\u0431\u0438\u043b, \u0438 \u0445\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0432\u0430\u043c\u0438.<\/p>\n<h2>\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0421\u0442\u0430\u0442\u044c\u044f \u0434\u043b\u0438\u043d\u043d\u0430\u044f, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 Point0, \u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0430\u043c\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435 \u0438 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u043a\u043e\u0434\u0430. \u0411\u043e\u043b\u0435\u0435 \u0433\u043b\u0443\u0431\u043e\u043a\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0436\u0438\u0432\u0451\u0442 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u0445 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438. \u0422\u0430\u043a\u0436\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432\u0438\u0434\u0435\u043e \u043e\u0431\u0437\u043e\u0440 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u043d\u0430 YouTube <a href=\"https:\/\/www.youtube.com\/watch?v=lhZ6eWMXMdg\" rel=\"noopener noreferrer nofollow\">https:\/\/www.youtube.com\/watch?v=lhZ6eWMXMdg<\/a> \u0438 \u0432 \u0412\u041a \u0432\u0438\u0434\u0435\u043e <a href=\"https:\/\/vkvideo.ru\/video-227165132_456239210\" rel=\"noopener noreferrer nofollow\">https:\/\/vkvideo.ru\/video-227165132_456239210<\/a><\/p>\n<p>\u0414\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0430 \u201cRoot\u201d \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u0432\u0441\u0451, \u044d\u0442\u043e \u0441\u0430\u043c\u043e\u0435 \u0432\u0430\u0436\u043d\u043e\u0435, \u0438 \u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0437\u0430 5 \u043c\u0438\u043d\u0443\u0442. \u0414\u0430\u043b\u0435\u0435, \u0435\u0441\u043b\u0438 \u0443\u0442\u043e\u043c\u0438\u0442\u0435\u0441\u044c, \u043b\u0438\u0441\u0442\u0430\u0439\u0442\u0435, \u043f\u043e\u0433\u043b\u044f\u0434\u044b\u0432\u0430\u044f \u043d\u0430 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438 \u0438 \u0437\u0430\u0446\u0435\u043f\u0438\u0432\u0448\u0438\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043a\u0443\u0441\u043a\u0438 \u043a\u043e\u0434\u0430. \u041f\u0440\u043e\u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u201cEngine\u201d \u0438 \u201cCLI\u201d. \u041b\u0438\u0441\u0442\u0430\u0439\u0442\u0435 \u0434\u0430\u043b\u044c\u0448\u0435 \u0434\u043e \u201cDeploy\u201d, \u0438 \u0434\u043e\u0447\u0438\u0442\u044b\u0432\u0430\u0439\u0442\u0435 \u0434\u043e \u043a\u043e\u043d\u0446\u0430.<\/p>\n<p>\u0410 \u0435\u0441\u043b\u0438 \u043e\u0441\u0438\u043b\u0438\u0442\u0435 \u0432\u0441\u044e \u0441\u0442\u0430\u0442\u044c\u044e \u0446\u0435\u043b\u0438\u043a\u043e\u043c, \u0431\u0443\u0434\u0435\u0442\u0435 \u043e\u0431\u043b\u0430\u0434\u0430\u0442\u044c \u0432\u0441\u0435\u043c\u0438 \u043d\u0443\u0436\u043d\u044b\u043c\u0438 \u0437\u043d\u0430\u043d\u0438\u044f\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u0445\u043e\u0442\u044c \u0441\u0435\u0439\u0447\u0430\u0441 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u043d\u0430 Point0.<\/p>\n<h2>\u0421\u043f\u0440\u0430\u0432\u043a\u0430<\/h2>\n<ul>\n<li>\n<p>\u0413\u0438\u0442\u0445\u0430\u0431: <a href=\"https:\/\/github.com\/1gr14\/point0\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/1gr14\/point0<\/a><\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f: <a href=\"https:\/\/1gr14.dev\/point0\" rel=\"noopener noreferrer nofollow\">https:\/\/1gr14.dev\/point0<\/a><\/p>\n<\/li>\n<li>\n<p>\u0412\u0438\u0434\u0435\u043e-\u043e\u0431\u0437\u043e\u0440 \u043d\u0430 YouTube: <a href=\"https:\/\/www.youtube.com\/watch?v=lhZ6eWMXMdg\" rel=\"noopener noreferrer nofollow\">https:\/\/www.youtube.com\/watch?v=lhZ6eWMXMdg<\/a><\/p>\n<\/li>\n<li>\n<p>\u0412\u0438\u0434\u0435\u043e-\u043e\u0431\u0437\u043e\u0440 \u043d\u0430 \u0412\u041a \u0432\u0438\u0434\u0435\u043e: <a href=\"https:\/\/vkvideo.ru\/video-227165132_456239210\" rel=\"noopener noreferrer nofollow\">https:\/\/vkvideo.ru\/video-227165132_456239210<\/a><\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0443\u0441\u0442\u043e\u0439 \u043f\u0440\u043e\u0435\u043a\u0442: <code>bun create point0-app<\/code><\/p>\n<\/li>\n<li>\n<p>\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u043f\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0443 llmstxt.org: <a href=\"https:\/\/1gr14.dev\/llms.txt\" rel=\"noopener noreferrer nofollow\">https:\/\/1gr14.dev\/llms.txt<\/a> \u0441\u043a\u043e\u0440\u043c\u0438\u0442\u0435 \u0435\u0451 \u0430\u0433\u0435\u043d\u0442\u0443, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u0442\u0432\u0435\u0442\u044b \u043d\u0430 \u043b\u044e\u0431\u044b\u0435 \u0432\u043e\u043f\u0440\u043e\u0441\u044b \u043f\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0443<\/p>\n<\/li>\n<li>\n<p>\u041f\u0430\u043f\u043a\u0430 \u0441 \u0442\u0435\u0441\u0442\u0430\u043c\u0438, \u0433\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0432\u0441\u0435\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u043a\u0435\u0439\u0441\u043e\u0432 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430: <a href=\"https:\/\/github.com\/1gr14\/point0\/tree\/main\/packages\/engine\/tests\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/1gr14\/point0\/tree\/main\/packages\/engine\/tests<\/a> \u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 <a href=\"https:\/\/github.com\/1gr14\/point0\/tree\/main\/packages\/engine\/tests\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/1gr14\/point0\/tree\/main\/packages\/engine\/tests<\/a><\/p>\n<\/li>\n<\/ul>\n<p>\u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043d\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434, \u044f \u043f\u0438\u0441\u0430\u043b \u0435\u0451 \u0440\u0443\u043a\u0430\u043c\u0438 \u043d\u0435\u0434\u0435\u043b\u044e. \u041d\u0430 \u0441\u0430\u0439\u0442\u0435 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0442\u0430\u0436\u0435 \u0441\u0442\u0430\u0442\u044c\u044f \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c, \u0432\u043e\u0442 \u043e\u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u043d\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0432\u043e\u0434. \u042d\u0442\u043e \u0441\u0442\u0430\u0442\u044c\u044f \u043d\u0435 \u201c\u043f\u0438\u0430\u0440\u201d, \u044d\u0442\u043e \u0430\u043d\u043e\u043d\u0441 \u043e\u043f\u0435\u043d\u0441\u043e\u0440\u0441 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441 MIT \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u043d\u0435\u0435 \u043d\u0438\u0433\u0434\u0435 \u043d\u0435 \u0431\u044b\u043b \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d, \u0442\u043e \u0435\u0441\u0442\u044c \u044d\u0442\u043e \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u0445\u0430\u0431\u0440\u0430.<\/p>\n<h2>Page<\/h2>\n<p>\u0427\u0442\u043e \u044f \u0445\u043e\u0442\u0435\u043b \u043e\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b:<\/p>\n<ul>\n<li>\n<p>\u041e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u043f\u0443\u0442\u044c \u043a \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435<\/p>\n<\/li>\n<li>\n<p>\u041e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u043a\u0430\u043a\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u043d\u0430 \u0433\u0440\u0443\u0437\u0438\u0442<\/p>\n<\/li>\n<li>\n<p>\u0427\u0442\u043e\u0431\u044b \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043b\u043e\u0430\u0434\u0438\u043d\u0433\u0430 \u0438 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u043e\u0448\u0438\u0431\u043a\u0438 \u043e\u0442\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b\u043e \u0441\u0430\u043c\u043e \u043f\u043e \u0441\u0435\u0431\u0435 \u0438 \u0431\u044b\u043b\u043e \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u0443\u0435\u043c\u044b\u043c<\/p>\n<\/li>\n<li>\n<p>\u0427\u0442\u043e\u0431\u044b \u0445\u043e\u0442\u044c \u0441 SSR, \u0445\u043e\u0442\u044c \u0431\u0435\u0437 SSR, \u043e\u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0430, \u0438 \u044f \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u043b \u043e\u0431 \u044d\u0442\u043e\u043c \u0434\u0443\u043c\u0430\u0442\u044c<\/p>\n<\/li>\n<li>\n<p>\u0427\u0442\u043e\u0431\u044b \u044f \u043c\u043e\u0433 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0432 \u043b\u044e\u0431\u044b\u0445 \u0444\u0430\u0439\u043b\u0430\u0445, \u0432 \u043b\u044e\u0431\u044b\u0445 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430\u0445 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430, \u0432 \u043b\u044e\u0431\u044b\u0445 \u043f\u0430\u043f\u043a\u0430\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0438 \u0447\u0442\u043e\u0431\u044b \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u043d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u0433\u0434\u0435 \u044f \u0434\u043e\u043b\u0436\u0435\u043d \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0438 \u043a\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u0444\u0430\u0439\u043b\u044b \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435<\/p>\n<\/li>\n<\/ul>\n<pre><code>import { root } from '@\/lib\/root'export const ideaPage = root  .lets('page', 'idea', '\/ideas\/:id')  .loader(({ params }) =&gt; {    \/\/ params \u0442\u0443\u0442 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 \u0441\u0442\u0440\u043e\u043a\u0435 \u0440\u043e\u0443\u0442\u0430 \u043c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 :id, \u0438 \u0442\u0430\u0439\u043f\u0441\u043a\u0440\u0438\u043f\u0442 \u0443\u043c\u0435\u0435\u0442 \u0442\u0430\u043a\u043e\u0435 \u043f\u0430\u0440\u0441\u0438\u0442\u044c    const idea = await prisma.idea.findUniqueOrThrow({      where: { id: params.id },    })    return { idea }  })  .head(({ data: { idea } }) =&gt; ({    \/\/ \u0442\u0443\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u0430\u043c\u0438 \u043f\u043e \u0441\u0435\u0431\u0435, \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u044b \u0432\u0435\u0440\u043d\u0443\u043b\u0438 \u0438\u0445 \u0438\u0437 \u043b\u043e\u0430\u0434\u0435\u0440\u0430    title: idea.title,    description: idea.content.slice(0, 100),  }))  .page(({ data: { idea } }) =&gt; (    \/\/ \u0442\u0443\u0442 \u0442\u043e\u0436\u0435 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435, \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e    &lt;div&gt;      &lt;h1&gt;{idea.title}&lt;\/h1&gt;      &lt;div&gt;{idea.content}&lt;\/div&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:87px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u043e\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043a\u0430. \u041a\u0430\u043a\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0442\u0443\u0442 \u044f \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0442\u044c \u0434\u0438\u0437\u0430\u0439\u043d \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u0434\u0430\u043b\u044c\u0448\u0435:<\/p>\n<ul>\n<li>\n<p>\u0412\u0441\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0431\u0443\u0434\u0435\u043c \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0438\u043d\u0442\u0430\u043c\u0438. \u0412\u043e\u0442 \u0442\u0443\u0442 \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435 \u043f\u043e\u0438\u043d\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043a\u0438, \u0430 \u043f\u043e\u0442\u043e\u043c \u044f \u0432\u0430\u043c \u043f\u043e\u043a\u0430\u0436\u0443 \u043a\u0432\u0435\u0440\u0438, \u043c\u0443\u0442\u0430\u0446\u0438\u0438, \u043b\u044d\u0439\u043e\u0443\u0442\u044b, \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u044b, \u0438 \u043f\u0440\u043e\u0447\u0435\u0435.<\/p>\n<\/li>\n<li>\n<p>\u0410\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044f \u043f\u043e\u0438\u043d\u0442 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043c\u043e\u0447\u044c \u043f\u043e\u043d\u044f\u0442\u044c \u0432\u0441\u0451 \u0447\u0442\u043e \u043d\u0430 \u043d\u0435\u0433\u043e \u0432\u043b\u0438\u044f\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u043a\u043e\u0434 \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u043e\u0438\u043d\u0442\u0430, \u043d\u0435 \u0434\u0435\u0440\u0436\u0430 \u0432 \u0433\u043e\u043b\u043e\u0432\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u0430\u043a\u0438\u0445-\u0442\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u0432 \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u0444\u0430\u0439\u043b\u0430\u0445, \u0438\u043b\u0438 \u0434\u0430\u0436\u0435 \u0434\u0440\u0443\u0433\u0438\u0445 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u0432 \u044d\u0442\u043e\u043c \u0436\u0435 \u0444\u0430\u0439\u043b\u0435. \u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u043c, \u0447\u0442\u043e \u0432\u0441\u0451 \u0447\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u044d\u0442\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u043f\u0440\u044f\u043c\u043e \u0432 \u043a\u043e\u0434\u0435 \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u043e\u0438\u043d\u0442\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0447\u0442\u043e \u043d\u0430 \u043d\u0435\u0451 \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0435\u043a\u0438\u0439 <code>root<\/code>, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043e\u043d\u0430 \u0440\u0430\u0441\u0442\u0451\u0442. <code>root<\/code> \u044d\u0442\u043e \u0442\u043e\u0436\u0435 \u043f\u043e\u0438\u043d\u0442, \u043f\u0440\u043e \u043d\u0438\u0445 \u0442\u043e\u0436\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u0447\u0443\u0442\u044c \u0434\u0430\u043b\u044c\u0448\u0435.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0438\u043d\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u0430\u043a\u0438\u0445-\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0432\u044b \u043d\u0435 \u0432\u0438\u0434\u0438\u0442\u0435 \u043a\u0430\u043a\u0443\u044e \u0432\u0451\u0440\u0441\u0442\u043a\u0443 \u0438\u043c\u0435\u044e\u0442 \u043c\u043e\u0438 \u043b\u043e\u0430\u0434\u0438\u043d\u0433 \u0438 \u044d\u0440\u0440\u043e\u0440 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u043d\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u0432 <code>root<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u0432\u0430\u043c \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b. \u0418 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u044d\u0442\u043e \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u043e \u0441\u0443\u0442\u0438 \u043c\u043d\u0435 \u0432\u0435\u0437\u0434\u0435 \u043d\u0430\u0434\u043e \u0438\u043c\u0435\u0442\u044c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0432\u0438\u0434 \u043b\u043e\u0430\u0434\u0438\u043d\u0433\u0430 \u0438 \u043e\u0448\u0438\u0431\u043a\u0438, \u0438 \u044f \u043d\u0435 \u0445\u043e\u0447\u0443 \u044d\u0442\u043e \u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043f\u043e\u0438\u043d\u0442\u0435 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b. \u0412 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u044f \u043c\u043e\u0433\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0445 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0445\u043e\u0442\u044c \u0434\u043b\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0445\u043e\u0442\u044c \u0434\u043b\u044f \u0433\u0440\u0443\u043f\u043f\u044b \u0441\u0442\u0440\u0430\u043d\u0438\u0446, \u0441\u043e\u0437\u0434\u0430\u0432 \u0438\u043c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u043f\u043e\u0438\u043d\u0442\u0430, \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f <code>base<\/code> \u043f\u043e\u0438\u043d\u0442, \u043d\u043e \u044d\u0442\u043e \u0442\u043e\u0436\u0435 \u043f\u043e\u0437\u0436\u0435.<\/p>\n<\/li>\n<li>\n<p>\u041b\u044e\u0431\u043e\u0439 \u043f\u043e\u0438\u043d\u0442 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 <code>.lets<\/code>, \u0447\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u201c\u0410 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443\/\u043a\u0432\u0435\u0440\u0438\/\u043c\u0443\u0442\u0430\u0446\u0438\u044e\/\u2026 \u0441 \u0438\u043c\u0435\u043d\u0435\u043c \u0442\u0430\u043a\u0438\u043c-\u0442\u043e\u201d, \u0434\u0430\u043b\u0435\u0435 \u0432 \u0438\u0434\u0435\u0430\u043b\u0435 \u0431\u044b \u043d\u0435 \u0438\u043c\u0435\u0442\u044c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u043d\u043e \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0432\u0441\u0451 \u0436\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0448\u0442\u0443\u043a\u0438, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u044d\u0442\u043e \u0435\u0451 \u043f\u0443\u0442\u044c, \u0447\u0442\u043e \u0432 \u0446\u0435\u043b\u043e\u043c \u043b\u043e\u0433\u0438\u0447\u043d\u043e<\/p>\n<\/li>\n<li>\n<p>\u041b\u044e\u0431\u043e\u0439 \u043f\u043e\u0438\u043d\u0442 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u043c, \u0447\u0442\u043e \u043c\u044b \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0438\u043b\u0438 \u0432 <code>.lets<\/code>. \u0421\u043a\u0430\u0437\u0430\u043b\u0438 <code>.lets('page', ...)<\/code>, \u0437\u043d\u0430\u0447\u0438\u0442 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0431\u0438\u043b\u0434\u0435\u0440\u0430 \u0431\u0443\u0434\u0435\u0442 <code>.page(...)<\/code>. \u0421\u043a\u0430\u0437\u0430\u043b\u0438 <code>.lets('query', ...)<\/code>, \u0437\u043d\u0430\u0447\u0438\u0442 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0431\u0443\u0434\u0435\u0442 <code>.query(...)<\/code>. \u0415\u0441\u0442\u044c \u0432 \u044d\u0442\u043e\u043c \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u043f\u043e\u044d\u0437\u0438\u044f, \u0440\u0435\u0444\u0440\u0435\u043d \u0442\u0430\u043a \u0441\u043a\u0430\u0437\u0430\u0442\u044c.<\/p>\n<\/li>\n<li>\n<p>\u041c\u044b \u043d\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0442\u0438\u043f\u044b, \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432, \u0432\u0441\u0451 \u0441\u0438\u0434\u0438\u0442 \u043d\u0430 \u0433\u0435\u043d\u0435\u0440\u0438\u043a\u0430\u0445 \u0441\u0430\u043c\u043e\u0433\u043e \u0431\u0438\u043b\u0434\u0435\u0440\u0430 \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u0430\u043c\u043e \u043f\u043e \u0441\u0435\u0431\u0435, \u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0438\u043f\u044b \u0441\u0430\u043c\u0438\u043c \u043d\u0435 \u043d\u0430\u0434\u043e<\/p>\n<\/li>\n<li>\n<p>\u0421\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u043a\u043e\u0434 \u0434\u043e\u043b\u0436\u043d\u044b \u043c\u043e\u0447\u044c \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e \u0441\u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0432 \u043e\u0434\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435, \u0432 \u043e\u0434\u043d\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043f\u043e\u0438\u043d\u0442\u0430, \u0438 \u044f \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u0431 \u044d\u0442\u043e\u043c \u043f\u0430\u0440\u0438\u0442\u044c\u0441\u044f. \u041e\u0431 \u044d\u0442\u043e\u043c \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0430\u0440\u0438\u0442\u044c\u0441\u044f \u0441\u0430\u043c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a, \u043a\u043e\u0434\u0441\u043f\u043b\u0438\u0442\u0438\u043d\u0433 \u0438\u043b\u0438 \u0447\u0442\u043e \u0442\u0430\u043c, \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0445\u043e\u0447\u0443 \u0431\u044b\u0442\u044c \u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0448\u0435\u043d, \u0447\u0442\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u0434 \u043d\u0435 \u043f\u043e\u043f\u0430\u0434\u0451\u0442 \u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439. \u0412 \u0438\u0442\u043e\u0433\u0435 \u044d\u0442\u0438\u043c \u0443 \u043d\u0430\u0441 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440, \u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043f\u043e\u0437\u0436\u0435<\/p>\n<\/li>\n<\/ul>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/page\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b<\/a>.<\/p>\n<h2>Mutation<\/h2>\n<p>\u0427\u0442\u043e \u044f \u0445\u043e\u0442\u0435\u043b \u043e\u0442 \u043c\u0443\u0442\u0430\u0446\u0438\u0438:<\/p>\n<ul>\n<li>\n<p>\u0427\u0442\u043e\u0431\u044b \u044f \u0435\u0451 \u043c\u043e\u0433 \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0432 \u0444\u0430\u0439\u043b\u0435 \u0433\u0434\u0435 \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f, \u0435\u0441\u043b\u0438 \u0437\u0430\u0445\u043e\u0447\u0443, \u0438 \u043e\u043d\u0430 \u0431\u044b \u043d\u0435 \u043b\u043e\u043c\u0430\u043b\u0430 HMR<\/p>\n<\/li>\n<li>\n<p>\u0427\u0442\u043e\u0431\u044b \u044f \u043c\u043e\u0433 \u0435\u0451 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0449\u0430\u044f\u0441\u044c \u043a \u043d\u0435\u0439 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u0430 \u043d\u0435 \u0447\u0435\u0440\u0435\u0437 \u0438\u043d\u0434\u0435\u043a\u0441 \u0444\u0430\u0439\u043b \u043a\u0430\u043a \u0432 tRPC, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 tRPC \u043a\u043e\u0433\u0434\u0430 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u0432 \u043c\u043d\u043e\u0433\u043e \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u043a\u043e\u0434\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0442\u043e\u0440\u043c\u043e\u0437\u0438\u0442\u044c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0438 \u043a \u0434\u0430\u0436\u0435 \u043e\u0434\u043d\u043e\u043c\u0443 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u0443 \u0442\u044f\u043d\u0443\u0442\u0441\u044f \u0442\u0438\u043f\u044b \u0432\u0441\u0435\u0445 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u0432<\/p>\n<\/li>\n<li>\n<p>\u0427\u0442\u043e\u0431\u044b \u0441\u0445\u0435\u043c\u0443 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u043b\u044e\u0431\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443. \u041c\u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e zod. \u041d\u043e \u043c\u044b \u0436\u0435 \u0434\u0435\u043b\u0430\u0435\u043c \u0441\u0430\u043c\u044b\u0439 \u043b\u0443\u0447\u0448\u0438\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a, \u0437\u043d\u0430\u0447\u0438\u0442 \u043d\u0443\u0436\u043d\u043e \u0432\u0441\u0435\u043c \u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u043b\u044e\u0434\u044f\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u044e\u0431\u0443\u044e \u0441\u0445\u0435\u043c\u0443 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438<\/p>\n<\/li>\n<li>\n<p>\u0427\u0442\u043e\u0431\u044b \u0441\u0445\u0435\u043c\u0430 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043c\u043e\u0433\u043b\u0430 \u0431\u044b\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0430 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0447\u0435\u0439\u043d\u0438\u043d\u0433\u0430 \u043f\u043e\u0438\u043d\u0442\u043e\u0432. \u0422\u043e \u0435\u0441\u0442\u044c \u0447\u0430\u0441\u0442\u044c \u0441\u0445\u0435\u043c\u044b \u0434\u043e\u043b\u0436\u043d\u0430 \u043c\u043e\u0447\u044c \u0431\u044b\u0442\u044c \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0430 \u0432 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u043c \u043f\u043e\u0438\u043d\u0442\u0435<\/p>\n<\/li>\n<li>\n<p>\u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0431\u044b\u043b\u0430 \u043e\u0431\u044b\u0447\u043d\u0430\u044f react-query \u043c\u0443\u0442\u0430\u0446\u0438\u044f \u043f\u043e \u0441\u0432\u043e\u0435\u0439 \u0441\u0443\u0442\u0438<\/p>\n<\/li>\n<\/ul>\n<pre><code>import { root } from '@\/lib\/root'import { z } from 'zod'\/\/ \u0424\u043e\u0440\u043c\u0430 \u2014 \u043d\u0435 \u0447\u0430\u0441\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430. \u041f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c,\/\/ \u0447\u0442\u043e \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0444\u043e\u0440\u043c \u0432 \u0432\u0430\u0448\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435import { Form, Input, Textarea, Button } from '@\/lib\/form'\/\/ \u0410 \u0432\u043e\u0442 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044f \u044d\u0442\u043e \u0447\u0430\u0441\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430, \u043d\u043e \u043e\u0431 \u044d\u0442\u043e\u043c \u043f\u043e\u0437\u0436\u0435import { navigate } from '@\/lib\/navigation'export const ideaUpdateMutation = root  .lets('mutation', 'ideaUpdate')  .input(    z.object({      id: z.string().min(1),      title: z.string().min(1),      content: z.string().min(1),    }), \/\/ \u0442\u0443\u0442 \u043c\u043e\u0433 \u0431\u044b \u0431\u044b\u0442\u044c \u0438 \u043d\u0435 zod, \u0430 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 TypeBox  )  .loader(async ({ input: { id, title, content } }) =&gt; {    const idea = await prisma.idea.update({      where: { id },      data: { title, content },    })    return { idea }  })  .mutation() \/\/ \u043c\u043e\u0436\u043d\u043e \u0442\u0443\u0442 \u043f\u0440\u043e\u043a\u0438\u043d\u0443\u0442\u044c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438,\/\/ \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0439\u0434\u0443\u0442 \u0432 useMutation\/fetchMutation \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e react-queryexport const ideaEditPage = root  .lets('page', 'ideaEdit', '\/ideas\/:id\/edit')  .loader(({ params }) =&gt; {    const idea = await prisma.idea.findUniqueOrThrow({      where: { id: params.id },    })    return { idea }  })  .head(({ data: { idea } }) =&gt; `Edit: ${idea.title}`)  .page(({ data: { idea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0434\u0435\u0438: {idea.title}&lt;\/h1&gt;      &lt;Form        defaultValues={{          title: idea.title,          content: idea.content,        }}        onSubmit={({ title, content }) =&gt; {          await ideaUpdateMutation.fetchMutation({            id: idea.id,            title,            content,          }) \/\/ \u0430 \u0442\u0443\u0442 \u0432\u0442\u043e\u0440\u044b\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c          \/\/  \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u043a\u0438\u043d\u0443\u0442\u044c \u043b\u044e\u0431\u044b\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0441\u043c\u0435\u0440\u0436\u0435\u043d\u044b \u0441 \u0440\u0430\u043d\u0435\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u0432 \u0441\u0430\u043c\u043e\u0439 \u043c\u0443\u0442\u0430\u0446\u0438\u0438          await navigate('idea', { id })        }}      &gt;        &lt;Input label=\"\u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a\" name=\"title\" \/&gt;        &lt;Textarea label=\"\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\" name=\"content\" \/&gt;        &lt;Button&gt;\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c&lt;\/Button&gt;      &lt;\/Form&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u043e\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u043c\u0443\u0442\u0430\u0446\u0438\u044f. \u042f \u043c\u043e\u0433\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0451 \u0445\u043e\u0442\u044c \u0432 \u044d\u0442\u043e\u043c \u0444\u0430\u0439\u043b\u0435, \u0445\u043e\u0442\u044c \u0432 \u0434\u0440\u0443\u0433\u043e\u043c, \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u044f \u0441\u0430\u043c\u0443 \u043c\u0443\u0442\u0430\u0446\u0438\u044e. \u0422\u0438\u043f\u044b \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0436\u0435\u043d\u044b, \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u043a\u043e\u0434\u0430 \u043d\u0435 \u0442\u043e\u0440\u043c\u043e\u0437\u0438\u0442, \u043e\u0449\u0443\u0449\u0430\u0435\u0442\u0441\u044f \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e. \u0412\u043e\u0442 \u044f \u043e\u0431\u044a\u044f\u0432\u0438\u043b \u043c\u0443\u0442\u0430\u0446\u0438\u044e, \u0432\u043e\u0442 \u044f \u0435\u0451 \u0432\u044b\u0437\u0432\u0430\u043b. \u041a\u0440\u0443\u0442\u043e!<\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043c\u0443\u0442\u0430\u0446\u0438\u0438, \u0432 \u043d\u0435\u0439 \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043c\u0443\u0442\u0430\u0446\u0438\u0438 react-query:<\/p>\n<pre><code>myMutation.getMutationKey(input, ...)myMutation.getMutationOptions()myMutation.getMutationCache()myMutation.getMutationsCache()myMutation.useMutation()myMutation.fetchMutation()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u0435, \u0447\u0442\u043e \u043f\u0435\u0440\u0432\u044b\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0438\u043d\u043f\u0443\u0442, \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 <code>mutationKey<\/code>, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0442\u0435\u043b\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u0430\u043c\u043e\u0439 \u043c\u0443\u0442\u0430\u0446\u0438\u0438<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/mutation\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u043c\u0443\u0442\u0430\u0446\u0438\u0438<\/a>.<\/p>\n<h2>Query<\/h2>\n<p>\u0412 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043a\u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044f \u043e\u0431\u0440\u0430\u0442\u0438\u043b \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0440\u043e\u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d \u043a\u043e\u0434 \u043b\u043e\u0430\u0434\u0435\u0440\u0430 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0434\u0435\u0438. \u0418 \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u0441\u0430\u043c \u043a\u043e\u0434 \u043b\u043e\u0430\u0434\u0435\u0440\u0430 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438 \u0435\u0451 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u041d\u043e \u044d\u0442\u043e \u043d\u0435 \u0442\u043e. \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u044f \u043f\u0440\u0438\u0448\u0451\u043b \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043b\u043e\u0430\u0434\u0435\u0440 \u043f\u043e \u0444\u0430\u043a\u0442\u0443 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e react-query \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0431\u044b\u043b\u043e \u0431\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e \u043e\u0434\u043d\u0430 \u043a\u0432\u0435\u0440\u0438, \u0441 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u043c \u043a\u0435\u0448\u0435\u043c, \u0447\u0442\u043e\u0431\u044b \u043b\u0438\u0448\u043d\u0438\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043d\u0435 \u0443\u0445\u043e\u0434\u0438\u043b\u0438 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440. \u0411\u044b\u0432\u0430\u044e\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0433\u0434\u0435 \u043b\u043e\u0430\u0434\u0435\u0440 \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u043e\u0434\u0438\u043d \u043d\u0430 \u0432\u0435\u0441\u044c \u043f\u0440\u043e\u0435\u043a\u0442, \u0442\u043e\u0433\u0434\u0430 \u0443\u0434\u043e\u0431\u043d\u043e \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u043b\u043e\u0430\u0434\u0435\u0440 \u043f\u0440\u044f\u043c\u043e \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435. \u0410 \u0435\u0441\u043b\u0438 \u043b\u043e\u0430\u0434\u0435\u0440 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f, \u0442\u043e\u0433\u0434\u0430 \u0440\u0435\u0437\u043e\u043d\u043d\u043e \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u0435\u0433\u043e \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u043a\u0432\u0435\u0440\u0438 \u0438 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0441\u0430\u043c\u0438\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u0445 \u0443\u0436\u0435 \u044d\u0442\u0443 \u043a\u0432\u0435\u0440\u0438.<\/p>\n<pre><code>import { root } from '@\/lib\/root'export const ideaViewQuery = root  .lets('query', 'ideaView')  .input(    z.object({      id: z.string().min(1),    }),  )  .loader(async ({ input: { id } }) =&gt; {    const idea = await prisma.idea.findUniqueOrThrow({      where: { id },    })    return { idea }  })  .query() \/\/ \u043c\u043e\u0436\u043d\u043e \u0442\u0443\u0442 \u043f\u0440\u043e\u043a\u0438\u043d\u0443\u0442\u044c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438,\/\/ \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0439\u0434\u0443\u0442 \u0432 useQuery\/fetchQuery \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e react-queryexport const ideaPage = root  .lets('page', 'idea', '\/ideas\/:id')  \/\/ \u0432\u043e\u0442 \u0442\u0443\u0442 \u043c\u044b \u0438\u043d\u0436\u0435\u043a\u0442\u0438\u043c \u044d\u0442\u0443 \u043a\u0432\u0435\u0440\u0438 \u0432 \u0441\u0430\u043c\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443  \/\/ \u0438 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c \u043a\u0430\u043a \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u0438\u0437 \u0440\u043e\u0443\u0442\u0430 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043c\u0430\u043f\u043b\u0435\u043d\u044b \u043d\u0430 \u0438\u043d\u043f\u0443\u0442 \u0441\u0430\u043c\u043e\u0439 \u043a\u0432\u0435\u0440\u0438  .with(ideaViewQuery, ({ params }) =&gt; ({ id: params.id }))  \/\/ \u0434\u0430\u043b\u044c\u0448\u0435 \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439, \u0438 \u0442\u0438\u043f\u044b \u0432\u0441\u0435 \u043d\u0430 \u043c\u0435\u0441\u0442\u0435, \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u0432\u044b\u0437\u0432\u0430\u0442\u0438\u043b\u0438 \u0438\u0445  \/\/ \u0438\u0437 \u0441\u0430\u043c\u043e\u0433\u043e \u0442\u0438\u043f\u0430 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0445 \u043a\u0432\u0435\u0440\u0438 \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0432\u044b\u0445\u0432\u0430\u0442\u0438\u043b\u0438 \u0438\u0437 \u0435\u0451 \u043b\u043e\u0430\u0434\u0435\u0440\u0430  .head(({ data: { idea } }) =&gt; ({    title: idea.title,    description: idea.content.slice(0, 100),  }))  .page(({ data: { idea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{idea.title}&lt;\/h1&gt;      &lt;div&gt;{idea.content}&lt;\/div&gt;    &lt;\/div&gt;  ))export const ideaEditPage = root  .lets('page', 'ideaEdit', '\/ideas\/:id\/edit')  \/\/ \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0438\u043d\u0436\u0435\u043a\u0442\u0438\u043c \u044d\u0442\u0443 \u0436\u0435 \u043a\u0432\u0435\u0440\u0438 \u0432 \u0434\u0440\u0443\u0433\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443  \/\/ \u043d\u0430 \u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0442\u0430\u043a\u0436\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c, \u0442\u0430\u043a \u043a\u0430\u043a \u0443 \u043d\u0430\u0441 \u0442\u0438\u043f  \/\/ params \u0432 \u0441\u0430\u043c\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u0441 \u0442\u0438\u043f\u043e\u043c \u0438\u043d\u043f\u0443\u0442\u0430 \u043a\u0432\u0435\u0440\u0438  .with(ideaViewQuery, ({ params }) =&gt; params)  .head(({ data: { idea } }) =&gt; `Edit: ${idea.title}`)  .page(({ data: { idea } }) =&gt; (    \/\/ ...    \/\/ \u0442\u0443\u0442 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u043e\u0432\u043e\u0433\u043e, \u0432\u0441\u0451 \u043f\u043e \u0441\u0442\u0430\u0440\u043e\u043c\u0443, \u0442\u0430\u043a \u0436\u0435 \u0444\u043e\u0440\u043c\u0430 \u0441 \u043c\u0443\u0442\u0430\u0446\u0438\u0435\u0439    \/\/ ...  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u043e\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u043a\u0432\u0435\u0440\u0438. \u0410 \u0442\u0430\u043a\u0436\u0435 \u0431\u044b\u043b \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d \u043d\u043e\u0432\u044b\u0439 \u043c\u0435\u0442\u043e\u0434 \u043f\u043e\u0438\u043d\u0442\u043e\u0432 \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <code>.with()<\/code>. \u042d\u0442\u043e\u0442 <code>.with()<\/code> \u044d\u0442\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u0448\u0432\u0435\u0439\u0446\u0430\u0440\u0441\u043a\u0438\u0439 \u043d\u043e\u0436, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u043d\u0436\u0435\u043a\u0442\u0438\u0442\u044c \u043a\u0432\u0435\u0440\u0438, \u043d\u043e \u0438 \u043c\u043d\u043e\u0433\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435, \u043f\u0440\u043e \u043d\u0435\u0433\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u0447\u0443\u0442\u044c \u043f\u043e\u0437\u0436\u0435.<\/p>\n<p>\u0421\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u0447\u0442\u043e \u043a\u0432\u0435\u0440\u0438 \u043a\u0430\u043a \u0438 \u043c\u0443\u0442\u0430\u0446\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0430 \u0433\u0434\u0435 \u0443\u0433\u043e\u0434\u043d\u043e \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e. \u0421\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u0434 \u0441\u0430\u043c \u043f\u043e \u0441\u0435\u0431\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043f\u0438\u043b\u0435\u043d \u0438\u0437 \u043d\u0435\u0451 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435. \u041f\u0440\u0438\u0447\u0451\u043c \u044d\u0442\u0430 \u043a\u0432\u0435\u0440\u0438 \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u043a\u0430\u043a \u0441\u0430\u043c\u0430\u044f \u043e\u0431\u044b\u0447\u043d\u0430\u044f \u043a\u0432\u0435\u0440\u0438 \u0432 \u043b\u044e\u0431\u043e\u043c \u043e\u0431\u044b\u0447\u043d\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435, \u0431\u0435\u0437 \u0432\u0441\u044f\u043a\u0438\u0445 <code>.with()<\/code><\/p>\n<pre><code>import { ideaViewQuery } from '@\/modules\/idea'export const MyUsualComponent = ({ id }: { id: string }) =&gt; {  const result = ideaViewQuery.useQuery({ id }) \/\/ \u043f\u0435\u0440\u0432\u044b\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0438\u0434\u0451\u0442 \u0438\u043d\u043f\u0443\u0442  \/\/ \u0432\u0442\u043e\u0440\u044b\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u043a\u0438\u043d\u0443\u0442\u044c \u043e\u043f\u0446\u0438\u0438 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e react-query, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0435\u043d\u044b  \/\/ \u0441 \u0442\u0435\u043c\u0438 \u043e\u043f\u0446\u0438\u044f\u043c\u0438 \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b \u043e\u0431\u044a\u044f\u0432\u0438\u043b\u0438 \u0432 \u0441\u0430\u043c\u043e\u043c \u043f\u043e\u0438\u043d\u0442\u0435 \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c .query({ ... }) \u043c\u0435\u0442\u043e\u0434\u0435  \/\/ \u0435\u0441\u043b\u0438 \u0432\u044b \u0438\u0445 \u0442\u0430\u043c \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u043b\u0438  \/\/ \u0432 result \u0441\u0435\u0439\u0447\u0430\u0441 \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0439 useQuery \u0438\u0437 react-query  \/\/ \u0432\u044b \u0434\u0430\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a: const result = useQuery(ideaViewQuery.getQueryOptions({ id }))  \/\/ \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0434\u043b\u0438\u043d\u043d\u0435\u0435 \u043f\u043e \u0437\u0430\u043f\u0438\u0441\u0438  if (result.isLoading) {    return &lt;div&gt;\u0417\u0430\u0433\u0440\u0443\u0437\u043a\u0430...&lt;\/div&gt;  }  if (result.error) {    \/\/ \u0410 \u043e\u0448\u0438\u0431\u043a\u0438 \u0443 \u043d\u0430\u0441 \u043a\u0441\u0442\u0430\u0442\u0438 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 unknown, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0441\u0432\u043e\u0439 ErrorPoint0    \/\/ \u041a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0430 \u0441\u0432\u043e\u0439 \u043a\u043b\u0430\u0441\u0441 \u043e\u0448\u0438\u0431\u043e\u043a, \u0438 \u0442\u043e\u0433\u0434\u0430 \u0437\u0434\u0435\u0441\u044c \u0431\u0443\u0434\u0435\u0442 \u0432\u0430\u0448 AppError    \/\/ \u042d\u0442\u043e \u0442\u043e\u0436\u0435 \u043e\u0442\u0434\u043b\u0435\u044c\u043d\u0430\u044f \u0442\u0435\u043c\u0430    return &lt;div&gt;{result.error.message}&lt;\/div&gt;  }  \/\/ \u043d\u0430 \u044d\u0442\u043e\u043c \u044d\u0442\u0430\u043f\u0435 \u043c\u044b \u043f\u043e \u0442\u0438\u043f\u0430\u043c \u0443\u0436\u0435 \u0437\u043d\u0430\u0435\u043c, \u0447\u0442\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u0437\u0434\u0435\u0441\u044c \u0435\u0441\u0442\u044c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0435\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438, \u0438 \u043d\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0438  return (    &lt;div&gt;      &lt;h1&gt;{result.data.idea.title}&lt;\/h1&gt;      &lt;div&gt;{result.data.idea.content}&lt;\/div&gt;    &lt;\/div&gt;  )}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u0434\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0432\u0441\u0435 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0439 react-query \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u043f\u0440\u044f\u043c\u043e \u0432 \u043f\u043e\u0438\u043d\u0442\u0435 \u0441\u0430\u043c\u043e\u0439 \u043a\u0432\u0435\u0440\u0438:<\/p>\n<pre><code>myQuery.useQuery(input, ...)myQuery.getQueryKey(input, ...)myQuery.getQueryOptions(...)myQuery.fetchQuery(...)myQuery.prefetchQuery(...)myQuery.getQueryData(...)myQuery.ensureQueryData(...)myQuery.refetchQuery(...)myQuery.setQueryData(...)myQuery.getQueryCache(...)myQuery.getQueriesCache(...)myQuery.getQueryState(...)myQuery.cancelQuery(...)myQuery.invalidateQuery(...)myQuery.removeQuery(...)myQuery.resetQuery(...)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u0435, \u0447\u0442\u043e \u043f\u0435\u0440\u0432\u044b\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0438\u043d\u043f\u0443\u0442, \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 <code>queryKey<\/code>, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0442\u0435\u043b\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u0430\u043c\u043e\u0439 \u043a\u0432\u0435\u0440\u0438. \u0410 \u0441\u0430\u043c <code>queryKey<\/code> \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0431\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e \u0432\u043e\u0442 \u0442\u0430\u043a\u0438\u043c:<\/p>\n<pre><code>const ideaViewQueryKey = ideaViewQuery.getQueryKey({ id: 'my-super-duper-id' })console.info(ideaViewQueryKey);[  'point0',  {    scope: this.scope, \/\/ \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \"root\", \u043d\u043e \u0435\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u043c\u043d\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432, \u0442\u043e \u0442\u0443\u0442 \u0431\u0443\u0434\u0435\u0442 \u0441\u043a\u043e\u0443\u043f \u0432\u0430\u0448\u0435\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430    \/\/ \u0434\u0430 \u0443 \u043d\u0430\u0441 \u043c\u043e\u0436\u043d\u043e \u0438\u043c\u0435\u0442\u044c \u043e\u0434\u0438\u043d \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u043c\u043d\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043e\u0434\u0438\u043d \u0441\u0430\u0439\u0442, \u0434\u0440\u0443\u0433\u043e\u0439 \u044d\u043a\u0441\u043f\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0430 \u0442\u0440\u0435\u0442\u0438\u0439 \u0430\u0434\u043c\u0438\u043d\u043a\u0430    \/\/ \u0438 \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0432\u0435\u0440\u0438 \u0438 \u043f\u0440\u043e\u0447\u0438\u0435 \u043f\u043e\u0438\u043d\u0442\u044b \u0438\u0437 \u043e\u0434\u043d\u043e\u0439 \u043a\u043e\u0434\u043e\u0432\u043e\u0439 \u0431\u0430\u0437\u044b, \u043f\u0440\u0438\u0447\u0451\u043c \u0438\u0437 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0440\u0435\u0437\u0430\u043d \u043a\u043e\u0434    \/\/ \u0434\u0440\u0443\u0433\u0438\u0445 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043e\u043d \u043d\u0435 \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f. \u0422\u043e \u0435\u0441\u0442\u044c \u0443 \u043d\u0430\u0441 1 \u0441\u0435\u0440\u0432\u0435\u0440 \u0438 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0445\u043e\u0447\u0435\u0448\u044c \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432.    \/\/ \u041f\u0440\u043e \u044d\u0442\u043e \u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u0432 \u0434\u043e\u043a\u0435, \u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u043d\u0430\u0439\u0442\u0435, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0442\u0443\u0442 \u043e\u0447\u0435\u043d\u044c \u0441\u0435\u0440\u044c\u0451\u0437\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a    type: this.type, \/\/ \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \"query\",    \/\/ \u043d\u043e \u0443 \u043d\u0430\u0441 \u0436\u0435 \u0431\u044b\u0432\u0430\u044e\u0442 \u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u043b\u043e\u0430\u0434\u0435\u0440 \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044d\u0442\u043e \u0442\u043e\u0436\u0435 \u043a\u0432\u0435\u0440\u0438 \u043f\u043e \u0441\u0443\u0442\u0438,    \/\/ \u0442\u0430\u043a \u0447\u0442\u043e \u0442\u0443\u0442 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438 \"page\", \u0438 \"layout\", \u0438 \u043c\u043d\u043e\u0433\u043e \u0447\u0442\u043e \u0435\u0449\u0451, \u043a\u043e\u0440\u043e\u0447\u0435 \u0442\u0438\u043f \u043f\u043e\u0438\u043d\u0442\u0430    name: this.name, \/\/ \u044d\u0442\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0438\u043d\u0442\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u043b\u0438 \u0432\u0442\u043e\u0440\u044b\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0432    \/\/ .lets('query', 'ideaView'), \u0442\u043e \u0435\u0441\u0442\u044c \"ideaView\"    mode: 'server', \/\/ \u0430 \u0443 \u043d\u0430\u0441 \u0435\u0449\u0451 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0435 \u043a\u0432\u0435\u0440\u0438 \u0431\u044b\u0432\u0430\u044e\u0442, \u0441\u043a\u043e\u0440\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443    finiteness: 'finite', \/\/ \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \"infiniteQuery\" \u0430 \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \"query\"    \/\/ \u0438 \u0431\u044b\u043b\u043e \u0431\u044b \u043b\u043e\u0433\u0438\u0447\u043d\u043e, \u0447\u0442\u043e \u043f\u0440\u0441\u0442\u043e \u043f\u043e\u043b\u0435 \"type\" \u0432\u044b\u0448\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u043d\u043e \u044d\u0442\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u043a \u043a\u0430\u0436\u0435\u0442\u0441\u044f    \/\/ \u0432\u0435\u0434\u044c \u0441\u0430\u043c\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043c\u043e\u0436\u0435\u0442 \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c, \u0447\u0442\u043e \u0435\u0451 \u043b\u043e\u0430\u0434\u0435\u0440 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043a\u0430\u043a infiniteQuery,    \/\/ \u0442\u043e\u0433\u0434\u0430 \u0442\u0443\u0442 \u0431\u0443\u0434\u0435\u0442 \"infinite\", \u0430 \"type\" \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \"page\"    tags: [], \/\/ \u043d\u0443 \u0443 \u043d\u0430\u0441 \u0435\u0449\u0451 \u043c\u043e\u0436\u043d\u043e \u0441\u0430\u043c \u043f\u043e\u0438\u043d\u0442 \u043f\u043e\u043a\u0440\u044b\u0442\u044c \u0442\u0435\u0433\u0430\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0442\u043e\u043c \u043f\u043e \u043d\u0438\u043c \u0444\u0438\u043b\u044c\u0442\u0440\u043e\u0432\u0430\u0442\u044c \u043a\u0432\u0435\u0440\u0438,    \/\/ \u043d\u043e \u043e\u0431 \u044d\u0442\u043e\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438, \u044f \u0442\u0443\u0442 \u0441\u0442\u0430\u0440\u0430\u044e\u0441\u044c \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0441\u0430\u043c\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435,    \/\/ \u0430 \u044d\u0442\u043e \u0443\u0436\u0435 \u0434\u0440\u0443\u0433\u0430\u044f \u0442\u0435\u043c\u0430    output: 'data', \/\/ \u0443\u0444... \u041d\u0443, \u0432 \u043e\u0431\u0449\u0435\u043c \u043f\u043e \u0438\u0434\u0435\u0435 \u0442\u0443\u0442 \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \"data\", \u043d\u043e \u0437\u0430\u0431\u0435\u0433\u0430\u044f \u0432\u043f\u0435\u0440\u0451\u0434 \u0441\u043a\u0430\u0436\u0443,    \/\/ \u0447\u0442\u043e \u0442\u0443\u0442 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438 \"queryClientDehydratedState\" \u0434\u043b\u044f \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0439, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0440\u0435\u0448\u0438\u043b\u0438 \u043f\u0440\u0435\u0444\u0435\u0442\u0447\u0438\u0442\u044c \u0432\u0441\u0435 \u043a\u0432\u0435\u0440\u0438 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435    \/\/ \u043f\u0435\u0440\u0435\u0434 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u043c \u043d\u0430 \u043d\u0435\u0451, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043d\u0435 \u043c\u043e\u0440\u0433\u0430\u043b \u043f\u043e \u0445\u043e\u0434\u0443 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430, \u043d\u043e \u043e\u0431 \u044d\u0442\u043e\u043c \u0442\u043e\u0436\u0435 \u043f\u043e\u0442\u043e\u043c    input: '{\"id\":\"my-super-duper-id\"}', \/\/ \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e \u0441\u0442\u0440\u0438\u043d\u0433\u0438\u0444\u0430\u0435\u043d\u044b\u0439 \u0438\u043d\u043f\u0443\u0442. \u041f\u0440\u0438\u0447\u0451\u043c \u0435\u0441\u043b\u0438 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 superjson    \/\/ \u043a\u0430\u043a \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440, \u0442\u043e\u0433\u0434\u0430 \u0442\u0443\u0442 \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a\u0436\u0435 \u0437\u0430\u0448\u0438\u0442\u0430 \u0442\u0430 \u0441\u0430\u043c\u0430\u044f \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f. \u041f\u0440\u043e \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440\u044b \u0442\u043e\u0436\u0435 \u043f\u043e\u0437\u0436\u0435, \u043d\u043e \u044d\u0442\u043e \u043f\u043e \u0441\u0443\u0442\u0438 \u0442\u0430\u043a\u0436\u0435    \/\/ \u0432 tRPC, \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u043e\u0432\u043e\u0433\u043e  },]<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u043e\u043e\u0431\u0449\u0435, \u0432\u044b \u0441\u0430\u043c\u0438 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0441 \u044d\u0442\u0438\u043c \u043a\u0432\u0435\u0440\u0438 \u043a\u0435\u0439 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442\u0435. \u042f \u0432\u0430\u043c \u044d\u0442\u043e\u0442 \u043a\u0432\u0435\u0440\u0438 \u043a\u0435\u0439 \u043f\u043e\u043a\u0430\u0437\u0430\u043b, \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0441\u043a\u043e\u0440\u043e \u0432 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u044f \u0431\u0443\u0434\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043e \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u0447\u0430\u0441\u0442\u044f\u0445 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u0433\u0434\u0435 \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0442\u043e\u0433\u043e \u0438\u0437 \u0447\u0435\u0433\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u044d\u0442\u043e\u0442 \u043a\u0432\u0435\u0440\u0438 \u043a\u0435\u0439 \u0441\u043e\u0441\u0442\u043e\u0438\u0442.<\/p>\n<p>\u0418 \u043f\u043e\u043a\u0430 \u0434\u0430\u043b\u0435\u043a\u043e \u043d\u0435 \u0443\u0448\u043b\u0438, \u043d\u0430\u043f\u043e\u043c\u0438\u043d\u0430\u044e, \u0447\u0442\u043e \u043b\u043e\u0430\u0434\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043e\u0431\u044a\u044f\u0432\u0438\u043b\u0438 \u0432 \u0441\u0430\u043c\u0438\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u0445 \u043f\u043e \u0442\u0438\u043f\u0443:<\/p>\n<pre><code>export const ideaPage = root  .lets('page', 'idea', '\/ideas\/:id')  .loader(({ params }) =&gt; {    const idea = await prisma.idea.findUniqueOrThrow({      where: { id: params.id },    })    return { idea }  })  .page(({ data: { idea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{idea.title}&lt;\/h1&gt;      &lt;div&gt;{idea.content}&lt;\/div&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u0435\u043b\u0430\u044e\u0442 \u0441\u0430\u043c\u0438 \u044d\u0442\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043a\u0432\u0435\u0440\u044f\u043c\u0438, \u0438 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code>ideaPage.fetchQuery({ id: 'my-super-duper-id' })ideaPage.useQuery({ id: 'my-super-duper-id' })\/\/ \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435, \u043a\u043e\u0440\u043e\u0447\u0435 \u044d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u0430\u044f \u043a\u0432\u0435\u0440\u0438, \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u0441 \u0442\u0435\u043c, \u0447\u0442\u043e \u044d\u0442\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u044b \u0434\u0430\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432\u043e\u0442 \u0442\u0430\u043a, \u043d\u043e \u044d\u0442\u043e \u0441\u0442\u0440\u0430\u043d\u043d\u043e, \u043d\u043e \u0442\u0430\u043a \u043c\u043e\u0436\u043d\u043e:<\/p>\n<pre><code>\/\/ \u0442\u0430 \u0436\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430, \u0442\u0443\u0442 \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439export const ideaPage = root  .lets('page', 'idea', '\/ideas\/:id')  .loader(({ params }) =&gt; {    const idea = await prisma.idea.findUniqueOrThrow({      where: { id: params.id },    })    return { idea }  })  .page(({ data: { idea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{idea.title}&lt;\/h1&gt;      &lt;div&gt;{idea.content}&lt;\/div&gt;    &lt;\/div&gt;  ))export const ideaEditPage = root  .lets('page', 'ideaEdit', '\/ideas\/:id\/edit')  \/\/ \u0430 \u0432\u043e\u0442 \u0442\u0443\u0442 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 \u0432\u043c\u0435\u0441\u0442\u043e \u043a\u0432\u0435\u0440\u0438 \u043f\u0440\u044f\u043c\u043e \u0441\u0430\u043c\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 ideaPage  .with(ideaPage, ({ params }) =&gt; params)  .head(({ data: { idea } }) =&gt; `Edit: ${idea.title}`)  .page(({ data: { idea } }) =&gt; (    \/\/ ...    \/\/ \u0442\u0443\u0442 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u043e\u0432\u043e\u0433\u043e, \u0432\u0441\u0451 \u043f\u043e \u0441\u0442\u0430\u0440\u043e\u043c\u0443, \u0442\u0430\u043a \u0436\u0435 \u0444\u043e\u0440\u043c\u0430 \u0441 \u043c\u0443\u0442\u0430\u0446\u0438\u0435\u0439    \/\/ ...  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u044d\u0442\u043e \u0445\u043e\u0442\u044c \u0438 \u0441\u0442\u0440\u0430\u043d\u043d\u043e, \u043d\u043e \u043a\u0430\u043a \u0431\u0443\u0434\u0442\u043e \u0431\u044b \u0434\u0430\u0436\u0435 \u043a\u0440\u0443\u0442\u043e. \u041d\u043e \u0442\u0443\u0442 \u0442\u0430\u043a\u043e\u0439 \u043d\u044e\u0430\u043d\u0441, \u0447\u0442\u043e \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u0435\u0441\u043b\u0438 \u043e\u0431\u044a\u044f\u0432\u0438\u043c \u044d\u0442\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u0444\u0430\u0439\u043b\u0430\u0445, \u0442\u043e \u0432 \u0444\u0430\u0439\u043b \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0433\u043e \u0431\u0430\u043d\u0434\u043b\u0430 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0434\u0435\u0438 \u043f\u043e\u043f\u0430\u0434\u0451\u0442 \u0442\u0430\u043a\u0436\u0435 \u0438 \u043a\u043e\u0434 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u0438\u0434\u0435\u0438, \u0430 \u043c\u044b \u0445\u043e\u0442\u0435\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u0432\u0435\u0440\u0438. \u0412 \u0446\u0435\u043b\u043e\u043c \u0435\u0441\u043b\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u0438\u0435 \u0442\u043e \u043e\u043a. \u0414\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u043e\u0434\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442, \u0441\u0431\u043e\u0440\u0449\u0438\u043a \u0432\u0441\u0451 \u0440\u0430\u0441\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442 \u043a\u0430\u043a \u043d\u0430\u0434\u043e, \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u043f\u0440\u043e\u0441 \u043e\u0431\u044a\u0451\u043c\u0430 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c\u043e\u0433\u043e \u0447\u0430\u043d\u043a\u0430 \u043d\u0430 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435. \u0423 \u043d\u0430\u0441 \u0432\u0441\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0433\u0440\u0443\u0437\u044f\u0442\u0441\u044f \u043b\u0435\u043d\u0438\u0432\u043e (\u043c\u043e\u0436\u043d\u043e \u043e\u0442\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0438 \u0433\u0440\u0443\u0437\u0438\u0442\u044c \u0432\u0441\u0435 \u0441\u0440\u0430\u0437\u0443), \u0442\u0430\u043a \u0447\u0442\u043e \u043b\u0443\u0447\u0448\u0435 \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043a\u0432\u0435\u0440\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e, \u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e. \u041d\u043e \u044d\u0442\u043e \u0434\u0435\u043b\u043e \u043a\u0430\u0436\u0434\u043e\u0433\u043e, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u043a\u0430\u043a \u043a\u043e\u043c\u0443 \u0443\u0433\u043e\u0434\u043d\u043e. \u042f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0445\u043e\u0442\u0435\u043b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u044b\u043c \u043e\u0442 \u0441\u043e\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u0439 \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u044c \u0432\u0441\u0435\u043c \u0442\u0432\u043e\u0440\u0438\u0442\u044c, \u0447\u0442\u043e \u0437\u0430\u0445\u043e\u0447\u0435\u0442\u0441\u044f, \u0438 \u0441\u0430\u043c\u0438\u043c \u0432\u044b\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u044e \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u0443 \u0438 \u0441\u043e\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u044f<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/query\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u043a\u0432\u0435\u0440\u0438<\/a>.<\/p>\n<h2>\u0421\u043e\u043a\u0440\u0430\u0449\u0451\u043d\u043d\u0430\u044f .lets \u043d\u043e\u0442\u0430\u0446\u0438\u044f<\/h2>\n<p>\u041a\u043e\u0433\u0434\u0430 \u044f \u043d\u0430\u0447\u0430\u043b \u043f\u0438\u0441\u0430\u0442\u044c \u044d\u043a\u0437\u0430\u043c\u043f\u043b\u044b \u0438 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u044b, \u043c\u043d\u0435 \u043f\u043e\u0434\u043d\u0430\u0434\u043e\u0435\u043b\u043e \u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u043e\u043a \u0432 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f\u0445 \u043f\u043e \u0442\u0438\u043f\u0443<\/p>\n<pre><code>export const ideaPage = root  .lets('page', 'idea', '\/ideas\/:id')  \/\/ ...  .page()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u044f \u043f\u043e\u0434\u0443\u043c\u0430\u043b, \u0447\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u0431\u044b \u0438\u043c\u0435\u0442\u044c \u043a\u043e\u0440\u043e\u0442\u043a\u0443\u044e \u043d\u043e\u0442\u0430\u0446\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u0436\u0435 \u0432 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435 \u043a\u0430\u043a \u0438 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u0432\u044b\u0448\u0435:<\/p>\n<pre><code>export const ideaPage = root.lets  .page('\/ideas\/:id')  \/\/ ...  .page()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a\u0430\u044f \u043d\u043e\u0442\u0430\u0446\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u043c \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u043c (\u043e \u043d\u0451\u043c \u043f\u043e\u0437\u0436\u0435), \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u043a\u0432\u0430\u043b\u044c\u043d\u043e \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442 \u043a\u043e\u0434 \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432 \u043a\u043e\u0434 \u0432 \u043f\u0435\u0440\u0432\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435. \u041f\u0440\u0430\u0432\u0438\u043b\u043e \u0443 \u043d\u0435\u0433\u043e \u0442\u0430\u043a\u043e\u0435: \u0431\u0435\u0440\u0451\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u043e\u0439 \u201cideaPage\u201d, \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u043a\u043e\u043d\u0447\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0442\u0438\u043f \u043f\u043e\u0438\u043d\u0442\u0430 \u201cPage\/Query\/\u2026\u201d, \u0442\u043e \u044d\u0442\u043e\u0442 \u0441\u0443\u0444\u0444\u0438\u043a\u0441 \u043e\u0442\u0440\u0435\u0437\u0430\u0435\u043c, \u0442\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0438\u043d\u0442\u0430 \u201cidea\u201d, \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043c\u0435\u043d\u044f\u0435\u043c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e \u043d\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0443\u044e\u0441\u044f.<\/p>\n<p>\u041e\u0431\u0430 \u0441\u043f\u043e\u0441\u043e\u0431\u0430 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u0438\u043d\u0442\u043e\u0432 \u0432\u0430\u043b\u0438\u0434\u043d\u044b, \u043e\u0431\u0430 \u043a\u0430\u043a \u043d\u0430\u0434\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u044b. \u041d\u043e \u0434\u0430\u043b\u0435\u0435 \u043f\u043e \u0442\u0435\u043a\u0441\u0442\u0443 \u044f \u0431\u0443\u0434\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0440\u043e\u0442\u043a\u0443\u044e \u043d\u043e\u0442\u0430\u0446\u0438\u044e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 \u0446\u0435\u043b\u043e\u043c \u0441\u0447\u0438\u0442\u0430\u044e \u0435\u0451 \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u043e\u0439.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/points\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u043f\u043e\u0438\u043d\u0442\u044b<\/a>.<\/p>\n<h2>Layout<\/h2>\n<p>\u0427\u0442\u043e \u044f \u0445\u043e\u0442\u0435\u043b \u043e\u0442 \u043b\u044d\u0439\u043e\u0443\u0442\u0430:<\/p>\n<ul>\n<li>\n<p>\u042f \u0445\u043e\u0442\u0435\u043b \u043c\u043e\u0447\u044c \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u043a\u0430\u043a\u043e\u0439 \u043b\u044d\u0439\u043e\u0443\u0442 \u043d\u0443\u0436\u0435\u043d \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0432 \u043a\u043e\u0434\u0435 \u0441\u0430\u043c\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0430 \u043d\u0435 \u0445\u043e\u0434\u0438\u0442\u044c \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0442\u044c \u0435\u0433\u043e \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435, \u0442\u0430\u043a \u0435\u0449\u0451 \u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0442\u0443\u0434\u0430 \u0440\u0443\u043a\u0430\u043c\u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c<\/p>\n<\/li>\n<li>\n<p>\u042f \u0445\u043e\u0442\u0435\u043b, \u0447\u0442\u043e\u0431\u044b \u043b\u044d\u0439\u043e\u0443\u0442 \u043c\u043e\u0433 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0447\u0430\u0441\u0442\u044c \u043f\u0443\u0442\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0431\u0443\u0434\u0435\u0442 \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435\u0439 \u0435\u0433\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0435\u0439<\/p>\n<\/li>\n<li>\n<p>\u0427\u0442\u043e\u0431\u044b \u043b\u044d\u0439\u043e\u0443\u0442 \u043a\u0430\u043a \u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043c\u043e\u0433\u043b\u0438 \u0438\u043c\u0435\u0442\u044c \u0441\u0432\u043e\u0438 \u043b\u043e\u0430\u0434\u0435\u0440\u044b\/\u043a\u0432\u0435\u0440\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u043a\u0430\u043a \u0438 \u043a\u0432\u0435\u0440\u0438 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0441\u0430\u043c\u0438 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b\u0438 \u0441\u0432\u043e\u0438 \u043b\u043e\u0430\u0434\u0438\u043d\u0433 \u0438 \u044d\u0440\u0440\u043e\u0440 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f<\/p>\n<\/li>\n<li>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435 \u043c\u0435\u0436\u0434\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u043b\u044d\u0439\u043e\u0443\u0442\u0430, \u043a\u0432\u0435\u0440\u0438 \u043b\u044d\u0439\u043e\u0443\u0442\u0430 \u043d\u0435 \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u043b\u0438\u0441\u044c \u0438 \u043b\u044d\u0439\u043e\u0443\u0442 \u043d\u0435 \u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043b\u0441\u044f<\/p>\n<\/li>\n<\/ul>\n<pre><code>export const ideasLayout = root.lets  .layout('\/idea')  \/\/ \u0432\u043e\u0442 \u0442\u0443\u0442 \u043c\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c .with(), .loader(), .head() \u0438 \u0442.\u0434.  .layout(({ children }) =&gt; {    return (      &lt;div&gt;        &lt;h1&gt;Ideas Layout&lt;\/h1&gt;        {children}      &lt;\/div&gt;    )  })\/\/ \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043e\u0442 \u043b\u044d\u0439\u043e\u0443\u0442\u0430 ideasLayoutexport const ideaPage = ideasLayout.lets  .page('\/:id')  \/\/ \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0440\u043e\u0443\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0442\u0430\u043a\u0438\u043c: \/idea\/:id  .with(ideaViewQuery, ({ params }) =&gt; ({ id: params.id }))  .page(({ data: { idea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{idea.title}&lt;\/h1&gt;      &lt;div&gt;{idea.content}&lt;\/div&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041b\u044d\u0439\u043e\u0443\u0442\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u0434\u0440\u0443\u0433 \u043e\u0442 \u0434\u0440\u0443\u0433\u0430:<\/p>\n<pre><code>export const generalLayout = root.lets  \/\/ \u043f\u0443\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c, \u0442\u043e\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 '\/' \u0434\u043b\u044f \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u043b\u044d\u0439\u043e\u0443\u0442\u0430,  \/\/ \u0438\u043b\u0438 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u0440\u043e\u0443\u0442 \u0435\u043b\u0441\u0438 \u0440\u0430\u043d\u0435\u0435 \u0431\u044b\u043b \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d  .layout()  \/\/ \u044f \u043f\u043e\u043d\u0438\u043c\u0430\u044e, \u0447\u0442\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f .layout().layout() \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u0441\u0442\u0440\u0430\u043d\u043d\u043e, \u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u0432\u043e\u0442 \u0434\u0438\u0437\u0430\u0439\u043d \u0443 \u0432\u0441\u0435\u0445 \u043f\u043e\u0438\u043d\u0442\u043e\u0432,  \/\/ \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u043f\u043e\u0438\u043d\u0442\u0430 \u043e\u0431\u044a\u044f\u0441\u043d\u0438\u0442\u044c, \u0447\u0442\u043e \u043c\u044b \u0441\u0442\u0440\u043e\u0438\u043c, \u0430 \u043f\u043e\u0442\u043e\u043c \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u044c \u0431\u0438\u043b\u0434\u0435\u0440 \u044d\u0442\u0438\u043c \u0436\u0435 \u0441\u043b\u043e\u0432\u043e\u043c.  \/\/ \u041d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u043f\u043e\u0447\u0442\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u0435\u0436\u0434\u0443 \u044d\u0442\u0438\u043c\u0438 \u0434\u0432\u0443\u043c\u044f \u043c\u043e\u043c\u0435\u043d\u0442\u0430\u043c\u0438 \u043c\u044b \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0445\u0435\u043b\u043f\u0435\u0440\u044b  \/\/ \u0432\u0440\u043e\u0434\u0435 .with(), .loader(), .head() \u0438 \u0442.\u0434. (\u0430 \u044d\u0442\u043e \u0434\u0430\u043b\u0435\u043a\u043e \u043d\u0435 \u0432\u0441\u0435 \u0445\u0435\u043b\u043f\u0435\u0440\u044b, \u043d\u043e \u043e\u0431 \u044d\u0442\u043e\u043c \u043f\u043e\u0437\u0436\u0435)  \/\/ \u0435\u0441\u043b\u0438 \u0441\u043c\u0443\u0449\u0430\u0435\u0442 \u043d\u0430 \u043c\u0435\u0441\u0442\u0430\u0445 \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c .lets('layout', 'general').layout()  .layout(({ children }) =&gt; {    return (      &lt;div&gt;        &lt;h1&gt;General Layout&lt;\/h1&gt;        {children}      &lt;\/div&gt;    )  })\/\/ \u0412\u043e\u0442 \u0442\u0443\u0442 \u043c\u044b \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u043c\u0441\u044f \u043e\u0442 generalLayout, \u0430 \u043d\u0435 \u043e\u0442 rootexport const ideasLayout = generalLayout  .layout('\/idea')  .layout(({ children }) =&gt; {    return (      &lt;div&gt;        &lt;h1&gt;Ideas Layout&lt;\/h1&gt;        {children}      &lt;\/div&gt;    )  })\/\/ \u0422\u0443\u0442 \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439export const ideaPage = ideasLayout.lets  .page('\/:id')  .with(ideaViewQuery, ({ params }) =&gt; ({ id: params.id }))  .page(({ data: { idea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{idea.title}&lt;\/h1&gt;      &lt;div&gt;{idea.content}&lt;\/div&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0435\u0449\u0451 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043b\u043e\u0430\u0434\u0435\u0440\u0430\u043c\u0438 \u043b\u044d\u0439\u043e\u0443\u0442\u0430, \u0438 \u043a\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u043b\u044d\u0439\u043e\u0443\u0442\u0430 \u0432 \u0441\u0430\u043c\u0438\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u0445. \u0418\u0434\u0435\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442 \u0441\u0430\u043c\u0438 \u043a\u0432\u0435\u0440\u0438 \u0438 \u043b\u043e\u0430\u0434\u0435\u0440\u044b \u043b\u044d\u0439\u043e\u0443\u0442\u0430, \u043d\u043e \u0441\u0430\u043c \u043b\u044d\u0439\u043e\u0443\u0442 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u043c. \u0410 \u0442\u0430\u043a\u0436\u0435 \u043c\u044b \u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u0435\u043c, \u0447\u0442\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0435\u043d\u0430, \u043f\u043e\u043a\u0430 \u043d\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u044f\u0442\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435 \u043b\u044d\u0439\u043e\u0443\u0442\u0430. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>useValue()<\/code> \u0434\u043b\u044f \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u043b\u044d\u0439\u043e\u0443\u0442\u0430 \u0432 \u0441\u0430\u043c\u0438\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u0445. \u0411\u043e\u043b\u044c\u0448\u0435 \u043f\u0440\u043e <code>useValue()<\/code> \u0438 <code>getValue()<\/code> \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043e \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0430\u0445, \u044d\u0442\u043e \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u0442\u0438\u043f \u043f\u043e\u0438\u043d\u0442\u043e\u0432, \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043d\u0430\u043c<\/p>\n<pre><code>export const ideaLayout = root.lets  .layout('\/idea\/:id')  .loader(({ params }) =&gt; {    \/\/ \u043f\u043e \u0441\u0443\u0442\u0438 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0447\u0442\u043e \u0438 .with(ideaViewQuery, ({ params }) =&gt; ({ id: params.id }))    const idea = await prisma.idea.findUniqueOrThrow({      where: { id: params.id },    })    return { idea }  })  .layout(({ children }) =&gt; {    return (      &lt;div&gt;        &lt;h1&gt;Ideas Layout&lt;\/h1&gt;        {children}      &lt;\/div&gt;    )  })export const ideaPage = ideaLayout.lets.page('\/').page(() =&gt; {  const { idea } = ideaLayout.useValue()  return (    &lt;div&gt;      &lt;h1&gt;{idea.title}&lt;\/h1&gt;      &lt;div&gt;{idea.content}&lt;\/div&gt;    &lt;\/div&gt;  )})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/layout\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u043b\u044d\u0439\u0430\u0443\u0442\u044b<\/a>.<\/p>\n<h2>Root<\/h2>\n<p>\u0420\u0443\u0442 \u044d\u0442\u043e \u0441\u0430\u043c\u044b\u0439 \u043f\u0435\u0440\u0432\u044b\u0439 \u043f\u043e\u0438\u043d\u0442, \u043e\u0442 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u0442\u0440\u043e\u044f\u0442\u0441\u044f \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u0438\u043d\u0442\u044b. \u0412 \u043d\u0451\u043c \u0443\u0434\u043e\u0431\u043d\u043e \u0437\u0430\u0434\u0430\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u044b \u0432\u0441\u0435\u043c \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u043f\u043e\u0438\u043d\u0442\u0430\u043c. \u0422\u0430\u043a\u0436\u0435 \u0432 \u0440\u0430\u0437\u0440\u0435\u0437\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043e\u043d \u0441\u0430\u043c \u043f\u043e \u0441\u0435\u0431\u0435 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0435\u0442 \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u043e\u0439.<\/p>\n<p>\u042f \u043f\u0440\u0438\u0432\u0435\u0434\u0443 \u043f\u0440\u0438\u043c\u0435\u0440 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u0443\u0442\u0430, \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445 \u043f\u043e\u0434\u043f\u0438\u0448\u0443, \u0447\u0442\u043e \u0437\u0430\u0447\u0435\u043c \u043d\u0443\u0436\u043d\u043e, \u043d\u043e \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043e\u0431\u043e \u0432\u0441\u0435\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u0440\u0430\u0437\u0434\u0435\u043b\u0430\u0445<\/p>\n<pre><code>import { Point0 } from '@point0\/core'import { zodSchemaHelper } from '@point0\/core\/schema\/zod'import { openapi } from '@point0\/openapi'import superjson from 'superjson'\/\/ \u0412 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u0432\u0441\u0435\u0445 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u043e\u0438\u043d\u0442\u043e\u0432, \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 root \u043d\u0435 \u043d\u0430\u0441\u043b\u0435\u0434\u0443\u0435\u0442\u0441\u044f \u043e\u0442 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u0438\u043d\u0442\u043e\u0432, \u0430 \u0441\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u043f\u0440\u044f\u043c\u043e \u0438\u0437 Point0\/\/ \u041a\u0441\u0442\u0430\u0442\u0438 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u0432\u0441\u0435 \u043f\u043e\u0438\u043d\u0442\u044b (\u0440\u0443\u0442, \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u043a\u0432\u0435\u0440\u0438, \u043c\u0443\u0442\u0430\u0446\u0438\u0438, \u043b\u044d\u0439\u043e\u0443\u0442\u044b, \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u044b) \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u043d\u0441\u0442\u0430\u043d\u0441\u044b \u0435\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0433\u043e \u043a\u043b\u0430\u0441\u0441\u0430 Point0export const root = Point0.lets  .root()  \/\/ \u0443\u0440\u043b \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 ideaViewQuery.fetchQuery({ id: '123' }) \u043c\u044b \u0437\u043d\u0430\u043b\u0438 \u043d\u0430 \u043a\u0430\u043a\u043e\u0439 origin \u043d\u0430\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u043f\u0440\u043e\u0441  .serverUrl(process.env.SERVER_URL)  \/\/ \u0443\u0440\u043b \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043d\u0443\u0436\u0435\u043d, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u0432\u044b\u0437\u043e\u0432\u0435 ideaViewPage.route.abs({ id: '123' }) \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 https:\/\/mydomain.com\/ideas\/123  .clientUrl(process.env.CLIENT_URL)  \/\/ \u043f\u043e \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0438 \u0441 trpc, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440. \u0427\u0435\u0440\u0435\u0437 \u043d\u0435\u0433\u043e \u043f\u0440\u043e\u0433\u043e\u043d\u044f\u0435\u0442\u0441\u044f \u0438\u043d\u043f\u0443\u0442 \u043a\u0432\u0435\u0440\u0435\u0439 \u043f\u0440\u0438 \u043e\u0442\u043f\u0440\u0430\u0432\u043a\u0435\/\u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438,  \/\/ \u0430 \u0442\u0430\u043a\u0436\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u0430\u043c\u0438\u043c\u0438 \u043b\u043e\u0430\u0434\u0435\u0440\u0430\u043c\u0438  .transformer(superjson)  \/\/ \u0441\u0445\u0435\u043c\u0430 \u0445\u0435\u043b\u043f\u0435\u0440\u044b \u043c\u044b \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0447\u044c \u0438\u0437 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u0438\u043d\u043f\u0443\u0442 \u0441\u0445\u0435\u043c \u0432\u0441\u044f\u043a\u0438\u0435 \u0448\u0442\u0443\u043a\u0438 \u0434\u043b\u044f openapi  \/\/ \u0430 \u0442\u0430\u043a\u0436\u0435 \u0434\u043b\u044f \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043a\u043e\u0440\u043d\u0435\u0440 \u043a\u0435\u0439\u0441\u043e\u0432 \u0432 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0441\u0451\u0440\u0447 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432. \u041a\u043e\u0440\u043e\u0447\u0435 \u043e\u0447\u0435\u043d\u044c \u0432\u043d\u0443\u0442\u0440\u044f\u043a\u043e\u0432\u0430\u044f \u0448\u0442\u0443\u043a\u0430.  \/\/ \u041d\u043e \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0435\u0451 \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u044b, \u0447\u0442\u043e\u0431\u044b Point0 \u0437\u043d\u0430\u043b \u043a\u0430\u043a\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435  \/\/ \u041f\u0440\u0438\u0447\u0451\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u0430\u044f, \u0442\u0430\u043a-\u0442\u043e \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0447\u0435\u0440\u0435\u0437 StandardSchema  \/\/ \u0422\u0430\u043a\u0436\u0435 \u0435\u0441\u0442\u044c \u0445\u0435\u043b\u043f\u0435\u0440\u044b \u0434\u043b\u044f zod, valibot, yup, arktype, typebox, superstruct  .schemaHelper(zodSchemaHelper())  \/\/ \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u043e\u0448\u0438\u0431\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0431\u0440\u043e\u0441\u0430\u0435\u0442 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a,  \/\/ \u043e\u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u043b\u0436\u043d\u0430 \u0438\u043c\u0435\u0442\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u043a\u0430\u043a \u0443 ErrorPoint0 \u0438\u043b\u0438 \u0448\u0438\u0440\u0435 (\u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e \u043e\u0448\u0438\u0431\u043a\u0443 \u0434\u0430\u043b\u044c\u0448\u0435 \u043f\u043e \u0442\u0435\u043a\u0441\u0442\u0443)  .errorClass(AppError)  \/\/ \u041f\u0440\u043e prefetch \u0442\u043e\u0436\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u0434\u0430\u043b\u044c\u0448\u0435, \u043d\u043e \u0438\u0434\u0435\u044f \u0442\u0430\u043a\u0430\u044f, \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0434\u043e \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0435\u0451 \u0434\u0430\u043d\u043d\u044b\u0435,  \/\/ \u0447\u0442\u043e\u0431\u044b \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0431\u044b\u043b\u0430 \u0443\u0436\u0435 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u0430. \u041f\u0440\u0438\u0447\u0451\u043c \u0443 \u043d\u0430\u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u043f\u0446\u0438\u0439 \u043a\u0430\u043a \u044d\u0442\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c,  \/\/ \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u0437\u0434\u0435\u0441\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f 'pageDehydratedStateAndClientQuery', \u0441\u0430\u043c\u0430\u044f \u043d\u0430\u0434\u0451\u0436\u043d\u0430\u044f, \u043d\u043e \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0434\u043e\u0440\u043e\u0433\u0430\u044f.  \/\/ \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043e \u0434\u043b\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446  .prefetchPageOnNavigate('pageDehydratedStateAndClientQuery')  \/\/ \u0410 \u0435\u0449\u0451 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u0440\u0438 \u043d\u0430\u0432\u0435\u0434\u0435\u043d\u0438\u0438 \u043d\u0430 \u0441\u0441\u044b\u043b\u043a\u0443, \u0447\u0442\u043e\u0431\u044b \u043f\u043e \u043e\u0449\u0443\u0449\u0435\u043d\u0438\u044f\u043c \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043e\u043d\u0430 \u043f\u043e\u0434\u0433\u0440\u0443\u0437\u0438\u043b\u0430\u0441\u044c \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435 \u043d\u0430 \u043d\u0435\u0451  \/\/ \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043e \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0438\u043b\u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0438  .prefetchPageOnLinkHover('pageDehydratedStateAndClientQuery')  \/\/ \u041c\u043e\u0436\u0435\u043c \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u044b\u0435 \u043e\u043f\u0446\u0438\u0438 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043a\u0432\u0435\u0440\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u043d\u0430 \u043c\u0435\u0441\u0442\u0430\u0445 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u0432\u0435\u0440\u0435\u0439  \/\/ \u0438 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u0438\u0445 \u0432\u044b\u0437\u043e\u0432\u0430  .queryOptions({    retry: false,    retryOnMount: false,    refetchOnMount: false,    refetchOnWindowFocus: false,    refetchOnReconnect: false,    refetchInterval: false,    refetchIntervalInBackground: false,    staleTime: 1 * 60 * 1000, \/\/ 1 minute  })  \/\/ \u0422\u0443\u0442 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f \u043d\u0430 \u0432\u0441\u044f\u043a\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u0434\u043b\u044f \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u0446\u0435\u043b\u0435\u0439, \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u043b\u0438\u0441\u044c \u043d\u0430 \u0432\u0441\u0435 \u043e\u0448\u0438\u0431\u043a\u0438  \/\/ \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 .clientOn() \u0438\u043b\u0438 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0435 \u0447\u0435\u0440\u0435\u0437 .serverOn()  .on('error', ({ side, name, error, meta, data }) =&gt; {    console.error({      error,      \/\/ side: client | server      side,      \/\/ name: \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f      name,      \/\/ meta: \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u0431\u044b\u0442\u0438\u044f \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0435 \u0434\u043b\u044f \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f      meta,      \/\/ data: \u0441\u044b\u0440\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0432\u043a\u043b\u044e\u0447\u0430\u044f \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u0430\u043c \u0440\u0435\u0441\u043f\u043e\u043d\u0441,      \/\/ \u043d\u0435 \u043d\u0430\u0434\u043e \u0438\u0445 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c, \u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u0438\u0437 \u043d\u0438\u0445, \u0447\u0442\u043e \u043d\u0443\u0436\u043d\u043e      \/\/ data, (\u043d\u0435 \u043b\u043e\u0433\u0438\u0440\u0443\u0435\u043c)    })  })  \/\/ \u041c\u043e\u0436\u043d\u043e \u0442\u0443\u0442 \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043b\u044f Unhead  .head('global', ({ loading, error }) =&gt; {    return {      ...(loading ? { title: 'Loading...' } : {}),      ...(error ? { title: error.message } : {}),      titleTemplate: '%s | My App',    }  })  \/\/ \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043b\u043e\u0430\u0434\u0438\u043d\u0433\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u043d \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u0432\u0435\u0440\u0438\/\u043b\u043e\u0430\u0434\u0435\u0440\u043e\u0432  \/\/ \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0445 \u0441\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435\u0439\/\u043b\u044d\u0439\u043e\u0443\u0442\u043e\u043c\/\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c\/\u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u043e\u043c  \/\/ \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d \u043d\u0430 \u043c\u0435\u0441\u0442\u0430\u0445  .loading(() =&gt; {    return &lt;Spinner size=\"3xl\" className=\"m-auto\" \/&gt;  })  \/\/ \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043e\u0448\u0438\u0431\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u043d \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u043e\u0448\u0438\u0431\u043a\u0438 \u043a\u0432\u0435\u0440\u0438\/\u043b\u043e\u0430\u0434\u0435\u0440\u043e\u0432  .error(({ error }) =&gt; {    return &lt;ErrorPageComponent error={error} \/&gt;  })  \/\/ \u041c\u043e\u0436\u043d\u043e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u041b\u043e\u0430\u0434\u0438\u043d\u0433 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432 \u044d\u0442\u043e \u0442\u043e\u0436\u0435 \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f  .componentError(({ error }) =&gt; {    return &lt;ErrorComponent error={error} \/&gt;  })  \/\/ \u0412\u043e\u0442 \u0442\u0443\u0442 \u043a\u0430\u043a \u0440\u0430\u0437 \u043f\u0440\u043e \u0442\u043e, \u0447\u0442\u043e \u0440\u0443\u0442 \u0432\u044b\u0441\u0442\u0443\u043f\u0430\u0435\u0442 \u0442\u0430\u043a\u0436\u0435 \u0438 \u0432\u0445\u043e\u0434\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u043e\u0439 \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430.  \/\/ \u041f\u0440\u043e \u043c\u0438\u0434\u043b\u0432\u0430\u0440\u044b \u043c\u044b \u0435\u0449\u0451 \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c. \u041e\u043d\u0438 \u043d\u0430\u0448\u0435\u043c\u0443 \u043a\u043e\u0434\u0443 \u043f\u043e\u0447\u0442\u0438 \u043d\u0435 \u043d\u0443\u0436\u043d\u044b, \u043d\u043e \u043e\u043d\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b  \/\/ \u041f\u0440\u0438 \u0436\u0435\u043b\u0430\u043d\u0438\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0435 \u043c\u0438\u0434\u043b\u0432\u0430\u0440\u044b \u043f\u043e \u0442\u0438\u043f\u0443 better-auth  .middleware(    '\/api\/auth\/*',    async ({ request }) =&gt; await betterAuthServer.handler(request.original),  )  \/\/ \u0412\u043e\u0442 \u0442\u0443\u0442 \u0432\u043e\u0442 \u043c\u043e\u0436\u043d\u043e \u0435\u0449\u0451 \u0438 \u043e\u043f\u0435\u043d\u0430\u043f\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c  .middleware(    openapi({      route: '\/openapi.json',      scalar: '\/scalar',      swagger: '\/swagger',    }),  )  \/\/ \u043a\u0430\u043a \u0438 \u0432\u0441\u0435 \u043f\u043e\u0438\u043d\u0442\u044b, \u0447\u0435\u043c \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f, \u0442\u0435\u043c \u0438 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f .root()  .root()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418\u0434\u0435\u044f \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e, \u043d\u0430\u0445\u043e\u0434\u044f\u0441\u044c \u0432 \u043b\u044e\u0431\u043e\u043c \u0444\u0430\u0439\u043b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043f\u043e\u0438\u043d\u0442, \u0432\u0441\u0451 \u0447\u0442\u043e \u043d\u0430 \u043d\u0435\u0433\u043e \u0432\u043b\u0438\u044f\u0435\u0442 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0431\u044b\u0441\u0442\u0440\u043e \u043d\u0430\u0439\u0442\u0438 \u043f\u043e \u0446\u0435\u043f\u043e\u0447\u043a\u0435 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u0435\u0439 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e \u043a\u043b\u0438\u043a\u0443 \u0432 \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440\u0435 \u043a\u043e\u0434\u0430. \u0423\u0441\u043b\u043e\u0432\u043d\u043e \u043e\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043a \u043b\u044d\u0439\u043e\u0443\u0442\u0443, \u043e\u0442 \u043b\u044d\u0439\u043e\u0443\u0442\u0430 \u043a \u0440\u0443\u0442\u0443, \u0438 \u0432\u0441\u0451, \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0441\u0430\u0439\u0434 \u044d\u0444\u0444\u0435\u043a\u0442\u043e\u0432.<\/p>\n<p>\u0410 \u0432\u043e\u0442 \u0442\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b\u043e \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u0435 \u0440\u0443\u0442\u0430, \u0434\u043e \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u044f \u043a\u043e\u0440\u043e\u0442\u043a\u043e\u0439 <code>.lets<\/code> \u043d\u043e\u0442\u0430\u0446\u0438\u0438:<\/p>\n<pre><code>\/\/ \u043f\u0435\u0440\u0432\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u0442\u0438\u043f \u043f\u043e\u0438\u043d\u0442\u0430, \u0432\u0442\u043e\u0440\u043e\u0439 \u0438\u043c\u044f \u043f\u043e\u0438\u043d\u0442\u0430export const root = Point0.lets('root', 'root')  \/\/ ...  .root()\/\/ \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u043b\u043e \u043a\u0440\u0438\u043d\u0436\u043e\u0432\u043e, \u043d\u043e \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u0432\u0430\u043b\u0438\u0434\u043d\u043e<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0442\u043c\u0435\u0447\u0443, \u0447\u0442\u043e \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u043c\u0435\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u0440\u0443\u0442\u0430. \u042d\u0442\u043e \u043d\u0443\u0436\u043d\u043e, \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0438\u043c\u0435\u0442\u044c \u0431\u043e\u043b\u0435\u0435 \u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440, \u0435\u0441\u0442\u044c \u0441\u0430\u0439\u0442, \u0438 \u0435\u0441\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043d\u0430 \u044d\u043a\u0441\u043f\u043e, \u0438 \u0430\u0434\u043c\u0438\u043d\u043a\u0443 \u043c\u044b \u0442\u043e\u0436\u0435 \u0440\u0435\u0448\u0438\u043b\u0438 \u0438\u043c\u0435\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c (\u044f \u0442\u0430\u043a \u043d\u0435 \u0434\u0435\u043b\u0430\u044e, \u0430\u0434\u043c\u0438\u043d\u043a\u0443 \u043f\u0440\u043e\u0449\u0435 \u0438\u043c\u0435\u0442\u044c \u0432 \u043e\u0434\u043d\u043e\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0441 \u0441\u0430\u0439\u0442\u043e\u043c, \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0432\u0441\u0435 \u0447\u0430\u043d\u043a\u0438 \u043f\u043e\u0434\u0433\u0440\u0443\u0436\u0430\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0430\u043c \u0433\u0434\u0435 \u043d\u0430\u0434\u043e). \u0422\u043e\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0440\u0443\u0442\u044b \u043e\u0442 \u0440\u0443\u0442\u043e\u0432:<\/p>\n<pre><code>\/\/ \u0432\u043e\u0442 \u043e\u0442 \u044d\u0442\u043e\u0433\u043e \u0440\u0443\u0442\u0430 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0440\u0443\u0442\u044b, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0447\u0438\u0441\u0442\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0435 \u044d\u043a\u0448\u0435\u043d\u044b,\/\/ \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0432\u0435\u0431\u0445\u0443\u043a\u0438, \u0438 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u043a\u0432\u0435\u0440\u0438export const root = Point0.lets  .root()  \/\/ \u0442\u0443\u0442 \u0442\u043e\u0433\u0434\u0430 \u043d\u0435 \u043d\u0430\u0434\u043e \u0432\u0448\u0438\u0432\u0430\u0442\u044c .loading(), .error(), \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435, \u0438\u0445 \u0432\u043e\u0448\u044c\u0451\u043c \u0434\u043b\u044f \u0440\u0443\u0442\u0430 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e  \/\/ ...  .root()\/\/ \u0432\u043e\u0442 \u043e\u0442 \u044d\u0442\u043e\u0433\u043e \u0440\u0443\u0442\u0430 \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0441\u0430\u0439\u0442\u0430export const siteRoot = root.lets  .root()  \/\/ ...  .root()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>\/\/ \u0432\u043e\u0442 \u043e\u0442 \u044d\u0442\u043e\u0433\u043e \u0440\u0443\u0442\u0430 \u0431\u0443\u0434\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0430\u0434\u043c\u0438\u043d\u043a\u0438export const adminRoot = root.lets  .root()  \/\/ ...  .root()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>\/\/ \u0432 \u044d\u043a\u0441\u043f\u043e \u0441\u0432\u043e\u0439 \u0440\u043e\u0443\u0442\u0435\u0440, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043c\u044b \u043e\u0442 \u043d\u0435\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u0435 \u0431\u0443\u0434\u0435\u043c,\/\/ \u043d\u043e \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u0432\u0435\u0440\u0438, \u043c\u0443\u0442\u0430\u0446\u0438\u0438, \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u044b, \u0438 \u0442\u0434export const expoRoot = root.lets  .root()  \/\/ ...  .root()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/root\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u0440\u0443\u0442<\/a>.<\/p>\n<h2>Base<\/h2>\n<p>\u0420\u0435\u0437\u043e\u043d\u043d\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c, \u0447\u0442\u043e \u0440\u0430\u0437 \u0443\u0436 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043e\u0431\u0449\u0438\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043f\u043e\u0438\u043d\u0442\u043e\u0432, \u0438\u043d\u043e\u0433\u0434\u0430 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043b\u0438\u0448\u044c \u0434\u043b\u044f \u0447\u0430\u0441\u0442\u0438 \u043f\u043e\u0438\u043d\u0442\u043e\u0432, \u0430 \u043d\u0435 \u0432\u0441\u0435\u0445. \u0422\u043e\u0433\u0434\u0430 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c <code>base<\/code>, \u0438 \u043f\u043e\u0442\u043e\u043c \u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0438\u043d\u0442\u044b \u043e\u0442 \u043d\u0435\u0433\u043e.<\/p>\n<pre><code>export const base = root.lets  .base()  .queryOptions({    retryOnMount: true,    \/\/ \u043b\u044e\u0431\u044b\u0435 \u043e\u0432\u0435\u0440\u0440\u0430\u0439\u0434\u044b \u0442\u0443\u0442  })  \/\/ \u043b\u044e\u0431\u044b\u0435 \u043e\u0432\u0435\u0440\u0440\u0430\u0439\u0434\u044b \u043f\u0440\u043e\u0447\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u043e\u0432 \u0442\u0430\u043a\u0436\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b  \/\/ \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0434\u0440\u0443\u0433\u043e\u0439 \u043b\u0430\u0434\u0438\u043d\u0433 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442  .loading(() =&gt; {    return &lt;MySpecialSpinner \/&gt;  })  .base()export const specialPage = base.lets.page('\/special').page(() =&gt; {  return &lt;div&gt;Special Page&lt;\/div&gt;})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043f\u043e \u0441\u0443\u0442\u0438 \u043c\u043d\u0435 \u043d\u0435 \u043e\u0441\u043e\u0431\u043e-\u0442\u043e \u0438 \u043f\u0440\u0438\u0433\u043e\u0436\u0434\u0430\u0435\u0442\u0441\u044f. \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043f\u043b\u0430\u0433\u0438\u043d\u044b, \u043f\u0440\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043f\u043e\u0437\u0436\u0435, \u0438 \u043e\u043d\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0438 \u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u043f\u043e\u0438\u043d\u0442\u0430 \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043c\u0435\u0442\u043e\u0434\u044b, \u0438 \u044d\u0442\u043e \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u043e\u043b\u0435\u0435 \u0443\u0434\u043e\u0431\u043d\u043e.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/base\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e base<\/a>.<\/p>\n<h2>Loading<\/h2>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0432\u0438\u0434\u0435\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043e\u0448\u0438\u0431\u043a\u0438, \u0430 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u043b\u043e\u0430\u0434\u0438\u043d\u0433\u0430 \u043d\u0430 \u043d\u0430\u0448\u0438\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u0445.<\/p>\n<pre><code>export const ideaPage = root.lets  .page('\/ideas\/:id')  .loading(() =&gt; {    return &lt;Spinner size=\"3xl\" className=\"m-auto\" \/&gt;  })  .loader(({ params }) =&gt; {    const idea = await prisma.idea.findUniqueOrThrow({      where: { id: params.id },    })    return { idea }  })  .page(({ data: { idea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{idea.title}&lt;\/h1&gt;      &lt;div&gt;{idea.content}&lt;\/div&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, <code>.loading()<\/code> \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u0442\u044c \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d \u0432 \u0446\u0435\u043f\u043e\u0447\u043a\u0435 \u0447\u0435\u0439\u043d\u0430 (\u0432 \u0441\u0430\u043c\u043e\u043c \u043f\u0435\u0439\u0434\u0436\u0435, \u0438\u043b\u0438 \u0433\u0434\u0435-\u0442\u043e \u0432 \u0435\u0433\u043e \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u0435) \u0434\u043e \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u043c\u044b \u0432\u0441\u0442\u0440\u0435\u0442\u0438\u043c\u0441\u044f \u0441 \u043c\u0435\u0442\u043e\u0434\u043e\u043c, \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0449\u0438\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u043b\u043e\u0430\u0434\u0438\u043d\u0433\u0430. \u0411\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0438\u0439 \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0439 <code>.loading()<\/code> \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442.<\/p>\n<p>\u0423\u0441\u043b\u043e\u0432\u0438\u0435 \u0442\u0430\u043a\u043e\u0435, \u0447\u0442\u043e \u0432 \u0437\u0430\u043c\u044b\u043a\u0430\u044e\u0449\u0438\u0439 <code>.page()<\/code> \u0434\u043e\u043b\u0436\u043d\u044b \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u043e\u043f\u0430\u0441\u0442\u044c \u0443\u0436\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u043b\u043e\u0430\u0434\u0438\u043d\u0433 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0445 \u0435\u0449\u0451 \u043d\u0435\u0442. \u0410 \u0442\u0430\u043a\u0436\u0435 \u044d\u0440\u0440\u043e\u0440 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0435\u0441\u043b\u0438 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0431\u044b\u043b\u0430 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0430 \u043e\u0448\u0438\u0431\u043a\u0430.<\/p>\n<p>\u041d\u0430\u0434\u043e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u0438 \u0432\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u043e\u043c ssr \u0432\u0441\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0443\u0436\u0435 \u043f\u043e\u0434\u0433\u0440\u0443\u0436\u0435\u043d\u044b, \u0437\u043d\u0430\u0447\u0438\u0442 \u043c\u044b \u043d\u0435 \u0443\u0432\u0438\u0434\u0438\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u0440\u0438 \u043f\u0435\u0440\u0432\u0438\u0447\u043d\u043e\u043c \u043e\u0442\u043a\u0440\u044b\u0442\u0438\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.<\/p>\n<p>\u041f\u0440\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435 \u043c\u0435\u0436\u0434\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438, \u0435\u0441\u043b\u0438 \u043c\u044b \u0432\u044b\u043a\u043b\u044e\u0447\u0438\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 (\u0432 \u0441\u0430\u043c\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0438\u043b\u0438 \u0432 \u0435\u0451 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u0435) <code>.prefetchPageOnNavigate('none')<\/code>, \u0442\u043e \u0442\u043e\u0433\u0434\u0430 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438, \u0432\u0435\u0434\u044c \u043c\u044b \u043d\u0435 \u0433\u0440\u0443\u0437\u0438\u043b\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u0435\u0440\u0435\u0434 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u043c.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0432\u043a\u043b\u044e\u0447\u0438\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 <code>.prefetchPageOnNavigate('pageDehydratedStateAndClientQuery')<\/code>, \u0442\u043e \u0442\u043e\u0433\u0434\u0430 \u043f\u0440\u0438 \u043a\u043b\u0438\u043a\u0435 \u043d\u0430 \u0441\u0441\u044b\u043b\u043a\u0443, \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043d\u0430\u0447\u043d\u0443\u0442 \u043f\u043e\u0434\u0433\u0440\u0443\u0436\u0430\u0442\u044c\u0441\u044f \u0434\u0430\u043d\u043d\u044b\u0435 (\u043d\u0435 html, \u0430 \u0438\u043c\u0435\u043d\u043d\u043e \u0441\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0435) \u0438 js \u0447\u0430\u043d\u043a\u0438 \u043d\u043e\u0432\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043c \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0451\u0442 \u043f\u0435\u0440\u0435\u0445\u043e\u0434, \u0438 \u0442\u043e\u0433\u0434\u0430 \u043c\u044b \u043d\u0430\u0448\u0435\u0433\u043e .loading() \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043d\u0435 \u0443\u0432\u0438\u0434\u0438\u043c.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u0432\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u043e\u0439 <code>.prefetchPageOnNavigate('pageDehydratedStateAndClientQuery')<\/code> \u0432\u0441\u0451 \u0436\u0435 \u043a\u0430\u043a-\u0442\u043e \u0434\u0430\u0442\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e \u043f\u043e\u043d\u044f\u0442\u044c, \u0447\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430, \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u044e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c NProgress \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440. \u0418 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0435\u0433\u043e \u043a\u0443\u0434\u0430-\u043d\u0438\u0431\u0443\u0434\u044c \u0432 \u043d\u0430\u0448 app.tsx:<\/p>\n<pre><code>import { useOnNavigate } from '@point0\/core\/navigation'import nprogress from 'nprogress'export const NProgress = () =&gt; {  useOnNavigate(() =&gt; {    \/\/ \u0432\u043e\u0442 \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043d\u0430\u0447\u0430\u043b\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043d\u0430 \u043d\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443    const timeout = setTimeout(() =&gt; {      nprogress.start()      \/\/ \u0432\u0434\u0440\u0443\u0433 \u043e\u0447\u0435\u043d\u044c \u0431\u044b\u0441\u0442\u0440\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u0441\u044f, \u0442\u043e\u0433\u0434\u0430 \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443    }, 30)    return () =&gt; {      \/\/ \u0432\u043e\u0442 \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0446\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043d\u0430 \u043d\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443      clearTimeout(timeout)      nprogress.done()    }  })  return null}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/loading-error\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0438 \u043e\u0448\u0438\u0431\u043a\u0438<\/a>.<\/p>\n<h2>Many Queries<\/h2>\n<p>\u0412 \u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u0442\u043a\u043d\u0443\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u043e\u0434\u043d\u043e\u0439 \u043a\u0432\u0435\u0440\u0438:<\/p>\n<pre><code>export const ideaBestQuery = root.lets  .query()  .loader(async () =&gt; {    const bestIdea = await prisma.idea.findFirst({      orderBy: {        rating: 'desc',      },    })    return { bestIdea }  })  .query()export const ideaPage = root.lets  .page('\/ideas\/:id')  .with(ideaViewQuery, ({ params }) =&gt; ({ id: params.id }))  .with(ideaBestQuery)  .page(    ({      \/\/ \u0432 data \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u043f\u0435\u0440\u0432\u0430\u044f \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u0430\u044f \u043a\u0432\u0435\u0440\u0438      data: { idea },      \/\/ \u043d\u043e \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 \u043c\u043d\u043e\u0436\u0435\u0441\u0442\u0432\u043e\u043c \u043a\u0432\u0435\u0440\u0438 \u044d\u0442\u043e\u0433\u043e \u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u043e\u0449\u0435 \u0434\u043e\u0431\u044b\u0442\u044c \u043d\u0443\u0436\u043d\u0443\u044e \u043a\u0432\u0435\u0440\u0438      \/\/ \u0447\u0435\u0440\u0435\u0437 queries, \u0433\u0434\u0435 \u0443\u0436\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043a\u0432\u0435\u0440\u0438 \u0445\u0440\u0430\u043d\u044f\u0442\u0441\u044f \u0432 \u043c\u0430\u0441\u0441\u0438\u0432\u0435 \u0432 \u043f\u043e\u0440\u044f\u0434\u043a\u0435 \u0438\u0445 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0438\u044f      queries: [ideaViewQueryResult, ideaBestQueryResult],    }) =&gt; (      &lt;div&gt;        &lt;h1&gt;{ideaViewQueryResult.data.idea.title}&lt;\/h1&gt;        &lt;div&gt;{ideaViewQueryResult.data.idea.content}&lt;\/div&gt;        &lt;hr \/&gt;        &lt;h2&gt;Best Idea&lt;\/h2&gt;        &lt;div&gt;{ideaBestQueryResult.data.bestIdea.title}&lt;\/div&gt;      &lt;\/div&gt;    ),  )<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0443\u0442 \u043f\u0440\u0430\u0432\u0438\u043b\u043e \u0442\u0430\u043a\u043e\u0435, \u0447\u0442\u043e \u0432\u0441\u0435 \u043a\u0432\u0435\u0440\u0438, \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0432 <code>.with()<\/code>, \u0432\u044b\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f \u043f\u0430\u0440\u0430\u043b\u043b\u0435\u043b\u044c\u043d\u043e \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e, \u043b\u043e\u0430\u0434\u0438\u043d\u0433 \u043c\u044b \u0432\u0438\u0434\u0438\u043c \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u044f\u0442\u0441\u044f \u0432\u0441\u0435. \u041e\u0448\u0438\u0431\u043a\u0443 \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u043f\u0435\u0440\u0432\u0443\u044e \u043f\u043e\u043f\u0430\u0432\u0448\u0443\u044e\u0441\u044f.<\/p>\n<p>\u041a\u043e\u0433\u0434\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u0447\u0435\u043c 1 \u043a\u0432\u0435\u0440\u0438, \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043f\u0435\u0440\u0435\u0434 \u0440\u0435\u043d\u0434\u0435\u0440\u043e\u043c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u043e\u0435 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435, \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c <code>.mapper()<\/code>:<\/p>\n<pre><code>export const ideaPage = root.lets  .page('\/ideas\/:id')  .with(ideaViewQuery, ({ params }) =&gt; ({ id: params.id }))  .with(ideaBestQuery)  .mapper(({ queries: [ideaViewQueryResult, ideaBestQueryResult] }) =&gt; ({    idea: ideaViewQueryResult.data.idea,    bestIdea: ideaBestQueryResult.data.bestIdea,  }))  .page(    ({      \/\/ \u0432 data \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u0432\u0441\u0451 \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u0432\u0435\u0440\u043d\u0443\u043b\u0438 \u0438\u0437 \u043c\u0430\u043f\u0435\u0440\u0430      data: { idea, bestIdea },    }) =&gt; (      &lt;div&gt;        &lt;h1&gt;{idea.title}&lt;\/h1&gt;        &lt;div&gt;{idea.content}&lt;\/div&gt;        &lt;hr \/&gt;        &lt;h2&gt;Best Idea&lt;\/h2&gt;        &lt;div&gt;{bestIdea.title}&lt;\/div&gt;      &lt;\/div&gt;    ),  )<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/with\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e .with()<\/a>, <a href=\"https:\/\/1gr14.dev\/point0\/latest\/mapper\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u043c\u0430\u043f\u043f\u0435\u0440<\/a>.<\/p>\n<h2>.with()<\/h2>\n<ul>\n<li>\n<p>\u0410 \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0432 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043a\u0432\u0435\u0440\u0435\u0439 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0438\u043d\u043f\u0443\u0442\u0430 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u0434\u0440\u0443\u0433\u043e\u0439 \u043a\u0432\u0435\u0440\u0438?<\/p>\n<\/li>\n<li>\n<p>\u0418\u043b\u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u0438\u043d\u043f\u0443\u0442\u0430 \u043a\u0432\u0435\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u0430\u043d\u043d\u044b\u0435 \u0432\u043e\u043e\u0431\u0449\u0435 \u0438\u0437 \u043a\u0430\u043a\u043e\u0433\u043e-\u0442\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0433\u043e \u0445\u0443\u043a\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0418\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u0441\u0442\u0430\u0442\u0443\u0441 \u043a\u0430\u0436\u0434\u043e\u0439 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u043a\u0432\u0435\u0440\u0438 \u0434\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430 \u0438\u0445 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u043e\u0442 \u0442\u0443\u0442 \u043d\u0430\u043c \u0438 \u043f\u0440\u0438\u0433\u043e\u0434\u044f\u0442\u0441\u044f \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 <code>.with()<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0440\u0430\u043d\u0435\u0435 \u043d\u0435 \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u043b\u0438.<\/p>\n<h3>.with() \u043a\u0430\u043a \u0438\u043d\u0436\u0435\u043a\u0442\u043e\u0440 \u043a\u0432\u0435\u0440\u0438<\/h3>\n<p>\u0420\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u0438\u043d\u0436\u0435\u043a\u0442 \u043e\u0434\u043d\u043e\u0439 \u043a\u0432\u0435\u0440\u0438 \u0432 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b:<\/p>\n<pre><code>\/\/ \u0432\u043e\u0442 \u044d\u0442\u043e \u043c\u044b \u0443\u0436\u0435 \u0432\u0438\u0434\u0435\u043b\u0438, \u0438 \u044d\u0442\u043e \u0443\u0434\u043e\u0431\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043aexport const prev_ideaPage = root.lets  .page('\/ideas\/:id')  .with(ideaViewQuery, ({ params }) =&gt; ({ id: params.id }))  .page(    ({      \/\/ \u0442\u0443\u0442 \u0443 \u043d\u0430\u0441 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438\u0437 \u043a\u0432\u0435\u0440\u0438      data: { idea },      \/\/ \u0442\u0443\u0442 \u0443 \u043d\u0430\u0441 \u0441\u0430\u043c\u0438 \u0437\u0430\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u043a\u0432\u0435\u0440\u0438      queries: [ideaViewQueryResult],    }) =&gt; &lt;h1&gt;{idea.title}&lt;\/h1&gt;,  )\/\/ \u043d\u043e \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432\u043e\u0442 \u0442\u0430\u043aexport const ideaPage = root.lets  .page('\/ideas\/:id')  .with(({ params }) =&gt; {    \/\/ \u043a\u0430\u0436\u0434\u044b\u0439 .with() \u0438\u043c\u0438\u0442\u0438\u0440\u0443\u0435\u0442 \u043e\u0431\u0451\u0440\u0442\u043a\u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430, \u043d\u0430\u0434 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c,    \/\/ \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0441\u0432\u043e\u0431\u043e\u0434\u043d\u043e \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0437\u0434\u0435\u0441\u044c \u043b\u044e\u0431\u044b\u0435 \u0445\u0443\u043a\u0438    \/\/ \u043d\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 useQuery() \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c data \u0438 queries \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u0430\u0445    return ideaViewQuery.useQuery({ id: params.id })  })  \/\/ \u0434\u0430\u043b\u0435\u0435 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439, \u0432\u0441\u0451 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0447\u0442\u043e \u0438 \u0432 prev_ideaPage  .page(({ data: { idea }, queries: [ideaViewQueryResult] }) =&gt; (    &lt;h1&gt;{idea.title}&lt;\/h1&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0420\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u0438\u043d\u0436\u0435\u043a\u0442 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u0438\u0445 \u043a\u0432\u0435\u0440\u0438 \u0432 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443:<\/p>\n<pre><code>\/\/ \u0432\u043e\u0442 \u044d\u0442\u043e \u043c\u044b \u0443\u0436\u0435 \u0432\u0438\u0434\u0435\u043b\u0438, \u0438 \u044d\u0442\u043e \u0443\u0434\u043e\u0431\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0430\u043aexport const prev_ideaPage = root.lets  .page('\/ideas\/:id')  .with(ideaViewQuery, ({ params }) =&gt; ({ id: params.id }))  .with(ideaBestQuery)  .page(({ queries: [ideaViewQueryResult, ideaBestQueryResult] }) =&gt; (    &lt;h1&gt;{idea.title}&lt;\/h1&gt;  ))\/\/ \u043d\u043e \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0432\u043e\u0442 \u0442\u0430\u043aexport const ideaPage = root.lets  .page('\/ideas\/:id')  .with(({ params }) =&gt; {    \/\/ \u043c\u043e\u0436\u043d\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043c\u0430\u0441\u0441\u0438\u0432 \u043a\u0432\u0435\u0440\u0438 \u043f\u0440\u044f\u043c\u043e \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e .with()    return [ideaViewQuery.useQuery({ id: params.id }), ideaBestQuery.useQuery()]  })  \/\/ \u0434\u0430\u043b\u0435\u0435 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439, \u0432\u0441\u0451 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0447\u0442\u043e \u0438 \u0432 prev_ideaPage  .page(({ queries: [ideaViewQueryResult, ideaBestQueryResult] }) =&gt; (    &lt;h1&gt;{ideaViewQueryResult.data.idea.title}&lt;\/h1&gt;    &lt;h2&gt;{ideaBestQueryResult.data.bestIdea.title}&lt;\/h2&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u043f\u043e\u0441\u043e\u0431 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0434\u043d\u043e\u0439 \u043a\u0432\u0435\u0440\u0438 \u0434\u043b\u044f \u0438\u043d\u043f\u0443\u0442\u0430 \u0432 \u0434\u0440\u0443\u0433\u0443\u044e \u043a\u0432\u0435\u0440\u0438:<\/p>\n<pre><code>export const ideaPage = root.lets  .page('\/ideas\/:id')  .with(({ params }) =&gt; {    const ideaViewQueryResult = ideaViewQuery.useQuery({ id: params.id })    \/\/ \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u0443 \u043d\u0430\u0441 \u0432 ideaViewQueryResult.data.idea.similarIds \u043b\u0435\u0436\u0430\u0442 id \u043f\u043e\u0445\u043e\u0436\u0438\u0445 \u0438\u0434\u0435\u0439    const ideaListQueryResult = ideaListQuery.useQuery(      \/\/ \u043f\u0435\u0440\u0432\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u044d\u0442\u043e \u0438\u043d\u043f\u0443\u0442 \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u043e,      \/\/ \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u0432\u0435\u0440\u043e\u044f\u0442\u043d\u043e \u0438\u043d\u043f\u0443\u0442 \u043e\u0436\u0438\u0434\u0430\u0435\u0442 ids \u0441\u0442\u0440\u043e\u0433\u043e \u043a\u0430\u043a \u043c\u0430\u0441\u0441\u0438\u0432,      \/\/ \u0430 \u043d\u0435 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u043b\u0438 \u0430\u043d\u0434\u0435\u0444\u0430\u0439\u043d\u0435\u0434, \u0438 \u0442\u043e\u0433\u0434\u0430 \u043f\u0440\u0438\u0434\u0451\u0442\u0441\u044f \u0434\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c as never      \/\/ \u0447\u0442\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u0443\u0436\u0430\u0441\u043d\u043e, \u0438 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431, \u043f\u0440\u043e \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u0434\u0430\u043b\u044c\u0448\u0435 \u043f\u043e \u0441\u0442\u0430\u0442\u044c\u0435      { ids: ideaViewQueryResult.data?.idea.similarIds } as never,      \/\/ \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u043a\u0438\u043d\u0443\u0442\u044c \u043e\u043f\u0446\u0438\u0438 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0439 useQuery \u0438\u0437 react-query      \/\/ \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043d\u0435 \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u043a\u0432\u0435\u0440\u0438 \u043f\u043e\u043a\u0430 \u043d\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u0441\u044f ideaViewQueryResult      { enabled: !!ideaViewQueryResult.data },    )    return [ideaViewQueryResult, ideaListQueryResult]  })  \/\/ \u0443 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u043e\u0439 \u043a\u0432\u0435\u0440\u0438 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u0442\u0430\u0442\u0443\u0441 \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e pending, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0434\u043e\u0441\u044e\u0434\u0430 \u043d\u0435 \u0434\u043e\u0439\u0434\u0451\u043c,  \/\/ \u043f\u043e\u043a\u0430 \u043d\u0435 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u0441\u044f ideaViewQueryResult  .page(({ queries: [ideaViewQueryResult, ideaListQueryResult] }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{ideaViewQueryResult.data.idea.title} &lt;\/h1&gt;      &lt;h2&gt;\u041f\u043e\u0445\u043e\u0436\u0438\u0435 \u0438\u0434\u0435\u0438&lt;\/h2&gt;      &lt;ul&gt;        {ideaListQueryResult.data.ideas.map((idea) =&gt; (          &lt;li key={idea.id}&gt;{idea.title}&lt;\/li&gt;        ))}      &lt;\/ul&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u043e \u043c\u043d\u0435 \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u043d\u0440\u0430\u0432\u044f\u0442\u0441\u044f \u044d\u0442\u0438 \u0442\u0440\u044e\u043a\u0438 \u0441 <code>enabled<\/code>, \u0434\u0430 \u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u0433\u0440\u043e\u043c\u043e\u0437\u0434\u043a\u043e \u043a\u0430\u043a-\u0442\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0441\u0442\u044c \u0438 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435, \u043e\u0431 \u044d\u0442\u043e\u043c \u0432 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0445 \u0440\u0430\u0437\u0434\u0435\u043b\u0430\u0445 <code>.with()<\/code><\/p>\n<h3>.with() \u043a\u0430\u043a \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f<\/h3>\n<p>\u0412\u043e\u0442 \u044d\u0442\u043e \u043d\u043e\u0432\u043e\u0435:<\/p>\n<pre><code>export const strangePage = root.lets  .page('\/strange')  .with(({ LoadingComponent, ErrorComponent }) =&gt; {    \/\/ \u0412 LoadingComponent \u043b\u0435\u0436\u0438\u0442 \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u0440\u0430\u043d\u0435\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u043b\u0438 \u0432 .loading() \u043c\u0435\u0442\u043e\u0434\u0435    \/\/ \u0412 ErrorComponent \u043b\u0435\u0436\u0438\u0442 \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u0440\u0430\u043d\u0435\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u043b\u0438 \u0432 .error() \u043c\u0435\u0442\u043e\u0434\u0435    const [isLoading, setIsLoading] = useState(true)    const error = useState(() =&gt;      Math.random() &gt; 0.5 ? new Error('\u041a\u0430\u043a \u0436\u0435 \u044f \u043e\u0448\u0438\u0431\u0430\u043b\u0430\u0441\u044c') : undefined,    )    useEffect(() =&gt; {      setTimeout(() =&gt; {        setIsLoading(false)      }, 1000)    }, [])    if (isLoading) {      return &lt;LoadingComponent \/&gt;    }    if (error) {      return &lt;ErrorComponent error={error} \/&gt;    }    \/\/ return undefined    \/\/ \u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c, \u0437\u043d\u0430\u0447\u0438\u0442 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b  })  \/\/ \u041c\u044b \u043d\u0435 \u0434\u043e\u0439\u0434\u0451\u043c \u0434\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0430, \u043f\u043e\u043a\u0430 \u0432\u0441\u0435 .with() \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0440\u0430\u0437\u0440\u0435\u0437\u043e\u043b\u0432\u043b\u0435\u043d\u044b  .page(() =&gt; &lt;h1&gt;\u042f \u0447\u0442\u043e-\u0442\u043e \u0433\u0440\u0443\u0437\u0438\u043b\u0430, \u0447\u0442\u043e \u043d\u0435 \u0437\u043d\u0430\u044e, \u043d\u043e \u0443 \u043c\u0435\u043d\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c&lt;\/h1&gt;)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u043f\u0440\u0438\u043c\u0435\u0440 \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u0441 \u0434\u0440\u0443\u0433\u043e\u0439 \u043d\u043e\u0442\u0430\u0446\u0438\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043c\u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435:<\/p>\n<pre><code>export const strangePage = root.lets  .page('\/strange')  .with(() =&gt; {    const [isLoading, setIsLoading] = useState(true)    const error = useState(() =&gt;      Math.random() &gt; 0.5 ? new Error('\u041a\u0430\u043a \u0436\u0435 \u044f \u043e\u0448\u0438\u0431\u0430\u043b\u0430\u0441\u044c') : undefined,    )    useEffect(() =&gt; {      setTimeout(() =&gt; {        setIsLoading(false)      }, 1000)    }, [])    if (isLoading) {      \/\/ \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0437\u0430\u0440\u0435\u0437\u0435\u0440\u0432\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0441\u043b\u043e\u0432\u043e 'loading'      \/\/ \u044d\u0442\u043e \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0447\u0442\u043e \u0438 return &lt;LoadingComponent \/&gt;      return 'loading'    }    if (error) {      \/\/ \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 instanceof Error      \/\/ \u044d\u0442\u043e \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0447\u0442\u043e \u0438 return &lt;ErrorComponent error={error} \/&gt;      return error    }    \/\/ return undefined    \/\/ \u0438\u043b\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c, \u0437\u043d\u0430\u0447\u0438\u0442 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043c\u0435\u0442\u043e\u0434\u044b  })  .page(() =&gt; &lt;h1&gt;\u042f \u0447\u0442\u043e-\u0442\u043e \u0433\u0440\u0443\u0437\u0438\u043b\u0430, \u0447\u0442\u043e \u043d\u0435 \u0437\u043d\u0430\u044e, \u043d\u043e \u0443 \u043c\u0435\u043d\u044f \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c&lt;\/h1&gt;)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>.with() \u043a\u0430\u043a \u0438\u043d\u0436\u0435\u043a\u0442\u043e\u0440 \u043f\u0440\u043e\u043f\u043e\u0432<\/h3>\n<p>\u0412\u043e\u0442 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u043c\u044b \u0432 \u043e\u0434\u043d\u043e\u043c <code>.with()<\/code> \u0445\u0443\u043a\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u0438\u0439, \u0438 \u0445\u043e\u0442\u0438\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u0434\u0440\u0443\u0433\u043e\u043c <code>.with()<\/code> \u0445\u0443\u043a\u0435, \u0438\u043b\u0438 \u043d\u0430 \u0441\u0430\u043c\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435. \u0422\u043e\u0433\u0434\u0430 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u043e\u043a\u0438\u0434\u044b\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u043f\u0441\u044b \u0432\u043d\u0438\u0437 \u043f\u043e \u043c\u0435\u0442\u043e\u0434\u0430\u043c \u043f\u043e\u0438\u043d\u0442\u0430.<\/p>\n<pre><code>export const strangePage = root.lets  .page('\/')  .with(() =&gt; {    \/\/ \u0435\u0441\u043b\u0438 \u043c\u044b \u0432\u0435\u0440\u043d\u0443\u043b\u0438 \u043d\u0435 \u0440\u0435\u0430\u043a\u0442 \u044d\u043b\u0435\u043c\u0435\u043d\u0442, \u043d\u0435 instanceof Error, \u043d\u0435 \u0441\u043b\u043e\u0432\u043e 'loading', \u043d\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043a\u0432\u0435\u0440\u0438,    \/\/ \u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442 \u043c\u044b \u0432\u0435\u0440\u043d\u0443\u043b\u0438 \u043f\u0440\u043e\u043f\u0441\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u0430\u0445 \u043f\u043e\u0438\u043d\u0442\u0430    return {      x: 1,      y: 2,    }  })  .with(({ props: { x, y } }) =&gt; {    return {      a: x * 10,      b: y * 100,      \/\/ \u043f\u0440\u043e\u043f\u0441\u044b \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0434\u0430\u0436\u0435 \u0441 \u0434\u0440\u0443\u0433\u0438\u043c \u0442\u0438\u043f\u043e\u043c      \/\/ \u0432 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0435 \u043c\u044b \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0431\u0443\u0434\u0435\u043c \u0432\u0438\u0434\u0435\u0442\u044c \u043a\u0430\u043a\u0438\u0435 \u043d\u0430\u0434\u043e \u0442\u0438\u043f\u044b \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 \u043c\u0435\u0442\u043e\u0434\u0430\u0445 \u043f\u043e\u0438\u043d\u0442\u0430      \/\/ \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u043e \u0441\u0443\u0442\u0438 \u044d\u0442\u043e nextProps = {...prevProps, ...newProps}      x: '\u044f \u0440\u0435\u0448\u0438\u043b, \u0447\u0442\u043e \u0431\u0443\u0434\u0443 \u0441\u0442\u0440\u043e\u043a\u043e\u0439',    }  })  .page(({ props: { a, b, x, y } }) =&gt; (    &lt;h1&gt;      {a} {b} {x} {y}    &lt;\/h1&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>.with() \u043a\u0430\u043a \u0432\u0440\u0430\u043f\u0435\u0440<\/h3>\n<p>\u0412 \u043f\u0440\u043e\u043f\u0441\u0430\u0445 \u043c\u0435\u0442\u043e\u0434\u0430 <code>.with()<\/code> \u0442\u0430\u043a\u0436\u0435 \u043b\u0435\u0436\u0438\u0442 <code>children<\/code>, \u0438 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e \u0441\u0443\u0442\u0438 \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u044c \u0442\u043e, \u0447\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 <code>.with()<\/code> \u0438 \u0441\u0430\u043c <code>.page()<\/code> \u0432 \u043b\u044e\u0431\u0443\u044e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044e:<\/p>\n<pre><code>export const ideaPage = root.lets  .page('\/ideas\/:id')  .with(({ children }) =&gt; {    return &lt;div style={{ border: '1px solid red' }}&gt;{children}&lt;\/div&gt;  })  .page(() =&gt; &lt;div id=\"page\"&gt;Hello!&lt;\/div&gt;)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>.with() \u043a\u0430\u043a \u0438\u0434\u0435\u044f<\/h3>\n<p>\u0412 \u043e\u0431\u0449\u0435\u043c \u044f \u043d\u0435 \u0437\u043d\u0430\u044e, \u043a\u0430\u043a \u043a\u043e\u0440\u043e\u0442\u043a\u043e \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0447\u0442\u043e \u044f \u0445\u043e\u0442\u0435\u043b \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0432 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u0451\u043c\u043e\u0432 \u043f\u043e\u043a\u0430\u0436\u0443. \u041f\u043e\u043d\u0430\u0447\u0430\u043b\u0443 \u0431\u0443\u0434\u0435\u0442 \u0435\u0440\u0443\u043d\u0434\u0430 \u043a\u0430\u043a\u0430\u044f-\u0442\u043e, \u0430 \u043f\u043e\u0442\u043e\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0445\u043e\u0440\u043e\u0448\u043e. \u042d\u0442\u043e \u0442\u043e \u043a \u0447\u0435\u043c\u0443 \u044f \u043f\u0440\u0438\u0448\u0451\u043b \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0430 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0435, \u0438 \u044d\u0442\u043e \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u0443\u0434\u043e\u0431\u043d\u043e, \u043a\u043e\u0433\u0434\u0430 \u043f\u0438\u0448\u0435\u0448\u044c \u0443\u0436\u0435 \u043d\u0435 \u043f\u0435\u0440\u0432\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0448\u044c \u0431\u043e\u043b\u0435\u0435 \u0441\u043b\u043e\u0436\u043d\u044b\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e \u0440\u0430\u0441\u043a\u0440\u043e\u044e\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0438\u0437\u0443\u0447\u0438\u043c \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0432 \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0435\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435.<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0442\u0435\u043f\u0435\u0440\u044c \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0437\u043d\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u0430\u043a \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0435\u0449\u0451 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>.with()<\/code> \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u0434\u0430\u043d\u043d\u044b\u0445 \u043e\u0434\u043d\u043e\u0439 \u043a\u0432\u0435\u0440\u0438 \u0432 \u0438\u043d\u043f\u0443\u0442\u0435 \u0434\u0440\u0443\u0433\u043e\u0439 \u043a\u0432\u0435\u0440\u0438:<\/p>\n<pre><code>export const ideaPage = root.lets  .page('\/ideas\/:id')  .with(ideaViewQuery, ({ params }) =&gt; ({ id: params.id }))  .with(({ queries: [ideaViewQueryResult] }) =&gt; {    \/\/ \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 .page() \u0432\u0441\u0435 .with() \u043f\u043e\u043b\u0443\u0447\u0430\u044e\u0442 \u0432 queries \u0432 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0438 \u043d\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0451\u043d\u043d\u043e\u0441\u0442\u0438,    \/\/ \u0442\u043e \u0435\u0441\u0442\u044c \u0442\u0443\u0442 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438 \u043e\u0448\u0438\u0431\u043a\u0430, \u0438 \u043b\u043e\u0430\u0434\u0438\u043d\u0433, \u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043a\u0432\u0435\u0440\u0438    \/\/ \u0438 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043a\u0430\u043a \u0445\u043e\u0442\u0438\u043c \u0438\u0445 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c    if (ideaViewQueryResult.isError) {      \/\/ \u0438\u0437\u0443\u0447\u0435\u043d\u043d\u043e\u0435 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 .with() \u043a\u0430\u043a \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f      return ideaViewQueryResult.error    }    if (ideaViewQueryResult.isLoading) {      \/\/ \u0438\u0437\u0443\u0447\u0435\u043d\u043d\u043e\u0435 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 .with() \u043a\u0430\u043a \u043c\u0435\u043d\u0435\u0434\u0436\u0435\u0440 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f      return 'loading'    }    \/\/ \u0438\u0437\u0443\u0447\u0435\u043d\u043d\u043e\u0435 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 .with() \u043a\u0430\u043a \u0438\u043d\u0436\u0435\u043a\u0442\u043e\u0440 \u043f\u0440\u043e\u043f\u043e\u0432    return { similarIds: ideaViewQueryResult.data.idea.similarIds }  })  \/\/ \u0434\u043e \u044d\u0442\u043e\u0433\u043e .with() \u043c\u044b \u043d\u0435 \u0434\u043e\u0439\u0434\u0451\u043c, \u043f\u043e\u043a\u0430 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u043f\u0435\u0440\u0435\u0445\u0432\u0430\u0442\u044b\u0432\u0430\u043b \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0447\u0435\u0440\u0435\u0437 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435  .with(ideaListQuery, ({ props: { similarIds } }) =&gt; ({ ids: similarIds }))  .page(({ queries: [ideaViewQueryResult, ideaListQueryResult] }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{ideaViewQueryResult.data.idea.title} &lt;\/h1&gt;      &lt;h2&gt;\u041f\u043e\u0445\u043e\u0436\u0438\u0435 \u0438\u0434\u0435\u0438&lt;\/h2&gt;      &lt;ul&gt;        {ideaListQueryResult.data.ideas.map((idea) =&gt; (          &lt;li key={idea.id}&gt;{idea.title}&lt;\/li&gt;        ))}      &lt;\/ul&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u043e \u043e\u043f\u044f\u0442\u044c \u0436\u0435 \u0432\u0441\u0435 \u044d\u0442\u0438 \u0440\u0443\u0447\u043d\u044b\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f\u043c\u0438 \u043a\u0432\u0435\u0440\u0438 \u043c\u043d\u0435 \u043d\u0435 \u043d\u0440\u0430\u0432\u044f\u0442\u0441\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u044b\u043b \u0441\u043e\u0437\u0434\u0430\u043d \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0445\u0435\u043b\u043f\u0435\u0440 <code>resolve()<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 \u0432\u0445\u043e\u0434 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043a\u0432\u0435\u0440\u0438, \u043f\u043e\u043a\u0430 \u043e\u043d\u0430 \u0433\u0440\u0443\u0437\u0438\u0442\u0441\u044f \u0438\u043b\u0438 \u043e\u0448\u0438\u0431\u0430\u0435\u0442\u0441\u044f, \u043e\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043b\u043e\u0430\u0434\u0438\u043d\u0433 \u0438\u043b\u0438 \u044d\u0440\u0440\u043e\u0440 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u0430 \u043f\u043e\u0441\u043b\u0435 \u0443\u0441\u043f\u0435\u0445\u0430 \u043c\u0430\u043f\u0438\u0442 \u0435\u0451 data \u043d\u0430 props, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u043f\u0440\u043e\u043a\u0438\u043d\u0443\u0442\u044b \u0434\u0430\u043b\u044c\u0448\u0435. \u0418\u0442\u043e\u0433\u043e \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0447\u0442\u043e \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432\u044b\u0448\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code>export const ideaPage = root.lets  .page('\/ideas\/:id')  .with(ideaViewQuery, ({ params }) =&gt; ({ id: params.id }))  .with(({ queries: [ideaViewQueryResult], resolve }) =&gt; {    \/\/ \u0432\u043e\u0442 \u044d\u0442\u043e \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0447\u0442\u043e \u0432 \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u0432\u044b\u0448\u0435 \u043d\u043e \u043a\u043e\u0440\u043e\u0442\u043a\u043e    return resolve(ideaViewQueryResult, ({ data }) =&gt; ({      similarIds: data.idea.similarIds,    }))  })  .with(ideaListQuery, ({ props: { similarIds } }) =&gt; ({ ids: similarIds }))  .page(({ queries: [ideaViewQueryResult, ideaListQueryResult] }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{ideaViewQueryResult.data.idea.title} &lt;\/h1&gt;      &lt;h2&gt;\u041f\u043e\u0445\u043e\u0436\u0438\u0435 \u0438\u0434\u0435\u0438&lt;\/h2&gt;      &lt;ul&gt;        {ideaListQueryResult.data.ideas.map((idea) =&gt; (          &lt;li key={idea.id}&gt;{idea.title}&lt;\/li&gt;        ))}      &lt;\/ul&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u043e \u043e\u043f\u044f\u0442\u044c \u0436\u0435 \u0433\u0440\u043e\u043c\u043e\u0437\u0434\u043a\u043e. \u0410 \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430, \u0440\u0435\u0437\u043e\u043b\u0432\u0438\u0442\u044c \u0434\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u044f \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u044c\u0441\u044f \u0447\u0430\u0441\u0442\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0431\u044b\u043b\u0430 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u0435\u0449\u0451 \u0431\u043e\u043b\u0435\u0435 \u043a\u043e\u0440\u043e\u0442\u043a\u0430\u044f \u043d\u043e\u0442\u0430\u0446\u0438\u044f, \u0432\u0448\u0438\u0432\u0430\u044e\u0449\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b \u0440\u0435\u0437\u043e\u043b\u0432 \u043f\u0440\u044f\u043c\u043e \u0432 \u0441\u0430\u043c \u043a\u0432\u0435\u0440\u0438 \u0438\u043d\u0436\u0435\u043a\u0448\u0435\u043d:<\/p>\n<pre><code>export const ideaPage = root.lets  .page('\/ideas\/:id')  .with(    ideaViewQuery,    ({ params }) =&gt; ({ id: params.id }),    \/\/ \u0442\u0443\u0442 \u043c\u043e\u0433\u043b\u0438 \u0431\u044b\u0442\u044c \u043e\u043f\u0446\u0438\u0438 \u0434\u043b\u044f useQuery, \u043d\u043e \u043d\u0430\u043c \u0442\u0443\u0442 \u043e\u043d\u0438 \u043d\u0435 \u043d\u0443\u0436\u043d\u044b    undefined,    ({ data }) =&gt; ({      similarIds: data.idea.similarIds,    }),  )  .with(ideaListQuery, ({ props: { similarIds } }) =&gt; ({ ids: similarIds }))  .page(({ queries: [ideaViewQueryResult, ideaListQueryResult] }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{ideaViewQueryResult.data.idea.title} &lt;\/h1&gt;      &lt;h2&gt;\u041f\u043e\u0445\u043e\u0436\u0438\u0435 \u0438\u0434\u0435\u0438&lt;\/h2&gt;      &lt;ul&gt;        {ideaListQueryResult.data.ideas.map((idea) =&gt; (          &lt;li key={idea.id}&gt;{idea.title}&lt;\/li&gt;        ))}      &lt;\/ul&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0449\u0451 \u044d\u0442\u043e\u0442 <code>resolve()<\/code> \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043c\u043e\u0447\u044c, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u043a\u0432\u0435\u0440\u0438, \u043d\u043e \u043d\u0435 \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0430 \u043f\u043e\u043f\u0430\u0434\u0430\u043b\u0430 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 queries, \u0438\u043b\u0438 \u0432 \u0441\u0430\u043c data. \u042d\u0442\u043e \u0431\u044b\u0432\u0430\u0435\u0442 \u043d\u0443\u0436\u043d\u043e, \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0445\u043e\u0442\u0438\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u044e\u0437\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043c\u044b \u0437\u0430\u043f\u0440\u043e\u0441\u0438\u043b\u0438 \u0447\u0435\u0440\u0435\u0437 \u043a\u0432\u0435\u0440\u0438 \u0433\u0434\u0435-\u0442\u043e \u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u043f\u043e\u0438\u043d\u0442\u0430\u0445, \u0442\u043e \u0435\u0441\u0442\u044c \u043f\u043e \u0441\u0443\u0442\u0438 \u043f\u0435\u0440\u0432\u044b\u043c, \u043d\u043e \u0445\u043e\u0442\u0438\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0435\u0433\u043e \u0432 props, \u0430 \u043d\u0435 \u0432 data. \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 data \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0438\u043c\u0435\u0442\u044c \u0441\u0430\u043c\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b:<\/p>\n<pre><code>export const ideaPage = root.lets  .page('\/ideas\/:id')  .with(({ resolve }) =&gt; {    \/\/ \u0442\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u043d\u0435 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u043b\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 useQuery \u0438\u0437 \u044d\u0442\u043e\u0433\u043e .with()    \/\/ \u0437\u043d\u0430\u0447\u0438\u0442, \u043e\u043d \u0438 \u043d\u0435 \u043f\u043e\u043f\u0430\u0434\u0451\u0442 \u043d\u0438 \u0432 \u043c\u0430\u0441\u0441\u0438\u0432 queries, \u043d\u0438 \u0432 data    \/\/ \u0430 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f resolve() \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0435\u0433\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 props    return resolve(getMeQuery.useQuery(), ({ data }) =&gt; ({ me: data.me }))  })  .with(ideaViewQuery, ({ params }) =&gt; ({ id: params.id }))  .page(({ data: { idea }, props: { me } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{idea.title} &lt;\/h1&gt;      &lt;p&gt;Hello, {me.name}!&lt;\/p&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/with\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e .with()<\/a>.<\/p>\n<h2>Context<\/h2>\n<p>\u0423 \u043d\u0430\u0441 \u043d\u0430 \u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u043a\u0432\u0435\u0440\u0438, \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u0438 \u043f\u0440\u043e\u0447\u0438\u0435 \u043f\u043e\u0438\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0438\u043c\u0435\u0442\u044c \u043b\u043e\u0430\u0434\u0435\u0440, \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e 1 \u043b\u043e\u0430\u0434\u0435\u0440. \u041d\u043e \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0438\u043c\u0435\u0442\u044c \u043a\u0430\u043a\u0443\u044e-\u0442\u043e \u043e\u0431\u0449\u0443\u044e \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u0443\u044e \u043b\u043e\u0433\u0438\u043a\u0443 \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u043f\u043e\u0438\u043d\u0442\u043e\u0432. \u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c, \u0445\u043e\u0442\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u043c\u043e\u0433\u043b\u0438 \u0432\u0438\u0434\u0435\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0438\u043b\u0438 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u043a\u0432\u0435\u0440\u0438\/\u043c\u0443\u0442\u0430\u0446\u0438\u044e.<\/p>\n<pre><code>\/\/ \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0445\u0435\u043b\u043f\u0435\u0440, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u044e\u0437\u0435\u0440\u0430 \u0438\u0437 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\/\/ \u0447\u0435\u0440\u0435\u0437 \u0445\u0435\u0430\u0434\u0435\u0440\u044b \u0438\u043b\u0438 \u043a\u0430\u043a \u0432\u0430\u043c \u0443\u0434\u043e\u0431\u043d\u043e, \u043c\u044b \u0435\u0449\u0451 \u043f\u043e\u0433\u043e\u0432\u043e\u0440\u0438\u043c \u043f\u0440\u043e \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044eimport { getMe } from '@\/lib\/auth'export const ideaPage = root.lets  .page('\/ideas\/:id')  .ctx(({ request }) =&gt; {    const me = await getMe(request)    if (!me) {      throw new Error('Unauthorized')    }    \/\/ \u0447\u0442\u043e \u043c\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c \u0438\u0437 .ctx() \u0442\u043e \u043f\u043e\u043f\u0430\u0434\u0430\u0435\u0442 \u0432 ctx \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0445 .loader() \u0438 .ctx()    \/\/ nextCtx = {...prevCtx, ...newCtx}    return { me }  })  \/\/ \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u043c\u0435\u0442\u044c \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443\u0433\u043e\u0434\u043d\u043e .ctx()  \/\/ \u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d .loader() \u043d\u0430 \u043f\u043e\u0438\u043d\u0442  .loader(async ({ params }) =&gt; {    const idea = await prisma.idea.findUniqueOrThrow({      where: { id: params.id },    })    return { idea }  })  .page(({ data: { idea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{idea.title}&lt;\/h1&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e \u0432\u044b\u0437\u0432\u0430\u0442\u044c <code>await getMe(request)<\/code> \u043f\u0440\u044f\u043c\u043e \u0432 \u0442\u0435\u043b\u0435 \u0441\u0430\u043c\u043e\u0433\u043e \u043b\u043e\u0430\u0434\u0435\u0440\u0430, \u043d\u043e \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 <code>.ctx()<\/code> \u0432\u044b \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u0431\u0443\u0434\u0435\u0442\u0435 \u0438\u043c\u0435\u0442\u044c \u0433\u0434\u0435-\u0442\u043e \u0432 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u043c \u043f\u043e\u0438\u043d\u0442\u0435, \u0438\u043b\u0438 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u043f\u043b\u0430\u0433\u0438\u043d\u044b (\u0443\u0436\u0435 \u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043f\u0440\u043e \u043d\u0438\u0445 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443). \u041d\u043e \u043f\u043e\u043a\u0430 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c <code>base<\/code> \u0434\u043b\u044f \u043f\u043e\u0438\u043d\u0442\u043e\u0432 \u0442\u0440\u0435\u0431\u0443\u044e\u0449\u0438\u0445 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438, \u0442\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code>import { getMe } from '@\/lib\/auth'export const authorizedBase = root.lets  .base()  .ctx(({ request }) =&gt; {    const me = await getMe(request)    if (!me) {      throw new Error('Unauthorized')    }    return { me }  })  .base()export const ideaPage = authorizedBase.lets  .page('\/ideas\/:id')  .loader(async ({ params }) =&gt; {    const idea = await prisma.idea.findUniqueOrThrow({      where: { id: params.id },    })    return { idea }  })  .page(({ data: { idea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{idea.title}&lt;\/h1&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0447\u0435\u043d\u044c \u0432\u0430\u0436\u043d\u043e \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e <code>.ctx()<\/code> \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0438\u043c\u0435\u0435\u0442 <code>.loader()<\/code>, \u043d\u0435\u0442 <code>.loader()<\/code>, \u0437\u043d\u0430\u0447\u0438\u0442 \u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0438\u043a\u0430\u043a\u043e\u0433\u043e \u043d\u0435\u0442, \u0442\u0430\u043a \u0447\u0442\u043e \u0438 \u043a\u043e\u0434 \u0432 <code>.ctx()<\/code> \u0432\u044b\u0437\u0432\u0430\u043d \u043d\u0435 \u0431\u0443\u0434\u0435\u0442.<\/p>\n<p>\u041d\u043e \u043a\u0430\u043a \u043f\u043e\u043a\u0430\u0437\u0430\u043b\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0430, \u044d\u0442\u043e\u0442 <code>base<\/code> \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0442\u0430\u043a \u0443\u0434\u043e\u0431\u0435\u043d, \u043a\u0430\u043a \u043f\u043b\u0430\u0433\u0438\u043d\u044b, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0438\u0437\u0443\u0447\u0430\u0442\u044c \u043f\u043b\u0430\u0433\u0438\u043d\u044b.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/ctx\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442<\/a>.<\/p>\n<h2>Plugin<\/h2>\n<p>\u041f\u043b\u0430\u0433\u0438\u043d \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0447\u0430\u0441\u0442\u044c \u043c\u0435\u0442\u043e\u0434\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0437\u0430\u0438\u043d\u0436\u0435\u043a\u0442\u0438\u0442\u044c \u0432 \u0446\u0435\u043f\u043e\u0447\u043a\u0443 \u043f\u043e\u0438\u043d\u0442\u0430.<\/p>\n<pre><code>import { getMe } from '@\/lib\/auth'export const authorizedPlugin = Point0.lets  .plugin()  .ctx(({ request }) =&gt; {    const me = await getMe(request)    if (!me) {      throw new Error('Unauthorized')    }    return { me }  })  .plugin()export const ideaPage = root.lets  .page('\/ideas\/:id')  .use(authorizedPlugin)  .loader(async ({ ctx: { me }, params }) =&gt; {    const idea = await prisma.idea.findUniqueOrThrow({      where: { id: params.id },    })    return { idea }  })  .page(({ data: { idea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{idea.title}&lt;\/h1&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043f\u043e\u0438\u043d\u0442\u044b \u043a\u0440\u043e\u043c\u0435 \u043f\u043b\u0430\u0433\u0438\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u043a\u0430\u043a \u0435\u0441\u0442\u044c, \u0438 \u043c\u044b \u043d\u0435 \u043c\u043e\u0436\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0438\u0445 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438, \u0447\u0442\u043e\u0431\u044b \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0438\u0445 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c (\u043d\u0443\u0436\u043d\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u0435\u0440\u0443, \u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043f\u043e\u0442\u043e\u043c), \u043d\u043e \u0432\u043e\u0442 \u043f\u043b\u0430\u0433\u0438\u043d \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0442\u044c \u0432 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440:<\/p>\n<pre><code>import { getMe } from '@\/lib\/auth'export const authorizedPlugin = ({  permsission,}: { permsission?: string } = {}) =&gt;  Point0.lets    .plugin()    .ctx(({ request }) =&gt; {      const me = await getMe(request)      if (!me) {        throw new Error('Unauthorized')      }      if (permsission &amp;&amp; !me.permissions.includes(permsission)) {        throw new Error('Forbidden')      }      return { me }    })    .plugin()export const ideaPage = root.lets  .page('\/ideas\/:id')  .use(authorizedPlugin({ permissions: ['ideaRead'] }))  .loader(async ({ ctx: { me }, params }) =&gt; {    const idea = await prisma.idea.findUniqueOrThrow({      where: { id: params.id },    })    return { idea }  })  .page(({ data: { idea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{idea.title}&lt;\/h1&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u044d\u0442\u043e \u043d\u0435 \u0442\u043e \u0447\u0442\u043e \u043f\u0438\u0448\u0443\u0442 \u0434\u0440\u0443\u0433\u0438\u0435 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0438, \u0430 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435, \u044d\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u0432\u0430\u0448\u0435\u0433\u043e \u043a\u043e\u0434\u0430, \u0447\u0442\u043e\u0431\u044b \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0443\u0434\u043e\u0431\u043d\u0435\u0435.<\/p>\n<p>\u041d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u043e\u043d\u043d\u043e\u0433\u043e \u043f\u043b\u0430\u0433\u0438\u043d\u0430 \u043b\u0443\u0447\u0448\u0435 \u0438\u043c\u0435\u0442\u044c \u0441\u0440\u0430\u0437\u0443 \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0446\u0438\u044e \u0438\u0437 <code>.ctx()<\/code> \u0438 <code>.with()<\/code>:<\/p>\n<pre><code>import { getMe } from '@\/lib\/auth'export const getMeQuery = root.lets  .query()  .loader(async ({ request }) =&gt; {    return { me: await getMe(request) }  })  .query({    staleTime: Infinity,  })export const authorizedPlugin = Point0.lets  .plugin()  \/\/ ctx \u044d\u0442\u043e \u0447\u0438\u0441\u0442\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u0430\u044f \u0448\u0442\u0443\u043a\u0430, \u043e\u043d \u0432\u044b\u0440\u0435\u0437\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435,  \/\/ \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u0438\u0434\u0435\u0442\u044c \u0435\u0433\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 .ctx() \u0438 .loader()  .ctx(({ request }) =&gt; {    const me = await getMe(request)    if (!me) {      throw new Error('Unauthorized')    }    return { me }  })  \/\/ .with() \u044d\u0442\u043e \u0448\u0442\u0443\u043a\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u0440\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430, \u0445\u043e\u0442\u044c \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435,  \/\/ \u0445\u043e\u0442\u044c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0435\u0441\u043b\u0438 \u0432\u043a\u043b\u044e\u0447\u0451\u043d ssr, \u043d\u043e \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0442\u0443\u0442 ctx \u043d\u0435 \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e\u0431\u044b \u043a\u043b\u0438\u0435\u043d\u0442 \u043d\u0435 \u043b\u043e\u043c\u0430\u043b\u0441\u044f  .with(({ resolve }) =&gt; {    return resolve(getMeQuery.useQuery(), ({ data }) =&gt; ({ me: data.me }))  })  .plugin()export const ideaPage = root.lets  .page('\/ideas\/:id')  \/\/ \u0434\u043b\u044f \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0438\u043c\u0435\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u043e, \u0447\u0442\u043e \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0432 \u043f\u043b\u0430\u0433\u0438\u043d\u0435 \u0438 .ctx()  \/\/ .ctx() \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b \u0432 \u043b\u043e\u0430\u0434\u0435\u0440\u0435 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c me, \u0430 \u0435\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d, \u0442\u043e \u043c\u044b \u0438 \u0442\u0430\u043a \u0443\u0432\u0438\u0434\u0438\u043c \u043e\u0448\u0438\u0431\u043a\u0443  \/\/ \u043a\u0430\u043a \u043e\u0448\u0438\u0431\u043a\u0443 \u0432\u044b\u0437\u043e\u0432\u0430 \u043a\u0432\u0435\u0440\u0438, \u0442\u0430\u043a \u0447\u0442\u043e \u0437\u0434\u0435\u0441\u044c .with() \u043f\u043e \u0441\u0443\u0442\u0438 \u0431\u044b\u043b \u043d\u0435 \u043d\u0443\u0436\u0435\u043d, \u043d\u043e \u043e\u043d \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u0432 \u0434\u0440\u0443\u0433\u043e\u043c \u043c\u0435\u0441\u0442\u0435  .use(authorizedPlugin)  .loader(async ({ ctx: { me }, params }) =&gt; {    const idea = await prisma.idea.findUniqueOrThrow({      where: { id: params.id },    })    return { idea }  })  .page(({ data: { idea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{idea.title}&lt;\/h1&gt;    &lt;\/div&gt;  ))export const introPage = root.lets  .page('\/intro')  \/\/ \u0430 \u0432\u043e\u0442 \u0442\u0443\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0432\u043e\u043e\u0431\u0449\u0435 \u0431\u0435\u0437 \u043b\u043e\u0430\u0434\u0435\u0440\u0430. \u041d\u0430\u043c \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435 \u043d\u0430 \u043d\u0435\u0451 \u0441 \u0434\u0440\u0443\u0433\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u043d\u0443\u0436\u0435\u043d \u0437\u0430\u043f\u0440\u043e\u0441 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440,  \/\/ \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043a \u043d\u0435\u0439 \u043d\u0435 \u043f\u0440\u0438\u0432\u044f\u0437\u0430\u043d\u0430 \u043d\u0438 \u043e\u0434\u043d\u0430 \u043a\u0432\u0435\u0440\u0438, \u0438 \u043d\u0438 \u043e\u0434\u0438\u043d \u043b\u043e\u0430\u0434\u0435\u0440 (\u0430 \u043b\u043e\u0430\u0434\u0435\u0440 \u044d\u0442\u043e \u0442\u043e\u0436\u0435 \u043b\u0438\u0448\u044c \u0441\u043f\u043e\u0441\u043e\u0431 \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u043a\u0432\u0435\u0440\u0438).  \/\/ \u0410 \u0437\u043d\u0430\u0447\u0438\u0442 \u0438 \u0442\u043e, \u0447\u0442\u043e \u043a\u043e\u0434 \u0432\u043d\u0443\u0442\u0440\u0438 .ctx() \u0432\u044b\u0437\u0432\u0430\u043d \u043d\u0435 \u0431\u0443\u0434\u0435\u0442.  \/\/ \u041d\u043e \u0443 \u043d\u0430\u0441 \u0442\u0443\u0442 \u0435\u0441\u0442\u044c .with() \u0432\u043d\u0443\u0442\u0440\u0438 \u043f\u043b\u0430\u0433\u0438\u043d\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u0430\u043a \u0440\u0430\u0437 \u0438 \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0443 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b  .use(authorizedPlugin)  \/\/ \u0412\u0430\u0436\u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u0447\u0442\u043e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043c\u043e\u0433\u0443\u0442 \u0434\u043e\u0431\u044b\u0442\u044c \u0432\u0441\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u043d \u0431\u0430\u043d\u0434\u043b\u0438\u0442\u0441\u044f \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c.  \/\/ \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u0441\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0434\u043e\u043b\u0436\u043d\u044b \u0431\u044b\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430  \/\/ \u0438\u0437 .loader()  .page(({ data: { idea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;\u0422\u043e\u043b\u044c\u043a\u043e \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c&lt;\/h1&gt;    &lt;\/div&gt;  ))export const ideaQuery = root.lets  .query()  .use(authorizedPlugin)  \/\/ \u0430 \u043a\u0432\u0435\u0440\u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u044f \u043a \u0440\u0435\u043d\u0434\u0435\u0440\u0443, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0442\u0443\u0442 \u0432\u043e\u043e\u0431\u0449\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0433\u043d\u043e\u0440\u0438\u0440\u043e\u0432\u0430\u043d .with()  \/\/ \u043d\u043e .ctx() \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d  .loader(async ({ ctx: { me }, params }) =&gt; {    const idea = await prisma.idea.findUniqueOrThrow({      where: { id: params.id },    })    return { idea }  })  .query()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043b\u0430\u0433\u0438\u043d\u043e\u0432 \u043c\u043e\u0436\u043d\u043e \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443\u0433\u043e\u0434\u043d\u043e, \u0438 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0443\u0433\u043e\u0434\u043d\u043e <code>.use()<\/code> \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439.<\/p>\n<p>\u041f\u043b\u0430\u0433\u0438\u043d\u044b \u0434\u0430\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0434\u0440\u0443\u0433 \u0432 \u0434\u0440\u0443\u0433\u0430. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0435\u0441\u0442\u044c \u043f\u043b\u0430\u0433\u0438\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442. \u041d\u043e \u043e\u043d \u043d\u0435 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u0443\u0435\u0442 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d \u044e\u0437\u0435\u0440 \u0438\u043b\u0438 \u043d\u0435\u0442. \u0418 \u0438\u043c\u0435\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u0438\u043d \u043f\u043b\u0430\u0433\u0438\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0437\u0430\u043f\u0440\u0435\u0449\u0430\u0435\u0442 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043d\u0435\u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0449\u0438\u0439 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0439 \u043f\u043b\u0430\u0433\u0438\u043d:<\/p>\n<pre><code>export const mePlugin = Point0.lets  .plugin()  .ctx(({ request }) =&gt; {    const me = await getMe(request) \/\/ user | undefined    return { me }  })  .plugin()export const authorizedPlugin = Point0.lets  .plugin()  .use(mePlugin)  .ctx(({ ctx: { me } }) =&gt; {    if (!me) {      throw new Error('Unauthorized')    }  })  .plugin()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/plugin\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u043f\u043b\u0430\u0433\u0438\u043d\u044b<\/a>.<\/p>\n<h2>Mountables<\/h2>\n<p>\u041c\u044b \u0440\u0430\u043d\u044c\u0448\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u0445 \u0438 \u043b\u044d\u0439\u0430\u0443\u0442\u0430\u0445, \u043a\u0430\u043a \u043e \u043f\u043e\u0438\u043d\u0442\u0430\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0447\u0442\u043e-\u0442\u043e \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c. \u0415\u0449\u0451 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0438 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u044b. \u0412\u0441\u0435 \u044d\u0442\u0438 4 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438: <code>page<\/code>, <code>layout<\/code>, <code>component<\/code>, <code>provider<\/code> \u2014 \u043d\u0430\u0437\u044b\u0432\u0430\u044e\u0442\u0441\u044f mountables. \u0422\u043e \u0435\u0441\u0442\u044c \u0432\u0441\u0435 \u043e\u043d\u0438 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0437\u0430\u043c\u043e\u0443\u043d\u0447\u0435\u043d\u044b \u0432 \u0440\u0435\u0430\u043a\u0442-\u0434\u0435\u0440\u0435\u0432\u0435. \u0418 \u043a\u043e \u0432\u0441\u0435\u043c \u043a \u043d\u0438\u043c \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u043c\u044b <code>.loader()<\/code>, <code>.mapper()<\/code>, <code>.with()<\/code>, <code>.use()<\/code>, \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435, \u0442\u043e \u0435\u0441\u0442\u044c \u043e\u043d\u0438 \u0432\u0441\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043f\u043e \u043e\u0434\u043d\u043e\u043c\u0443 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0443, \u0438 \u0435\u0441\u043b\u0438 \u0432\u044b \u043f\u043e\u043d\u044f\u043b\u0438 \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043e\u0434\u0438\u043d \u0438\u0437 \u043d\u0438\u0445, \u0442\u043e \u0432\u044b \u043f\u043e\u0439\u043c\u0451\u0442\u0435 \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0438 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435.<\/p>\n<p>\u041a\u0430\u0440\u0434\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0438 \u043b\u044d\u0439\u043e\u0443\u0442\u044b \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c, \u0438 \u043d\u0435 \u0437\u0430\u0431\u044b\u0442\u044c \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c. \u041e\u043d\u0438 \u0441\u0430\u043c\u0438 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0431\u0440\u0430\u043d\u044b \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440\u043e\u043c, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0444\u0430\u0439\u043b\u0438\u043a <code>points.ts<\/code>, \u0433\u0434\u0435 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u043f\u0435\u0440\u0435\u0447\u0438\u0441\u043b\u0435\u043d\u044b, \u0447\u0442\u043e\u0431\u044b \u0438 \u043a\u043b\u0438\u0435\u043d\u0442 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440 \u0437\u043d\u0430\u043b\u0438 \u043e\u0431 \u0438\u0445 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0438 (\u043f\u0440\u043e \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043f\u043e\u0442\u043e\u043c).<\/p>\n<p>\u0410 \u0432\u043e\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0438 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u044b \u043e\u0431\u044a\u044f\u0432\u0438\u0432, \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0441\u0430\u043c\u0438 \u0433\u0434\u0435-\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0438\u0445 \u0438\u0437\u0443\u0447\u0438\u043c.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/mountable\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u043c\u0430\u0443\u043d\u0442\u0430\u0431\u043b\u044b<\/a>.<\/p>\n<h2>Component<\/h2>\n<p>\u041c\u043d\u043e\u0433\u043e \u0431\u044b\u043b\u043e \u0440\u0430\u0437\u0433\u043e\u0432\u043e\u0440\u043e\u0432 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u0432 \u043e\u0434\u043d\u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0432\u043e\u0442\u043a\u043d\u0443\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u0432\u0435\u0440\u0438. \u0410 \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u044d\u0442\u043e \u043d\u0435 \u0442\u0430\u043a \u0443\u0436 \u0447\u0430\u0441\u0442\u043e \u0438 \u043d\u0443\u0436\u043d\u043e. \u0427\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u0440\u0430\u0437\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043d\u0443\u0436\u043d\u044b \u0440\u0430\u0437\u043d\u044b\u043c \u0447\u0430\u0441\u0442\u044f\u043c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0438 \u043d\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u0441\u0430\u043c\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435, \u043f\u0440\u043e\u0449\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c \u0441\u0430\u043c\u0438\u043c \u0434\u043e\u0433\u0440\u0443\u0436\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0435 \u0438\u043c \u0434\u0430\u043d\u043d\u044b\u0435.<\/p>\n<pre><code>export const ideaPage = root.lets  .page('\/ideas\/:id')  .loader(async ({ params }) =&gt; {    const idea = await prisma.idea.findUniqueOrThrow({      where: { id: params.id },    })    return { idea }  })  .page(({ data: { idea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{idea.title}&lt;\/h1&gt;      &lt;SimilarIdeas input={{ ids: idea.similarIds }} \/&gt;    &lt;\/div&gt;  ))export const SimilarIdeas = root.lets  .component()  .input(z.object({ ids: z.array(z.string()) }))  .loader(async ({ input: { ids } }) =&gt; {    const ideas = await prisma.idea.findMany({ where: { id: { in: ids } } })    return { ideas }  })  .component(({ data: { ideas } }) =&gt; (    &lt;div&gt;      &lt;h2&gt;\u041f\u043e\u0445\u043e\u0436\u0438\u0435 \u0438\u0434\u0435\u0438&lt;\/h2&gt;      &lt;ul&gt;        {ideas.map((idea) =&gt; (          &lt;li key={idea.id}&gt;{idea.title}&lt;\/li&gt;        ))}      &lt;\/ul&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u0430\u043a \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u0443 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043a\u0430\u043a \u0438 \u043e\u0431\u044b\u0447\u043d\u043e\u0439 \u043a\u0432\u0435\u0440\u0438, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0441\u0445\u0435\u043c\u0443 \u0438\u043d\u043f\u0443\u0442\u0430 \u0438 \u043b\u043e\u0430\u0434\u0435\u0440, \u043f\u0440\u0438\u0447\u0451\u043c \u0441\u0430\u043c \u0436\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043a\u0432\u0435\u0440\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u0438\u043c\u0435\u0435\u0442 \u043c\u0435\u0442\u043e\u0434\u044b (\u043a\u0430\u043a \u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430, \u0438 \u043b\u044d\u0439\u043e\u0443\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0431\u044a\u044f\u0432\u0438\u043b\u0438 \u0441\u0432\u043e\u0439 \u043b\u043e\u0430\u0434\u0435\u0440):<\/p>\n<pre><code>SimilarIdeas.useQuery(input, ...)SimilarIdeas.getQueryKey(input, ...)SimilarIdeas.getQueryOptions(...)SimilarIdeas.fetchQuery(...)SimilarIdeas.prefetchQuery(...)SimilarIdeas.getQueryData(...)SimilarIdeas.ensureQueryData(...)SimilarIdeas.refetchQuery(...)SimilarIdeas.setQueryData(...)SimilarIdeas.getQueryCache(...)SimilarIdeas.getQueriesCache(...)SimilarIdeas.getQueryState(...)SimilarIdeas.cancelQuery(...)SimilarIdeas.invalidateQuery(...)SimilarIdeas.removeQuery(...)SimilarIdeas.resetQuery(...)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u0430\u043a \u0438 \u0432\u0441\u0435 \u043c\u0430\u0443\u043d\u0442\u0430\u0431\u043b\u044b, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>.with()<\/code>, \u0438 \u0432\u0441\u0451 \u0447\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0432 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u0445 \u0438 \u043b\u044d\u0439\u043e\u0443\u0442\u0430\u0445, \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0438 \u0437\u0434\u0435\u0441\u044c.<\/p>\n<p>\u041d\u0430\u0434\u043e \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e <code>.input()<\/code> \u044d\u0442\u043e \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u0438 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438\u043d\u043f\u0443\u0442 \u0432\u043d\u0443\u0442\u0440\u0438 \u0440\u0435\u043d\u0434\u0435\u0440\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043c\u044b \u043d\u0435 \u0432\u0438\u0434\u0438\u043c, \u0442\u0430\u043a \u043a\u0430\u043a \u043e\u043d \u043d\u0435 \u0431\u044b\u043b \u0432\u0430\u043b\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u043d \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u0438 \u0447\u0442\u043e \u043e\u043d \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u0439 \u0438 \u0435\u0433\u043e \u0442\u0438\u043f \u0441\u043e\u0432\u043f\u0430\u0434\u0430\u0435\u0442 \u043c\u044b \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435 \u043c\u043e\u0436\u0435\u043c. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u0438\u0431\u043e <code>.sharedInput()<\/code>, \u043b\u0438\u0431\u043e \u0435\u0441\u043b\u0438 \u0432\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0445\u043e\u0442\u0438\u0442\u0435 \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043f\u0440\u043e\u043f\u0441\u044b, \u0442\u043e \u0442\u043e\u0433\u0434\u0430 \u043a\u0430\u043a \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u043f\u0440\u043e\u043f\u0441\u044b \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0438\u0445 \u0438 \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c. \u041f\u0440\u043e <code>.sharedInput()<\/code> \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043f\u043e\u0437\u0436\u0435, \u0430 \u043f\u0440\u043e \u0432\u0445\u043e\u0434\u043d\u044b\u0435 \u043f\u0440\u043e\u043f\u0441\u044b \u0441\u0435\u0439\u0447\u0430\u0441:<\/p>\n<pre><code>export const ideaPage = root.lets  .page('\/ideas\/:id')  .with(ideaViewQuery, ({ params }) =&gt; ({ id: params.id }))  .page(({ data: { idea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{idea.title}&lt;\/h1&gt;      &lt;SimilarIdeas ids={idea.similarIds} \/&gt;    &lt;\/div&gt;  ))export const SimilarIdeas = root.lets  \/\/ \u0432\u043e\u0442 \u0442\u0443\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u043a\u0438\u043d\u0443\u043b\u0438 \u0442\u0438\u043f \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u043f\u0440\u043e\u043f\u0441\u043e\u0432 \u043a\u0430\u043a\u043e\u0439 \u0437\u0430\u0445\u043e\u0442\u0435\u043b\u0438 \u0438 \u0433\u043e\u0442\u043e\u0432\u043e  .component&lt;{ ids: string[] }&gt;()  \/\/ \u0432\u043e\u0442 \u0442\u0443\u0442 \u0438\u0445 \u0434\u043e\u0431\u044b\u043b\u0438 \u0438 \u043f\u0440\u043e\u043a\u0438\u043d\u0443\u043b\u0438 \u0432 \u043a\u0432\u0435\u0440\u0438  .with(ideaListQuery, ({ props: { ids } }) =&gt; ({ ids }))  .component(({ data: { ideas } }) =&gt; (    &lt;div&gt;      &lt;h2&gt;\u041f\u043e\u0445\u043e\u0436\u0438\u0435 \u0438\u0434\u0435\u0438&lt;\/h2&gt;      &lt;ul&gt;        {ideas.map((idea) =&gt; (          &lt;li key={idea.id}&gt;{idea.title}&lt;\/li&gt;        ))}      &lt;\/ul&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u0442\u043e\u0442 \u0436\u0435 \u0441\u0430\u043c\u044b\u0439 \u043a\u043e\u0434 \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430, \u043d\u043e \u043f\u043e\u0434\u0445\u043e\u0434 \u0434\u0440\u0443\u0433\u043e\u0439. \u0415\u0449\u0451 \u0440\u0430\u0437 \u043e\u0442\u043c\u0435\u0447\u0443, \u0447\u0442\u043e \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u0443\u0434\u043e\u0431\u043d\u0435\u0435 \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043a\u0432\u0435\u0440\u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e, \u0430 \u043d\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0442\u044c \u043b\u043e\u0430\u0434\u0435\u0440\u044b \u0432 \u0441\u0430\u043c\u0438\u0445 \u043c\u0430\u0443\u043d\u0442\u0430\u0431\u043b\u0430\u0445.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/component\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b<\/a>.<\/p>\n<h2>Provider<\/h2>\n<p>\u042f \u0440\u0430\u043d\u044c\u0448\u0435 \u043b\u044e\u0431\u0438\u043b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0442\u044c \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u043c \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u0435, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0442\u043e\u043c \u043c\u043e\u0447\u044c \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u043b\u044e\u0431\u043e\u043c \u043c\u0435\u0441\u0442\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0418 \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0434\u0443\u043c\u0430\u043b, \u0447\u0442\u043e \u0445\u043e\u0440\u043e\u0448\u043e \u0431\u044b \u043d\u0430\u043c \u0441\u0440\u0430\u0437\u0443 \u0438\u043c\u0435\u0442\u044c \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0432\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u0430\u043a \u0438 \u0432\u0441\u0435 \u043c\u0430\u0443\u043d\u0442\u0430\u0431\u043b\u044b \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u0438\u0442\u044c \u043b\u044e\u0431\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0445\u043e\u0442\u044c \u0441\u0430\u043c, \u0445\u043e\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u043a\u0432\u0435\u0440\u0438, \u0430 \u043f\u043e\u0442\u043e\u043c \u0440\u0430\u0437\u0434\u0430\u0442\u044c \u0438\u0445 \u0432\u0441\u0435\u043c \u0434\u0435\u0442\u044f\u043c.<\/p>\n<pre><code>export const MeProvider = root.lets  .provider()  .loader(async ({ request }) =&gt; {    return { me: await getMe(request) }  })  .provider()\/\/ \u0413\u0434\u0435-\u0442\u043e \u0432\u043d\u0443\u0442\u0440\u0438 app.tsxexport const App = () =&gt; {  return (    &lt;QueryClientProvider client={queryClient}&gt;      &lt;MeProvider&gt;        &lt;Router \/&gt;      &lt;\/MeProvider&gt;    &lt;\/QueryClientProvider&gt;  )}\/\/ \u0413\u0434\u0435-\u0442\u043e \u0432 \u043a\u0430\u043a\u043e\u043c-\u0442\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435export const UserInfo = () =&gt; {  const { me } = MeProvider.useValue()  return &lt;div&gt;Hello, {me.name}!&lt;\/div&gt;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0442\u043e, \u0447\u0442\u043e \u0443 \u043d\u0435\u0433\u043e \u0432 data. \u041d\u043e \u0432 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438, \u0435\u0441\u043b\u0438 \u0443 \u043d\u0430\u0441 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440 \u0432\u044b\u0437\u0432\u0430\u043b \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u0432\u0435\u0440\u0438, \u0438\u043b\u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u043a\u0432\u0435\u0440\u0438 \u043d\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u043b, \u0430 \u0432\u044b\u0437\u044b\u0432\u0430\u043b \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0445\u0443\u043a\u0438, \u0442\u043e \u043d\u0430\u043c \u0431\u044b \u043d\u0430\u0434\u043e \u043f\u0440\u0438\u0432\u0435\u0441\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043f\u043e\u0440\u044f\u0434\u043e\u043a<\/p>\n<pre><code>export const MeProvider = root.lets  .provider()  .with(() =&gt; {    const x = useSomethingSpecial()    return { x }  })  .with(getMeQuery)  \/\/ \u044d\u0442\u043e \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435 \u0447\u0442\u043e \u0438 .mapper(), \u043f\u0440\u043e\u0441\u0442\u043e \u0443\u0434\u043e\u0431\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u044d\u0442\u043e \u0432 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c \u043c\u0435\u0442\u043e\u0434\u0435 .provider()  .provider(({ data: { me }, props: { x } }) =&gt; ({ me, x }))export const UserInfo = () =&gt; {  const { me, x } = MeProvider.useValue()  return (    &lt;div&gt;      Hello, {me.name}! You are {x}!    &lt;\/div&gt;  )}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u043e \u0447\u0435\u0441\u0442\u043d\u043e, \u044f \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c-\u0442\u043e \u0432\u0441\u0435 \u044d\u0442\u0438 \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u044b \u0438 \u043d\u0443\u0436\u043d\u044b, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u0440\u043e\u0449\u0435 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u043f\u043b\u0430\u0433\u0438\u043d. \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432\u0441\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u044d\u0442\u043e \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043a\u0432\u0435\u0440\u0435\u0439, \u0430 \u043a\u0432\u0435\u0440\u0438 \u043a\u0435\u0448\u0438\u0440\u0443\u044e\u0442\u0441\u044f. \u0418 \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u043b\u0438\u0448\u043d\u0438\u0445 \u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u043e\u0432 \u043c\u044b \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c. \u041d\u043e \u0442\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435 \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u044b, \u0432\u0434\u0440\u0443\u0433 \u043f\u0440\u0438\u0433\u043e\u0434\u044f\u0442\u0441\u044f.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/provider\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u044b<\/a>.<\/p>\n<h2>Infinite Query<\/h2>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 Infinite Query. \u041f\u043e \u0441\u0443\u0442\u0438 \u0442\u0430\u043a\u0436\u0435 \u043a\u0430\u043a \u0438 \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u043a\u0432\u0435\u0440\u0438, \u043d\u043e \u0435\u0441\u0442\u044c \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0438 \u0432 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430 \u043e\u0442\u0432\u0435\u0447\u0430\u044e\u0449\u0435\u0433\u043e \u0437\u0430 \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0442\u043e\u0440 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 <code>page<\/code> (<code>page<\/code> \u0432 infiniteQuery, \u043d\u0435 \u043d\u0430\u0448\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430):<\/p>\n<pre><code>export const ideaListQuery = root.lets  .infiniteQuery()  .input(    z.object({      page: z.number().default(0),      limit: z.number().default(2),    }),  )  .loader(async ({ input: { page, limit } }) =&gt; {    const ideasCount = await prisma.idea.count()    const ideas = await prisma.idea.findMany({      take: limit,      skip: page * limit,      orderBy: { updatedAt: 'desc' },    })    const nextCursor = ideasCount &gt; (page + 1) * limit ? page + 1 : undefined    return { ideas, ideasCount, nextCursor }  })  .infiniteQuery({    \/\/ \u0432 \u043e\u0431\u044b\u0447\u043d\u044b\u0445 query, \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c    \/\/ \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043b\u044e\u0431\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0440\u043e\u0434\u043d\u043e\u0439 react-query useInfiniteQuery    \/\/ \u043d\u043e \u0441\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u043d\u0430\u0448 \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \"pageParamFromInput\"    \/\/ \u044d\u0442\u043e \u043a\u043b\u044e\u0447 (\u043f\u0443\u0442\u044c) \u0432 \u0438\u043d\u043f\u0443\u0442\u0435 \u043a \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044e, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a pageParam    pageParamFromInput: 'page',    getNextPageParam: (lastPage) =&gt; lastPage.nextCursor,    initialPageParam: 0,  })export const ideaListPage = generalLayout.lets  .page('\/ideas')  \/\/ \u0442\u0430\u043a \u043a\u0430\u043a \u0432\u0441\u0435 \u043a\u043b\u044e\u0447\u0438 \u0438\u043d\u043f\u0443\u0442\u0430 ideaListQuery \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435, \u0442\u043e \u0438 \u0432\u0442\u043e\u0440\u044b\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043f\u0435\u0440\u0435\u0434\u0430\u0432\u0430\u0442\u044c  .with(ideaListQuery)  .mapper(({ data }) =&gt; {    \/\/ data \u0437\u0434\u0435\u0441\u044c \u044d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0439 \u0438\u0437 useInfiniteQuery    \/\/ \u043d\u0438\u0447\u0435\u0433\u043e \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u043e\u0433\u043e \u0437\u0434\u0435\u0441\u044c \u043d\u0435\u0442, \u043f\u0440\u043e\u0441\u0442\u043e \u0432 \u043c\u044d\u043f\u043f\u0435\u0440\u0435 \u0443\u0434\u043e\u0431\u043d\u043e \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0443\u0435\u043c \u043d\u0430\u0448\u0438 \u0434\u0430\u043d\u043d\u044b\u0435    return {      ideas: data.pages.flatMap((page) =&gt; page.ideas),      total: data.pages[0].ideasCount,    }  })  .head(({ data: { total } }) =&gt; {    return `${total} ideas`  })  .page(({ data: { ideas, total }, queries: [query] }) =&gt; {    return (      &lt;div&gt;        &lt;h1&gt;Ideas&lt;\/h1&gt;        &lt;div&gt;          {ideas.map((idea) =&gt; (            &lt;h2 key={idea.id}&gt;{idea.title}&lt;\/h2&gt;          ))}        &lt;\/div&gt;        {query.hasNextPage &amp;&amp; (          &lt;button            disabled={query.isFetchingNextPage}            onClick={() =&gt; {              query.fetchNextPage().catch(console.error)            }}          &gt;            {query.isFetchingNextPage ? 'Loading more...' : 'Load more'}          &lt;\/button&gt;        )}      &lt;\/div&gt;    )  })<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <code>.infiniteQuery()<\/code> \u043f\u0440\u044f\u043c\u043e \u0432\u0448\u0438\u0442\u043e\u0439 \u0432 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0435\u0451 \u043b\u043e\u0430\u0434\u0435\u0440. \u0422\u043e \u0435\u0441\u0442\u044c \u0442\u043e\u0442 \u0436\u0435 \u0441\u0430\u043c\u044b\u0439 \u043a\u043e\u0434, \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0438 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c. \u041e\u0434\u043d\u0430\u043a\u043e \u043d\u0430\u0434\u043e \u0443\u0447\u0435\u0441\u0442\u044c, \u0447\u0442\u043e \u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b-\u0442\u043e \u043d\u0435\u0442 \u201cinput\u201d, \u0443 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0432\u043c\u0435\u0441\u0442\u043e \u044d\u0442\u043e\u0433\u043e <code>params<\/code> \u0440\u043e\u0443\u0442\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438 \u0441\u0451\u0440\u0447 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u0430\u043a \u0440\u0430\u0437 \u0441\u0435\u0439\u0447\u0430\u0441 \u0438 \u043f\u043e\u043a\u0430\u0436\u0443:<\/p>\n<pre><code>export const ideaListPage = root.lets  .page('\/ideas')  .search(    z.object({      page: z.coerce.number&lt;number | string&gt;().default(0),      limit: z.coerce.number&lt;number | string&gt;().default(2),    }),  )  .loader(async ({ search: { page, limit } }) =&gt; {    const ideasCount = await prisma.idea.count()    const ideas = await prisma.idea.findMany({      take: limit,      skip: page * limit,      orderBy: { updatedAt: 'desc' },    })    const nextCursor = ideasCount &gt; (page + 1) * limit ? page + 1 : undefined    return { ideas, ideasCount, nextCursor }  })  .infiniteQuery({    getNextPageParam: (lastPage) =&gt; lastPage.nextCursor,    initialPageParam: 0,    \/\/ \u0432\u043e\u0442 \u0442\u0443\u0442 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f '?.page' \u0437\u043d\u0430\u0447\u0438\u0442 \u0447\u0442\u043e \u0431\u0435\u0440\u0451\u043c \u0438\u0437 \u0441\u0451\u0440\u0447 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432    pageParamFromInput: '?.page',  })  \/\/ \u0434\u0430\u043b\u044c\u0448\u0435 \u0432\u0441\u0451 \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439  .mapper(({ data }) =&gt; {    return {      ideas: data.pages.flatMap((page) =&gt; page.ideas),      total: data.pages[0].ideasCount,    }  })  .head(({ data: { total } }) =&gt; {    return `${total} ideas`  })  .page(({ data: { ideas, total }, queries: [query] }) =&gt; {    return (      &lt;div&gt;        &lt;h1&gt;Ideas&lt;\/h1&gt;        &lt;div&gt;          {ideas.map((idea) =&gt; (            &lt;h2 key={idea.id}&gt;{idea.title}&lt;\/h2&gt;          ))}        &lt;\/div&gt;        {query.hasNextPage &amp;&amp; (          &lt;button            disabled={query.isFetchingNextPage}            onClick={() =&gt; {              query.fetchNextPage().catch(console.error)            }}          &gt;            {query.isFetchingNextPage ? 'Loading more...' : 'Load more'}          &lt;\/button&gt;        )}      &lt;\/div&gt;    )  })<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/infinite-query\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0435 \u043a\u0432\u0435\u0440\u0438<\/a>.<\/p>\n<h2>clientLoader(), clientInput(), sharedInput()<\/h2>\n<p>\u0415\u0449\u0451 \u0432 Point0 \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0438\u0441\u0442\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0435 \u043a\u0432\u0435\u0440\u0438, \u043b\u043e\u0430\u0434\u0435\u0440\u044b, \u043c\u0443\u0442\u0430\u0446\u0438\u0438. \u0412\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u0436\u0435, \u0438 \u0432\u0441\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u0438\u0435 \u0436\u0435 \u043a\u0430\u043a \u0438 \u0434\u043b\u044f \u043e\u0431\u044b\u0447\u043d\u044b\u0445 \u043f\u043e\u0438\u043d\u0442\u043e\u0432, \u043d\u043e \u0442\u0430\u043a\u0438\u0435 \u043a\u0432\u0435\u0440\u0438 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u044b \u0432\u043e \u0432\u0440\u0435\u043c\u044f SSR, \u0430 \u0442\u0435\u043b\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 <code>loader<\/code> \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d\u043e \u043f\u0440\u044f\u043c\u043e \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u0430. \u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b:<\/p>\n<pre><code>export const ideaPage = root  .lets('page', 'idea', '\/ideas\/:id')  .clientLoader(({ params }) =&gt; {    const idea = await fetch(`https:\/\/example.com\/ideas\/${params.id}`).then(      (res) =&gt; res.json(),    )    return { idea }  })  .page(({ data: { idea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{idea.title}&lt;\/h1&gt;      &lt;div&gt;{idea.content}&lt;\/div&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u043a\u0432\u0435\u0440\u0438:<\/p>\n<pre><code>export const ideaQuery = root.lets  .query()  .clientInput(z.object({ id: z.string().min(1) }))  .clientLoader(({ params }) =&gt; {    const idea = await fetch(`https:\/\/example.com\/ideas\/${params.id}`).then(      (res) =&gt; res.json(),    )    return { idea }  })  .query()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/loader\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u043b\u043e\u0430\u0434\u0435\u0440\u044b<\/a>, <a href=\"https:\/\/1gr14.dev\/point0\/latest\/validation\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044e<\/a>.<\/p>\n<h2>Location<\/h2>\n<p>\u0412\u043d\u0443\u0442\u0440\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446, \u043b\u044d\u0439\u043e\u0443\u0442\u043e\u0432 \u0438 \u043b\u043e\u0430\u0434\u0435\u0440\u043e\u0432 \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 <code>location<\/code>. \u0412 \u043b\u043e\u0430\u0434\u0435\u0440\u0435, \u043a\u0430\u043a \u043c\u044b \u0443\u0436\u0435 \u0432\u0438\u0434\u0435\u043b\u0438, \u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u043d\u0443\u0436\u0435\u043d \u043d\u0435 \u0432\u0435\u0441\u044c <code>location<\/code>, \u0430 \u0434\u0432\u0435 \u0435\u0433\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0447\u0430\u0441\u0442\u0438 \u2014 <code>params<\/code> (\u0438\u0437 \u043f\u0443\u0442\u0438 \u0440\u043e\u0443\u0442\u0430) \u0438 <code>search<\/code> (\u0438\u0437 \u043a\u0432\u0435\u0440\u0438-\u0441\u0442\u0440\u043e\u043a\u0438), \u043e\u0434\u043d\u0430\u043a\u043e \u0442\u0430\u043c \u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u0438 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 <code>location<\/code>.<\/p>\n<p>\u0412 <code>location.search<\/code> \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u043d\u0435\u0432\u0430\u043b\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c, \u0438 \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0433\u043e <code>location.search<\/code> \u044d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442, \u0430 \u043d\u0435 \u0441\u0442\u0440\u043e\u043a\u0430, \u043f\u0440\u0438\u0447\u0451\u043c \u043e\u0431\u044a\u0435\u043a\u0442 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0434\u0430\u0436\u0435 \u043d\u0435 \u043e\u0434\u043d\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u043c. \u0421\u0442\u0440\u043e\u043a\u0430 \u0442\u043e\u0436\u0435 \u0435\u0441\u0442\u044c, \u043d\u043e \u043e\u043d\u0430 \u0432 <code>location.searchString<\/code>. \u0410 \u043e\u0431\u044a\u0435\u043a\u0442 \u0432 <code>search<\/code> \u043d\u0435 \u043e\u0434\u043d\u043e\u0443\u0440\u043e\u0432\u043d\u0435\u0432\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0432 \u0442\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u0432\u044b \u043f\u0435\u0440\u0435\u0439\u0434\u0451\u0442\u0435 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u043e \u0443\u0440\u043b\u0443 \u0432 \u0441\u0442\u0438\u043b\u0435 qs: <a href=\"http:\/\/example.com\/ideas\/42?a=1&amp;b=2&amp;c.x=3&amp;c.y=4&amp;d%5B%5D=5&amp;d%5B%5D=6\" rel=\"noopener noreferrer nofollow\">http:\/\/example.com\/ideas\/42?a=1&amp;b=2&amp;c.x=3&amp;c.y=4&amp;d[]=5&amp;d[]=6<\/a>.<\/p>\n<pre><code>export const ideaPage = root.lets  .page('\/ideas\/:id')  .loader(async ({ location }) =&gt; {    console.log(location.search)    \/\/ { a: '1', b: '2', 'c': { x: '3', y: '4' }, 'd': [ '5', '6' ] }    return { idea: 'Fake idea' }  })  .page(    ({      data: { idea },      \/\/ \u0442\u0443\u0442 \u0442\u043e\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u044b\u0442\u044c location      location,    }) =&gt; &lt;h1&gt;{idea}&lt;\/h1&gt;,  )<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0434\u043e\u0431\u044b\u0442\u044c <code>location<\/code> \u043c\u043e\u0436\u043d\u043e \u0447\u0435\u0440\u0435\u0437 \u0432\u044b\u0437\u043e\u0432 <code>useLocation()<\/code> \u0432 \u043b\u044e\u0431\u043e\u043c \u043c\u0435\u0441\u0442\u0435 \u043a\u043e\u0434\u0430 \u0432\u043d\u0443\u0442\u0440\u0438 \u0440\u043e\u0443\u0442\u0435\u0440\u0430 (\u043f\u0440\u043e \u0440\u0443\u0442\u0435\u0440 \u0441\u043a\u043e\u0440\u043e \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443):<\/p>\n<pre><code>import { useLocation } from '@point0\/core\/navigation'export const Breadcrumbs = () =&gt; {  const location = useLocation()  \/\/ location.pathname    \u2014 \u043f\u0443\u0442\u044c \u0431\u0435\u0437 \u043a\u0432\u0435\u0440\u0438 \u0438 \u0445\u0435\u0448\u0430: \"\/ideas\/42\"  \/\/ location.search      \u2014 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u043a\u0432\u0435\u0440\u0438-\u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432: { tab: 'news' }  \/\/ location.searchString \u2014 \u0441\u044b\u0440\u0430\u044f \u043a\u0432\u0435\u0440\u0438-\u0441\u0442\u0440\u043e\u043a\u0430: \"tab=news\"  \/\/ location.hash        \u2014 \u044f\u043a\u043e\u0440\u044c: \"#comments\" (\u0438\u043b\u0438 \u043f\u0443\u0441\u0442\u043e)  \/\/ location.hrefRel     \u2014 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0439 url: \"\/ideas\/42?tab=news#comments\"  \/\/ location.href        \u2014 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u044b\u0439 url, \u0435\u0441\u043b\u0438 \u0438\u0437\u0432\u0435\u0441\u0442\u0435\u043d origin  return &lt;div&gt;{location.pathname}&lt;\/div&gt;}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code>useLocation()<\/code> \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u0435\u043d \u2014 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0441\u0430\u043c \u043f\u0435\u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u0441\u044f \u043f\u0440\u0438 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438. \u0415\u0441\u043b\u0438 \u0436\u0435 <code>location<\/code> \u043d\u0443\u0436\u0435\u043d \u0432\u043d\u0435 React (\u0432 \u043a\u0430\u043a\u043e\u043c-\u043d\u0438\u0431\u0443\u0434\u044c \u0445\u0435\u043b\u043f\u0435\u0440\u0435), \u0435\u0441\u0442\u044c \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u044b\u0439 <code>getLocation()<\/code>.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/navigation\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044e<\/a>.<\/p>\n<h2>Route<\/h2>\n<p>\u041f\u0440\u043e \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440, \u044f \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043f\u043e\u0437\u0436\u0435, \u043d\u043e \u043d\u0430\u0434\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u0447\u0442\u043e \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u043d\u0430\u043c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0439 \u0444\u0430\u0439\u043b\u0438\u043a \u0441 \u0440\u043e\u0443\u0442\u0430\u043c\u0438, \u043e\u043f\u0438\u0440\u0430\u044f\u0441\u044c \u043d\u0430 \u0442\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0447\u0442\u043e \u043c\u044b \u0441\u0430\u043c\u0438 \u043e\u0431\u044a\u044f\u0432\u0438\u043b\u0438 \u0432 \u0441\u0432\u043e\u0451\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0441\u0430\u043c\u0438 \u043f\u043e \u0441\u0435\u0431\u0435 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0432\u0438\u0434\u0443 \u0441\u0430\u043c\u043e\u0439 \u0438\u0445 \u0441\u0442\u0440\u043e\u043a\u0438: <code>\/ideas\/:id<\/code>, <code>\/ideas\/:id\/edit<\/code>, \u0438 \u0442.\u0434. \u041f\u043e\u043b\u043e\u0436\u0438\u043c \u0435\u0433\u043e \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u0432 \u0444\u0430\u0439\u043b <code>src\/generated\/point0\/routes.ts<\/code>:<\/p>\n<pre><code>import { Routes } from '@1gr14\/route0'export const routes = Routes.create({  home: '\/',  about: '\/about',  ideaList: '\/ideas',  ideaCreate: '\/ideas\/new',  ideaView: '\/ideas\/:id',  ideaUpdate: '\/ideas\/:id\/edit',})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0417\u0430 \u044d\u0442\u043e \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <a href=\"https:\/\/1gr14.dev\/route0\" rel=\"noopener noreferrer nofollow\"><code>@1gr14\/route0<\/code><\/a>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043d\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0440\u043e\u0443\u0442\u0435\u0440\u043e\u043c, \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0448\u0442\u0443\u043a\u0430 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u0442\u0440\u043e\u043a\u043e\u0432\u044b\u043c\u0438 \u043f\u0443\u0442\u044f\u043c\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438. \u041e\u043d\u0430 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0430 \u0433\u0434\u0435 \u0443\u0433\u043e\u0434\u043d\u043e \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 Point0.<\/p>\n<p>\u0421 \u044d\u0442\u0438\u043c\u0438 \u0440\u043e\u0443\u0442\u0430\u043c\u0438 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code>routes.ideaView({ id: '123' }) \/\/ \"\/ideas\/123\"routes.ideaView.abs({ id: '123' }) \/\/ \"https:\/\/example.com\/ideas\/123\"<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u0430\u043c\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043c\u043d\u043e\u0433\u043e \u0447\u0435\u0433\u043e \u0443\u043c\u0435\u0435\u0442, \u043e\u043d\u0430 \u0438 \u0432\u0430\u043b\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043c\u043e\u0436\u0435\u0442, \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435, \u043d\u043e \u044d\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c Point0, \u0430 \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u043d\u0430\u043c \u043e\u043d\u0430 \u043d\u0443\u0436\u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0447\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u044b\u0432\u0430\u0442\u044c \u043f\u0443\u0442\u0438.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/navigation\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044e<\/a>.<\/p>\n<h2>Router and Navigation<\/h2>\n<p>\u0427\u0442\u043e \u044f \u0445\u043e\u0442\u0435\u043b \u043e\u0442 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438:<\/p>\n<ul>\n<li>\n<p>\u0427\u0442\u043e\u0431\u044b \u0443 \u043c\u0435\u043d\u044f \u0431\u044b\u043b \u043e\u0431\u044a\u0435\u043a\u0442 \u0441\u043e \u0432\u0441\u0435\u043c\u0438 \u043f\u0443\u0442\u044f\u043c\u0438 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u043c\u043e\u0433 \u0431\u044b \u0432\u0435\u0441\u0442\u0438 \u0441\u0430\u043c, \u0430 \u043c\u043e\u0433 \u0431\u044b \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438<\/p>\n<\/li>\n<li>\n<p>\u0427\u0442\u043e\u0431\u044b \u043c\u043d\u0435 \u043d\u0435 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u043b\u043e\u0441\u044c \u0432\u0441\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0441\u0430\u043c\u043e\u043c\u0443 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0442\u044c \u0432\u043d\u0443\u0442\u0440\u0438 app.tsx \u0438\u043b\u0438 \u0433\u0434\u0435 \u0442\u0430\u043c \u0435\u0449\u0451 \u0438 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438\u0445 \u0441 \u043b\u044d\u0439\u043e\u0443\u0442\u0430\u043c\u0438, \u0432\u0435\u0434\u044c \u0438 \u0435\u0436\u0443 \u043f\u043e \u043f\u0443\u0442\u044f\u043c \u0441\u0430\u043c\u0438\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u043f\u043e\u043d\u044f\u0442\u043d\u043e, \u043a\u0430\u043a \u043e\u043d\u0438 \u0442\u0430\u043c \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u044b\u0441\u0442\u0440\u043e\u0438\u0442\u044c\u0441\u044f<\/p>\n<\/li>\n<li>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u043c\u0443 \u043f\u0443\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u043c\u0443\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0437\u0430\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u0440\u0438 \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043d\u0433\u0435, \u0430 \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u043f\u043e\u0438\u043d\u0442\u0430-\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0441 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u043c\u0438<\/p>\n<\/li>\n<li>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0432\u044b\u0439 \u0437\u0430\u0445\u043e\u0434 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0431\u044b\u043b SSR, \u0447\u0442\u043e\u0431\u044b \u043c\u044b \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0433\u043e\u0442\u043e\u0432\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u0430 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b \u043f\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c \u0434\u0430\u043b\u0435\u0435 \u0431\u044b\u043b\u0438 SPA-\u0448\u043d\u044b\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043c\u0438\u043d\u0438\u043c\u0443\u043c \u0434\u0430\u043d\u043d\u044b\u0445<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0430\u043c\u0438\u043c \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0444\u0430\u0439\u043b, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c\u0441\u044f \u0432\u0441\u0435 \u043d\u0430\u0448\u0438 \u0445\u0435\u043b\u043f\u0435\u0440\u044b \u0434\u043b\u044f \u043e\u0440\u0433\u0430\u043d\u0438\u0437\u0430\u0446\u0438\u0438 \u0440\u043e\u0443\u0442\u0438\u043d\u0433\u0430, \u0432\u0441\u0435 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u044b \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u043f\u0435\u0440\u0435\u0434\u0430\u043d\u043d\u044b\u043c \u0432 <code>createNavigation<\/code> <code>routes<\/code>. \u041f\u043e\u043b\u043e\u0436\u0438\u043c \u044d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u0432 <code>src\/lib\/navigation.ts<\/code>:<\/p>\n<pre><code>import { createNavigation } from '@point0\/react-dom\/router'import {  \/\/ \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u044e\u0431\u044b\u0435 wouter \u0445\u0443\u043a\u0438, \u043a\u0430\u043a\u0438\u0435 \u0432\u0430\u043c \u043d\u0440\u0430\u0432\u044f\u0442\u0441\u044f  navigate as browserNavigate,  useBrowserLocation as hook,} from 'wouter\/use-browser-location'import { routes } from '@\/generated\/point0\/routes'export const {  navigate,  Link,  NavLink,  Redirect,  redirect,  Router,  RouterRoutes,} = createNavigation({  routes,  navigate: browserNavigate,  hook,})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0441\u0443\u043d\u0443\u0442\u044c <code>Router<\/code>\/<code>RouterRoutes<\/code> \u0432 \u043d\u0430\u0448 <code>app.client.tsx<\/code>. \u042f \u043f\u0440\u043e \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 <code>app.client.tsx<\/code> \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043f\u043e\u0437\u0436\u0435, \u043f\u043e\u043a\u0430 \u043a\u0430\u043a \u0435\u0441\u0442\u044c:<\/p>\n<pre><code>import { Router, RouterRoutes } from '@\/lib\/navigation'import { UnheadProvider } from '@point0\/core\/unhead'import { QueryClientProvider } from '@tanstack\/react-query'import { queryClient } from '@\/lib\/query-client'import { Head } from '@unhead\/react'export default function App() {  return (    &lt;QueryClientProvider client={queryClient}&gt;      &lt;UnheadProvider&gt;        &lt;Head&gt;          &lt;link rel=\"shortcut icon\" href=\"\/favicon.ico\" \/&gt;        &lt;\/Head&gt;        &lt;Router&gt;          {\/* \u0412\u043e\u0442 \u0442\u0443\u0442 \u0443\u0436\u0435 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0440\u043e\u0443\u0442\u0435\u0440\u0430, \u0442\u043e \u0435\u0441\u0442\u044c \u0442\u0443\u0442 \u043c\u043e\u0436\u0435\u043c \u0432\u044b\u0437\u044b\u0432\u0430\u0442\u044c \u0445\u0443\u043a useLocation() \u0438 \u043f\u0440\u043e\u0447\u0438\u0435 *\/}          &lt;RouterRoutes \/&gt;        &lt;\/Router&gt;      &lt;\/UnheadProvider&gt;    &lt;\/QueryClientProvider&gt;  )}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0430\u0432\u0438\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u043e \u043d\u0430 \u043c\u0435\u0441\u0442\u0430\u0445:<\/p>\n<pre><code>\/\/ \u043f\u043e \u0438\u043c\u0435\u043d\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0441 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u043c \u0438\u043d\u043f\u0443\u0442\u043e\u043cawait navigate('idea', { id: '123' })\/\/ \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0446\u0438\u0438 \u0441\u0430\u043c\u043e\u0433\u043e wouterawait navigate('idea', { id: '123' }, { replace: true })\/\/ \u0430 \u0442\u0430\u043a\u0436\u0435 \u043e\u043f\u0446\u0438\u0438 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u044b\u0435 \u0441 \u043f\u0440\u0435\u0444\u0435\u0442\u0447\u0438\u043d\u0433\u043e\u043c,\/\/ \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0435\u0441\u043b\u0438 \u043c\u044b \u0432\u0435\u0437\u0434\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043b\u0438 .prefetchPageOnNavigate('pageDehydratedStateAndClientQuery')\/\/ \u0442\u0443\u0442 \u044d\u0442\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044cawait navigate('idea', { id: '123' }, { prefetch: 'none' })\/\/ \u0430 \u0435\u0449\u0451 scrollToHash \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u0430\u043c \u043f\u043e \u0441\u0435\u0431\u0435, \u043d\u043e \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0435\u0433\u043e \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0443await navigate(  'idea',  \/\/ \u0447\u0442\u043e\u0431\u044b \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0447\u0442\u043e \u0438\u0434\u0451\u0442 \u043f\u043e\u0441\u043b\u0435 # \u0432 \u0443\u0440\u043b\u0435, \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u0434\u043e \u0434\u043e\u043f\u0438\u0441\u0430\u0442\u044c '#': \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435  { id: '123', '#': 'comments' },  \/\/ \u044d\u0442\u043e \u0438 \u0442\u0430\u043a \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u0430\u044f \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430, \u0435\u0441\u043b\u0438 \u0445\u044d\u0448 \u043d\u0430 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043f\u0435\u0440\u0435\u0435\u0434\u0435\u043c \u043f\u043b\u0430\u0432\u043d\u043e,  \/\/ \u0430 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435 \u043d\u0430 \u043d\u043e\u0432\u0443\u044e, \u0441\u0440\u0430\u0437\u0443 \u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c\u0441\u044f \u043d\u0430 \u043c\u0435\u0441\u0442\u0435  { scrollToHash: 'pushHardCurrentSmooth' },)\/\/ \u0435\u0449\u0451 \u043c\u043e\u0436\u043d\u043e \u0441\u0451\u0440\u0447 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u044b \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c:await navigate(  'ideas',  \/\/ \u0447\u0442\u043e\u0431\u044b \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u0447\u0442\u043e \u0438\u0434\u0451\u0442 \u043f\u043e\u0441\u043b\u0435 ? \u0432 \u0443\u0440\u043b\u0435, \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u0434\u043e \u0434\u043e\u043f\u0438\u0441\u0430\u0442\u044c '?': \u043e\u0431\u044a\u0435\u043a\u0442  { '?': { filter: 'fresh', sort: 'desc' } },)\/\/ \u0410 \u043c\u043e\u0436\u0435\u043c \u0441\u0440\u0430\u0437\u0443 \u0443\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u044d\u0442\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u0430 \u043d\u0430 \u043d\u043e\u0432\u043e\u0439 \u0432\u043a\u043b\u0430\u0434\u043a\u0435:await navigate('idea', { id: '123' }, { newTab: true })\/\/ \u0430 \u043c\u043e\u0436\u043d\u043e \u0438 \u043f\u043e \u0441\u044b\u0440\u043e\u043c\u0443 \u0443\u0440\u043b\u0443, \u0435\u0441\u043b\u0438 \u043e\u0447\u0435\u043d\u044c \u043d\u0430\u0434\u043eawait navigate.to('\/ideas\/123?tab=news')\/\/ \u0438 \u043a\u043b\u0430\u0441\u0441\u0438\u043a\u0430navigate.back()navigate.forward()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u0441\u044b\u043b\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043f\u043e \u0442\u0430\u043a\u043e\u043c\u0443 \u0436\u0435 \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0443, \u0447\u0442\u043e \u0438 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u043d\u0430\u044f \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044f, \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u043c\u0435\u0441\u0442\u043e <code>navigate<\/code> \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f <code>Link<\/code>:<\/p>\n<pre><code>import { Link } from '@\/lib\/navigation'\/\/ \u043e\u0431\u044b\u0447\u043d\u0430\u044f \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u0441\u0441\u044b\u043b\u043a\u0430&lt;Link route=\"idea\" input={{ id: '123' }}&gt;\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0438\u0434\u0435\u044e&lt;\/Link&gt;\/\/ \u043c\u043e\u0436\u043d\u043e \u043f\u043e \u0443\u0440\u043b\u0443&lt;Link to=\"\/ideas\/123\"&gt;\u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0438\u0434\u0435\u044e&lt;\/Link&gt;\/\/ \u0432\u043d\u0435\u0448\u043d\u044f\u044f \u0441\u0441\u044b\u043b\u043a\u0430 \u2014 \u0443\u0445\u043e\u0434\u0438\u0442 \u0438\u0437 SPA \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u044b\u0439 &lt;a&gt;\/\/ \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u0437\u0432\u0430\u043d\u044b \u0445\u0443\u043a\u0438 \u043f\u0440\u0435\u0444\u0435\u0442\u0447\u0430 \u0438 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438&lt;Link href=\"https:\/\/example.com\"&gt;\u041d\u0430\u0440\u0443\u0436\u0443&lt;\/Link&gt;\/\/ \u043f\u0440\u0438 \u043d\u0430\u0432\u0435\u0434\u0435\u043d\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u0435\u0444\u0435\u0442\u0447\u0438\u0442\u044c \u0438\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u0443 \u0441\u0441\u044b\u043b\u043a\u0443 (\u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443 \u0440\u0443\u0442\u0430)&lt;Link route=\"idea\" input={{ id: '123' }} prefetchOnHover=\"serverAndClientQuery\"&gt;  \u041e\u0442\u043a\u0440\u044b\u0442\u044c \u0438\u0434\u0435\u044e&lt;\/Link&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p><code>NavLink<\/code> \u2014 \u044d\u0442\u043e \u0442\u0430 \u0436\u0435 \u0441\u0441\u044b\u043b\u043a\u0430, \u043d\u043e \u043e\u043d\u0430 \u0437\u043d\u0430\u0435\u0442, \u0430\u043a\u0442\u0438\u0432\u043d\u0430 \u043b\u0438 \u043e\u043d\u0430 \u0441\u0435\u0439\u0447\u0430\u0441, \u0438 \u0443\u043c\u0435\u0435\u0442 \u0434\u0430\u0432\u0430\u0442\u044c \u0440\u0430\u0437\u043d\u044b\u0435 \u043a\u043b\u0430\u0441\u0441\u044b \u0434\u043b\u044f \u0440\u0430\u0437\u043d\u044b\u0445 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 (\u0442\u043e\u0447\u043d\u043e\u0435 \u0441\u043e\u0432\u043f\u0430\u0434\u0435\u043d\u0438\u0435, \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u0443\u0442\u0438, \u043f\u043e\u0442\u043e\u043c\u043e\u043a \u0438 \u0442.\u0434.):<\/p>\n<pre><code>&lt;NavLink  route=\"home\"  className=\"px-3 py-1.5 text-slate-700 hover:bg-slate-100\"  \/\/ \u043a\u043e\u0433\u0434\u0430 \u043c\u044b \u0443\u0436\u0435 \u043d\u0430 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u2014 \u0433\u0430\u0441\u0438\u043c \u043a\u043b\u0438\u043a\u0438 \u0438 \u043f\u043e\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u0435\u043c  exactClassName=\"pointer-events-none text-slate-300\"&gt;  Home&lt;\/NavLink&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u0435\u0449\u0451 \u0432\u043e\u0442 \u0442\u0430\u043a \u043c\u043e\u0436\u043d\u043e \u0432 \u043d\u0435\u0451 \u043a\u043b\u0430\u0441\u0441\u044b \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c:<\/p>\n<pre><code>&lt;NavLink  route=\"home\"  className={{    default: 'px-3 py-1.5 text-slate-700 hover:bg-slate-100',    exact: 'pointer-events-none text-slate-300',  }}&gt;  Home&lt;\/NavLink&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0449\u0451 \u0435\u0441\u0442\u044c \u043f\u0430\u0440\u0430 \u0445\u0443\u043a\u043e\u0432 \u0434\u043b\u044f \u0440\u0435\u0430\u043a\u0446\u0438\u0438 \u043d\u0430 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u044b. <code>useOnNavigate()<\/code> \u044f \u0443\u0436\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043f\u0440\u043e \u043b\u043e\u0430\u0434\u0438\u043d\u0433 (\u0442\u0430\u043c \u043c\u044b \u0432\u0435\u0448\u0430\u043b\u0438 \u043d\u0430 \u043d\u0435\u0433\u043e NProgress). \u0410 <code>useIsNavigating()<\/code> \u043f\u0440\u043e\u0441\u0442\u043e \u0433\u043e\u0432\u043e\u0440\u0438\u0442, \u0438\u0434\u0451\u0442 \u043b\u0438 \u0441\u0435\u0439\u0447\u0430\u0441 \u043f\u0435\u0440\u0435\u0445\u043e\u0434 \u2014 \u0443\u0434\u043e\u0431\u043d\u043e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0440\u0438\u0442\u0443\u0448\u0438\u0442\u044c \u043a\u043e\u043d\u0442\u0435\u043d\u0442, \u043f\u043e\u043a\u0430 \u0433\u0440\u0443\u0437\u0438\u0442\u0441\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430:<\/p>\n<pre><code>import { useIsNavigating } from '@point0\/core\/navigation'export const generalLayout = root.lets.layout().layout(({ children }) =&gt; {  const isNavigating = useIsNavigating()  return &lt;div style={{ opacity: isNavigating ? 0.6 : 1 }}&gt;{children}&lt;\/div&gt;})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0443 \u043d\u0430\u0441 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 <code>index.client.ts<\/code> \u0444\u0430\u0439\u043b, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043a\u0430\u043a \u0440\u0430\u0437 \u0438 \u043f\u0440\u043e\u043a\u0438\u0434\u044b\u0432\u0430\u0435\u0442 \u043d\u0430\u0448\u0438 \u043f\u043e\u0438\u043d\u0442\u044b (\u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 \u043d\u0430\u0448\u0438\u0445 \u043f\u043e\u0438\u043d\u0442\u043e\u0432 \u0441 \u043b\u0435\u043d\u0438\u0432\u044b\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0434\u043b\u044f \u043d\u0430\u0441 \u0441\u043e\u0431\u0440\u0430\u043b \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440), \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0447\u0435\u043c\u0443 \u0441\u0430\u043c <code>RouterRoutes<\/code> \u0437\u043d\u0430\u0435\u0442 \u043e\u0431\u043e \u0432\u0441\u0435\u0445 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0445 \u043f\u043e\u0438\u043d\u0442\u0430\u0445. \u0418 \u043c\u043e\u0436\u0435\u0442 \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0434\u0435\u0440\u0435\u0432\u043e. \u041e\u043d \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u0442 \u043f\u043e \u0440\u043e\u0443\u0442\u0430\u043c \u043e\u0442 \u0431\u043e\u043b\u0435\u0435 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u043d\u044b\u0445 \u043a \u043c\u0435\u043d\u0435\u0435 \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u043d\u044b\u043c. \u0422\u043e \u0435\u0441\u0442\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u043c\u0435\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u2018\/ideas\/new\u2019 \u0438 \u2018\/ideas\/:id\u2019 \u0438 \u043e\u043d\u0438 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u043a\u043e\u043d\u0444\u043b\u0438\u043a\u0442\u043e\u0432\u0430\u0442\u044c<\/p>\n<pre><code>import App from '@\/app.client'import points from '@\/generated\/point0\/points.client'import '@\/styles\/index.css'import { ErrorBoundary } from '@\/ui\/error-boundary'import { mount } from '@point0\/react-dom\/mount'mount(  &lt;ErrorBoundary&gt;    &lt;App \/&gt;  &lt;\/ErrorBoundary&gt;,  points,)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/navigation\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044e<\/a>.<\/p>\n<h2>Redirect<\/h2>\n<p>\u0420\u0435\u0434\u0438\u0440\u0435\u043a\u0442 \u2014 \u0431\u043b\u0438\u0437\u043a\u0438\u0439 \u0440\u043e\u0434\u0441\u0442\u0432\u0435\u043d\u043d\u0438\u043a \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438, \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u044b \u043d\u0435 \u0441\u0430\u043c\u0438 \u043a\u043b\u0438\u043a\u0430\u0435\u043c, \u0430 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043f\u043e \u043a\u0430\u043a\u043e\u043c\u0443-\u0442\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044e. \u0418 \u0442\u0443\u0442 \u0435\u0441\u0442\u044c \u0434\u0432\u0435 \u0441\u0442\u043e\u0440\u043e\u043d\u044b: \u043a\u043b\u0438\u0435\u043d\u0442 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440.<\/p>\n<p>\u041d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0432\u0441\u0451 \u043e\u0447\u0435\u0432\u0438\u0434\u043d\u043e \u2014 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044f \u043f\u043e \u0443\u0441\u043b\u043e\u0432\u0438\u044e. \u041c\u043e\u0436\u043d\u043e \u0438\u043c\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e \u0447\u0435\u0440\u0435\u0437 <code>navigate(...)<\/code>, \u0430 \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043a\u043b\u0430\u0440\u0430\u0442\u0438\u0432\u043d\u043e \u2014 \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>Redirect<\/code>:<\/p>\n<pre><code>import { Redirect } from '@\/lib\/navigation'export const secretPage = root.lets.page('\/secret').page(() =&gt; {  const { me } = MeProvider.useValue()  if (!me) {    \/\/ \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043b\u0438 \u2014 \u0437\u043d\u0430\u0447\u0438\u0442 \u0440\u0435\u0434\u0438\u0440\u0435\u043a\u0442\u0438\u043c, \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0438 \u043f\u0440\u0438 SSR    return &lt;Redirect route=\"login\" \/&gt;  }  return &lt;h1&gt;\u0421\u0435\u043a\u0440\u0435\u0442\u043d\u0430\u044f \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430&lt;\/h1&gt;})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 (\u0432 <code>.loader()<\/code> \u0438\u043b\u0438 <code>.ctx()<\/code>) \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0438\u043b\u0438 \u0432\u044b\u043a\u0438\u043d\u0443\u0442\u044c redirect()<\/p>\n<pre><code>import { redirect } from '@\/lib\/navigation'import { AppError } from '@\/lib\/error'export const redirectUnauthorizedPlugin = Point0.lets  .plugin()  .ctx(({ request }) =&gt; {    const me = await getMe(request)    if (!me) {      throw redirect('login')      \/\/ return redirect('login') \u0442\u043e\u0436\u0435 \u043e\u043a    }    return { me }  })  .plugin()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u0436\u0435 redirect \u0445\u0435\u043b\u043f\u0435\u0440 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 <code>.with()<\/code>:<\/p>\n<pre><code>export const redirectUnauthorizedPlugin = Point0.lets  .plugin()  .use(mePlugin)  .with(({ props: { me } }) =&gt; {    if (!me) {      \/\/ \u0437\u0434\u0435\u0441\u044c \u043d\u0435 \u043d\u0430\u0434\u043e \u0434\u0435\u043b\u0430\u0442\u044c throw, \u044d\u0442\u043e \u0436\u0435 \u043a\u0430\u043a \u0431\u044b \u0440\u0435\u0430\u043a\u0442-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442      \/\/ \u043c\u044b \u0432 \u0440\u0435\u0430\u043a\u0442-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u0445 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0432\u044b\u0438\u043a\u0438\u0434\u044b\u0432\u0430\u0435\u043c, \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u043c      return redirect('login')      \/\/ return &lt;Redirect route=\"login\" \/&gt; \u0442\u043e\u0436\u0435 \u043e\u043a    }  })  .plugin()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h2>.middleware()<\/h2>\n<p>\u0422\u043e \u0447\u0442\u043e \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430\u0445 \u043e\u0441\u043d\u043e\u0432\u0430, \u0443 \u043d\u0430\u0441 \u0430\u043d\u0442\u0438\u043f\u0430\u0442\u0442\u0435\u0440\u043d. \u0414\u043b\u044f \u043d\u0430\u0448\u0438\u0445 \u043f\u043e\u0438\u043d\u0442\u043e\u0432 \u043c\u0438\u0434\u043b\u0432\u0430\u0440\u044b \u043d\u0435 \u043d\u0443\u0436\u043d\u044b, \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043b\u043e\u0430\u0434\u0435\u0440\u044b \u0438 ctx. \u041d\u043e \u0435\u0441\u0442\u044c \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0438, \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u043d\u0443\u0436\u043d\u044b \u0438\u043c\u0435\u043d\u043d\u043e \u043c\u0438\u0434\u043b\u0432\u0430\u0440\u044b: CORS, \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438, \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u0438. \u041e\u0431\u044b\u0447\u043d\u043e \u043c\u0438\u0434\u043b\u0432\u0430\u0440\u044b \u043c\u044b \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0432 \u0441\u0430\u043c \u0440\u0443\u0442, \u0442\u043e\u0433\u0434\u0430 \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u0432\u0441\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u043f\u0440\u043e\u0439\u0434\u0443\u0442 \u0447\u0435\u0440\u0435\u0437 \u043d\u0438\u0445. \u0412 \u043e\u0441\u043e\u0431\u044b\u0445 \u0441\u043b\u0443\u0447\u0430\u044f\u0445 \u043c\u043e\u0436\u043d\u043e \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0438 \u0432 \u0441\u0430\u043c\u0438 \u043f\u043e\u0438\u043d\u0442\u044b, \u0442\u043e\u0433\u0434\u0430 \u043f\u0440\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043a \u044d\u0442\u043e\u043c\u0443 \u043f\u043e\u0438\u043d\u0442\u0443 \u0435\u0433\u043e \u043c\u0438\u0434\u043b\u0432\u0430\u0440\u0430 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0430 \u043a \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c.<\/p>\n<p>\u0420\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0442\u0430\u043a\u0436\u0435 \u043a\u0430\u043a \u0438 \u043c\u0438\u0434\u043b\u0432\u0430\u0440\u044b \u0432 \u044d\u043a\u0441\u043f\u0440\u0435\u0441\u0441 \u0438 \u0432 \u043f\u0440\u043e\u0447\u0438\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430\u0445:<\/p>\n<pre><code>\/\/ \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0445\u043e\u0442\u0438\u043c \u0437\u0430\u043c\u0435\u0440\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430const root = Point0.lets  .root()  .middleware(async ({ next }) =&gt; {    const startedAt = performance.now()    const result = await next()    const duration = performance.now() - startedAt    console.log(`Request took ${duration}ms`)    return result  })  .root()\/\/ \u043c\u043e\u0436\u0435\u043c \u043e\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u0446\u0435\u043f\u043e\u0447\u043a\u0443 \u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u0441\u0432\u043e\u0439 \u043e\u0442\u0432\u0435\u0442\/\/ \u044d\u0442\u043e \u0431\u0435\u0441\u043a\u043e\u043d\u0435\u0447\u043d\u043e \u0434\u0435\u0441\u0442\u0440\u0443\u043a\u0442\u0438\u0432\u043d\u043e, \u043d\u0435 \u0434\u0435\u043b\u0430\u0439\u0442\u0435 \u0442\u0430\u043a, \u043d\u043e \u0438\u0434\u0435\u044f \u044f\u0441\u043d\u0430\/\/ \u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043c\u044b \u0441\u043b\u043e\u043c\u0430\u0435\u043c \u0432\u0441\u0435 \u043d\u0430\u0448\u0438 \u043f\u043e\u0438\u043d\u0442\u044bconst root = Point0.lets  .root()  .middleware(async ({ next }) =&gt; {    return new Response('Hello, world!', { status: 200 })  })  .root()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043d\u0430\u0448\u0438\u0445 \u043c\u0438\u0434\u043b\u0432\u0430\u0440 \u0432 \u0442\u043e\u043c, \u0447\u0442\u043e <code>next()<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043d\u0435 Response, \u043e\u043d \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u043e\u0441\u043e\u0431\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442. \u0422\u043e \u0435\u0441\u0442\u044c \u043c\u0438\u0434\u043b\u0432\u0430\u0440\u0430 \u043e\u0431\u044f\u0437\u0430\u043d\u0430 \u043b\u0438\u0431\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c Response, \u043b\u0438\u0431\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 <code>next()<\/code>. \u0412\u043d\u0443\u0442\u0440\u0438 <code>next()<\/code> \u043b\u0435\u0436\u0438\u0442 \u043e\u0431\u044a\u0435\u043a\u0442, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u044e\u0449\u0438\u0439, \u0447\u0442\u043e \u0432 \u0438\u0442\u043e\u0433\u0435 \u043c\u044b \u0437\u0430\u043f\u0440\u043e\u0441\u0438\u043b\u0438, \u0432\u043a\u043b\u044e\u0447\u0430\u044f Response, \u043d\u043e \u043d\u0435 \u0442\u043e\u043b\u044c\u043a\u043e \u0435\u0433\u043e:<\/p>\n<pre><code>const root = Point0.lets  .root()  .middleware(async ({ next }) =&gt; {    const result = await next()    console.log(result.variant.type) \/\/ \"endpoint\" | \"error\" | \"middleware\" | \"options\" | \"page\" | \"publicdir\"    \/\/ \u0438 \u043c\u043d\u043e\u0433\u043e \u0447\u0435\u0433\u043e \u0435\u0449\u0451, \u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0441\u0430\u043c\u043e\u0439 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438    return result  })  .root()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043f\u0435\u0440\u0432\u044b\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u043f\u0443\u0442\u044c, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u0443\u0434\u0435\u0442 \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043c\u0438\u0434\u043b\u0432\u0430\u0440\u0430:<\/p>\n<pre><code>export const root = Point0.lets  .root()  \/\/ \u043e\u0442\u0434\u0430\u0451\u043c \u0432\u0441\u0451, \u0447\u0442\u043e \u043f\u0440\u0438\u0448\u043b\u043e \u043d\u0430 \/api\/auth\/*, \u0432 better-auth  .middleware('\/api\/auth\/*', async ({ request }) =&gt; {    \/\/ request.original \u2014 \u044d\u0442\u043e \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 Request \u0438\u0437 Fetch API    return await betterAuthServer.handler(request.original)  })  .root()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0447\u0442\u043e-\u0442\u043e \u0432 \u043c\u0438\u0434\u043b\u0432\u0430\u0440\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0433\u043e, \u0447\u0442\u043e \u043f\u043e\u0442\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u0432 \u043d\u0430\u0448\u0438\u0445 <code>.ctx()<\/code> \u0438 <code>.loader()<\/code>, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u043e\u0436\u0438\u0442\u044c \u044d\u0442\u043e \u0432 <code>request.state<\/code> \u0438\u043b\u0438 <code>request.cache<\/code> (\u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043f\u0440\u043e request):<\/p>\n<pre><code>export const root = Point0.lets  .root()  .middleware(({ request, next }) =&gt; {    request.state.x = 123    return next()  })  .root()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u0445 \u043c\u0438\u0434\u043b\u0432\u0430\u0440. \u042d\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043c\u0438\u0434\u043b\u0432\u0430\u0440\u043e\u0439:<\/p>\n<pre><code>import { openapi } from '@point0\/openapi'import { cors } from '@point0\/cors'import { basicAuth } from '@point0\/basic-auth'export const root = Point0.lets  .root()  .middleware(cors({ origin: true, credentials: true }))  .middleware(basicAuth({ users: { admin: 'adminpassword' } }))  .middleware(openapi({ route: '\/openapi.json', scalar: '\/scalar' }))  .root()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/middleware\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e .middleware()<\/a>.<\/p>\n<h2>Request<\/h2>\n<p>\u0412 \u043b\u043e\u0430\u0434\u0435\u0440\u044b, <code>.ctx()<\/code> \u0438 \u043c\u0438\u0434\u043b\u0432\u0430\u0440\u044b \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u043e\u0431\u044a\u0435\u043a\u0442 <code>request<\/code> \u2014 \u044d\u0442\u043e \u043d\u0430\u0448\u0430 \u043e\u0431\u0451\u0440\u0442\u043a\u0430 \u043d\u0430\u0434 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u043c Fetch-\u0437\u0430\u043f\u0440\u043e\u0441\u043e\u043c. \u0412\u0441\u0435 \u043f\u043e\u043b\u044f \u0442\u0430\u043c \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0438 \u043a \u043d\u0438\u043c, \u0442\u0430\u043a \u0447\u0442\u043e \u044d\u0442\u043e \u043d\u0435\u0434\u043e\u0440\u043e\u0433\u0430\u044f \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u044f \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441.<\/p>\n<pre><code>export const meQuery = root.lets  .query()  .loader(async ({ request }) =&gt; {    \/\/ \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 Request \u0438\u0437 Fetch API \u2014 \u043d\u0430 \u0441\u043b\u0443\u0447\u0430\u0439, \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u043d\u043e \u043f\u0440\u044f\u043c\u043e \u0435\u0433\u043e    request.original    \/\/ \u043c\u0435\u0442\u043e\u0434 \u0432 \u0432\u0435\u0440\u0445\u043d\u0435\u043c \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0435: 'GET' | 'POST' | ...    request.method    \/\/ \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438, \u043d\u043e\u0440\u043c\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0432 \u043d\u0438\u0436\u043d\u0438\u0439 \u0440\u0435\u0433\u0438\u0441\u0442\u0440    const auth = request.headers['authorization']    \/\/ \u043a\u0443\u043a\u0438 \u0443\u0436\u0435 \u0440\u0430\u0441\u043f\u0430\u0440\u0441\u0435\u043d\u044b \u0432 \u043e\u0431\u044a\u0435\u043a\u0442    const session = request.cookies['session']    \/\/ \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u043d\u043d\u0430\u044f \u043b\u043e\u043a\u0430\u0446\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 (pathname, search, ...)    request.location    \/\/ \u0438 \u0443\u0434\u043e\u0431\u043d\u043e\u0435 \u0445\u0440\u0430\u043d\u0438\u043b\u0438\u0449\u0435 \u043d\u0430 \u0432\u0440\u0435\u043c\u044f \u043e\u0434\u043d\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u2014 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0447\u0442\u043e\u0431\u044b    \/\/ \u043d\u0435 \u0434\u0451\u0440\u0433\u0430\u0442\u044c \u0441\u0435\u0441\u0441\u0438\u044e \u0434\u0432\u0430\u0436\u0434\u044b \u0437\u0430 \u0437\u0430\u043f\u0440\u043e\u0441    request.state.me ??= await getMe(request)    \/\/ \u0432\u043e \u0432\u0440\u0435\u043c\u044f ssr, \u043c\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0432 1 \u0437\u0430\u043f\u0440\u043e\u0441 \u043a \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u0434\u0430\u043d\u043d\u044b\u0445 \u043a\u0432\u0435\u0440\u0435\u0439, \u0441\u043e\u0437\u0434\u0430\u0451\u043c \u0443\u0436\u0435 \u043f\u0440\u044f\u043c\u043e \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435    \/\/ \u0435\u0449\u0451 \u0437\u0430\u043f\u0440\u043e\u0441\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u043e\u0445\u043e\u0434\u044f \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u0436\u0435 \u043f\u0443\u0442\u044c, \u0438 \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0441\u0442\u0435\u0439\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043c\u0435\u0436\u0434\u0443 \u044d\u0442\u0438\u043c\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0430\u043c\u0438    \/\/ \u043b\u0443\u0447\u0448\u0435 \u043a\u043b\u0430\u0441\u0442\u044c \u043d\u0435 \u0432 request.state \u0430 \u0432 request.cache    request.cache.me ??= await getMe(request)    \/\/ ip-\u0430\u0434\u0440\u0435\u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u0430    request.from.ip    \/\/ user-agent \u043a\u043b\u0438\u0435\u043d\u0442\u0430    request.from.userAgent    \/\/ location \u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u0431\u044b\u043b \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d \u0437\u0430\u043f\u0440\u043e\u0441    request.from.location    return { me: request.cache.me }  })  .query()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u0430\u043a\u0438\u0445-\u0442\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u0445\u0435\u043b\u043f\u0435\u0440\u043e\u0432, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u044c <code>request<\/code> \u0435\u0449\u0451 \u0438 \u0447\u0435\u0440\u0435\u0437 <code>getRequest<\/code> \u0438\u043b\u0438 <code>getRequestOrUndefined<\/code>:<\/p>\n<pre><code>import { getRequest, getRequestOrUndefined } from '@point0\/core'\/\/ \u0435\u0441\u043b\u0438 \u0440\u0435\u043a\u0432\u0435\u0441\u0442 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d \u0432 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438 (node async storage \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043f\u043e\u043b\u043e\u0436\u0438\u043b\u0438 \u0440\u0435\u043a\u0432\u0435\u0441\u0442 \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u0430),\/\/ \u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043a\u0438\u043d\u0443\u0442\u0430 \u043e\u0448\u0438\u0431\u043a\u0430, \u0442\u0438\u043f \u0437\u0434\u0435\u0441\u044c Request0const request1 = getRequest()\/\/ \u0435\u0441\u043b\u0438 \u0440\u0435\u043a\u0432\u0435\u0441\u0442 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d \u0432 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438, \u0442\u043e \u0431\u0443\u0434\u0435\u0442 undefined,\/\/ \u0442\u0438\u043f \u0437\u0434\u0435\u0441\u044c Request0 | undefinedconst request2 = getRequestOrUndefined()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430\u043c \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u044d\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 CookieStore.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/request\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e Request<\/a>.<\/p>\n<h2>Response<\/h2>\n<p>\u041e\u0442\u0432\u0435\u0442\u043e\u043c \u043c\u044b \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u0447\u0435\u0440\u0435\u0437 \u0445\u0435\u043b\u043f\u0435\u0440 <code>set<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442 \u0442\u0443\u0434\u0430 \u0436\u0435, \u043a\u0443\u0434\u0430 \u0438 <code>request<\/code> (\u0432 \u043b\u043e\u0430\u0434\u0435\u0440\u044b, <code>.ctx()<\/code>, \u043c\u0438\u0434\u043b\u0432\u0430\u0440\u044b). \u0418\u043c \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438, \u043a\u0443\u043a\u0438 \u0438 \u0441\u0442\u0430\u0442\u0443\u0441, \u043d\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u044f <code>Response<\/code> \u0440\u0443\u043a\u0430\u043c\u0438:<\/p>\n<pre><code>export const loginMutation = root.lets  .mutation()  .input(z.object({ email: z.string(), password: z.string() }))  .loader(async ({ input, set }) =&gt; {    const { user, token } = await auth.login(input)    \/\/ \u0432\u044b\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043a\u0443\u043a\u0443 (\u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e path '\/', sameSite 'lax')    set.cookies('session', token, {      httpOnly: true,      secure: true,      maxAge: 60 * 60 * 24,    })    \/\/ \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a    set.headers('X-User-Id', user.id)    \/\/ \u0441\u0442\u0430\u0442\u0443\u0441    set.status(201)    return { user }  })  .mutation()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u0443\u043a\u0443 \u0443\u0434\u0430\u043b\u044f\u044e\u0442, \u043f\u0435\u0440\u0435\u0434\u0430\u0432 <code>undefined<\/code> \u0432\u043c\u0435\u0441\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f: <code>set.cookies('session', undefined)<\/code>. \u0410 \u0435\u0441\u043b\u0438 \u043d\u0443\u0436\u0435\u043d \u0441\u043e\u0432\u0441\u0435\u043c \u043a\u0430\u0441\u0442\u043e\u043c\u043d\u044b\u0439 \u043e\u0442\u0432\u0435\u0442 \u2014 \u0431\u0430\u0439\u0442\u044b, \u0440\u0435\u0434\u0438\u0440\u0435\u043a\u0442 \u043d\u0430 \u0444\u0430\u0439\u043b, \u0447\u0442\u043e \u0443\u0433\u043e\u0434\u043d\u043e \u2014 \u0438\u0437 \u043c\u0438\u0434\u043b\u0432\u0430\u0440\u044b \u0438\u043b\u0438 \u043b\u043e\u0430\u0434\u0435\u0440\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439 <code>Response<\/code>, \u0438 \u0432\u0441\u0435 \u0432\u044b\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0447\u0435\u0440\u0435\u0437 <code>set<\/code> \u044d\u0444\u0444\u0435\u043a\u0442\u044b \u043a \u043d\u0435\u043c\u0443 \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0442\u0441\u044f.<\/p>\n<p>\u0414\u043b\u044f \u0443\u0434\u043e\u0431\u0441\u0442\u0432\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u0430\u043a\u0438\u0445-\u0442\u043e \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0445 \u0445\u0435\u043b\u043f\u0435\u0440\u043e\u0432, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u044d\u0444\u0444\u0435\u043a\u0442\u044b \u0440\u0435\u043a\u0432\u0435\u0441\u0442\u0430 \u0447\u0435\u0440\u0435\u0437 <code>getEffects<\/code> \u0438\u043b\u0438 <code>getEffectsOrUndefined<\/code>:<\/p>\n<pre><code>import { getEffects, getEffectsOrUndefined } from '@point0\/core'\/\/ \u0435\u0441\u043b\u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u044b \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u044b \u0432 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438 (node async storage \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043f\u043e\u043b\u043e\u0436\u0438\u043b\u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u044b \u0432 \u043c\u043e\u043c\u0435\u043d\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u0430),\/\/ \u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u043a\u0438\u043d\u0443\u0442\u0430 \u043e\u0448\u0438\u0431\u043a\u0430, \u0442\u0438\u043f \u0437\u0434\u0435\u0441\u044c Effects0const effects1 = getEffects()\/\/ \u0435\u0441\u043b\u0438 \u044d\u0444\u0444\u0435\u043a\u0442\u044b \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u044b \u0432 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438, \u0442\u043e \u0431\u0443\u0434\u0435\u0442 undefined,\/\/ \u0442\u0438\u043f \u0437\u0434\u0435\u0441\u044c Effects0 | undefinedconst effects2 = getEffectsOrUndefined()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430\u043c \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u0441\u044f \u044d\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 CookieStore.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/response\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e Response<\/a>.<\/p>\n<h2>File Upload<\/h2>\n<p>\u0424\u0430\u0439\u043b \u2014 \u044d\u0442\u043e \u0447\u0430\u0441\u0442\u044c \u0438\u043d\u043f\u0443\u0442\u0430, \u043f\u0440\u043e\u0441\u0442\u043e \u0432 \u0441\u0445\u0435\u043c\u0435 \u043e\u043d \u043e\u043f\u0438\u0441\u0430\u043d \u043a\u0430\u043a \u0444\u0430\u0439\u043b. \u041d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u043a\u043b\u0430\u0434\u0451\u0442\u0435 <code>File<\/code> \u0432 \u0438\u043d\u043f\u0443\u0442 \u043c\u0443\u0442\u0430\u0446\u0438\u0438, \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0435 \u0435\u0433\u043e \u0432 \u043b\u043e\u0430\u0434\u0435\u0440\u0435. FormData \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0441\u043e\u0431\u0435\u0440\u0451\u0442 \u0441\u0430\u043c.<\/p>\n<pre><code>import { z } from 'zod'export const ideaCreateMutation = root.lets  .mutation()  .input(    z.object({      title: z.string().min(1),      content: z.string().min(1),      image: z.file().optional(), \/\/ \u0432\u043e\u0442 \u043e\u043d, \u0444\u0430\u0439\u043b    }),  )  .loader(async ({ input }) =&gt; {    \/\/ \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 input.image \u2014 \u044d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0439 File (\u043d\u0430\u0441\u043b\u0435\u0434\u043d\u0438\u043a Blob)    const imageBase64 = input.image      ? Buffer.from(await input.image.arrayBuffer()).toString('base64')      : undefined    const idea = await prisma.idea.create({      data: { title: input.title, content: input.content, image: imageBase64 },    })    return { idea }  })  .mutation()export const ideaCreatePage = root.lets  .page('\/ideas\/create')  .head(() =&gt; `\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438\u0434\u0435\u0438`)  .page(() =&gt; {    const [image, setImage] = useState&lt;File | undefined&gt;(undefined)    return (      &lt;div&gt;        &lt;h1&gt;\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438\u0434\u0435\u0438&lt;\/h1&gt;        &lt;Form          defaultValues={{            title: idea.title,            content: idea.content,          }}          onSubmit={({ title, content }) =&gt; {            const { idea } = await ideaCreateMutation.fetchMutation({              id: idea.id,              title,              content,              image, \/\/ \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u043a\u0438\u0434\u044b\u0432\u0430\u0435\u043c \u0444\u0430\u0439\u043b \u043a\u0430\u043a \u0435\u0441\u0442\u044c            })            await navigate('idea', { id: idea.id })          }}        &gt;          &lt;input            type=\"file\"            onChange={(e) =&gt; {              const file = e.target.files?.[0] || undefined              \/\/ \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u043b \u0431\u0435\u0437 \u0432\u043e\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u044b\u0445 \u0445\u0435\u043b\u043f\u0435\u0440\u043e\u0432, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u043a\u0430\u043a \u044d\u0442\u043e \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u043d\u043e              setImage(file)            }}          \/&gt;          &lt;Input label=\"\u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a\" name=\"title\" \/&gt;          &lt;Textarea label=\"\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\" name=\"content\" \/&gt;          &lt;Button&gt;\u0421\u043e\u0437\u0434\u0430\u0442\u044c&lt;\/Button&gt;        &lt;\/Form&gt;      &lt;\/div&gt;    )  })<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/file-upload\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443 \u0444\u0430\u0439\u043b\u043e\u0432<\/a>.<\/p>\n<h2>Action<\/h2>\n<p>\u0423 \u043d\u0430\u0441 \u0434\u043b\u044f \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u044f \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443 \u0435\u0441\u0442\u044c \u043a\u0432\u0435\u0440\u0438 \u0438 \u043c\u0443\u0442\u0430\u0446\u0438\u0438. \u041d\u0435 \u0445\u0432\u0430\u0442\u0430\u0435\u0442 \u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0445 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u0432. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0442 \u044d\u043a\u0448\u0435\u043d\u044b, \u0433\u0434\u0435 \u043c\u044b \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0438\u0440\u0443\u0435\u043c \u043c\u0435\u0442\u043e\u0434 \u0438 \u043f\u0443\u0442\u044c.<\/p>\n<pre><code>export const stripeWebhookAction = root.lets  .action('POST', '\/api\/webhooks\/stripe')  .loader(async ({ request }) =&gt; {    const event = await stripe.webhooks.constructEvent(      await request.original.text(),      request.headers['stripe-signature'],      process.env.STRIPE_WEBHOOK_SECRET,    )    await handleStripeEvent(event)    return { received: true }  })  .action()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u044d\u043a\u0448\u0435\u043d \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u0432\u0445\u043e\u0434\u043d\u0443\u044e \u0441\u0445\u0435\u043c\u0443 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u043e\u0432 \u0440\u043e\u0443\u0442\u0430, \u0441\u0435\u0440\u0447\u0430, \u0431\u043e\u0434\u0438, \u0445\u0435\u0434\u0435\u0440\u043e\u0432. \u0415\u0441\u043b\u0438 \u043e\u0431\u044a\u044f\u0432\u0438\u043c \u0441\u0445\u0435\u043c\u0443 \u0431\u043e\u0434\u0438, \u0442\u043e\u0433\u0434\u0430 \u0431\u043e\u0434\u0438 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u043c \u0441\u0430\u043c \u0438 \u0440\u0430\u0441\u043f\u0430\u0440\u0448\u0435\u043d \u043a\u0430\u043a json\/formData, \u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0432 <code>request.rawBody<\/code><\/p>\n<pre><code>const action = root.lets  .action('POST', '\/api\/my-test\/:id')  .params(z.object({ id: z.coerce.number().min(1) }))  .headers(z.object({ x: z.string().min(1) }))  .search(z.object({ y: z.string().min(1) }))  .body(z.object({ b: z.number().min(1), d: z.bigint() }))  \/\/ \u0438 \u043f\u0440\u0438 \u0440\u0430\u0431\u043e\u0442\u0435 \u0441 action, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0435 \u043f\u0438\u0441\u0430\u0442\u044c .loader()  \/\/ \u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u044d\u0442\u043e\u0442 \u0436\u0435 \u043b\u043e\u0430\u0434\u0435\u0440 \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0432 \u0437\u0430\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u043c .action()  .action(({ request, headers, search, body, params }) =&gt; {    return {      headers,      search,      params,      body,      bodyUsed: request.original.bodyUsed,    }  })<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u0435\u0449\u0451 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0430\u043c\u0438 \u0436\u0435 \u044d\u043a\u0448\u0435\u043d\u044b \u0445\u043e\u0442\u044c \u043a\u0430\u043a \u043a\u0432\u0435\u0440\u0438, \u0445\u043e\u0442\u044c \u043a\u0430\u043a \u043c\u0443\u0442\u0430\u0446\u0438\u044e, \u0445\u043e\u0442\u044c \u043a\u0430\u043a \u0438\u043d\u0444\u0438\u043d\u0438\u0442\u0438 \u043a\u0432\u0435\u0440\u0438:<\/p>\n<pre><code>export const ideaUpdateAction = root.lets  .action('PUT', '\/api\/ideas\/:id')  .body(    z.object({      title: z.string().min(1),      content: z.string().min(1),    }),  )  .loader(async ({ params: { id }, body: { title, content } }) =&gt; {    const idea = await prisma.idea.update({      where: { id },      data: { title, content },    })    return { idea }  })  \/\/ \u0438 \u0432\u043e\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u043c \u044d\u0442\u043e \u043d\u0443\u0436\u043d\u044b\u043c \u0441\u043b\u043e\u0432\u043e\u043c.  \/\/ \u0434\u0430, \u044f \u0433\u043e\u0432\u043e\u0440\u0438\u043b \u0447\u0442\u043e \u0432\u0441\u0435 \u043f\u043e\u0438\u043d\u0442\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043d\u0430\u0447\u0438\u043d\u0430\u0442\u044c\u0441\u044f \u0442\u0435\u043c \u0436\u0435 \u0441\u043b\u043e\u0432\u043e\u043c, \u0441 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043d\u0430\u0447\u0430\u043b\u0441\u044f .lets  \/\/ \u043d\u043e action \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u044b\u0439, \u0435\u043c\u0443 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u043a\u043e\u043d\u0447\u0438\u0442\u044c\u0441\u044f \u043d\u0430 .query() \u0438\u043b\u0438 .mutation() \u0438\u043b\u0438 .infiniteQuery()  .mutation()export const ideaEditPage = root  .lets('page', 'ideaEdit', '\/ideas\/:id\/edit')  .loader(({ params }) =&gt; {    const idea = await prisma.idea.findUniqueOrThrow({      where: { id: params.id },    })    return { idea }  })  .head(({ data: { idea } }) =&gt; `Edit: ${idea.title}`)  .page(({ data: { idea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0434\u0435\u0438: {idea.title}&lt;\/h1&gt;      &lt;Form        defaultValues={{          title: idea.title,          content: idea.content,        }}        onSubmit={({ title, content }) =&gt; {          await ideaUpdateAction.fetchMutation({            \/\/ \u0432\u0441\u0451 \u043a\u0430\u043a \u0432 \u043e\u0431\u044b\u0447\u043d\u043e\u0439 \u043c\u0443\u0442\u0430\u0446\u0438\u0438, \u043d\u043e \u0432 \u043f\u0440\u043e\u0441\u0442\u044b\u0445 \u043c\u0443\u0442\u0430\u0446\u0438\u044f\u0445 \u0443 \u043d\u0430\u0441 \u0438\u043d\u043f\u0443\u0442 \u043f\u043b\u043e\u0441\u043a\u0438\u0439            \/\/ \u0430 \u0432 \u044d\u043a\u0448\u0435\u043d\u0430\u0445 \u0440\u0430\u0437\u0434\u0435\u043b\u0451\u043d \u043d\u0430 search, params, body            params: { id: idea.id },            body: { title, content },          })          await navigate('idea', { id })        }}      &gt;        &lt;Input label=\"\u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a\" name=\"title\" \/&gt;        &lt;Textarea label=\"\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435\" name=\"content\" \/&gt;        &lt;Button&gt;\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c&lt;\/Button&gt;      &lt;\/Form&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0425\u043e\u0447\u0443 \u0442\u0430\u043a\u0436\u0435 \u043e\u0442\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043d\u0430\u0448\u0438 \u043f\u0440\u043e\u0441\u0442\u044b\u0435 <code>mutation<\/code>, <code>query<\/code>, <code>infiniteQuery<\/code>, \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 trpc, \u043d\u0435 \u0448\u043b\u0451\u044e\u0442 \u0432\u0441\u0451 \u043d\u0430 \u043e\u0434\u0438\u043d \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442, \u043e\u043d\u0438 \u0442\u043e\u0436\u0435 \u0438\u043c\u0435\u044e\u0442 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0435 \u0443\u0440\u043b\u044b. \u0418 \u043a\u0432\u0435\u0440\u0438, \u0438 \u043c\u0443\u0442\u0430\u0446\u0438\u0438 \u0448\u043b\u044e\u0442 POST \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0441 \u0438\u043d\u043f\u0443\u0442\u043e\u043c \u0432 \u0431\u043e\u0434\u0438 \u043d\u0430 \u0441\u0432\u043e\u0438 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u044b\u0435 kebab-cased \u0443\u0440\u043b\u044b \u0432\u0438\u0434\u0430 <code>\/_point0\/&lt;scope&gt;\/&lt;type&gt;\/&lt;\u0438\u043c\u044f-\u0432-\u043a\u0435\u0431\u0430\u0431-\u043a\u0435\u0439\u0441\u0435&gt;<\/code> \u2014 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, <code>\/_point0\/root\/query\/query-name-kebab-cased<\/code> \u0438 <code>\/_point0\/root\/mutation\/mutation-name-kebab-cased<\/code>. \u0418 \u0432 \u0441\u0432\u044f\u0437\u0438 \u0441 \u044d\u0442\u0438\u043c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043f\u043e\u043b\u043d\u0443\u044e \u043a\u0430\u0440\u0442\u0438\u043d\u0443 \u043d\u0430\u0448\u0438\u0445 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u0432 \u0432 OpenAPI-\u0441\u0445\u0435\u043c\u0435.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/action\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u044d\u043a\u0448\u0435\u043d\u044b<\/a>.<\/p>\n<h2>OpenAPI<\/h2>\n<p>\u0420\u0430\u0437 \u0443\u0436 \u0432\u0441\u0435 \u043d\u0430\u0448\u0438 \u043a\u0432\u0435\u0440\u0438, \u043c\u0443\u0442\u0430\u0446\u0438\u0438 \u0438 \u044d\u043a\u0448\u0435\u043d\u044b \u0438\u043c\u0435\u044e\u0442 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 \u0438\u043d\u043f\u0443\u0442 \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043a\u0430\u043a \u043d\u0430\u0441\u0442\u043e\u044f\u0449\u0438\u0435 HTTP-\u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u044b, \u043c\u043e\u0436\u0435\u043c \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u043e \u043d\u0438\u043c OpenAPI-\u0441\u0445\u0435\u043c\u0443. \u0417\u0430 \u044d\u0442\u043e \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u043f\u0430\u043a\u0435\u0442 <code>@point0\/openapi<\/code>, \u0438 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u043e\u043d \u043e\u0434\u043d\u043e\u0439 \u043c\u0438\u0434\u043b\u0432\u0430\u0440\u043e\u0439:<\/p>\n<pre><code>import { openapi } from '@point0\/openapi'export const root = Point0.lets  .root()  .middleware(    openapi({      route: '\/openapi.json', \/\/ \u0441\u0430\u043c\u0430 \u0441\u0445\u0435\u043c\u0430      scalar: '\/scalar', \/\/ \u043a\u0440\u0430\u0441\u0438\u0432\u044b\u0439 UI (Scalar)      swagger: '\/swagger', \/\/ \u0438\u043b\u0438 \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u0438\u0439 Swagger UI      filter: 'all', \/\/ \u043a\u0430\u043a\u0438\u0435 \u043f\u043e\u0438\u043d\u0442\u044b \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c    }),  )  .root()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u0445\u0435\u043c\u0430 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0438\u0437 \u0438\u043d\u043f\u0443\u0442-\u0441\u0445\u0435\u043c \u0432\u0430\u0448\u0438\u0445 \u043f\u043e\u0438\u043d\u0442\u043e\u0432 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438. \u041e\u0434\u043d\u0430\u043a\u043e \u043e\u0443\u0442\u043f\u0443\u0442 \u0442\u0430\u0439\u043f \u044f \u043f\u043e\u043a\u0430 \u0438\u0437 \u0442\u0438\u043f\u043e\u0432 \u043d\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u044e (\u044d\u0442\u043e \u043f\u043b\u0430\u043d \u043d\u0430 \u0431\u0443\u0434\u0443\u0449\u0435\u0435), \u0442\u0430\u043a \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u0432 \u043e\u043f\u0435\u043d \u0430\u043f\u0438 \u0441\u0445\u0435\u043c\u0435 \u043d\u0443\u0436\u0435\u043d \u043e\u0443\u0442\u043f\u0443\u0442 \u0442\u0430\u0439\u043f, \u0435\u0433\u043e \u043d\u0430\u0434\u043e \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0447\u0435\u0440\u0435\u0437 <code>.response(schema)<\/code>. \u0427\u0442\u043e\u0431\u044b \u0434\u043e\u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u0432\u044b\u0434\u0430\u0447\u0443 \u043e\u043f\u0435\u043d\u0430\u043f\u0438, \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435, \u0442\u0435\u0433\u0438, <code>operationId<\/code> \u0438\u043b\u0438 \u043f\u043e\u043c\u0435\u0442\u0438\u0442\u044c \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442 \u043a\u0430\u043a <code>deprecated<\/code>, \u0443 \u043f\u043e\u0438\u043d\u0442\u0430 \u0435\u0441\u0442\u044c \u043c\u0435\u0442\u043e\u0434 <code>.openapi()<\/code>:<\/p>\n<pre><code>export const ideaUpdateAction = root.lets  .action('PUT', '\/api\/ideas\/:id')  .body(    z.object({      title: z.string().min(1),      content: z.string().min(1),    }),  )  .response(z.object({ idea: ideaSchema }))  .openapi({    summary: '\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u0438\u0434\u0435\u044e',    description: '\u0421\u043e\u0437\u0434\u0430\u0451\u0442 \u043d\u043e\u0432\u0443\u044e \u0438\u0434\u0435\u044e \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0435\u0451',    tags: ['ideas'],    \/\/ \u043b\u044e\u0431\u044b\u0435 \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043e\u043f\u0435\u043d\u0430\u043f\u0438  })  .action(async ({ params: { id }, body: { title, content } }) =&gt; {    const idea = await prisma.idea.update({      where: { id },      data: { title, content },    })    return { idea }  })<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h2>Infer<\/h2>\n<p>\u0418\u043d\u043e\u0433\u0434\u0430 \u043d\u0443\u0436\u043d\u043e \u0432\u044b\u0442\u0430\u0449\u0438\u0442\u044c \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0442\u0438\u043f \u0438\u0437 \u043f\u043e\u0438\u043d\u0442\u0430 \u2014 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0442\u0434\u0430\u0451\u0442 \u043a\u0432\u0435\u0440\u0438, \u0438\u043b\u0438 \u0442\u0438\u043f \u0435\u0451 \u0438\u043d\u043f\u0443\u0442\u0430, \u0447\u0442\u043e\u0431\u044b \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0441\u0432\u043e\u0451\u043c \u043a\u043e\u0434\u0435.<\/p>\n<pre><code>\/\/ \u0442\u0438\u043f \u0434\u0430\u043d\u043d\u044b\u0445, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u0435\u0440\u043d\u0451\u0442 \u043b\u043e\u0430\u0434\u0435\u0440 \u043a\u0432\u0435\u0440\u0438type IdeaViewData = typeof ideaViewQuery.Infer.QueriedData\/\/ \u2192 { idea: Idea }\/\/ \u0442\u0438\u043f \u0441\u044b\u0440\u043e\u0433\u043e \u0438\u043d\u043f\u0443\u0442\u0430 \u043a\u0432\u0435\u0440\u0438type IdeaViewInput = typeof ideaViewQuery.Infer.InputRaw\/\/ \u2192 { id: string }<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043c \u043b\u0435\u0436\u0438\u0442 \u043c\u043d\u043e\u0433\u043e \u0447\u0435\u0433\u043e (<code>InputRaw<\/code>, <code>QueriedData<\/code>, <code>Error<\/code>, <code>Ctx<\/code> \u0438 \u0434\u0435\u0441\u044f\u0442\u043a\u0438 \u0434\u0440\u0443\u0433\u0438\u0445), \u043d\u043e \u0432 \u043e\u0431\u044b\u0447\u043d\u043e\u0439 \u0440\u0430\u0431\u043e\u0442\u0435 \u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u043d\u0443\u0436\u043d\u044b \u0438\u043c\u0435\u043d\u043d\u043e \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0438\u043d\u043f\u0443\u0442. \u042d\u0442\u043e \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u043e \u043f\u043e \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0443 \u2014 <code>Infer<\/code> \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0442\u0438\u043f\u0430\u0445.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/infer\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e Infer<\/a>.<\/p>\n<h2>Query Client<\/h2>\n<p>\u0422\u0430\u043a \u043a\u0430\u043a \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u0443 \u043d\u0430\u0441 react-query, \u0433\u0434\u0435-\u0442\u043e \u0436\u0438\u0432\u0451\u0442 \u0435\u0433\u043e <code>QueryClient<\/code>. \u0421\u043e\u0437\u0434\u0430\u0451\u0442\u0441\u044f \u043e\u043d \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u0431\u044b\u0442\u044c \u043e\u0431\u0449\u0438\u043c \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 (\u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u2014 \u0441\u0432\u043e\u0439 \u0438\u043d\u0441\u0442\u0430\u043d\u0441 \u043d\u0430 \u043a\u0430\u0436\u0434\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441, \u0447\u0442\u043e\u0431\u044b \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043d\u0435 \u0441\u043c\u0435\u0448\u0438\u0432\u0430\u043b\u0438\u0441\u044c):<\/p>\n<pre><code>\/\/ @\/lib\/query-clientimport { createQueryClient } from '@point0\/core'import { QueryClient } from '@tanstack\/react-query'export const queryClient = createQueryClient(() =&gt; new QueryClient())<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u0434\u0430\u043b\u044c\u0448\u0435 \u043e\u043d \u043f\u0435\u0440\u0435\u0434\u0430\u0451\u0442\u0441\u044f \u0432 \u043e\u0431\u044b\u0447\u043d\u044b\u0439 <code>QueryClientProvider<\/code> \u0432 \u0432\u0430\u0448\u0435\u043c <code>app.client.tsx<\/code>. \u041d\u0430\u0434\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u0447\u0442\u043e <code>queryClient<\/code> \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d \u043a\u0430\u043a \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u0432\u0435\u0440\u0438 \u043a\u043b\u0438\u0435\u043d\u0442, \u043d\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043f\u0440\u043e\u043a\u0441\u0438 \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c, \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e, \u0447\u0442\u043e\u0431\u044b, \u043a\u043e\u0433\u0434\u0430 \u0432\u044b \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0435 <code>queryClient.anyMethod()<\/code>, \u043c\u044b \u0431\u0440\u0430\u043b\u0438 \u0431\u044b \u0441\u0430\u043c \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 <code>queryClient<\/code> \u0438\u0437 \u0430\u0441\u0438\u043d\u043a \u0441\u0442\u043e\u0440\u0430, \u0441\u043e\u0437\u0434\u0430\u043d\u043d\u043e\u0433\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435. \u0422\u043e \u0435\u0441\u0442\u044c \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043a\u0430\u043a \u043f\u0440\u0438\u0432\u044b\u043a\u043b\u0438, \u0430 \u0432\u0441\u044f \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0441\u0442\u044c \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/query-client\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e Query Client<\/a>.<\/p>\n<h2>Error Class<\/h2>\n<p>\u041e\u0448\u0438\u0431\u043a\u0438 \u0432 Point0 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 <code>unknown<\/code>. \u0423 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043a\u043b\u0430\u0441\u0441 <code>ErrorPoint0<\/code>, \u0438 \u0432 \u043b\u044e\u0431\u043e\u043c <code>error<\/code> (\u0432 <code>.error()<\/code> \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435, \u0432 <code>result.error<\/code> \u0443 \u043a\u0432\u0435\u0440\u0438) \u0432\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0435 \u0438\u043c\u0435\u043d\u043d\u043e \u0435\u0433\u043e, \u0441 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u043c\u0438 \u043f\u043e\u043b\u044f\u043c\u0438.<\/p>\n<p>\u041f\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0443 \u0442\u0430\u043c \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u043f\u043e\u043b\u044f, \u0432\u0441\u0435 \u043e\u043f\u0438\u0446\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0435:<\/p>\n<pre><code>const error = new ErrorPoint0('message', {  code: 'ERROR_CODE', \/\/ \u043b\u044e\u0431\u0430\u044f \u0441\u0442\u0440\u043e\u043a\u0430 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0442\u0438\u043f\u0443, \u0447\u0442\u043e\u0431\u044b \u0432\u044b \u043c\u043e\u0433\u043b\u0438 \u0435\u0433\u043e \u0440\u0430\u0441\u0448\u0438\u0440\u0438\u0442\u044c, \u043d\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043e\u043d\u0438 \u0432\u0441\u0435 \u0444\u0438\u043a\u0441\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435  status: 500, \/\/ \u043b\u044e\u0431\u043e\u0435 \u0447\u0438\u0441\u043b\u043e  meta: {}, \/\/ \u043b\u044e\u0431\u043e\u0439 \u043e\u0431\u044a\u0435\u043a\u0442  redirect: new RedirectTask(), \/\/ \u0442\u0443\u0442 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 RedirectTask  response: new Response(), \/\/ \u0442\u0443\u0442 Response, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043e\u0442\u0432\u0435\u0442 \u0440\u0435\u0441\u043f\u043e\u043d\u0441, \u0438\u043d\u0430\u0447\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u0430\u044f \u043e\u0448\u0438\u0431\u043a\u0430 \u043f\u043e\u043b\u0435\u0442\u0438\u0442 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442  headers: new Headers(), \/\/ \u0442\u0443\u0442 Headers, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u0435\u0442 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438 \u043e\u0442\u0432\u0435\u0442\u0430})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410 \u0442\u0430\u043a\u0436\u0435 \u0438\u043c\u0435\u044e\u0442\u0441\u044f \u043c\u0435\u0442\u043e\u0434\u044b:<\/p>\n<pre><code>ErrorPoint0.from(unknown) \/\/ \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 ErrorPoint0 \u0438\u043d\u0441\u0442\u0430\u043d\u0441 \u0438\u0437 \u0447\u0435\u0433\u043e \u0443\u0433\u043e\u0434\u043d\u043eErrorPoint0.serializePublic(error) \/\/ \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443 \u0432 public \u0444\u043e\u0440\u043c\u0430\u0442, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442ErrorPoint0.serializePrivate(error) \/\/ \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0443\u0435\u0442 \u043e\u0448\u0438\u0431\u043a\u0443 \u0432 private \u0444\u043e\u0440\u043c\u0430\u0442, \u0447\u0442\u043e\u0431\u044b \u043e\u0442\u043f\u0440\u0430\u0432\u0438\u0442\u044c \u0432 \u043b\u043e\u0433\u0438<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u0434\u043c\u0435\u043d\u0438\u0442\u044c \u043a\u043b\u0430\u0441\u0441 \u043e\u0448\u0438\u0431\u043a\u0438 \u043d\u0430 \u0441\u0432\u043e\u0439 \u0447\u0435\u0440\u0435\u0437 <code>.errorClass()<\/code> \u043d\u0430 \u0440\u0443\u0442\u0435. \u0422\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u0435 \u043e\u0434\u043d\u043e: \u0432\u0430\u0448 \u043a\u043b\u0430\u0441\u0441 \u0434\u043e\u043b\u0436\u0435\u043d \u0438\u043c\u0435\u0442\u044c \u0442\u0443 \u0436\u0435 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0438\u043b\u0438 \u0448\u0438\u0440\u0435, \u0447\u0442\u043e \u0438 <code>ErrorPoint0<\/code> \u0438 \u0431\u044b\u0442\u044c <code>instanceof Error<\/code>. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0438\u0441\u0445\u043e\u0434\u043d\u0438\u043a \u043e\u0448\u0438\u0431\u043a\u0438 \u0432 Point0, \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u0434\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u043d\u0443\u0436\u043d\u044b\u0435 \u0432\u0430\u043c \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438.<\/p>\n<p>\u041d\u043e \u0443 \u043c\u0435\u043d\u044f \u0435\u0441\u0442\u044c \u0435\u0449\u0451 \u043e\u0434\u043d\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <a href=\"https:\/\/1gr14.dev\/error0\" rel=\"noopener noreferrer nofollow\"><code>@1gr14\/error0<\/code><\/a> \u0434\u043b\u044f \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445, \u0440\u0430\u0441\u0448\u0438\u0440\u044f\u0435\u043c\u044b\u0445 \u043f\u043b\u0430\u0433\u0438\u043d\u0430\u043c\u0438 \u043e\u0448\u0438\u0431\u043e\u043a. \u041c\u043e\u0436\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0451:<\/p>\n<pre><code>import { Error0 } from '@1gr14\/error0'import { causePlugin } from '@1gr14\/error0\/plugins\/cause'import { codeStatusPlugin } from '@1gr14\/error0\/plugins\/code-status'import { flatOriginalPlugin } from '@1gr14\/error0\/plugins\/flat-original'import { metaPlugin } from '@1gr14\/error0\/plugins\/meta'import { redirectPlugin } from '@1gr14\/error0\/plugins\/point0-redirect'import { expectedPlugin } from '@1gr14\/error0\/plugins\/expected'import { responsePlugin } from '@1gr14\/error0\/plugins\/response'import { stackPlugin } from '@1gr14\/error0\/plugins\/stack'export const AppError = Error0.mark('AppError')  .use(    codeStatusPlugin({      codes: {        UNAUTHORIZED: 401,        FORBIDDEN: 403,        UNSUBSCRIBED: 403,      },      transport: 'public',    }),  )  .use(metaPlugin())  .use(causePlugin())  .use(responsePlugin())  .use(redirectPlugin())  .use(flatOriginalPlugin())  .use(expectedPlugin({ transport: 'public' }))  .use(stackPlugin())export type AppError = InstanceType&lt;typeof AppError&gt;export const root = Point0.lets.root().errorClass(AppError).root()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041e\u0448\u0438\u0431\u043a\u0430 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0435\u0434\u0435\u0442 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442, \u0438 \u043c\u044b \u043d\u0435 \u0445\u043e\u0442\u0438\u043c \u0441\u043b\u0438\u0442\u044c \u043d\u0430\u0440\u0443\u0436\u0443 \u0441\u0442\u0435\u043a \u0438 \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u0438. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0447\u0435 \u043e\u0448\u0438\u0431\u043a\u0430 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f \u0434\u0432\u0443\u043c\u044f \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0441\u043f\u043e\u0441\u043e\u0431\u0430\u043c\u0438: <code>serializePublic<\/code> \u0432 \u043f\u0440\u043e\u0434\u0435 (\u043a\u043b\u0438\u0435\u043d\u0442 \u0432\u0438\u0434\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e\u0435 \u2014 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u043a\u043e\u0434, \u0440\u0435\u0434\u0438\u0440\u0435\u043a\u0442) \u0438 <code>serializePrivate<\/code> \u0432 \u0434\u0435\u0432-\u0440\u0435\u0436\u0438\u043c\u0435 (\u0432\u0438\u0434\u043d\u043e \u0432\u0441\u0451 \u2014 \u0441\u0442\u0435\u043a, \u043c\u0435\u0442\u0443, \u0441\u0442\u0430\u0442\u0443\u0441). \u0412 \u043b\u043e\u0433\u0438 \u0432\u0441\u0435\u0433\u0434\u0430 \u0443\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u043b\u043d\u0430\u044f, \u043f\u0440\u0438\u0432\u0430\u0442\u043d\u0430\u044f \u0432\u0435\u0440\u0441\u0438\u044f. \u0422\u0430\u043a \u0447\u0442\u043e \u0432 \u043f\u0440\u043e\u0434\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0435 \u0443\u0432\u0438\u0434\u0438\u0442 \u043b\u0438\u0448\u043d\u0435\u0433\u043e, \u0430 \u0432\u044b \u0432 \u043b\u043e\u0433\u0430\u0445 \u0443\u0432\u0438\u0434\u0438\u0442\u0435 \u0432\u0441\u0451.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/error-handling\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u043e\u0448\u0438\u0431\u043e\u043a<\/a>.<\/p>\n<h2>Eventer<\/h2>\n<p>\u0414\u043b\u044f \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u0433\u043e \u0432 \u043f\u043e\u0438\u043d\u0442\u0430\u0445 \u0435\u0441\u0442\u044c \u044d\u0432\u0435\u043d\u0442\u0435\u0440. \u0415\u0434\u0438\u043d\u0430\u044f \u0448\u0438\u043d\u0430 \u0441\u043e\u0431\u044b\u0442\u0438\u0439, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u0443\u0434\u043e\u0431\u043d\u043e \u0432\u0435\u0448\u0430\u0442\u044c \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438 \u043d\u0430\u0431\u043b\u044e\u0434\u0430\u0435\u043c\u043e\u0441\u0442\u044c. \u041f\u043e\u0434\u043f\u0438\u0441\u0430\u0442\u044c\u0441\u044f \u043c\u043e\u0436\u043d\u043e \u043d\u0430 \u043e\u0431\u0435 \u0441\u0442\u043e\u0440\u043e\u043d\u044b (<code>.on<\/code>), \u0438\u043b\u0438 \u0440\u0430\u0437\u0434\u0435\u043b\u044c\u043d\u043e (<code>.serverOn<\/code> \/ <code>.clientOn<\/code>):<\/p>\n<pre><code>export const root = Point0.lets  .root()  .on('error', ({ side, name, error, meta }) =&gt; {    console.error({ ...meta, side, name, error })  })  .root()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u043e\u0431\u044b\u0442\u0438\u0439 \u043c\u043d\u043e\u0433\u043e \u2014 \u0441\u0442\u0430\u0440\u0442\/\u0443\u0441\u043f\u0435\u0445\/\u043e\u0448\u0438\u0431\u043a\u0430 \u0434\u043b\u044f \u043a\u0432\u0435\u0440\u0438, \u0438\u043d\u0444\u0438\u043d\u0438\u0442-\u043a\u0432\u0435\u0440\u0438, \u043c\u0443\u0442\u0430\u0446\u0438\u0439, \u043f\u0440\u0435\u0444\u0435\u0442\u0447\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446, \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0445 \u0444\u0435\u0442\u0447\u0435\u0439. \u0412 \u043a\u043e\u043b\u0431\u044d\u043a \u043f\u0440\u0438\u0445\u043e\u0434\u0438\u0442: <code>side<\/code> (\u043a\u043b\u0438\u0435\u043d\u0442\/\u0441\u0435\u0440\u0432\u0435\u0440), <code>name<\/code> (\u0438\u043c\u044f \u0441\u043e\u0431\u044b\u0442\u0438\u044f), <code>error<\/code> (\u0435\u0441\u043b\u0438 \u0435\u0441\u0442\u044c), <code>meta<\/code> (\u0442\u043e, \u0447\u0442\u043e \u0431\u0435\u0437\u043e\u043f\u0430\u0441\u043d\u043e \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c) \u0438 <code>data<\/code> (\u0441\u044b\u0440\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435, \u0432\u043a\u043b\u044e\u0447\u0430\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u0441\u0430\u043c response \u2014 \u0438\u0445 \u043b\u043e\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0435 \u0441\u0442\u043e\u0438\u0442, \u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u0438\u0437 \u043d\u0438\u0445 \u0447\u0442\u043e-\u0442\u043e \u043c\u043e\u0436\u043d\u043e).<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/events\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u0441\u043e\u0431\u044b\u0442\u0438\u044f<\/a>.<\/p>\n<h2>Engine<\/h2>\n<p>Engine \u2014 \u044d\u0442\u043e \u0438 \u043a\u043e\u043d\u0444\u0438\u0433, \u0438 \u0440\u0430\u043d\u0442\u0430\u0439\u043c. \u041e\u0434\u0438\u043d \u0444\u0430\u0439\u043b <code>src\/engine.ts<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u0432\u0441\u0451: \u0433\u0434\u0435 \u0441\u0435\u0440\u0432\u0435\u0440, \u0433\u0434\u0435 \u043a\u043b\u0438\u0435\u043d\u0442(\u044b), \u043a\u0430\u043a\u043e\u0439 \u0443 \u043d\u0438\u0445 \u043f\u043e\u0440\u0442, \u0433\u0434\u0435 \u0438\u0441\u043a\u0430\u0442\u044c \u043f\u043e\u0438\u043d\u0442\u044b, \u043a\u0443\u0434\u0430 \u0433\u0435\u043d\u0435\u0440\u0438\u0442\u044c \u0444\u0430\u0439\u043b\u044b, \u0447\u0442\u043e \u043e\u0442\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u0430\u043a \u0441\u0442\u0430\u0442\u0438\u043a\u0443. CLI \u0431\u0435\u0440\u0451\u0442 \u044d\u0442\u0443 \u0436\u0435 <code>engine<\/code>, \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u043f\u043e \u0442\u0438\u043f\u0443 <code>engine.dev(...)<\/code>, <code>engine.build(...)<\/code>. \u0414\u0430\u0436\u0435 \u0432\u0441\u0435 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0445\u043e\u0434\u044f\u0442 \u0447\u0435\u0440\u0435\u0437 <code>engine.fetch(request)<\/code><\/p>\n<pre><code>import { Engine } from '@point0\/engine'export const engine = Engine.create({  file: import.meta.url, \/\/ \u0434\u0432\u0438\u0436\u043e\u043a \u0434\u043e\u043b\u0436\u0435\u043d \u0437\u043d\u0430\u0442\u044c, \u0433\u0434\u0435 \u043e\u043d \u0441\u0430\u043c \u043b\u0435\u0436\u0438\u0442  ssr: true, \/\/ \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043d\u0433  pointsGlob: '**\/*.{ts,tsx,mdx}', \/\/ \u0433\u0434\u0435 \u0438\u0441\u043a\u0430\u0442\u044c \u043f\u043e\u0438\u043d\u0442\u044b  server: {    scope: 'root',    port: process.env.SERVER_PORT || process.env.PORT,    entry: { main: '.\/index.server.ts' },    points: async () =&gt; await import('.\/generated\/point0\/points.server'),    generate: { points: '.\/generated\/point0\/points.server.ts' },    outdir: '..\/dist\/server',  },  \/\/ clients: [{}, {}] \u0435\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432  client: {    scope: 'root',    port: process.env.CLIENT_PORT,    indexHtml: '.\/index.html',    app: async () =&gt; await import('.\/app.client'),    points: async () =&gt; await import('.\/generated\/point0\/points.client'),    generate: {      points: '.\/generated\/point0\/points.client.ts',      routes: {        outfile: '.\/generated\/point0\/routes.ts',        origin: 'process.env.CLIENT_URL',      },    },    publicdir: { source: ['..\/public'], outdir: '..\/dist\/client' },    outdir: '..\/dist\/client',  },})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u0435\u0440\u0432\u0435\u0440 \u0432\u0441\u0435\u0433\u0434\u0430 \u043e\u0434\u0438\u043d. \u041a\u043b\u0438\u0435\u043d\u0442\u043e\u0432 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e, \u0442\u043e\u0433\u0434\u0430 \u0443 \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0431\u0443\u0434\u0435\u0442 \u0441\u0432\u043e\u0439 <code>scope<\/code>, \u0441\u0432\u043e\u0438 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u0438\u043d\u0442\u044b, \u0441\u0432\u043e\u0439 \u0431\u0430\u043d\u0434\u043b.<\/p>\n<p>\u0418 \u0441\u0440\u0430\u0437\u0443 \u043f\u043e\u043a\u0430\u0436\u0443 3 \u0444\u0430\u0439\u043b\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0443\u0436\u043d\u044b, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0434\u043d\u044f\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440.<\/p>\n<pre><code>\/\/ src\/preload.tsimport { engine } from '.\/engine'\/\/ \u044d\u0442\u043e \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u0431\u0430\u043d \u043f\u043b\u0430\u0433\u0438\u043d \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430\/\/ \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b\u0440\u0435\u0437\u0430\u0435\u0442 \u0438\u0437 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u043a\u043e\u0434, \u0430 \u0438\u0437 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0433\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439\/\/ \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043c\u043d\u043e\u0433\u043e \u0447\u0435\u0433\u043e \u0435\u0449\u0451 \u0434\u0435\u043b\u0430\u0435\u0442, \u043d\u043e \u043e\u0431 \u044d\u0442\u043e\u043c \u0432 \u0434\u0440\u0443\u0433\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435\/\/ \u0442\u0430\u043a\u0436\u0435 \u044d\u0442\u0430 \u0448\u0442\u0443\u043a\u0430 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442 \u043d\u0443\u0436\u043d\u044b\u0435 \u044d\u043d\u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043b\u0438 \u0432 engine.tsawait engine.preload()\/\/ \u043c\u044b \u0445\u0440\u0430\u043d\u0438\u043c \u044d\u0442\u043e \u043a\u0430\u043a \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0444\u0430\u0439\u043b, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u043d \u043d\u0430\u043c \u043c\u043e\u0436\u0435\u0442 \u043f\u0440\u0438\u0433\u043e\u0434\u0438\u0442\u044c\u0441\u044f \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430\/\/ \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0442\u0435\u0441\u0442\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u043f\u0440\u0435\u043b\u043e\u0430\u0434 \u043f\u043b\u0430\u0433\u0438\u043d\u0430 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>\/\/ src\/index.server.ts\/\/ \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0433\u0440\u0443\u0437\u0438\u043c \u043f\u0440\u0435\u043b\u043e\u0430\u0434await import('.\/preload.js')\/\/ \u0437\u0430\u0442\u0435\u043c \u0441\u0430\u043c \u043a\u043e\u0434 \u0441\u0435\u0440\u0432\u0435\u0440\u0430await import('.\/app.server.js')\/\/ \u0427\u0442\u043e\u0431\u044b \u0442\u0441 \u043d\u0435 \u0440\u0443\u0433\u0430\u043b\u0441\u044f, \u044d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043f\u0443\u0441\u0442\u043e\u0439 \u043c\u043e\u0434\u0443\u043b\u044cexport {}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>\/\/ src\/app.server.tsimport { engine } from '@\/engine.js'\/\/ \u0443 \u043d\u0430\u0441 \u0441\u0435\u0440\u0432\u0438\u0442\u0441\u044f \u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0435\u0440await engine.serve()\/\/ \u043d\u043e \u044d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u0444\u0430\u0439\u043b, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0434\u0435\u0441\u044c \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u044f\u043a\u0438\u0435 \u0432\u043e\u0440\u043a\u0435\u0440\u044b\/\/ \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u043a\u0440\u043e\u043d\u044b, \u0432\u0430\u043b\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u043d\u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/engine-config\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u043a\u043e\u043d\u0444\u0438\u0433 \u0434\u0432\u0438\u0436\u043a\u0430<\/a>, <a href=\"https:\/\/1gr14.dev\/point0\/latest\/engine-runtime\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u0440\u0430\u043d\u0442\u0430\u0439\u043c \u0434\u0432\u0438\u0436\u043a\u0430<\/a>.<\/p>\n<h2>CLI<\/h2>\n<p>\u0421\u0430\u043c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0431\u0438\u043d\u0430\u0440\u044c <code>point0<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438 \u0434\u0440\u0430\u0439\u0432\u0438\u0442 \u0432\u0441\u0451 \u043f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 <code>src\/engine.ts<\/code>:<\/p>\n<pre><code>point0 dev        # \u0434\u0435\u0432-\u0441\u0435\u0440\u0432\u0435\u0440 (\u0441\u0435\u0440\u0432\u0435\u0440 + \u043a\u043b\u0438\u0435\u043d\u0442\u044b), \u0432\u043e\u0442\u0447\u0438\u043d\u0433, \u043a\u043e\u0434\u043e\u0433\u0435\u043d \u043d\u0430 \u043b\u0435\u0442\u0443point0 dev --hot  # \u0442\u043e \u0436\u0435, \u043d\u043e \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u043c hot-reloadpoint0 generate   # \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c points\/routes\/meta (\u0441\u043c. \u0440\u0430\u0437\u0434\u0435\u043b \u043f\u0440\u043e \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440)point0 build      # \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d-\u0441\u0431\u043e\u0440\u043a\u0430 \u0432 dist\/point0 compile &lt;file&gt;  # \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c, \u0432\u043e \u0447\u0442\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u043f\u0440\u0435\u0432\u0440\u0430\u0442\u0438\u043b \u0444\u0430\u0439\u043b (\u0434\u043b\u044f \u043e\u0442\u043b\u0430\u0434\u043a\u0438)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c <code>package.json<\/code> \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u044d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e:<\/p>\n<pre><code class=\"json\">{  \"scripts\": {    \"dev\": \"point0 dev --hot\",    \"generate\": \"point0 generate\",    \"build\": \"point0 build\",    \"start\": \"NODE_ENV=production bun run .\/dist\/server\/index.server.js\"  }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0423 \u043a\u043e\u043c\u0430\u043d\u0434 \u0435\u0441\u0442\u044c \u0444\u043b\u0430\u0433\u0438 \u2014 <code>--side server|client<\/code> (\u043f\u043e\u0434\u043d\u044f\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u043d\u0443 \u0441\u0442\u043e\u0440\u043e\u043d\u0443), <code>--scope &lt;scope&gt;<\/code> (\u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u043a\u043b\u0438\u0435\u043d\u0442), <code>--mode<\/code>, <code>--env<\/code> \u0438 \u0434\u0440\u0443\u0433\u0438\u0435, \u043d\u043e \u044d\u0442\u043e \u0443\u0436\u0435 \u0434\u0435\u0442\u0430\u043b\u0438 \u0434\u043b\u044f \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/cli\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e CLI<\/a>.<\/p>\n<h2>MCP<\/h2>\n<p><code>point0-project-mcp<\/code> \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0430\u0433\u0435\u043d\u0442\u0443 \u043e\u0440\u0438\u0435\u043d\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0432\u0430\u0448\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435: \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c \u0441\u043f\u0438\u0441\u043e\u043a \u0432\u0441\u0435\u0445 \u043f\u043e\u0438\u043d\u0442\u043e\u0432, \u043d\u0430\u0439\u0442\u0438 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0439 \u043f\u043e \u0443\u0440\u043b\u0443, \u0441\u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0444\u0430\u0439\u043b (\u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u0447\u0442\u043e \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u043e\u0442 \u043f\u043e\u0438\u043d\u0442\u0430 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435, \u0430 \u0447\u0442\u043e \u2014 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435), \u043f\u0440\u043e\u0442\u0440\u0435\u0439\u0441\u0438\u0442\u044c \u0446\u0435\u043f\u043e\u0447\u043a\u0443 \u0438\u043c\u043f\u043e\u0440\u0442\u043e\u0432. \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u0442\u0430\u043a. \u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u0443 \u0432\u0430\u0441 cursor \u0438 claude code. \u0422\u043e\u0433\u0434\u0430 \u0432 <code>.cursor\/mcp.json<\/code> \u0438 <code>mcp.json<\/code> \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c:<\/p>\n<pre><code class=\"json\">{  \"mcpServers\": {    \"point0-project-mcp\": {      \"command\": \"bun\",      \"args\": [\"run\", \"mcp:point0:project\"]    }  }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0410 \u0432 package.json \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c:<\/p>\n<pre><code class=\"json\">{  \"scripts\": {    \"mcp:point0:project\": \"point0-mcp --meta .\/src\/generated\/point0\/meta.ts\"  }}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>meta.ts \u0434\u043b\u044f \u043d\u0430\u0441 \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440.<\/p>\n<p>\u0418 \u0435\u0449\u0451 \u0435\u0441\u0442\u044c <code>point0-docs-mcp<\/code> \u2014 \u044d\u0442\u043e \u043f\u043e\u0438\u0441\u043a \u043f\u043e \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0441\u0430\u043c\u043e\u0433\u043e Point0 (\u0433\u0438\u0431\u0440\u0438\u0434\u043d\u044b\u0439: \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0441\u043b\u043e\u0432\u0430 \u043f\u043b\u044e\u0441 \u0441\u0435\u043c\u0430\u043d\u0442\u0438\u043a\u0430). \u0427\u0442\u043e\u0431\u044b \u0430\u0433\u0435\u043d\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u043b \u043f\u0440\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u043f\u043e \u0430\u043a\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0439 \u0434\u043e\u043a\u0435, \u0430 \u043d\u0435 \u043f\u043e \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043e\u043d \u0442\u0430\u043c \u0441\u0435\u0431\u0435 \u043d\u0430\u043f\u0440\u0438\u0434\u0443\u043c\u044b\u0432\u0430\u043b.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/mcp-project\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e MCP \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/a>, <a href=\"https:\/\/1gr14.dev\/point0\/latest\/mcp-docs\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e MCP \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438<\/a>.<\/p>\n<h2>Publicdir<\/h2>\n<p>\u0421\u0442\u0430\u0442\u0438\u043a\u0443 (favicon, \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438, \u0448\u0440\u0438\u0444\u0442\u044b, <code>robots.txt<\/code>, <code>.well-known\/...<\/code>) \u043e\u0442\u0434\u0430\u0451\u0442 publicdir. \u0423\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u0442\u0435 \u0434\u0438\u0440\u0435\u043a\u0442\u043e\u0440\u0438\u044e-\u0438\u0441\u0442\u043e\u0447\u043d\u0438\u043a, \u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u044f\u043c\u043e \u0442\u0443\u0442 \u0436\u0435 \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0438 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0444\u0430\u0439\u043b\u044b \u0444\u0443\u043d\u043a\u0446\u0438\u0435\u0439, \u0438\u043b\u0438 \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043f\u043e\u0434\u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0438:<\/p>\n<pre><code>export const engine = Engine.create({  \/\/ ...  client: {    \/\/ ...    publicdir: {      source: [        '..\/public', \/\/ \u0432\u0441\u0451 \u0438\u0437 \u044d\u0442\u043e\u0439 \u043f\u0430\u043f\u043a\u0438 \u043e\u0442\u0434\u0430\u0451\u0442\u0441\u044f \u0441 \u043a\u043e\u0440\u043d\u044f        {          \/\/ \u043a\u043b\u044e\u0447 \u043f\u0443\u0442\u044c \u043a \u0444\u0430\u0439\u043b\u0443, \u043e\u0442\u0432\u0435\u0442 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0435\u0451 \u043a\u043e\u043d\u0442\u0435\u043d\u0442          'robots.txt': () =&gt; 'User-agent: *\\nDisallow: \/',          '.well-known\/appspecific\/com.chrome.devtools.json': () =&gt; '{}',        },        \/\/ \u0438\u043b\u0438 \u043f\u043e\u0434\u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0438, \u0442\u043e\u0433\u0434\u0430 \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u043f\u043e:        \/\/ \/a\/one.txt        \/\/ \/b\/two.json        { '\/a': '..\/public-a' },        { '\/b': '..\/public-b' },      ],      outdir: '..\/dist\/client', \/\/ \u043a\u0443\u0434\u0430 \u0441\u043a\u043e\u043f\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438 \u0441\u0431\u043e\u0440\u043a\u0435    },  },})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412 \u0434\u0435\u0432\u0435 \u0444\u0430\u0439\u043b\u044b \u043e\u0442\u0434\u0430\u044e\u0442\u0441\u044f \u043d\u0430 \u043b\u0435\u0442\u0443, \u043f\u0440\u0438 \u0441\u0431\u043e\u0440\u043a\u0435 \u2014 \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u043e\u043f\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0432 <code>outdir<\/code>. \u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0440\u0430\u0437\u0434\u0430\u0447\u0438 \u0432 \u043f\u0440\u043e\u0434\u0435 \u0441\u0442\u0430\u0442\u0438\u043a\u0430 \u043a\u0435\u0448\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0432 \u043f\u0430\u043c\u044f\u0442\u0438 \u0432 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u0433\u043e \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u043e\u0433\u043e \u043e\u0431\u044a\u0451\u043c\u0430 \u043f\u0430\u043c\u044f\u0442\u0438.<\/p>\n<p>\u041d\u043e \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u044d\u0442\u043e \u0432\u0441\u0451 \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 \u0438\u0437\u0432\u0440\u0430\u0449\u0435\u043d\u0438\u0435, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0441\u043a\u043e\u0440\u0435\u0435 \u0432\u0441\u0435\u0433\u043e \u0432\u044b \u0431\u0443\u0434\u0435\u0442\u0435 \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code>export const engine = Engine.create({  \/\/ ...  client: {    \/\/ ...    publicdir: {      source: '..\/public',      outdir: '..\/dist\/client',    },  },})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/publicdir\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e publicdir<\/a>.<\/p>\n<h2>Generator<\/h2>\n<p>\u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u043d\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u0442\u0438\u043f\u044b, \u043e\u043d \u043f\u043e \u0441\u0443\u0442\u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u043d\u0434\u0435\u043a\u0441 \u0444\u0430\u0439\u043b\u044b. \u0412 trpc \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u044b \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e, \u0432 point0 \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438. \u0422\u0430\u043a\u0436\u0435 \u043c\u0435\u0441\u0442\u043e, \u043a\u0443\u0434\u0430 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0444\u0430\u0439\u043b\u044b, \u0432\u044b \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u0442\u0435 \u0441\u0430\u043c\u0438 \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 <code>engine<\/code>.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043e\u0442\u043c\u0435\u0447\u0443, \u0447\u0442\u043e \u0434\u043b\u044f \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438 \u043d\u0430\u043c \u0434\u0430\u0436\u0435 \u043d\u0435 \u043d\u0443\u0436\u043d\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0448 \u043a\u043e\u0434 \u0431\u044b\u043b \u0432\u0430\u043b\u0438\u0434\u043d\u044b\u043c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432\u0441\u0451 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043f\u043e\u0441\u0440\u0435\u0434\u0441\u0442\u0432\u043e\u043c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0430\u043d\u0430\u043b\u0438\u0437\u0430 \u043a\u043e\u0434\u0430, \u0438 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u043c\u0443 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u043e \u0438 \u043f\u043e\u0447\u0442\u0438 \u043d\u0435\u0443\u0431\u0438\u0432\u0430\u0435\u043c\u043e.<\/p>\n<p>\u0412\u0441\u0451 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u0441\u043c\u0435\u043b\u043e \u043a\u043b\u0430\u0441\u0442\u044c \u0432 <code>.gitignore<\/code>, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u0440\u0438 \u0431\u0438\u043b\u0434\u0435, \u043c\u044b \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u0432\u0441\u0451 \u0431\u0443\u0434\u0435\u043c \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0437\u0430\u043d\u043e\u0432\u043e \u0434\u043b\u044f \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u0438. \u0410 \u0432\u043e \u0432\u0440\u0435\u043c\u044f dev \u0440\u0435\u0436\u0438\u043c\u0430, \u0432\u0441\u0451 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043d\u0430 \u043b\u0435\u0442\u0443.<\/p>\n<h3>points.server.ts<\/h3>\n<p>\u041f\u0440\u043e\u0441\u0442\u043e \u043c\u0430\u0441\u0441\u0438\u0432 \u0438\u0437 \u043f\u043e\u0438\u043d\u0442\u043e\u0432, \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0445 \u0432 \u0432\u0430\u0448\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435. \u041e\u043d \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u0442\u043e\u043c \u043f\u0440\u043e\u043a\u0438\u043d\u0443\u0442\u044c \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 \u0441\u0430\u043c\u0443 <code>engine<\/code>, \u0438 \u043f\u0440\u0438 \u0440\u0430\u0437\u0434\u0430\u0447\u0435 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0447\u0435\u0440\u0435\u0437 <code>engine.serve()<\/code> \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u043f\u0440\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043d\u0430\u0439\u0442\u0438 \u043d\u0443\u0436\u043d\u044b\u0439 \u043f\u043e\u0438\u043d\u0442. \u0412\u043e\u0442 \u043f\u0440\u0438\u043c\u0435\u0440 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0438:<\/p>\n<pre><code>import type { PointsDefinition } from '@point0\/core'import { root as root_0 } from '..\/..\/lib\/root.js'import {  default as unnamed_1,  ideaBestComponent as ideaBestComponent_8,} from '..\/..\/pages\/home.js'import { page as page_2 } from '..\/..\/pages\/about.mdx'import { ideaListPage as ideaListPage_3 } from '..\/..\/pages\/idea-list.js'import {  ideaCreatePage as ideaCreatePage_4,  ideaUpdatePage as ideaUpdatePage_6,  ideaCreateMutation as ideaCreateMutation_9,  ideaUpdateMutation as ideaUpdateMutation_11,} from '..\/..\/pages\/idea-create-update.js'import { ideaViewPage as ideaViewPage_5 } from '..\/..\/pages\/idea-view.js'import {  ideaNewsPage as ideaNewsPage_7,  ideaNewsPostCreateMutation as ideaNewsPostCreateMutation_10,} from '..\/..\/pages\/idea-news.js'import { ideaViewQuery as ideaViewQuery_12 } from '..\/..\/lib\/idea.js'export default [  root_0,  unnamed_1,  page_2,  ideaListPage_3,  ideaCreatePage_4,  ideaViewPage_5,  ideaUpdatePage_6,  ideaNewsPage_7,  ideaBestComponent_8,  ideaCreateMutation_9,  ideaNewsPostCreateMutation_10,  ideaUpdateMutation_11,  ideaViewQuery_12,] as PointsDefinition&lt;  (typeof root_0)['Infer']['RequiredCtx'],  (typeof root_0)['Infer']['Error']&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>points.client.ts<\/h3>\n<p>\u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0432 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u0445 \u0443\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b \u0442\u043e\u0447\u043d\u043e \u0442\u0430\u043a\u043e\u0439 \u0436\u0435 \u0444\u0430\u0439\u043b \u043a\u0430\u043a \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0445 \u043f\u043e\u0438\u043d\u0442\u043e\u0432, \u0442\u043e \u0435\u0441\u0442\u044c \u0441\u043e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u043e\u043c, \u0442\u043e\u0433\u0434\u0430 \u043f\u043e \u0441\u0443\u0442\u0438 \u0432\u0441\u0435 \u0444\u0430\u0439\u043b\u044b \u043f\u043e\u043f\u0430\u0434\u0443\u0442 \u0432 \u043e\u0434\u0438\u043d \u0431\u0430\u043d\u0434\u043b. \u041d\u043e \u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043b\u0435\u043d\u0438\u0432\u0443\u044e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0443, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u043c\u0430\u0441\u0441\u0438\u0432 \u0441 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u043e\u043c. \u041f\u043e\u0442\u043e\u043c \u044d\u0442\u0438 \u043f\u043e\u0438\u043d\u0442\u044b \u043c\u044b \u043f\u0440\u043e\u043a\u0438\u0434\u044b\u0432\u0430\u0435\u043c \u0432 \u043d\u0430\u0448\u0435\u043c <code>index.client.ts<\/code>, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u0438 \u0431\u0438\u043b\u0434\u0435 \u043f\u043e\u0438\u043d\u0442\u044b \u043f\u043e\u043f\u0430\u043b\u0438 \u0432 \u0431\u0430\u043d\u0434\u043b \u0440\u0430\u0437\u043d\u044b\u043c\u0438 \u0447\u0430\u043d\u043a\u0430\u043c\u0438.<\/p>\n<pre><code>import type { PointsDefinition } from '@point0\/core'import { root as root_0 } from '..\/..\/lib\/root.js'export default [  root_0,  {    type: 'page',    name: 'home',    route: '\/',    polh: true,    layouts: ['generalLayout'],    point: async () =&gt; (await import('..\/..\/pages\/home.js')).default,  },  {    type: 'page',    name: 'about',    route: '\/about',    polh: true,    layouts: ['generalLayout'],    point: async () =&gt; (await import('..\/..\/pages\/about.mdx')).page,  },  {    type: 'page',    name: 'ideaList',    route: '\/ideas',    polh: true,    layouts: ['generalLayout'],    point: async () =&gt; (await import('..\/..\/pages\/idea-list.js')).ideaListPage,  },  {    type: 'page',    name: 'ideaCreate',    route: '\/ideas\/new',    polh: true,    layouts: ['generalLayout'],    point: async () =&gt;      (await import('..\/..\/pages\/idea-create-update.js')).ideaCreatePage,  },  {    type: 'page',    name: 'ideaView',    route: '\/ideas\/:id',    polh: true,    layouts: ['generalLayout', 'idea'],    point: async () =&gt; (await import('..\/..\/pages\/idea-view.js')).ideaViewPage,  },  {    type: 'page',    name: 'ideaUpdate',    route: '\/ideas\/:id\/edit',    polh: true,    layouts: ['generalLayout'],    point: async () =&gt;      (await import('..\/..\/pages\/idea-create-update.js')).ideaUpdatePage,  },  {    type: 'page',    name: 'ideaNews',    route: '\/ideas\/:id\/news',    polh: true,    layouts: ['generalLayout', 'idea'],    point: async () =&gt; (await import('..\/..\/pages\/idea-news.js')).ideaNewsPage,  },  {    type: 'layout',    name: 'generalLayout',    route: '\/',    point: async () =&gt; (await import('..\/..\/layouts\/general.js')).generalLayout,  },  {    type: 'layout',    name: 'idea',    route: '\/ideas\/:id',    point: async () =&gt; (await import('..\/..\/layouts\/idea.js')).ideaLayout,  },] as PointsDefinition&lt;  (typeof root_0)['Infer']['RequiredCtx'],  (typeof root_0)['Infer']['Error']&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>routes.ts<\/h3>\n<p>\u041f\u0440\u043e \u0440\u043e\u0443\u0442\u044b \u0443\u0436\u0435 \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438. \u041c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u043c \u0441\u043e \u0432\u0441\u0435\u0445 \u043f\u043e\u0438\u043d\u0442\u043e\u0432 \u0440\u043e\u0443\u0442\u044b:<\/p>\n<pre><code>import { Routes } from '@1gr14\/route0'export const routes = Routes.create(  {    home: '\/',    about: '\/about',    ideaList: '\/ideas',    ideaCreate: '\/ideas\/new',    ideaView: '\/ideas\/:id',    ideaUpdate: '\/ideas\/:id\/edit',    ideaNews: '\/ideas\/:id\/news',  },  { origin: process.env.CLIENT_URL },)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>meta.ts<\/h3>\n<p>\u041f\u043e\u043b\u043d\u0430\u044f \u043c\u0435\u0442\u0430 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u043f\u043e\u0438\u043d\u0442\u0430\u0445, \u043e\u043d\u0430 \u0442\u0430\u043a\u0436\u0435 \u043d\u0443\u0436\u043d\u0430 \u0434\u043b\u044f MCP \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0430\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442 \u0432\u0430\u0448 \u043f\u0440\u043e\u0435\u043a\u0442. \u0422\u0430\u043c \u043a\u043e\u043d\u0442\u0435\u043d\u0442 \u043f\u0440\u0438\u043c\u0435\u0440\u043d\u043e \u0442\u0430\u043a\u043e\u0439:<\/p>\n<pre><code>import { Route0 } from '@1gr14\/route0'import { Engine } from '@point0\/engine'export default {  engine: {    file: '\/Users\/iserdmi\/cc\/opensource\/1gr14\/point0\/examples\/basic\/src\/engine.ts',    import: async () =&gt;      (        await Engine.findAndImportSelf({          engineFile:            '\/Users\/iserdmi\/cc\/opensource\/1gr14\/point0\/examples\/basic\/src\/engine.ts',        })      ).engine,    server: {      scope: 'root',    },    clients: [      {        scope: 'root',      },    ],  },  points: [    {      scope: 'root',      type: 'root',      name: 'root',      id: 'root:root:root',      tags: [],      description: undefined,      route: undefined,      endpoint: undefined,      pos: {        file: '\/Users\/iserdmi\/cc\/opensource\/1gr14\/point0\/examples\/basic\/src\/lib\/root.tsx',        line: 9,        column: 20,      },      import: async () =&gt; (await import('..\/..\/lib\/root.js')).root,      valid: true,      errors: [],      ssr: true,      parents: [],      layouts: [],    },    {      scope: 'root',      type: 'page',      name: 'home',      id: 'root:page:home',      tags: [],      description: undefined,      route: Route0.create('\/'),      endpoint: {        method: 'GET',        route: Route0.create('\/_point0\/root\/page\/home'),      },      pos: {        file: '\/Users\/iserdmi\/cc\/opensource\/1gr14\/point0\/examples\/basic\/src\/pages\/home.tsx',        line: 37,        column: 15,      },      import: async () =&gt; (await import('..\/..\/pages\/home.js')).default,      valid: true,      errors: [],      ssr: true,      parents: [        {          scope: 'root',          type: 'layout',          name: 'generalLayout',          id: 'root:layout:generalLayout',          pos: {            file: '\/Users\/iserdmi\/cc\/opensource\/1gr14\/point0\/examples\/basic\/src\/layouts\/general.tsx',            line: 5,            column: 29,          },        },        {          scope: 'root',          type: 'root',          name: 'root',          id: 'root:root:root',          pos: {            file: '\/Users\/iserdmi\/cc\/opensource\/1gr14\/point0\/examples\/basic\/src\/lib\/root.tsx',            line: 9,            column: 20,          },        },      ],      layouts: [        {          scope: 'root',          type: 'layout',          name: 'generalLayout',          id: 'root:layout:generalLayout',          pos: {            file: '\/Users\/iserdmi\/cc\/opensource\/1gr14\/point0\/examples\/basic\/src\/layouts\/general.tsx',            line: 5,            column: 29,          },        },      ],    },    \/\/ ...  ],}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h3>assets.d.ts<\/h3>\n<p>\u0423 \u043d\u0430\u0441 \u0438\u043c\u043f\u043e\u0440\u0442 \u0430\u0441\u0441\u0435\u0442\u043e\u0432 \u0442\u043e\u0436\u0435 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0441\u0430\u043c\u0438\u043c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u043c \u0441\u043e \u0432\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u043c svgr, \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0432\u044b\u0431\u043e\u0440\u0430 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u0439 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0444\u0430\u0439\u043b\u043e\u0432, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u044b, \u0430 \u043f\u0440\u0438 \u0431\u0438\u043b\u0434\u0435 \u043f\u043e\u043f\u0430\u0441\u0442\u044c \u0432 dist \u043f\u0430\u043f\u043a\u0443. \u0421\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043d\u0430\u0434\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0442\u0438\u043f\u044b \u0434\u043b\u044f \u0438\u043c\u043f\u043e\u0440\u0442\u043e\u0432 \u0430\u0441\u0441\u0435\u0442\u043e\u0432. \u0413\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440 \u0441\u0430\u043c \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442 \u043d\u0443\u0436\u043d\u044b\u0439 \u0444\u0430\u0439\u043b:<\/p>\n<pre><code>declare module '*.svg?react' {  import type { FC, SVGProps } from 'react'  const ReactComponent: FC&lt;SVGProps&lt;SVGSVGElement&gt;&gt;  export default ReactComponent}declare module '*.png' {  const src: string  export default src}declare module '*.png?url' {  const src: string  export default src}declare module '*.png?file' {  const src: string  export default src}declare module '*.png?text' {  const src: string  export default src}declare module '*.png?raw' {  const src: string  export default src}declare module '*.jpg' {  const src: string  export default src}declare module '*.jpg?url' {  const src: string  export default src}declare module '*.jpg?file' {  const src: string  export default src}declare module '*.jpg?text' {  const src: string  export default src}declare module '*.jpg?raw' {  const src: string  export default src}\/\/ \u043f\u0440\u043e\u0447\u0438\u0435 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/generator\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u0433\u0435\u043d\u0435\u0440\u0430\u0442\u043e\u0440<\/a>.<\/p>\n<h2>Compiler<\/h2>\n<p>\u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043f\u043b\u0430\u043d\u0438\u0440\u043e\u0432\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u0435\u0440 \u0431\u0443\u0434\u0435\u0442 \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0437\u0430 \u0442\u043e, \u0447\u0442\u043e\u0431\u044b \u0432\u044b\u0440\u0435\u0437\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u0434 \u0438\u0437 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0433\u043e, \u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u0438\u0437 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0433\u043e. \u041f\u043e\u0442\u043e\u043c \u043e\u043d \u0442\u0430\u043a\u0436\u0435 \u0441\u0442\u0430\u043b \u043e\u0442\u0432\u0435\u0447\u0430\u0442\u044c \u0438 \u0437\u0430 \u0438\u043d\u044a\u0435\u043a\u0446\u0438\u044e \u043b\u044e\u0431\u044b\u0445 \u0431\u0430\u0431\u0435\u043b \u043f\u043b\u0430\u0433\u0438\u043d\u043e\u0432, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 \u0430\u0441\u0441\u0435\u0442\u043e\u0432, \u043f\u0440\u0435\u043f\u044f\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435 \u043d\u0435\u0436\u0435\u043b\u0430\u0442\u0435\u043b\u044c\u043d\u044b\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u0430\u043c, \u043f\u043e\u0438\u0441\u043a \u043f\u043e\u0438\u043d\u0442\u043e\u0432 \u043a\u0430\u043a \u0442\u0430\u043a\u043e\u0432\u044b\u0445, \u043f\u0430\u0440\u0441\u0438\u043d\u0433 mdx \u0444\u0430\u0439\u043b\u043e\u0432, \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u043d\u044b\u0445 env \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0443 env \u0445\u0435\u043b\u043f\u0435\u0440\u043e\u0432.<\/p>\n<p>\u0421\u0430\u043c \u043a\u043e\u043c\u043f\u0438\u043b\u0435\u0440 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \u043d\u0430 \u0432\u044b\u0431\u043e\u0440: bun \u043f\u043b\u0430\u0433\u0438\u043d, vite \u043f\u043b\u0430\u0433\u0438\u043d, babel \u043f\u043b\u0430\u0433\u0438\u043d. \u041f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u043e\u043d\u0438 \u0432\u0441\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442 \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u043a\u043e\u0434, \u0442\u0430\u043a \u0447\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0435 bun, \u0442\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u0435\u0440 \u043a\u0430\u043a \u043f\u043b\u0430\u0433\u0438\u043d \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u0432\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0435 <code>engine.preload()<\/code>, \u0438\u043c\u0435\u043d\u043d\u043e \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432 \u043d\u0430\u0448\u0435\u0439 \u043e\u0431\u0432\u044f\u0437\u043a\u0435 \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u044d\u0442\u043e \u0434\u043e \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u043f\u0440\u043e\u0447\u0438\u0439 \u043a\u043e\u043d\u0442\u0435\u043a\u0441\u0442, \u0447\u0442\u043e\u0431\u044b \u043f\u043b\u0430\u0433\u0438\u043d \u0431\u044b\u043b \u043f\u0440\u0438\u043c\u0435\u043d\u0451\u043d \u0434\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u0430, \u0438 \u043d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u0438\u043c\u043f\u043e\u0440\u0442\u0430 \u0432\u0435\u0441\u044c \u043a\u043e\u0434 \u0443\u0436\u0435 \u0431\u044b\u043b \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u043e \u043f\u043e\u0434\u0440\u0435\u0437\u0430\u043d \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430. \u0414\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u044d\u0442\u043e\u0442 \u0436\u0435 \u043f\u043b\u0430\u0433\u0438\u043d \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 bun static plugin.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043a\u0430\u043a \u0432\u0430\u0448 \u043a\u043e\u0434 \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u0430\u043d\u0434\u0443:<\/p>\n<pre><code class=\"bash\">point0 compile &lt;file&gt; --side &lt;server|client&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0412\u043e\u0442 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u0430\u043a\u043e\u0439 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0444\u0430\u0439\u043b:<\/p>\n<pre><code>\/\/ src\/pages\/idea.tsximport { root } from '@\/lib\/root'import { prisma } from '@\/lib\/prisma'import { SomethingForClient } from '@\/components\/something-for-client'export const ideaPage = root  .lets('page', 'idea', '\/ideas\/:id')  .loader(({ params }) =&gt; {    const idea = await prisma.idea.findUniqueOrThrow({      where: { id: params.id },    })    return { idea }  })  .page(({ data: { idea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{idea.title}&lt;\/h1&gt;      &lt;div&gt;{idea.content}&lt;\/div&gt;      &lt;SomethingForClient \/&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c, \u0447\u0442\u043e \u0443 \u0432\u0430\u0441 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d ssr, \u0442\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0432\u043e\u0442 \u0442\u0430\u043a:<\/p>\n<pre><code>\/\/ point0 compile src\/pages\/idea.tsx --side serverimport { root } from '@\/lib\/root'import { prisma } from '@\/lib\/prisma'\/\/ \u043d\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u044b \u0441\u0430\u043c\u0438 \u0431\u0443\u0434\u0443\u0442 \u0443\u0434\u0430\u043b\u0435\u043d\u044b \u043f\u043e\u0441\u043b\u0435 \u0432\u044b\u0440\u0435\u0437\u043a\u0438 \u043a\u043e\u0434\u0430export const ideaPage = root  .lets('page', 'idea', '\/ideas\/:id')  .loader(({ params }) =&gt; {    const idea = await prisma.idea.findUniqueOrThrow({      where: { id: params.id },    })    return { idea }  })  .page()\/\/ point0 compile src\/pages\/idea.tsx --side clientimport { root } from '@\/lib\/root'import { SomethingForClient } from '@\/components\/something-for-client'\/\/ \u0430 \u0432\u043e\u0442 \u0442\u0443\u0442 \u043f\u0440\u0438\u0437\u043c\u0430 \u0441\u0430\u043c\u0430 \u0432\u044b\u0440\u0435\u0437\u0430\u043b\u0430\u0441\u044cexport const ideaPage = root  .lets('page', 'idea', '\/ideas\/:id')  .loader()  .page(({ data: { idea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{idea.title}&lt;\/h1&gt;      &lt;div&gt;{idea.content}&lt;\/div&gt;      &lt;SomethingForClient \/&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u043a\u043e\u0434 \u043e\u0441\u0442\u0430\u043b\u0441\u044f \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0440\u0430\u0431\u043e\u0447\u0438\u043c \u0434\u043b\u044f \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u043e\u0439 \u0441\u0440\u0435\u0434\u044b. \u041a\u043b\u0438\u0435\u043d\u0442 \u043d\u0435 \u0437\u043d\u0430\u0435\u0442 \u0442\u0435\u043b\u0430 \u043b\u043e\u0430\u0434\u0435\u0440\u0430, \u043d\u043e \u0437\u043d\u0430\u0435\u0442, \u0447\u0442\u043e \u043e\u043d \u0435\u0441\u0442\u044c, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0437\u043d\u0430\u0435\u0442 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0438 \u043f\u0443\u0442\u044c \u043f\u043e\u0438\u043d\u0442\u0430, \u0442\u0430\u043a \u0447\u0442\u043e \u0438\u043c\u0435\u0435\u0442 \u0432\u0441\u0451 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440. \u0410 \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0438\u043c\u0435\u0435\u0442 \u0432\u044b\u043a\u043b\u044e\u0447\u0435\u043d\u043d\u044b\u0439 ssr, \u0434\u043e\u043b\u0436\u0435\u043d \u0437\u043d\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0430\u043c\u043e \u0442\u0435\u043b\u043e \u043b\u043e\u0430\u0434\u0435\u0440\u0430 \u0438 \u043e\u043f\u044f\u0442\u044c \u0436\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0438\u043d\u0442\u0430 \u0438 \u043f\u0443\u0442\u044c, \u0447\u0442\u043e\u0431\u044b \u0437\u043d\u0430\u0442\u044c, \u0447\u0442\u043e \u043e\u0442\u0432\u0435\u0442\u0438\u0442\u044c \u043a\u043b\u0438\u0435\u043d\u0442\u0443, \u043a\u043e\u0433\u0434\u0430 \u0442\u043e\u0442 \u0437\u0430\u043f\u0440\u043e\u0441\u0438\u0442.<\/p>\n<p>\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0434\u043e\u043f\u0440\u043e\u043a\u0438\u043d\u0443\u0442\u044c \u0441\u0432\u043e\u0438 babel \u043f\u043b\u0430\u0433\u0438\u043d\u044b \u0432 \u043a\u043e\u043c\u043f\u0438\u043b\u0435\u0440 \u0447\u0435\u0440\u0435\u0437:<\/p>\n<pre><code>export const engine = Engine.create({  \/\/ ...  compiler: {    babel: {      plugins: ['babel-plugin-react-compiler'],    },  },})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u043e\u043c\u043f\u0438\u043b\u0435\u0440 \u043a\u0435\u0448\u0438\u0440\u0443\u0435\u0442 \u0432\u0441\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438, \u0442\u0430\u043a \u0447\u0442\u043e \u043f\u0440\u0438 \u0441\u0430\u043c\u043e\u043c \u043f\u0435\u0440\u0432\u043e\u043c \u0437\u0430\u043f\u0443\u0441\u043a\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043f\u0440\u043e\u0445\u043e\u0434\u0438\u0442 \u0447\u0443\u0442\u044c \u0431\u043e\u043b\u044c\u0448\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438, \u0430 \u0434\u0430\u043b\u0435\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u043e\u0447\u0435\u043d\u044c \u0431\u044b\u0441\u0442\u0440\u043e, \u0438 \u0440\u0435\u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u044f \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0444\u0430\u0439\u043b\u0430, \u0438\u043b\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u0441\u0430\u043c\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430.<\/p>\n<p>\u041f\u043e\u0434\u0447\u0438\u0441\u0442\u0438\u0442\u044c \u043a\u0435\u0448, \u043c\u043e\u0436\u043d\u043e \u043a\u043e\u043c\u0430\u043d\u0434\u043e\u0439:<\/p>\n<pre><code class=\"bash\">point0 prune<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/compiler\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440<\/a>.<\/p>\n<h2>HMR<\/h2>\n<p>\u0420\u0430\u0437 \u0443\u0436 \u0437\u0430\u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438 \u043f\u0440\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440, \u0445\u043e\u0447\u0443 \u0440\u0430\u0441\u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u043a\u0430\u043a \u044f \u043e\u0431\u043c\u0430\u043d\u0443\u043b \u0440\u0435\u0430\u043a\u0442 \u0438 \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u043b HMR \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043f\u0440\u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0435 \u043b\u044e\u0431\u044b\u0445 \u043f\u043e\u0438\u043d\u0442\u043e\u0432 \u0438\u0437 \u0444\u0430\u0439\u043b\u0430. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0438 \u043c\u0443\u0442\u0430\u0446\u0438\u044e, \u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u0438 \u043a\u0432\u0435\u0440\u0438. \u041f\u043e \u0441\u0443\u0442\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u043c \u0441 \u0442\u043e\u0447\u043a\u0438 \u0437\u0440\u0435\u043d\u0438\u044f \u0440\u0435\u0430\u043a\u0442\u0430 \u0438\u0437 \u043d\u0438\u0445 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442. \u041d\u043e \u0432\u043e \u0432\u0440\u0435\u043c\u044f dev \u0440\u0435\u0436\u0438\u043c\u0430, \u043a\u043e\u043c\u043f\u0438\u043b\u0435\u0440 \u0434\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 <code>._tail(() =&gt; null)<\/code> \u0432 \u043a\u043e\u043d\u0435\u0446 \u043f\u043e\u0438\u043d\u0442\u0430:<\/p>\n<pre><code>export const ideaUpdateMutation = root  .lets('mutation', 'ideaUpdate')  .input(    z.object({      id: z.string().min(1),      title: z.string().min(1),      content: z.string().min(1),    }),  )  .loader(async ({ input: { id, title, content } }) =&gt; {    const idea = await prisma.idea.update({      where: { id },      data: { title, content },    })    return { idea }  })  .mutation()  ._tail(() =&gt; null)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421\u0430\u043c <code>ideaUpdateMutation<\/code> \u044d\u0442\u043e \u0438 \u0435\u0441\u0442\u044c \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0451\u043d\u043d\u0430\u044f \u0438\u0437 <code>_tail(() =&gt; null)<\/code>, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438 bun \u0438 vite \u0441\u0447\u0438\u0442\u0430\u044e\u0442, \u0447\u0442\u043e \u044d\u0442\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442. \u0410 \u043c\u044b \u0441\u0430\u043c\u0438 \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u043e\u0431\u0440\u0430\u0449\u0430\u0435\u043c\u0441\u044f \u043a <code>ideaUpdateMutation<\/code> \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043a \u0435\u0451 \u043c\u0435\u0442\u043e\u0434\u0430\u043c, \u0430 \u043e\u043d\u0438 \u0432\u0441\u0435 \u043d\u0430 \u043c\u0435\u0441\u0442\u0435.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/dev\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u0434\u0435\u0432-\u0440\u0435\u0436\u0438\u043c<\/a>.<\/p>\n<h2>Assets<\/h2>\n<p>\u042f \u0434\u0443\u043c\u0430\u043b \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442\u044c \u0430\u0441\u0441\u0435\u0442\u0430\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043d\u0430\u0442\u0438\u0432\u043d\u043e \u043a\u0430\u043a bun \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 \u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u041d\u043e \u0442\u0430\u043a \u043d\u0435\u043b\u044c\u0437\u044f, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u0440\u0438 ssr, bun \u043e\u0442\u0434\u0430\u0451\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u044b\u0439 \u043f\u0443\u0442\u044c \u043a \u0444\u0430\u0439\u043b\u0443 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u0430 \u043a\u043b\u0438\u0435\u043d\u0442 \u043d\u0430 \u0442\u043e\u043c \u0436\u0435 bun \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0442\u0434\u0430\u0451\u0442 \u0441\u0441\u044b\u043b\u043a\u0443 \u043d\u0430 \u0430\u0441\u0441\u0435\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043f\u0430\u0434\u0451\u0442 \u0432 \u0431\u0430\u043d\u0434\u043b. \u041d\u043e \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u043c\u0438 \u0441\u0440\u0435\u0434\u0441\u0442\u0432\u0430\u043c\u0438 bun \u0441\u0438\u043d\u0445\u0440\u043e\u043d\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u043d\u0435\u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0437\u0430\u0441\u0442\u0430\u0432\u0438\u043b \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440 \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043e \u0432\u0441\u0435\u043c \u044d\u0442\u0438\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u0438 \u0443\u0436 \u0437\u0430\u043e\u0434\u043d\u043e \u0441\u0440\u0430\u0437\u0443 \u0432\u043a\u0440\u0443\u0442\u0438\u043b SVGR.<\/p>\n<pre><code>import logoUrl from '@\/assets\/logo.png' \/\/ \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u2014 url \u0434\u043e \u0444\u0430\u0439\u043b\u0430import GemIcon from '@\/assets\/gem.svg?react' \/\/ ?react \u2014 \u044d\u0442\u043e React-\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 (\u0447\u0435\u0440\u0435\u0437 SVGR)import logoText from '@\/assets\/logo.png?text' \/\/ ?text \u2014 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u0441\u0442\u0440\u043e\u043a\u043e\u0439<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>&lt;img src={logoUrl} \/&gt;&lt;GemIcon className=\"w-5 h-5\" \/&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u0430\u043a\u0438\u0435 \u044d\u043a\u0441\u0442\u0435\u043d\u0448\u0435\u043d\u044b \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0430\u0441\u0441\u0435\u0442\u0430\u043c\u0438, \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435 <code>engine<\/code>:<\/p>\n<pre><code>export const engine = Engine.create({  \/\/ ...  assets: {    enabled: true,    extensions: ['png', 'jpg', 'jpeg', 'gif', 'svg'],    defaultMode: 'url', \/\/ \u043c\u043e\u0436\u043d\u043e \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u0431\u0435\u0437 '?' \u043d\u0435 \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0430\u0441\u0441\u0435\u0442\u043e\u043c, \u0438\u043b\u0438 \u043a\u0430\u043a\u0438\u043c \u0438\u043c\u0435\u043d\u043d\u043e \u0442\u0438\u043f\u043e\u043c \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0431\u0435\u0437 \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u044f '?'    svgr: {}, \/\/ svgr \u043e\u043f\u0446\u0438\u0438  },})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u0430 \u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f <code>assets.d.ts<\/code>. \u041e\u043f\u044f\u0442\u044c \u0436\u0435, \u043c\u043e\u0436\u043d\u043e \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0432 \u043a\u043e\u043d\u0444\u0438\u0433\u0435 <code>assets<\/code>, \u0442\u043e\u0433\u0434\u0430 \u0431\u0443\u0434\u0435\u0442 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/assets\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u0430\u0441\u0441\u0435\u0442\u044b<\/a>.<\/p>\n<h2>Env Variables<\/h2>\n<p>\u041b\u043e\u0433\u0438\u0447\u043d\u043e, \u0447\u0442\u043e \u0432 \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u043e\u043f\u0430\u0434\u0430\u044e\u0442 \u0432\u0441\u0435 env \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0430. \u0410 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442 \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u043f\u0430\u0434\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u044b\u0435 \u043d\u0430\u043c\u0438.<\/p>\n<pre><code>export const engine = Engine.create({  \/\/ ...  client: {    env: {      \/\/ \u0432\u043e\u0442 \u044d\u0442\u0438 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0432 index.html \u043f\u0440\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443      vars: ['SERVER_URL', 'CLIENT_SENTRY_DSN'],      \/\/ \u0432\u043e\u0442 \u044d\u0442\u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u0435\u0447\u0435\u043d\u044b \u043f\u0440\u044f\u043c\u043e \u0432 index.html \u043f\u0440\u0438 \u0431\u0438\u043b\u0434\u0435 \u044d\u0442\u043e\u0433\u043e index.html      consts: ['MIXPANEL_TOKEN'],    },  },})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041c\u043d\u0435 \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u0434\u0445\u043e\u0434 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435, \u0447\u0435\u043c \u0443\u043a\u0430\u0437\u0430\u043d\u0438\u0435 \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u043e\u0432 \u043f\u043e \u0442\u0438\u043f\u0443 \u201cPUBLIC_\u201d, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043d\u0430 \u043f\u0440\u0430\u043a\u0442\u0438\u043a\u0435 \u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u0443 \u043c\u0435\u043d\u044f \u0433\u0434\u0435-\u0442\u043e \u0435\u0441\u0442\u044c \u0441\u0445\u0435\u043c\u0430 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u044d\u043d\u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445, \u0438 \u043c\u043d\u0435 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0443\u0434\u043e\u0431\u043d\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u0442\u044c \u0432 \u043a\u043e\u043d\u0444\u0438\u0433 \u0435\u0451 \u043a\u043b\u044e\u0447\u0438, \u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0432\u0441\u0435\u043c \u044d\u0442\u0438\u043c \u0438\u0437 \u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0435\u0441\u0442\u0430.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u0431\u043e\u043b\u044c\u0448\u0435 \u043f\u043e\u0434\u0445\u043e\u0434 \u0441 \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u0430\u043c\u0438, \u0442\u043e \u043c\u043e\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code>export const engine = Engine.create({  \/\/ ...  client: {    env: {      \/\/ \u0442\u0435\u043f\u0435\u0440\u044c \u0432\u0441\u0435 \u044d\u043d\u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441 \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u043e\u043c PUBLIC_ \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0432 index.html \u043f\u0440\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u043a \u0441\u0435\u0440\u0432\u0435\u0440\u0443      vars: 'PUBLIC_*',      \/\/ \u0432\u0441\u0435 \u044d\u043d\u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441 \u043f\u0440\u0435\u0444\u0438\u043a\u0441\u043e\u043c CONST_PUBLIC_ \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u0435\u0447\u0435\u043d\u044b \u043f\u0440\u044f\u043c\u043e \u0432 index.html \u043f\u0440\u0438 \u0431\u0438\u043b\u0434\u0435 \u044d\u0442\u043e\u0433\u043e index.html      consts: 'CONST_PUBLIC_*',    },  },})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0449\u0451 \u043f\u043e \u043a\u0430\u043a\u0438\u043c-\u0442\u043e \u043f\u0440\u0438\u0447\u0438\u043d\u0430\u043c \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u0445\u043e\u0442\u0435\u0442\u044c \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043f\u0435\u0447\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b \u0438\u043b\u0438 \u043e\u0442\u043a\u0443\u0434\u0430-\u0442\u043e \u0432\u0437\u044f\u0432\u0448\u0438\u0435\u0441\u044f \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u0430\u043a:<\/p>\n<pre><code>export const engine = Engine.create({  \/\/ ...  client: {    env: {      vars: {        A: 1,      },      consts: {        B: 2,      },    },  },})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043a\u043e\u043c\u0431\u0438\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432\u0441\u0435 \u044d\u0442\u0438 \u043f\u043e\u0434\u0445\u043e\u0434\u044b:<\/p>\n<pre><code>export const engine = Engine.create({  \/\/ ...  client: {    env: {      vars: [        {          A: 1,        },        'PUBLIC_*',        'SERVER_URL',        'CLIENT_URL',      ],      consts: [        {          B: 2,        },        'CONST_PUBLIC_*',        'MIXPANEL_TOKEN',      ],    },  },})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0442\u043e\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u043f\u0440\u043e\u043a\u0438\u043d\u0443\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432 \u044d\u043d\u0432\u044b, \u043d\u043e \u0441\u0430\u043c\u043e\u0435 \u0433\u043b\u0430\u0432\u043d\u043e\u0435 \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043a\u0430\u043a\u0438\u0435 \u0438\u0437 \u044d\u0442\u0438\u0445 \u044d\u043d\u0432\u043e\u0432 \u0431\u0443\u0434\u0443\u0442 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430\u043c\u0438, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u0431\u0443\u0434\u0443\u0442 \u043f\u043e\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u043a\u0430\u043a \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f, \u0430 \u0437\u043d\u0430\u0447\u0438\u0442 \u0438 \u043d\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0439 \u043a\u043e\u0434 \u043f\u043e\u0441\u043b\u0435 \u0438\u0445 \u0432\u043d\u0435\u0434\u0440\u0435\u043d\u0438\u044f \u0431\u0443\u0434\u0435\u0442 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u0434\u0440\u0435\u0437\u0430\u043d:<\/p>\n<pre><code>export const engine = Engine.create({  \/\/ ...  server: {    env: {      \/\/ \u0442\u0443\u0442 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u043f\u0440\u043e\u043a\u0438\u043d\u0443\u0442\u044c \u043a\u0430\u043a\u0438\u0445-\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0439 \u043f\u0440\u0438 \u0436\u0435\u043b\u0430\u043d\u0438\u0438      vars: {        X: 3,      },      \/\/ \u0430 \u0432\u043e\u0442 \u0442\u0443\u0442 \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043a\u0430\u043a\u0438\u0435 \u044d\u043d\u0432 \u0441\u0442\u0430\u043d\u0443\u0442 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u0430\u043c\u0438      consts: ['ENABLED_*'],    },  },})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u043f\u043e\u0442\u043e\u043c \u0433\u0434\u0435-\u0442\u043e \u0432 \u043a\u043e\u0434\u0435<\/p>\n<pre><code>\/\/ \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b\u044c\u043d\u043eif (process.env.ENABLED_X === 'true') {  console.log('X is enabled')} else {  console.log('X is disabled')}\/\/ \u043f\u043e\u0441\u043b\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 (\u0430 \u043e\u043d\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0438 \u0432 \u0434\u0435\u0432 \u0441\u0440\u0435\u0434\u0435 \u0438 \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u0431\u0438\u043b\u0434\u0430)\/\/ \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0440\u0435\u0436\u0435\u0442\u0441\u044f \u0432\u0441\u0451 \u043b\u0438\u0448\u043d\u0435\u0435 \u0438 \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f:console.log('X is enabled')\/\/ \u0415\u0441\u043b\u0438 \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u044b \u0441\u0442\u0430\u043b\u0438 \u043d\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u043c\u0438, \u043e\u043d\u0438 \u0442\u043e\u0436\u0435 \u0432\u044b\u0440\u0435\u0436\u0443\u0442\u0441\u044f<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<h2>Env Helpers<\/h2>\n<p>\u0415\u0441\u0442\u044c \u0443 \u043d\u0430\u0441 \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u043e\u0431\u044a\u0435\u043a\u0442 <code>env<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432 \u0444\u0443\u043b\u0441\u0442\u0435\u043a \u043f\u0440\u043e\u0435\u043a\u0442\u0435. \u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043d\u0430 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0431\u044b\u0442\u044c:<\/p>\n<pre><code>import { env } from '@point0\/core'\/\/ \u0412\u043e\u0442 \u044d\u0442\u0438 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043e\u043f\u044f\u0442\u044c \u0436\u0435 \u0437\u0430\u043c\u0435\u043d\u044f\u044e\u0442\u0441\u044f \u043d\u0430 \u043a\u043e\u043d\u0441\u0442\u0430\u043d\u0442\u044b \u0438 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u044e\u0442env.mode.name \/\/ 'development' | 'production' | 'test' \/\/ \u044d\u0442\u043e \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435, \u0447\u0442\u043e \u0438 process.env.NODE_ENVenv.mode.is.production \/\/ true | falseenv.mode.is.test \/\/ true | falseenv.mode.is.development \/\/ true | falseenv.side.name \/\/ 'server' | 'client'env.side.is.server \/\/ true | falseenv.side.is.client \/\/ true | falseenv.build.was \/\/ true | false \/\/ \u043c\u043e\u0436\u043d\u043e \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u043a\u0430\u043a \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 \u043a\u043e\u0434 \u0434\u043e \u0431\u0438\u043b\u0434\u0430, \u0438 \u043f\u043e\u0441\u043b\u0435 \u0431\u0438\u043b\u0434\u0430<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0421 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u044d\u0442\u043e\u0433\u043e \u0436\u0435 \u0445\u0435\u043b\u043f\u0435\u0440\u0430 \u043c\u043e\u0436\u0435\u043c \u0432\u0440\u0443\u0447\u043d\u0443\u044e \u0437\u0430\u043d\u0438\u043c\u0430\u0442\u044c\u0441\u044f \u043a\u043e\u0434 \u0441\u043f\u043b\u0438\u0442\u0438\u043d\u0433\u043e\u043c. \u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0447\u0438\u0441\u0442\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u0445\u0435\u043b\u043f\u0435\u0440, \u0438 \u0447\u0438\u0441\u0442\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439, \u043d\u043e \u0443 \u043d\u0438\u0445 \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0442\u0438\u043f. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u0440\u0435\u043a\u0438\u043d\u0433 \u044d\u0432\u0435\u043d\u0442\u0430. \u041d\u043e \u043d\u0430 \u043c\u0435\u0441\u0442\u0430\u0445 \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0434\u0438\u043d \u0438 \u0442\u043e\u0442 \u0436\u0435 \u0445\u0435\u043b\u043f\u0435\u0440. \u0422\u043e\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0442\u0430\u043a:<\/p>\n<pre><code>import { env } from '@point0\/core'import { mixpanelServerTrackEvent } from '@\/lib\/mixpanel\/server'import { mixpanelClientTrackEvent } from '@\/lib\/mixpanel\/client'export const trackEvent = env.side.define({  client: mixpanelClientTrackEvent,  server: mixpanelServerTrackEvent,})trackEvent('eventName', { property: 'value' })<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0446\u0438\u0438 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442 \u044d\u0442\u043e \u0438\u043b\u0438 \u0441\u0435\u0440\u0432\u0435\u0440 \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0432\u043e\u0442 \u0442\u0430\u043a\u043e\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code>\/\/ clientimport { env } from '@point0\/core'import { mixpanelClientTrackEvent } from '@\/lib\/mixpanel\/client'export const trackEvent = mixpanelClientTrackEvent\/\/ serverimport { env } from '@point0\/core'import { mixpanelServerTrackEvent } from '@\/lib\/mixpanel\/server'export const trackEvent = mixpanelServerTrackEvent<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041f\u0440\u0438\u0447\u0451\u043c \u0432 \u044d\u0442\u043e\u0442 \u0441\u0430\u043c\u044b\u0439 <code>env.side.define<\/code> \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043f\u0440\u043e\u043a\u0438\u0434\u044b\u0432\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u043f\u0440\u043e\u0441\u0442\u043e \u043b\u044e\u0431\u044b\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f. \u0418 \u0434\u0430\u0436\u0435 \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u043e\u0434\u043d\u043e\u0433\u043e \u0442\u0438\u043f\u0430, \u0442\u043e\u0433\u0434\u0430 \u0442\u0430\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0438\u0440\u0443\u044e\u0449\u0438\u0439 \u0442\u0438\u043f \u0431\u0443\u0434\u0435\u0442 \u044e\u043d\u0438\u043e\u043d\u043e\u043c.<\/p>\n<p>\u0410 \u0435\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0447\u0442\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0432 \u0444\u0430\u0439\u043b\u0435, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0435\u0441\u0442\u044c \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u0434, \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code>import { env } from '@point0\/core'\/\/ \u0442\u0443\u0442 \u0442\u0438\u043f \u0431\u0443\u0434\u0435\u0442 `undefined | ((name: string) =&gt; string)`\/\/ \u0442\u0430\u043a \u043a\u0430\u043a \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0442\u043e \u044d\u0442\u043e undefinedconst myServerOnlyFn1 = env.side.define.server((name: string) =&gt; {  return `Hello, ${name}!`})\/\/ \u043d\u043e \u043d\u0435 \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0435\u0441\u043b\u0438 \u0432\u044b \u0441\u0430\u043c\u0438 \u0441\u0435\u0431\u0435 \u043e\u0431\u0435\u0449\u0430\u0435\u0442\u0435 \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\/\/ \u044d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435, \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0430\u043a:const myServerOnlyFn2 = env.side.define.unsafe.server((name: string) =&gt; {  return `Hello, ${name}!`})\/\/ \u0442\u043e\u0433\u0434\u0430 \u0442\u0438\u043f \u0431\u0443\u0434\u0435\u0442 `(name: string) =&gt; string`<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043c \u0435\u0449\u0451 \u0445\u0435\u043b\u043f\u0435\u0440\u044b \u0435\u0441\u0442\u044c, \u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/env\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e env-\u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435<\/a>.<\/p>\n<h2>Importer<\/h2>\n<p>\u0423\u0447\u0438\u0442\u044b\u0432\u0430\u044f, \u0447\u0442\u043e \u043a\u043e\u0434 \u0432\u044b\u0440\u0435\u0437\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u043e\u043c, \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u043b\u0435\u0433\u043a\u043e \u0447\u0442\u043e-\u0442\u043e \u043d\u0430\u043f\u0443\u0442\u0430\u0442\u044c \u0438 \u0437\u0430\u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u0434 \u0432 \u043a\u043b\u0438\u0435\u043d\u0442 \u0438 \u043d\u0430\u043e\u0431\u043e\u0440\u043e\u0442. \u041d\u043e \u0447\u0430\u0449\u0435 \u0432\u0441\u0435\u0433\u043e \u043c\u044b \u0437\u043d\u0430\u0435\u043c \u0437\u0430\u0440\u0430\u043d\u0435\u0435, \u043a\u0430\u043a\u0438\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 \u044f\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0438\u043c\u0435\u043d\u043d\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u043c\u0438 \u0438\u043b\u0438 \u0438\u043c\u0435\u043d\u043d\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u043c\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u0435\u0431\u044f \u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0441\u0438\u0442\u044c.<\/p>\n<p>\u0414\u043e\u043f\u0443\u0441\u0442\u0438\u043c \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0444\u0430\u0439\u043b <code>src\/lib\/prisma.ts<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0442\u043e\u0447\u043d\u043e \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u043e\u043f\u0430\u0441\u0442\u044c \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442, \u0442\u043e\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u0432 \u0444\u0430\u0439\u043b\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c <code>import '@point0\/core\/server-only'<\/code>. \u0422\u0435\u043f\u0435\u0440\u044c \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u043e\u043c\u043f\u0438\u043b\u0435\u0440 \u0443\u0432\u0438\u0434\u0438\u0442, \u0447\u0442\u043e \u043c\u044b \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c <code>src\/lib\/prisma.ts<\/code> \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435, \u043e\u043d \u0432\u044b\u0431\u0440\u043e\u0441\u0438\u0442 \u043e\u0448\u0438\u0431\u043a\u0443:<\/p>\n<pre><code>import '@point0\/core\/server-only'export const prisma = new PrismaClient()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0430\u043a\u043e\u0433\u043e \u0436\u0435 \u044d\u0444\u0444\u0435\u043a\u0442\u0430 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u0441\u0442\u0438\u0447\u044c \u0447\u0435\u0440\u0435\u0437 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043a\u043e\u043d\u0444\u0438\u0433\u0430 <code>engine<\/code>:<\/p>\n<pre><code>export const engine = Engine.create({  \/\/ ...  client: {    importer: {      deny: [        \/\/ \u043f\u0443\u0442\u0438 \u043a \u0444\u0430\u0439\u043b\u0430\u043c \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u043c \u0441 .        '.\/lib\/prisma.ts',        \/\/ \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u044b\u0435 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0438 \u043f\u0438\u0448\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044e \u043f\u0430\u043a\u0435\u0442\u0430        'dotenv',      ],    },  },})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u041a\u043e\u0433\u0434\u0430 \u044f \u0430\u0434\u0430\u043f\u0442\u0438\u0440\u043e\u0432\u0430\u043b Point0 \u043a expo, \u043e\u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c, \u0447\u0442\u043e \u0442\u0430\u043c \u0435\u0441\u0442\u044c \u0442\u0430\u043a\u043e\u0439 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0443\u0436\u043d\u043e \u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u0432\u0438\u0434\u0435\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440\u0443, \u043d\u043e \u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0435\u0433\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 const <code>styles = StyleSheet.create({})<\/code>. \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u044b \u0435\u0433\u043e \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0435\u043c \u0432 \u0444\u0430\u0439\u043b\u0435 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043c\u043e\u0436\u0435\u0442 \u0438\u043c\u0435\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u043c\u0435\u0435\u0442 \u043d\u0430\u0448 \u043b\u043e\u0430\u0434\u0435\u0440 \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430. \u0418 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u044f \u043d\u0435 \u043c\u043e\u0433\u0443 \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043f\u0440\u0435\u0442\u0438\u0442\u044c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0438\u043c\u043f\u043e\u0440\u0442 \u0438\u0437 \u2018react-native\u2019. \u041e\u0434\u043d\u0430\u043a\u043e \u044f \u043d\u0435 \u0445\u043e\u0447\u0443 \u0432\u043e\u043e\u0431\u0449\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c \u0435\u0433\u043e \u043a\u043e\u0434. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043d\u0435 \u0437\u0430\u043f\u0440\u0435\u0442\u0438\u0442\u044c \u043c\u043e\u0434\u0443\u043b\u044c, \u0430 \u043c\u043e\u043a\u043d\u0443\u0442\u044c \u0435\u0433\u043e. \u041f\u043e\u0441\u043b\u0435 \u043c\u043e\u043a\u0430, \u043e\u043d \u043c\u043e\u0436\u0435\u0442 \u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0442\u043e \u0443\u0433\u043e\u0434\u043d\u043e, \u0438 \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442\u044c.<\/p>\n<pre><code>export const engine = Engine.create({  \/\/ ...  server: {    importer: {      mock: ['react-native', 'expo-router'],    },  },})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/importer\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u0435\u0440<\/a>.<\/p>\n<h2>Mdx<\/h2>\n<p>Mdx \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u0438\u0441\u0430\u0442\u044c \u043a\u0430\u043a \u0431\u044b \u043c\u0430\u0440\u043a\u0434\u0430\u0443\u043d, \u043d\u043e \u0442\u0430\u043a\u0436\u0435 \u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c React \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b. \u0415\u0441\u043b\u0438 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0432 \u0442\u0430\u043a\u043e\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u0442\u043e \u043c\u044b \u0434\u0435\u043b\u0430\u0435\u043c \u044d\u0442\u043e \u0442\u0430\u043a:<\/p>\n<pre><code>import { Link } from '@\/lib\/navigation'import { generalLayout } from '@\/layouts\/general'export const page = generalLayout  .lets('page', 'about', '\/about')  .loader(async () =&gt; {    const lastIdea = await prisma.idea.findFirst({ orderBy: { id: 'desc' } })    return { lastIdea }  })  .head('About')  .page((props) =&gt; (    &lt;div className=\"prose\"&gt;      {\/* \u0412\u043e\u0442 \u0437\u0434\u0435\u0441\u044c \u043b\u0435\u0436\u0438\u0442 \u0441\u0430\u043c \u043a\u043e\u043d\u0442\u0435\u043d\u0442, \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0439 \u043d\u0438\u0436\u0435 *\/}      &lt;MDXContent {...props} \/&gt;    &lt;\/div&gt;  ))IdeaNick \u2014 \u043f\u043b\u043e\u0449\u0430\u0434\u043a\u0430 \u0434\u043b\u044f \u0438\u0434\u0435\u0439.\u0421\u0432\u0435\u0436\u0430\u044f \u0438\u0434\u0435\u044f: &lt;Link route=\"idea\"input={{ id: props.data.lastIdea.id }}&gt;{props.data.lastIdea.title}&lt;\/Link&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u044d\u0442\u043e \u0432\u0441\u0451 \u0442\u0430 \u0436\u0435 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u044f \u043f\u043e\u0438\u043d\u0442\u0430 (\u0441 \u043b\u043e\u0430\u0434\u0435\u0440\u043e\u043c, <code>.head()<\/code>, <code>.page()<\/code>), \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 \u2014 \u044d\u0442\u043e Markdown \u0441 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c\u044e \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u043b\u044e\u0431\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/mdx\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e MDX<\/a>.<\/p>\n<h2>\u041e\u0431\u0432\u044f\u0437\u043a\u0430<\/h2>\n<p>\u041c\u044b \u0432 \u0440\u0430\u0437\u043d\u044b\u0445 \u0447\u0430\u0441\u0442\u044f\u0445 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438 \u0433\u043e\u0432\u043e\u0440\u0438\u043b\u0438 \u043e \u0442\u043e\u043c, \u0447\u0442\u043e \u0438 \u043a\u0443\u0434\u0430 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u043e\u0431\u0435\u0440\u0451\u043c \u0432\u0441\u0451 \u0432\u043e\u0435\u0434\u0438\u043d\u043e \u0438 \u043e\u043a\u043e\u043d\u0447\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u0431\u0435\u0440\u0451\u043c \u043f\u0440\u0438\u043d\u0446\u0438\u043f \u0440\u0430\u0431\u043e\u0442\u044b:<\/p>\n<pre><code>\/\/ engine.ts\/\/ \u041d\u0430\u0448 \u043a\u043e\u043d\u0444\u0438\u0433 \u0438 \u043e\u0434\u043d\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u043e \u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u0445\u0435\u043b\u043f\u0435\u0440 \u0434\u043b\u044f \u0441\u0435\u0440\u0432\u0438\u043d\u0433\u0430 \u043f\u043e\u0438\u043d\u0442\u043e\u0432.\/\/ \u041e\u0447\u0435\u043d\u044c \u0432\u0430\u0436\u043d\u043e \u0441\u044e\u0434\u0430 \u043d\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0442\u043e, \u0447\u0442\u043e \u0434\u043e\u043b\u0436\u043d\u043e \u043f\u0440\u043e\u0439\u0442\u0438 \u0447\u0435\u0440\u0435\u0437 \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440export const engine = Engine.create({  \/\/ ...  ssr: true,  server: {    \/\/ ...    \/\/ \u0432\u043e\u0442 \u044d\u0442\u043e\u0442 \u044d\u043d\u0442\u0440\u0438 \u0431\u0443\u0434\u0435\u0442 \u0437\u0430\u043f\u0443\u0449\u0435\u043d \u0432\u043e \u0432\u0440\u0435\u043c\u044f \u0432\u044b\u0437\u043e\u0432\u0430 point0 dev    \/\/ \u043f\u043e\u0441\u043b\u0435 \u0431\u0438\u043b\u0434\u0430, \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0431\u0443\u0434\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c bun dist\/server\/index.server.js    entry: { main: '.\/index.server.ts' },    \/\/ \u044d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0438 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0432\u0441\u0435 \u043d\u0430\u0448\u0438 \u043f\u043e\u0438\u043d\u0442\u044b    generate: { points: '.\/generated\/point0\/points.server.ts' },    \/\/ \u0432\u043e\u0442 \u0441\u044e\u0434\u0430 \u043c\u044b \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u044d\u0442\u0438 \u0441\u0430\u043c\u044b\u0435 \u043f\u043e\u0438\u043d\u0442\u044b, \u0447\u0442\u043e\u0431\u044b \u0434\u043e \u043c\u043e\u043c\u0435\u043d\u0442\u0430    \/\/ \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u0430 \u043c\u044b \u0443\u0441\u043f\u0435\u043b\u0438 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u044c bun \u043f\u043b\u0430\u0433\u0438\u043d \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430    points: async () =&gt; await import('.\/generated\/point0\/points.server'),    outdir: '..\/dist\/server',  },  client: {    \/\/ ...    indexHtml: '.\/index.client.html',    app: async () =&gt; await import('.\/app.client'),    points: async () =&gt; await import('.\/generated\/point0\/points.client'),    generate: {      points: '.\/generated\/point0\/points.client.ts',      routes: {        outfile: '.\/generated\/point0\/routes.ts',        origin: 'process.env.CLIENT_URL',      },    },    outdir: '..\/dist\/client',    publicdir: {      source: '..\/public',      outdir: '..\/dist\/client',    },  },})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>\/\/ preload.ts\/\/ \u043d\u0443\u0436\u0435\u043d \u0447\u0442\u043e\u0431\u044b \u0432 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u043c \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0435 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u0442\u044c \u0431\u0430\u043d \u043f\u043b\u0430\u0433\u0438\u043d, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430 \u043b\u0435\u0442\u0443\/\/ \u0431\u0443\u0434\u0435\u0442 \u043a\u043e\u043c\u043f\u0438\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0448 \u043a\u043e\u0434, \u0432\u044b\u0440\u0435\u0437\u0430\u0442\u044c \u043a\u043e\u0434, \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435\/\/ \u0430 \u0442\u0430\u043a\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442 \u043d\u0443\u0436\u043d\u044b\u0435 \u044d\u043d\u0432 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043b\u0438 \u0432 engine.tsimport { engine } from '@\/engine'await engine.preload({ nodeEnvFallback: 'development' })<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>\/\/ index.server.ts\/\/ \u044d\u043d\u0442\u0440\u0438 \u043f\u043e\u0438\u043d\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u0430, \u043d\u0443\u0436\u0435\u043d \u0447\u0442\u043e\u0431\u044b \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c bun \u043f\u043b\u0430\u0433\u0438\u043d,\/\/ \u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0442\u043e\u043c \u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439await import('.\/preload.js')await import('.\/app.server.js')export {}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>\/\/ app.server.ts\/\/ \u0437\u0434\u0435\u0441\u044c \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043b\u044e\u0431\u043e\u0439 \u0434\u0440\u0443\u0433\u043e\u0439 \u043d\u0430\u0448 \u0441\u0435\u0440\u0432\u0440\u043d\u044b\u0439 \u043a\u043e\u0434, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0438\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0431\u0430\u0437\u044b \u0434\u0430\u043d\u043d\u044b\u0445\/\/ \u0437\u0430\u043f\u0443\u0441\u043a \u0432\u043e\u0440\u043a\u0435\u0440\u043e\u0432, \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u044f \u044d\u043d\u0432\u043e\u0432, \u0438 \u0442\u0430\u043a \u0434\u0430\u043b\u0435\u0435import { engine } from '@\/engine.js'await engine.serve()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>\/\/ bunfig.toml\/\/ noOrphans \u041f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0435 \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u043f\u043e\u0434\u0432\u0438\u0441\u0448\u0438\u0445 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u0432\/\/ \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0437\u0430\u043a\u0440\u044b\u0442\u0438\u044f \u0442\u0435\u0440\u043c\u0438\u043d\u0430\u043b\u0430[run]noOrphans = true\/\/ \u043d\u0435 \u043d\u0430\u0434\u043e \u0434\u043e\u0431\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u044e\u0434\u0430 preload.ts \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 preload \u0441\u043a\u0440\u0438\u043f\u0442\u0430\/\/ \u043a\u0430\u0437\u0430\u043b\u043e\u0441\u044c \u0431\u044b \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e, \u043d\u043e \u043d\u0435\u0442.\/\/ \u0412\u0435\u0434\u044c \u043f\u0440\u0435\u043b\u043e\u0430\u0434 \u0441\u043a\u0440\u0438\u043f\u0442 \u0433\u0440\u0443\u0437\u0438\u0442\u0441\u044f \u043b\u044e\u0431\u044b\u043c bun \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u043e\u043c, \u0438 \u0435\u0441\u043b\u0438 \u0432\u044b \u043e\u0434\u043d\u0430\u0436\u0434\u044b\/\/ \u0431\u0443\u0434\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u043b\u0438\u0431\u043e \u0434\u0440\u0443\u0433\u0438\u0435 \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0438\u0435 cli \u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u044b\u0435 bun\/\/ \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442 \u0433\u0440\u0443\u0437\u0438\u0442\u044c \u044d\u0442\u043e\u0442 \u0441\u043a\u0440\u0438\u043f\u0442, \u0430 \u043e\u043d \u0438\u043c \u043d\u0435 \u043d\u0443\u0436\u0435\u043d<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>&lt;!-- index.client.html --&gt;&lt;!doctype html&gt;&lt;html lang=\"en\"&gt;  &lt;head&gt;    &lt;meta charset=\"utf-8\" \/&gt;    &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" \/&gt;    &lt;title&gt;My App&lt;\/title&gt;  &lt;\/head&gt;  &lt;body&gt;    &lt;div id=\"root\"&gt;&lt;\/div&gt;    &lt;script type=\"module\" src=\".\/index.client.tsx\"&gt;&lt;\/script&gt;  &lt;\/body&gt;&lt;\/html&gt;<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>\/\/ index.client.tsx\/\/ \u044d\u0442\u043e\u0442 \u0444\u0430\u0439\u043b \u043d\u0438\u043a\u043e\u0433\u0434\u0430 \u043d\u0435 \u0443\u0432\u0438\u0434\u0438\u0442 \u0441\u0435\u0440\u0432\u0435\u0440, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0437\u0434\u0435\u0441\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u043c\u0435\u043b\u043e \u0432\u0430\u043b\u0438\u0434\u0438\u0440\u043e\u0432\u0430\u0442\u044c\/\/ \u044d\u043d\u0432\u044b \u043a\u043b\u0438\u0435\u043d\u0442\u0430. \u0412 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u043e\u043c \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u043e\u0435 React \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435.import App from '@\/app.client'import points from '@\/generated\/point0\/points.client'import '@\/styles\/index.css'import { ErrorBoundary } from '@\/ui\/error-boundary'import { mount } from '@point0\/react-dom\/mount'\/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f mount \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0442\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0439\u0442\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u043d\u044b\u0435 \u0438\u0437 SSR \u0434\u0430\u043d\u043d\u044b\u0435, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438\/\/ Query Client Dehydrated State, \u0438 \u0433\u0438\u0434\u0440\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043f\u043e\u0432\u0435\u0440\u0445 \u043d\u0435\u0433\u043e.mount(  &lt;ErrorBoundary&gt;    &lt;App \/&gt;  &lt;\/ErrorBoundary&gt;,  \/\/ \u041f\u0440\u043e\u043a\u0438\u0434\u044b\u0432\u0430\u044f \u0441\u044e\u0434\u0430 \u043f\u043e\u0438\u043d\u0442\u044b, \u043e\u043d\u0438 \u0441\u0442\u0430\u043d\u043e\u0432\u044f\u0442\u0441\u044f \u0433\u043b\u043e\u0431\u0430\u043b\u044c\u043d\u043e \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0434\u043b\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f  points,)<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>\/\/ app.client.tsximport { Router, RouterRoutes } from '@\/lib\/navigation'import { UnheadProvider } from '@point0\/core\/unhead'import { QueryClientProvider } from '@tanstack\/react-query'import { NProgress } from '@\/components\/other\/nprogress'import { Toaster } from '@\/components\/ui\/sonner'import { ThemeProvider } from '@\/components\/ui\/theme'import { ErrorPageComponent } from '@\/components\/other\/error'import { queryClient } from '@\/lib\/query-client'import { Head } from '@unhead\/react'export default function App() {  return (    &lt;QueryClientProvider client={queryClient}&gt;      {\/* UnheadProvider \u044d\u0442\u043e \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u0430\u044f \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c, \u0447\u0435\u0440\u0435\u0437 \u043d\u0435\u0433\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043d\u0430\u0448 .head() \u0432 \u043f\u043e\u0438\u043d\u0442\u0430\u0445.      \u0412\u044b \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u043d\u044b\u0435 unhead \u0445\u0435\u043b\u043f\u0435\u0440\u044b useHead(), useSeoMeta(), \u043d\u0430 \u043c\u0435\u0441\u0442\u0430\u0445, \u0433\u0434\u0435 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e *\/}      &lt;UnheadProvider&gt;        &lt;Head&gt;          {\/* \u0432\u0441\u0451 \u0432 \u0445\u0435\u0434\u0435 \u0441\u0432\u044f\u0437\u0430\u043d\u043d\u043e\u0435 \u0441 \u0430\u0441\u0441\u0435\u0442\u0430\u043c\u0438 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0439\u0442\u0435 \u0437\u0434\u0435\u0441\u044c, \u0430 \u043d\u0435 \u0432 index.client.html          \u0438\u043d\u0430\u0447\u0435 bun \u0431\u0443\u0434\u0435\u0442 \u043b\u043e\u043c\u0430\u0442\u044c \u0438\u0445 \u0443\u0440\u043b\u044b \u0438 \u043f\u044b\u0442\u0430\u0442\u044c\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0432\u043e\u0438\u043c\u0438 \u0430\u0441\u0441\u0435\u0442\u0430\u043c\u0438, \u0430 \u043d\u0430\u043c \u044d\u0442\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e \u0434\u043b\u044f \u0444\u0430\u0432\u044b\u043a\u043e\u043d\u0430          \u0438 \u0435\u043c\u0443 \u043f\u043e\u0434\u043e\u0431\u043d\u044b\u0445 *\/}          &lt;link rel=\"shortcut icon\" href=\"\/favicon.ico\" \/&gt;        &lt;\/Head&gt;        &lt;ThemeProvider \/&gt;        &lt;Router&gt;          &lt;NProgress \/&gt;          &lt;Toaster \/&gt;          {\/* \u0412\u0441\u044f \u0441\u0432\u044f\u0437\u044c \u043c\u0435\u0436\u0434\u0443 \u0430\u0434\u0440\u0435\u0441\u0430\u043c\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0438 \u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u043c\u0438 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u0430 \u0440\u043e\u0443\u0442\u0435\u0440\u0443 \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u0442\u043e\u043c\u0443, \u0447\u0442\u043e          \u0432 index.client.tsx \u043c\u044b \u043f\u0440\u043e\u043a\u0438\u043d\u0443\u043b\u0438 \u0438\u0445 \u0432 mount \u0444\u0443\u043d\u043a\u0446\u0438\u044e *\/}          &lt;RouterRoutes            Page404={() =&gt; (              &lt;ErrorPageComponent title=\"404\" description=\"Page not found\" \/&gt;            )}          \/&gt;        &lt;\/Router&gt;      &lt;\/UnheadProvider&gt;    &lt;\/QueryClientProvider&gt;  )}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/engine-runtime\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u043e\u0431\u0432\u044f\u0437\u043a\u0443<\/a>.<\/p>\n<h2>SSR<\/h2>\n<p>\u042f \u0445\u043e\u0442\u0435\u043b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043c\u044b \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0447\u0443\u0432\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u0438 \u0432\u043a\u043b\u044e\u0447\u0451\u043d ssr, \u0438\u043b\u0438 \u043d\u0435 \u0432\u043a\u043b\u044e\u0447\u0451\u043d. \u041a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u043f\u0438\u0448\u0435\u043c, \u0434\u043e\u043b\u0436\u0435\u043d \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u043e. \u0418\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043a\u043e\u0433\u0434\u0430 \u044f \u0434\u0435\u043b\u0430\u043b <code>.loader()<\/code> \u0432 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u044f \u0434\u0443\u043c\u0430\u043b, \u0447\u0442\u043e \u0431\u0443\u0434\u0443 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0435\u0433\u043e \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442 \u0447\u0435\u0440\u0435\u0437 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0438 \u0432\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0432 index.html. \u0418 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0442\u0430\u043a \u0438 \u0441\u0434\u0435\u043b\u0430\u043b, \u043d\u043e \u043f\u043e\u0442\u043e\u043c \u043f\u0440\u0438\u0448\u0451\u043b \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043b\u0443\u0447\u0448\u0435 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0447\u0438\u0442\u0430\u0442\u044c \u0447\u0442\u043e \u0432\u0441\u0451 \u044d\u0442\u043e \u043a\u0432\u0435\u0440\u0438, \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c \u0432 index.html \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0434\u0435\u0433\u0438\u0434\u0440\u0430\u0446\u0438\u0438 \u043a\u0432\u0435\u0440\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430. \u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043f\u043e \u0441\u0443\u0442\u0438 \u0445\u043e\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0431\u044b\u043b\u0430 \u0437\u0430\u043f\u0440\u043e\u0448\u0435\u043d\u0430 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 SSR, \u0442\u0430\u043c \u0431\u0443\u0434\u0435\u0442 \u0434\u0435\u0433\u0438\u0434\u0440\u0435\u0439\u0442\u0435\u0434 \u043a\u0432\u0435\u0440\u0438 \u043a\u043b\u0438\u0435\u043d\u0442, \u0445\u043e\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u0431\u044b\u043b\u0430 \u0433\u043e\u043b\u044b\u043c index.html, \u0430 \u0437\u0430\u043f\u0440\u043e\u0441\u044b \u0443\u0448\u043b\u0438 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440 \u0443\u0436\u0435 \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0441\u044f \u0442\u043e \u0436\u0435 \u0441\u0430\u043c\u043e\u0435.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e \u043f\u0435\u0440\u0435\u0434 \u0440\u0435\u043d\u0434\u0435\u0440\u043e\u043c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u044f \u0432\u044b\u0447\u0438\u0441\u043b\u044f\u043b \u043a\u0430\u043a\u0438\u0435 \u0443 \u043d\u0435\u0451 \u0438 \u0435\u0451 \u043b\u044d\u0439\u043e\u0443\u0442\u043e\u0432 \u0435\u0441\u0442\u044c \u043b\u043e\u0430\u0434\u0435\u0440\u044b, \u0438 \u0432\u044b\u0437\u044b\u0432\u0430\u043b \u0438\u0445 \u043a\u043e\u0434, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0441\u0443\u043d\u0443\u0442\u044c \u0432 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u0432\u0435\u0440\u0438 \u043a\u043b\u0438\u0435\u043d\u0442, \u0447\u0442\u043e\u0431\u044b \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043b\u0430\u0441\u044c \u0431\u0435\u0437 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0439 \u043b\u043e\u0430\u0434\u0438\u043d\u0433\u0430. \u041d\u043e \u043f\u043e\u0442\u043e\u043c \u044f \u0441\u0434\u0435\u043b\u0430\u043b <code>.with()<\/code> \u0432 \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u0432\u0435\u0440\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u043e\u0433\u0443\u0442 \u043e\u0436\u0438\u0434\u0430\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0430. \u0410 \u043f\u043e\u0442\u043e\u043c \u0435\u0449\u0451 \u0438 \u043f\u043e\u0434\u044a\u0435\u0445\u0430\u043b\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e \u0441\u0443\u0442\u0438 \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0438\u0437\u0432\u0435\u0441\u0442\u043d\u043e \u0435\u0441\u0442\u044c \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0438\u043b\u0438 \u0438\u0445 \u0442\u0430\u043c \u043d\u0435\u0442.<\/p>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435 \u043f\u043e SSR \u043f\u0440\u0438\u043d\u044f\u0442\u043e \u0442\u0430\u043a\u043e\u0435. \u042f \u0440\u0435\u043d\u0434\u0435\u0440\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u0435\u0440\u0432\u044b\u0439 \u0440\u0430\u0437. \u0421\u043c\u043e\u0442\u0440\u044e \u043d\u0430 \u0441\u0442\u0435\u0439\u0442 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u043e\u0433\u043e \u043a\u0432\u0435\u0440\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0430, \u0435\u0441\u043b\u0438 \u0442\u0430\u043c \u0435\u0441\u0442\u044c \u043a\u0432\u0435\u0440\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043e\u0442\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u043a point0, \u043e\u043d\u0438 \u0432 \u0441\u0442\u0430\u0442\u0443\u0441\u0435 pending, \u044f \u0438\u0445 \u0440\u0430\u043d\u044c\u0448\u0435 \u0432 \u044d\u0442\u043e\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u0435 \u043d\u0435 \u0432\u0438\u0434\u0435\u043b, \u0438 \u043e\u043d\u0438 enabled, \u0442\u043e\u0433\u0434\u0430 \u044f \u0437\u043d\u0430\u044f \u0438\u0445 <code>queryKey<\/code>, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0435\u0441\u0442\u044c \u0432\u0441\u0451 \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043d\u044f\u0442\u044c \u043a \u043a\u0430\u043a\u043e\u043c\u0443 \u043f\u043e\u0438\u043d\u0442\u0443 \u043e\u0442\u043d\u043e\u0441\u0438\u0442\u0441\u044f \u043a\u0432\u0435\u0440\u044f, \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0444\u0435\u0442\u0447\u0443 \u044d\u0442\u043e\u0442 \u043a\u0432\u0435\u0440\u0438 \u043f\u0440\u044f\u043c\u043e \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u043f\u0440\u0435\u0432\u0440\u0430\u0449\u0430\u044f \u0441\u0442\u0430\u0442\u0443\u0441 \u044d\u0442\u043e\u0433\u043e \u043a\u0432\u0435\u0440\u0438 \u043b\u0438\u0431\u043e \u0432 \u0443\u0441\u043f\u0435\u0445, \u043b\u0438\u0431\u043e \u0432 \u044d\u0440\u0440\u043e\u0440, \u043d\u0435 \u0432\u0430\u0436\u043d\u043e. \u0417\u0430\u0442\u0435\u043c \u044f \u0440\u0435\u043d\u0434\u0435\u0440\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0435\u0449\u0451 \u0440\u0430\u0437. \u0418 \u0442\u0430\u043a \u043f\u043e \u043a\u0440\u0443\u0433\u0443, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043a\u043e\u043d\u0447\u0430\u0442\u0441\u044f \u043d\u0435\u0440\u0430\u0437\u0440\u0435\u0437\u043e\u043b\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u043a\u0432\u0435\u0440\u0438. \u041f\u043e \u0444\u0430\u043a\u0442\u0443 \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f 2\u20134 \u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u0430 \u043d\u0430 \u0437\u0430\u043f\u0440\u043e\u0441.<\/p>\n<p>\u041d\u0430\u0434\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u0447\u0442\u043e SSR \u0444\u0430\u043a\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0434\u0430\u043b\u0435\u0435 \u043f\u0440\u0438 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u0438 \u043c\u044b \u0443\u0436\u0435 \u043d\u0435 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c html, \u043c\u044b \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043a\u0430\u0447\u0438\u0432\u0430\u0435\u043c js \u0447\u0430\u043d\u043a \u0441\u0430\u043c\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u043f\u043b\u044e\u0441 \u0437\u0430\u043f\u0440\u0430\u0448\u0438\u0432\u0430\u0435\u043c \u043d\u0443\u0436\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0438 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0438\u0445 \u0432 \u043a\u0432\u0435\u0440\u0438 \u043a\u043b\u0438\u0435\u043d\u0442. \u0418 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u044d\u0442\u0438\u043c \u0443 \u043d\u0430\u0441 \u0438 \u0435\u0441\u0442\u044c \u0432\u0441\u0435 \u044d\u0442\u0438 \u043e\u043f\u0446\u0438\u0438 \u0432 <code>.prefetchPageOnNavigate('pageDehydratedStateAndClientQuery')<\/code>.<\/p>\n<p>\u041f\u0440\u0438 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0435 <code>pageDehydratedStateAndClientQuery<\/code> \u043c\u044b \u043f\u0435\u0440\u0435\u0434 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u043e\u043c \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u043e\u043f\u0440\u043e\u0441\u0438\u043c \u0441\u0435\u0440\u0432\u0435\u0440 \u0432 \u0443\u043c\u0435 \u043e\u0442\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0437\u0430\u0440\u0435\u0437\u043e\u043b\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u043a\u0432\u0435\u0440\u0438 \u043a\u043b\u0438\u0435\u043d\u0442, \u0438 \u0432\u0435\u0440\u043d\u0443\u0442\u044c \u043d\u0430\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0430\u043c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u0435\u0433\u043e \u0434\u0435\u0433\u0438\u0434\u0440\u0430\u0446\u0438\u0438. \u041f\u0440\u0438 \u043f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0434\u0435\u0433\u0438\u0434\u0440\u0430\u0446\u0438\u0438 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435, \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0434\u0441\u0443\u043d\u0435\u043c \u0435\u0433\u043e \u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u043a\u0432\u0435\u0440\u0438 \u043a\u043b\u0438\u0435\u043d\u0442. \u0422\u0430\u043a\u0436\u0435 \u043f\u0440\u0438 \u0442\u0430\u043a\u043e\u0439 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0435 \u0431\u0443\u0434\u0443\u0442 \u0432\u044b\u0437\u0432\u0430\u043d\u044b \u0432\u0441\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u043d\u044b\u0435 <code>.clientLoader()<\/code> \u0443\u0436\u0435 \u043d\u0430 \u0441\u0430\u043c\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435. \u0414\u043b\u044f \u043d\u0430\u0441 \u043a\u0430\u043a \u0434\u043b\u044f \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432, \u044d\u0442\u043e \u0441\u0430\u043c\u044b\u0439 \u0443\u0434\u043e\u0431\u043d\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u0432 \u043f\u043b\u0430\u043d\u0435 DX. \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0442\u043e\u0433\u0434\u0430 \u043c\u044b \u0442\u043e\u0447\u043d\u043e \u0437\u043d\u0430\u0435\u043c, \u0447\u0442\u043e \u0432\u0441\u0435 \u043d\u0443\u0436\u043d\u044b\u0435 \u043a\u0432\u0435\u0440\u0438 \u0441\u043e\u0431\u0435\u0440\u0443\u0442\u0441\u044f. \u041d\u043e \u043c\u044b \u043f\u043b\u0430\u0442\u0438\u043c \u0437\u0430 \u044d\u0442\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u043c\u0438 \u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u0430\u043c\u0438. \u042f \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0432\u0438\u0436\u0443 \u0432 \u044d\u0442\u043e\u043c \u043d\u0438\u0447\u0435\u0433\u043e \u0443\u0436\u0430\u0441\u043d\u043e\u0433\u043e, \u043d\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u044e \u0442\u0435\u0445, \u043a\u0442\u043e \u0445\u043e\u0442\u0435\u043b \u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u043e\u0432, \u0438 \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0443 \u043d\u0430\u0441 \u0442\u043e\u0436\u0435 \u0435\u0441\u0442\u044c \u0440\u0435\u0448\u0435\u043d\u0438\u0435.<\/p>\n<p>\u0415\u0441\u0442\u044c \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0430 <code>serverAndClientQuery<\/code>, \u0442\u043e\u0433\u0434\u0430 \u043c\u044b \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0431\u0443\u0434\u0435\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c \u043d\u0438 \u0440\u0430\u0437\u0443 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0435 \u043e\u0442 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043a \u0434\u0440\u0443\u0433\u043e\u0439, \u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u043b\u043e\u0430\u0434\u0435\u0440\u044b \u043b\u044d\u0439\u043e\u0443\u0442\u043e\u0432 \u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0438\u043c \u0442\u043e\u043b\u044c\u043a\u043e \u0438\u0445. \u041d\u043e \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u0435\u0441\u043b\u0438 \u043a\u0432\u0435\u0440\u0438 \u0431\u044b\u043b\u0438 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u044b \u0432 <code>.with()<\/code>, \u0438\u043b\u0438 \u0432 \u043a\u0430\u043a\u0438\u0445-\u0442\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430\u0445 \u0432\u043d\u0443\u0442\u0440\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0442\u043e\u0433\u0434\u0430 \u043e\u043d\u0438 \u043d\u0435 \u0431\u0443\u0434\u0443\u0442 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0435\u043d\u044b, \u0438 \u043f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0430 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443, \u043f\u043e\u0434\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u0443\u044e \u0442\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c, \u043c\u044b \u0443\u0432\u0438\u0434\u0438\u043c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043b\u043e\u0430\u0434\u0438\u043d\u0433\u0430 \u043d\u0430 \u0442\u0430\u043a\u0438\u0445 \u043c\u0435\u0441\u0442\u0430\u0445.<\/p>\n<p>\u041f\u0440\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0438 \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0438 <code>serverAndClientQuery<\/code>, \u0447\u0442\u043e\u0431\u044b \u0438\u0437\u0431\u0435\u0436\u0430\u0442\u044c \u043b\u043e\u0430\u0434\u0438\u043d\u0433\u0430 \u043d\u0430 \u043c\u0435\u0441\u0442\u0430\u0445, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0432 \u043f\u043e\u0438\u043d\u0442\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0438\u043b\u0438 \u043b\u044d\u0439\u043e\u0443\u0442\u0430 \u043f\u0440\u043e\u043f\u0438\u0441\u0430\u0442\u044c <code>.onPrefetchPage()<\/code>:<\/p>\n<pre><code>export const IdeaBestComponent = root.lets  .component()  .loader(async () =&gt; {    const bestIdea = await prisma.idea.findFirst({      orderBy: {        rating: 'desc',      },    })  })  .component(({ data: { bestIdea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{bestIdea.title}&lt;\/h1&gt;    &lt;\/div&gt;  ))export const ideaPage = root.lets  .page('\/idea\/:id')  .onPrefetchPage(async ({ location }) =&gt; {    await Promise.all([      ideaViewQuery.prefetchQuery({ id: location.params.id }),      IdeaBestComponent.prefetchQuery(),    ])  })  .with(ideaViewQuery, ({ params }) =&gt; ({ id: params.id }))  .page(({ data: { idea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;{idea.title}&lt;\/h1&gt;    &lt;\/div&gt;  ))<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u0435\u0441\u043b\u0438 \u0432\u0430\u043c \u0432\u0430\u0436\u043d\u043e \u0438\u0437\u0431\u0435\u0433\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0445 \u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u043e\u0432, \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 <code>.prefetchPageOnNavigate('serverAndClientQuery')<\/code> \u0438 \u0434\u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0439\u0442\u0435 \u0432\u0441\u0451 \u0447\u0442\u043e \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0432 <code>.onPrefetchPage()<\/code>.<\/p>\n<p>\u0410 \u043f\u0435\u0440\u0432\u044b\u0439 \u0437\u0430\u0445\u043e\u0434 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u043e \u043f\u0440\u044f\u043c\u043e\u0439 \u0441\u0441\u044b\u043b\u043a\u0435 \u0440\u0435\u0448\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u043c \u0436\u0435 \u0441\u0430\u043c\u044b\u043c <code>.onPrefetchPage()<\/code> \u2014 \u043e\u043d \u0438 \u0442\u0430\u043a \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u043e\u0434\u0438\u043d \u0440\u0430\u0437 \u043f\u0435\u0440\u0435\u0434 \u043f\u0435\u0440\u0432\u044b\u043c \u0440\u0435\u043d\u0434\u0435\u0440\u043e\u043c, \u0442\u0430\u043a \u0447\u0442\u043e \u0432\u0441\u0451, \u0447\u0442\u043e \u0432\u044b \u0442\u0430\u043c \u043f\u0440\u043e\u0433\u0440\u0435\u043b\u0438, \u0443\u0436\u0435 \u043b\u0435\u0436\u0438\u0442 \u0432 \u043a\u044d\u0448\u0435, \u0438 \u0446\u0438\u043a\u043b \u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u043e\u0432 \u0441\u0445\u043b\u043e\u043f\u044b\u0432\u0430\u0435\u0442\u0441\u044f. \u0410 \u0435\u0441\u043b\u0438 \u043b\u043e\u0430\u0434\u0435\u0440\u044b \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0443\u043a\u0430\u0437\u0430\u043d\u044b \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u0430 \u043d\u0435 \u0447\u0435\u0440\u0435\u0437 <code>.with(query)<\/code>, \u043c\u043e\u0436\u043d\u043e \u0434\u0430\u0436\u0435 \u043d\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0435\u0432 \u0440\u0443\u043a\u0430\u043c\u0438 \u2014 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u0435 <code>prefetchLoadersBeforePageRender<\/code>, \u0438 point0 \u0441\u0430\u043c \u0437\u0430\u043f\u0440\u0435\u0444\u0435\u0442\u0447\u0438\u0442 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u043b\u043e\u0430\u0434\u0435\u0440\u044b \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0438 \u0435\u0451 \u043b\u044d\u0439\u043e\u0443\u0442\u043e\u0432. \u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 <code>allowedRerendersCount: 0<\/code>, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u043e\u0434\u043d\u043e \u0443\u0431\u0440\u0430\u0442\u044c \u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u044b \u043d\u0430 \u0441\u0442\u0430\u0431\u0438\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0441\u0442\u043e\u0440\u0430\/\u043a\u0443\u043a:<\/p>\n<pre><code>export const engine = Engine.create({  \/\/ ...  ssr: {    prefetchLoadersBeforePageRender: true,    allowedRerendersCount: 0,  },})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u043e\u0433\u0434\u0430 \u043f\u0435\u0440\u0435\u0434 \u0440\u0435\u043d\u0434\u0435\u0440\u043e\u043c \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u0431\u0443\u0434\u0443\u0442 \u0437\u0430\u043f\u0440\u0435\u0444\u0435\u0442\u0447\u0435\u043d\u044b <code>.loader()<\/code>-\u043a\u0432\u0435\u0440\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0438 \u0435\u0451 \u043b\u044d\u0439\u043e\u0443\u0442\u043e\u0432 (\u0441 \u0438\u043d\u043f\u0443\u0442\u0430\u043c\u0438 \u0438\u0437 \u0440\u043e\u0443\u0442\u0430) \u0438 \u0432\u044b\u0437\u0432\u0430\u043d\u044b \u0432\u0441\u0435 \u0445\u0443\u043a\u0438 <code>onPrefetchPage()<\/code>, \u0442\u0430\u043a \u0447\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0451\u0442 \u0442\u043e\u043b\u044c\u043a\u043e 1 \u0440\u0435\u043d\u0434\u0435\u0440. <code>prefetchLoadersBeforePageRender<\/code> \u0442\u0440\u043e\u0433\u0430\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043a\u0432\u0435\u0440\u0438, \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u0435 \u0447\u0435\u0440\u0435\u0437 <code>.loader()<\/code> \u2014 \u0442\u0435, \u0447\u0442\u043e \u0432\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0447\u0435\u0440\u0435\u0437 <code>.with()<\/code>, \u0431\u0435\u0440\u0443\u0442 \u0438\u043d\u043f\u0443\u0442\u044b \u043d\u0430 \u044d\u0442\u0430\u043f\u0435 \u0440\u0435\u043d\u0434\u0435\u0440\u0430 \u0438 \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u043e\u0431\u043d\u0430\u0440\u0443\u0436\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u043e\u043c, \u0442\u0430\u043a \u0447\u0442\u043e \u0438\u0445 \u0433\u0440\u0435\u0439\u0442\u0435 \u0432 <code>.onPrefetchPage()<\/code> \u0441\u0430\u043c\u0438.<\/p>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043d\u0430\u0434\u043e \u043f\u043e\u043d\u0438\u043c\u0430\u0442\u044c, \u0447\u0442\u043e \u043a\u043e\u0434, \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u0439 \u0432 <code>.onPrefetchPage()<\/code> \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0432\u044b\u0437\u0432\u0430\u043d \u043a\u0430\u043a \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u0442\u0430\u043a \u0438 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 (\u0438\u043b\u0438 \u0437\u0430\u043a\u0440\u0435\u043f\u0438\u0442\u0435 \u0435\u0433\u043e \u0437\u0430 \u043e\u0434\u043d\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u043e\u0439 \u0447\u0435\u0440\u0435\u0437 <code>.serverOnPrefetchPage()<\/code> \/ <code>.clientOnPrefetchPage()<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b\u0440\u0435\u0437\u0430\u044e\u0442 \u0442\u0435\u043b\u043e \u0438\u0437 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0431\u0430\u043d\u0434\u043b\u0430). \u041d\u043e \u043d\u0435\u0442 \u043d\u0438\u043a\u0430\u043a\u043e\u0439 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u0447\u0442\u043e\u0431\u044b \u043f\u043e-\u043f\u0440\u0435\u0436\u043d\u0435\u043c\u0443 \u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0430\u043c <code>ideaViewQuery.prefetchQuery({ id: location.params.id })<\/code>, \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0437\u0430\u043f\u0440\u043e\u0441 \u0443\u0439\u0434\u0451\u0442 \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0432 \u0438\u043d\u0442\u0435\u0440\u043d\u0435\u0442\u0435. \u0410 \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d\u043e \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440\u0435, \u0442\u043e \u0442\u043e\u0442 \u0436\u0435 \u0441\u0430\u043c\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u0432 \u043e\u0431\u0445\u043e\u0434 \u0441\u0435\u0442\u0438 \u0443\u0439\u0434\u0451\u0442 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0432 <code>engine.fetch(request)<\/code> \u0441 \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435\u043c \u0432\u0441\u0435\u0445 \u0445\u0435\u0434\u0435\u0440\u043e\u0432, \u043a\u0443\u043a\u0438\u0441\u043e\u0432 \u0438 \u043f\u0440\u043e\u0447\u0435\u0433\u043e \u043e\u0442 \u0438\u0437\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<p>\u041d\u043e \u0447\u0435\u0441\u0442\u043d\u043e, \u043c\u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f, \u043f\u0440\u043e\u0441\u0442\u043e \u043c\u043d\u043e\u0433\u043e\u043a\u0440\u0430\u0442\u043d\u043e \u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u0442\u044c, \u043e\u0447\u0435\u043d\u044c \u0443\u0434\u043e\u0431\u043d\u043e. \u042f \u0434\u0443\u043c\u0430\u044e, \u0435\u0441\u043b\u0438 \u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u043d\u0435\u0442 \u0433\u0438\u0433\u0430\u043d\u0442\u0441\u043a\u043e\u0439 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0438, \u0442\u043e \u0432\u044b \u044d\u0442\u043e\u0433\u043e \u0434\u0430\u0436\u0435 \u043d\u0435 \u043f\u043e\u0447\u0443\u0432\u0441\u0442\u0432\u0443\u0435\u0442\u0435. \u0410 \u0435\u0441\u043b\u0438 \u043d\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u043f\u043e\u044f\u0432\u0438\u0442\u0441\u044f, \u0432\u0441\u0435\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0434\u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0432 \u043e\u0441\u043e\u0431\u043e \u0447\u0443\u0432\u0441\u0442\u0432\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043c\u0435\u0441\u0442\u0430\u0445 <code>.onPrefetchPage()<\/code> \u0438 \u043f\u043e\u043c\u0435\u043d\u044f\u0442\u044c \u043f\u043e\u043b\u0438\u0442\u0438\u043a\u0443 \u043d\u0430 <code>.prefetchPageOnNavigate('serverAndClientQuery')<\/code>, \u043d\u0435 \u0438\u0437\u043c\u0435\u043d\u044f\u044f \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0443\u0447\u0430\u0441\u0442\u043a\u0438 \u043a\u043e\u0434\u0430.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c <code>.on('engineFetchSettled', (event) =&gt; console.log(event.data.request.renders))<\/code> \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0434\u0441\u043a\u0430\u0436\u0435\u0442 \u0432\u0430\u043c, \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u043e\u0432 \u0441\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043c\u0435\u0442\u0440\u0438\u043a\u0438, \u0438 \u043f\u0440\u0430\u0432\u0438\u0442\u044c \u043f\u0440\u0438\u0446\u0435\u043b\u044c\u043d\u043e \u0432 \u0442\u0435\u0445 \u043c\u0435\u0441\u0442\u0430\u0445, \u0433\u0434\u0435 \u043c\u043d\u043e\u0433\u043e \u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u043e\u0432.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/ssr\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e SSR<\/a>.<\/p>\n<h2>SsrStore<\/h2>\n<p>\u0410 \u0440\u0430\u0437 \u0443\u0436 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0434\u0435\u043b\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440, \u0442\u0430\u043a \u0434\u0430\u0432\u0430\u0439 \u0442\u0443\u0442 \u0436\u0435 \u0442\u043e\u0433\u0434\u0430 \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u0441\u0442\u043e\u0440 \u0432\u0432\u0435\u0434\u0451\u043c. \u042f \u0441\u043e\u043c\u043d\u0435\u0432\u0430\u043b\u0441\u044f \u0432 \u0442\u043e\u043c, \u043c\u043e\u0436\u0435\u0442 \u043b\u0438 \u043e\u043d \u0432\u043e\u043e\u0431\u0449\u0435 \u0431\u044b\u0442\u044c \u043f\u043e\u043b\u0435\u0437\u0435\u043d. \u041d\u043e \u043f\u043e\u0442\u043e\u043c \u044f \u0441\u0442\u043e\u043b\u043a\u043d\u0443\u043b\u0441\u044f \u0441 \u0442\u0430\u043a\u043e\u0439 \u0441\u0438\u0442\u0443\u0430\u0446\u0438\u0435\u0439.<\/p>\n<pre><code>import { create } from 'zustand\/react'const useBreadcrumb = create&lt;{  items: Array&lt;[string, string]&gt;  setItems: (items: Array&lt;[string, string]&gt;) =&gt; void}&gt;((set) =&gt; ({  items: [],  setItems: (items) =&gt; set({ items }),}))export const adminLayout = root.lets  .layout('\/admin')  .layout(({ children }) =&gt; {    const items = useBreadcrumb((state) =&gt; state.items)    return (      &lt;div&gt;        &lt;div id=\"header\"&gt;          &lt;h1&gt;Admin Panel&lt;\/h1&gt;          &lt;div id=\"breadcrumb\"&gt;            {items.map(([label, href]) =&gt; (              &lt;a key={href} href={href}&gt;                {label}              &lt;\/a&gt;            ))}          &lt;\/div&gt;        &lt;\/div&gt;        &lt;div id=\"content\"&gt;{children}&lt;\/div&gt;      &lt;\/div&gt;    )  })  .layout()export const adminUsersPage = adminLayout.lets  .page('\/users')  .page(({ data: { idea } }) =&gt; {    const setItems = useBreadcrumb((state) =&gt; state.setItems)    useEffect(() =&gt; {      setItems([        ['Dashboard', '\/admin'],        ['Users', '\/users'],      ])    }, [setItems])    return (      &lt;div&gt;        &lt;h1&gt;{idea.title}&lt;\/h1&gt;      &lt;\/div&gt;    )  })<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u0442\u0430\u043a-\u0442\u043e \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u043d\u043e \u043f\u043e\u0441\u043b\u0435 \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0440\u0435\u043d\u0434\u0435\u0440\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0443 \u043c\u0435\u043d\u044f \u0445\u043b\u0435\u0431\u043d\u044b\u0435 \u043a\u0440\u043e\u0448\u043a\u0438 \u0431\u044b\u043b\u0438 \u043f\u0443\u0441\u0442\u044b\u043c\u0438! \u0418 \u043f\u043e\u0434\u0433\u0440\u0443\u0437\u0438\u043b\u0438\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u043e\u0441\u043b\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043b\u0441\u044f js, \u0438 \u043e\u043d\u0438 \u0431\u044b\u043b\u0438 \u0432\u044b\u0441\u0447\u0438\u0442\u0430\u043d\u044b. \u042f \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c SsrStore. \u041c\u043e\u0436\u043d\u043e \u043f\u043e\u0434\u0443\u043c\u0430\u0442\u044c, \u0447\u0442\u043e \u043e\u043d\u043e \u0442\u043e\u0433\u043e \u043d\u0435 \u0441\u0442\u043e\u0438\u0442, \u0438 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043a\u0430\u043a-\u0442\u043e \u0438\u043d\u0430\u0447\u0435 \u0432\u043e\u043f\u0440\u043e\u0441 \u0440\u0435\u0448\u0438\u0442\u044c. \u041d\u043e \u044f \u0434\u0443\u043c\u0430\u044e, \u043c\u044b \u0435\u0449\u0451 \u043d\u0430\u0439\u0434\u0451\u043c \u0445\u043e\u0440\u043e\u0448\u0438\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0434\u043b\u044f SsrStore, \u0438 \u043f\u0443\u0441\u0442\u044c \u044d\u0442\u0438 \u0445\u043b\u0435\u0431\u043d\u044b\u0435 \u043a\u0440\u043e\u0448\u043a\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u0442\u0430\u043d\u0443\u0442 \u043f\u043e\u0432\u043e\u0434\u043e\u043c \u0441\u043e\u0437\u0434\u0430\u0442\u044c SsrStore.<\/p>\n<pre><code>import { SsrStore } from '@point0\/core\/ssr-store'import { useEffectSsr } from '@point0\/core'export const $breadcrumb = SsrStore.define&lt;Array&lt;[string, string]&gt;&gt;(  \/\/ \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u0430 \u0432 ssr store  'breadcrumb',  \/\/ \u0444\u0443\u043d\u043a\u0446\u0438\u044f, \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u044e\u0449\u0430\u044f \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435  () =&gt; [],)export const adminLayout = root.lets  .layout('\/admin')  .layout(({ children }) =&gt; {    const items = $breadcrumb.use()    return (      &lt;div&gt;        &lt;div id=\"header\"&gt;          &lt;h1&gt;Admin Panel&lt;\/h1&gt;          &lt;div id=\"breadcrumb\"&gt;            {items.map(([label, href]) =&gt; (              &lt;a key={href} href={href}&gt;                {label}              &lt;\/a&gt;            ))}          &lt;\/div&gt;        &lt;\/div&gt;        &lt;div id=\"content\"&gt;{children}&lt;\/div&gt;      &lt;\/div&gt;    )  })  .layout()export const adminUsersPage = adminLayout.lets  .page('\/users')  .page(({ data: { idea } }) =&gt; {    \/\/ \u044d\u0442\u043e \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u044d\u0444\u0444\u0435\u043a\u0442, \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u043e \u0432\u0440\u0435\u043c\u044f ssr \u043e\u043d \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0437\u0432\u0430\u043d \u043c\u0433\u043d\u043e\u0432\u0435\u043d\u043d\u043e,    \/\/ \u0430 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u043f\u043e \u043f\u0440\u0430\u0432\u0438\u043b\u0430\u043c \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e useEffect    useEffectSsr(() =&gt; {      $breadcrumb.set([        ['Dashboard', '\/admin'],        ['Users', '\/users'],      ])    }, [])    return (      &lt;div&gt;        &lt;h1&gt;{idea.title}&lt;\/h1&gt;      &lt;\/div&gt;    )  })<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0443\u0442 \u0432\u0441\u0451 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0442\u0430\u043a. \u0420\u0435\u043d\u0434\u0435\u0440\u0438\u043c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443. \u0415\u0441\u043b\u0438 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0441\u0442\u043e\u0440\u0430 \u0431\u044b\u043b\u043e \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u043e, \u0440\u0435\u0440\u0435\u043d\u0434\u0435\u0440\u0438\u043c, \u0438 \u0442\u0430\u043a \u0434\u043e \u0442\u0435\u0445 \u043f\u043e\u0440, \u043f\u043e\u043a\u0430 \u043d\u0435 \u0441\u0442\u0430\u0431\u0438\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u0442\u0441\u044f. \u0422\u043e \u0435\u0441\u0442\u044c \u043d\u0435 \u043d\u0430\u0434\u043e \u0437\u0430\u0441\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0442\u0443\u0434\u0430 new Date(), \u0438 \u0442\u043e, \u0447\u0442\u043e \u043f\u0440\u0438\u043d\u0446\u0438\u043f\u0438\u0430\u043b\u044c\u043d\u043e \u043d\u0435 \u0441\u0435\u0440\u0438\u0430\u043b\u0438\u0437\u0443\u0435\u0442\u0441\u044f. \u0417\u0430\u0442\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0432\u0448\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 index.html. \u0410 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u043f\u0440\u0438 \u0437\u0430\u043f\u0440\u043e\u0441\u0435 \u0445\u043b\u0435\u0431\u043d\u044b\u0445 \u043a\u0440\u043e\u0448\u0435\u043a, \u043c\u044b \u0443\u0436\u0435 \u0437\u043d\u0430\u0435\u043c \u0444\u0438\u043d\u0430\u043b\u044c\u043d\u043e\u0435 \u0432\u044b\u0447\u0438\u0441\u043b\u0435\u043d\u043d\u043e\u0435 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0438 \u043a\u0440\u043e\u0448\u043a\u0438 \u0441\u0440\u0430\u0437\u0443 \u0432\u0438\u0434\u043d\u044b.<\/p>\n<p>\u041e\u0442\u043c\u0435\u0447\u0443, \u0447\u0442\u043e \u0441\u0432\u044f\u0437\u044c \u0437\u0434\u0435\u0441\u044c \u043e\u0434\u043d\u043e\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u044f\u044f. \u0414\u0430\u043d\u043d\u044b\u0435 \u0443\u0445\u043e\u0434\u044f\u0442 \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442, \u043d\u043e \u043d\u0435 \u0443\u0445\u043e\u0434\u044f\u0442 \u0441 \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u043d\u0430 \u0441\u0435\u0440\u0432\u0435\u0440. \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u0442\u043e\u0440 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435, \u043e\u043d \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0441\u0442\u043e\u0440. \u0421\u0432\u044f\u0437\u044c \u0432 SsrStore \u043e\u0434\u043d\u043e\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u044f\u044f \u043d\u0430\u0440\u043e\u0447\u043d\u043e, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e, \u0434\u043b\u044f \u0434\u0432\u0443\u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u0439 \u0441\u0432\u044f\u0437\u0438 \u043c\u0435\u0436\u0434\u0443 \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u043c \u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u043e\u043c \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c CookieStore.<\/p>\n<p>\u0422\u0430\u043a\u0436\u0435 \u043e\u0442\u043c\u0435\u0447\u0443, \u0447\u0442\u043e SsrStore \u0432\u043e\u0432\u0441\u0435 \u043d\u0435 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u0435\u0441\u043b\u0438 \u043e\u043d \u0432\u0430\u043c \u043d\u0435 \u043d\u0443\u0436\u0435\u043d, \u043e\u043d \u0434\u0430\u0436\u0435 \u043d\u0435 \u0432\u043e\u0439\u0434\u0451\u0442 \u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u0431\u0430\u043d\u0434\u043b.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/ssr-store\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e SsrStore<\/a>.<\/p>\n<h2>CookieStore<\/h2>\n<p>\u0412\u043e\u043e\u0431\u0449\u0435 \u0441 \u043a\u0443\u043a\u0430\u043c\u0438, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0438 \u0431\u0435\u0437 CookieStore. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u043f\u043e\u043a\u0430\u0436\u0443, \u043a\u0430\u043a \u043c\u044b \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u043c \u0441 \u043d\u0438\u043c\u0438 \u043d\u0430 \u0431\u0430\u0437\u043e\u0432\u043e\u043c \u0443\u0440\u043e\u0432\u043d\u0435:<\/p>\n<pre><code>\/\/ auth \u2014 \u0432\u0430\u0448\u0438 \u0445\u0435\u043b\u043f\u0435\u0440\u044b \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0438\/\/ \u0442\u043e \u0435\u0441\u0442\u044c \u043d\u0435 \u0447\u0430\u0441\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430, \u0430 \u0432\u0430\u0448 \u043a\u043e\u0434import auth from '@\/lib\/auth'export const signInMutation = root.lets  .mutation()  .input(z.object({ email: z.string(), password: z.string() }))  .loader(async ({ input, set }) =&gt; {    const { token, user } = await auth.signIn(input)    set.cookies('token', token, {      httpOnly: true,    })    return { user }  })export const updateProfileMutation = root.lets  .mutation()  .input(z.object({ name: z.string() }))  .loader(async ({ input, request, set }) =&gt; {    const token = request.cookies['token']    const { user } = await auth.verifyToken(token)    const updatedUser = await prisma.user.update({      where: { id: user.id },      data: { name: input.name },    })    return { user: updatedUser }  })  .mutation()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0418 \u0434\u043b\u044f \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0448\u0442\u0443\u043a, \u044d\u0442\u043e \u0431\u0443\u0434\u0442\u043e \u0431\u044b \u0434\u0430\u0436\u0435 \u0438 \u0445\u043e\u0440\u043e\u0448\u043e \u0442\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c, \u043d\u043e \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u0442\u0441\u044f \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043f\u043e\u043c\u043d\u0438\u0442\u044c \u043f\u043e\u0434 \u043a\u0430\u043a\u0438\u043c \u043a\u043b\u044e\u0447\u043e\u043c \u043c\u044b \u043a\u0430\u043a\u0443\u044e \u043a\u0443\u043a\u0443 \u0437\u0430\u043f\u0438\u0441\u0430\u043b\u0438. \u041d\u0443 \u0438 \u043a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u044f \u043e\u0431\u044b\u0447\u043d\u043e \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u044e \u0434\u0435\u043b\u0430\u044e \u0447\u0435\u0440\u0435\u0437 better-auth, \u0430 \u0442\u0430\u043c \u043e\u043d \u0441\u0430\u043c \u0432\u0441\u0435\u043c \u044d\u0442\u0438\u043c \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442. \u0422\u0435\u043c \u043d\u0435 \u043c\u0435\u043d\u0435\u0435 \u0432\u0441\u0451 \u044d\u0442\u043e \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u043e \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u043d\u0430 CookieStore.<\/p>\n<pre><code>const $token = CookieStore.define&lt;string&gt;({ name: 'token', httpOnly: true })export const root = Point0.lets  .root()  \/\/ ...  .plugin(CookieStore.plugin())  \/\/ ...  .root()export const signInMutation = root.lets  .mutation()  .input(z.object({ email: z.string(), password: z.string() }))  .loader(async ({ input, set }) =&gt; {    const { token, user } = await auth.signIn(input)    $token.set(token)    return { user }  })export const updateProfileMutation = root.lets  .mutation()  .input(z.object({ name: z.string() }))  .loader(async ({ input, request, set }) =&gt; {    const token = $token.get()    const { user } = await auth.verifyToken(token)    const updatedUser = await prisma.user.update({      where: { id: user.id },      data: { name: input.name },    })    return { user: updatedUser }  })  .mutation()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0443\u0442 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0437\u0430\u043c\u0435\u0442\u0438\u0442\u044c, \u0447\u0442\u043e \u043c\u044b \u043d\u0435 \u043f\u0440\u043e\u043a\u0438\u0434\u044b\u0432\u0430\u0435\u043c \u0432 $token \u0441\u0430\u043c request, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u0440\u043e\u0434\u0435 \u043a\u0430\u043a \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u0434\u043e\u0441\u0442\u0430\u0442\u044c \u043a\u0443\u043a\u0438. \u042d\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u043f\u043e\u0442\u043e\u043c\u0443, \u0447\u0442\u043e CookieStore \u043c\u043e\u0436\u0435\u0442 \u0438 \u0441\u0430\u043c \u0434\u043e\u0441\u0442\u0430\u0442\u044c request \u0438\u0437 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e request \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 node async storage, \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u043c\u044b \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u0432\u0435\u0441\u044c \u043a\u043e\u0434 \u043f\u0435\u0440\u0435\u0434 \u043d\u0430\u0447\u0430\u043b\u043e\u043c \u0438\u0441\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430.<\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c, \u043a\u0430\u043a \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c CookieStore \u0434\u043b\u044f \u043a\u0443\u043a, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044e\u0442\u0441\u044f \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435 \u0438 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435. \u041d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 \u0442\u0451\u043c\u043d\u0430\u044f \u0438\u043b\u0438 \u0441\u0432\u0435\u0442\u043b\u0430\u044f \u0442\u0435\u043c\u0430.<\/p>\n<pre><code>import { useHead } from '@unhead\/react'import { CookieStore } from '@point0\/core\/cookie-store'type ColorMode = 'dark' | 'light'export const $colorMode = CookieStore.define&lt;ColorMode&gt;('color-mode')\/\/ \u0418\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u043a\u0430\u043a \u043a\u043d\u043e\u043f\u043a\u0443 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u0441\u0445\u0435\u043c\u044bexport const ThemeSwitcher = () =&gt; {  const colorMode = $colorMode.use()  return (    &lt;button      onClick={() =&gt; $colorMode.set(colorMode === 'dark' ? 'light' : 'dark')}    &gt;      {colorMode}    &lt;\/button&gt;  )}\/\/ \u0412\u043e\u0442\u043a\u043d\u0438\u0442\u0435 \u044d\u0442\u043e \u0432 app.client.tsxexport const ThemeProvider = () =&gt; {  const colorMode = $colorMode.use()  useHead({    htmlAttrs: {      class: {        dark: colorMode === 'dark',        light: colorMode === 'light',      },    },  })  return null}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u0441 \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u043f\u0440\u0438\u043b\u0435\u0442\u0430\u0435\u0442 html \u0441\u0440\u0430\u0437\u0443 \u0441 \u043a\u043b\u0430\u0441\u0441\u043e\u043c dark \u0438\u043b\u0438 light, \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a\u043e\u0439 \u0446\u0432\u0435\u0442 \u0440\u0435\u0436\u0438\u043c\u0430 \u043c\u044b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438 \u0432 \u043a\u0443\u043a\u0443. \u0410 \u043d\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u043a\u0430\u043a \u043e\u0431\u044b\u0447\u043d\u044b\u0439 \u0440\u0435\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0441\u0442\u043e\u0440.<\/p>\n<p>\u0412 CookieStore \u0435\u0449\u0451 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u0435\u0441\u0442\u044c, \u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043d\u0435 \u043f\u0440\u0438\u043c\u0438\u0442\u0438\u0432\u044b, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u0440\u0438\u043c\u0435\u043d\u0438\u0442\u044c \u043a \u043d\u0438\u043c \u0442\u0440\u0430\u043d\u0441\u0444\u043e\u0440\u043c\u0435\u0440 \u043f\u043e \u0442\u0438\u043f\u0443 superjson. \u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438.<\/p>\n<p>\u041a\u0430\u043a \u0438 SsrStore, CookieStore \u0442\u043e\u0436\u0435 \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u0438 \u0435\u0441\u043b\u0438 \u0435\u0433\u043e \u043d\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c, \u0442\u043e \u043e\u043d \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u0432\u043a\u043b\u044e\u0447\u0451\u043d \u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u0431\u0430\u043d\u0434\u043b.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/cookie-store\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e CookieStore<\/a>.<\/p>\n<h2>Testing<\/h2>\n<p>\u041a\u0430\u043a \u0438 \u043b\u044e\u0431\u043e\u0435 \u043e\u0431\u044b\u0447\u043d\u043e\u0435 \u0444\u0443\u043b\u0441\u0442\u0435\u043a \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e playwright. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432 \u0434\u0435\u0432 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0438, \u043b\u0438\u0431\u043e \u0431\u0438\u043b\u0434\u0438\u043c \u0435\u0433\u043e \u0438 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c. \u0414\u0430\u043b\u0435\u0435 \u043e\u0431\u044b\u0447\u043d\u044b\u0435 playwright \u0442\u0435\u0441\u0442\u044b.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0445\u043e\u0442\u0438\u0442\u0435 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0435 \u0442\u0435\u0441\u0442\u044b, \u0431\u0435\u0437 \u043f\u043e\u0434\u043d\u044f\u0442\u0438\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430 \u0434\u043b\u044f \u0442\u0435\u0441\u0442\u0430 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u0432, \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a:<\/p>\n<pre><code>\/\/ src\/test\/setup\/preload.int.test.tsimport { engine } from '@\/engine'await import('@\/preload')\/\/ \u042d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0437\u0430\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 engine \u043f\u0440\u043e\u0447\u0438\u0442\u0430\u0442\u044c \u043f\u043e\u0434\u0433\u0440\u0443\u0436\u0435\u043d\u043d\u044b\u0435 \u0432 \u043d\u0435\u0451 \u043f\u043e\u0438\u043d\u0442\u044b.\/\/ \u041a\u043e\u0433\u0434\u0430 \u0432 \u043e\u0431\u044b\u0447\u043d\u043e\u043c \u0441\u0435\u0440\u0432\u0435\u0440\u0435 \u043c\u044b \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c engine.serve(), \u044d\u0442\u0430 \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438.\/\/ \u041d\u043e \u0432 \u0438\u043d\u0442\u0435\u0433\u0440\u0430\u0446\u0438\u043e\u043d\u043d\u044b\u0445 \u0442\u0435\u0441\u0442\u0430\u0445 \u043c\u044b \u043d\u0435 \u0445\u043e\u0442\u0438\u043c \u043f\u043e\u0434\u043d\u0438\u043c\u0430\u0442\u044c \u0441\u0435\u0440\u0432\u0435\u0440, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0432\u044b\u0437\u044b\u0432\u0430\u0435\u043c \u044d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0432\u0440\u0443\u0447\u043d\u0443\u044e.\/\/ \u043d\u0435 \u043f\u0443\u0442\u0430\u0442\u044c \u0441 engine.preload(), \u044d\u0442\u043e \u0440\u0430\u0437\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438await engine.prepare()export {}<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>\/\/ bunfig.toml\/\/ \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043b\u0443\u0447\u0448\u0435 \u0438\u043c\u0435\u0442\u044c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 .\/src\/test\/setup\/preload.ts\/\/ \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0438\u044f \u0444\u0430\u0439\u043b\u0430 \u0441 \u0442\u0435\u0441\u0442\u043e\u043c \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0438\u0439 preload\/\/ \u043d\u043e \u0434\u043b\u044f \u043f\u0440\u0438\u043c\u0435\u0440\u0430 \u043f\u043e\u043a\u0430 \u043f\u043e\u0439\u0434\u0451\u0442 \u0438 \u0442\u0430\u043a[test]preload = [\".\/src\/test\/setup\/preload.int.test.ts\"]<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>\/\/ src\/idea\/api.tsdescribe('ideaViewQuery', () =&gt; {  test('returns one idea by id', async () =&gt; {    const user = await createTestUser()    const created = await seedIdea({ authorId: user.id, title: 'Viewable' })    \/\/ engine.withFetch \u044d\u0442\u043e \u043e\u0431\u0451\u0440\u0442\u043a\u0430 \u043d\u0430\u0434 node async storage, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u0434\u043c\u0435\u043d\u0438\u0442\u044c    \/\/ fetch \u0434\u043b\u044f \u043f\u043e\u0438\u043d\u0442\u043e\u0432 \u043f\u043e\u0434 \u043a\u0430\u043f\u043e\u0442\u043e\u043c \u043d\u0430 engine.fetch    const result = await engine.withFetch(async () =&gt; {      return await ideaViewQuery.fetchServer({ id: created.id })    })    \/\/ \u0437\u0434\u0435\u0441\u044c result \u0432\u0435\u0440\u043d\u043e \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d, \u0438 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u0435\u043c, \u0447\u0442\u043e \u0432\u0435\u0440\u043d\u0443\u043b \u043b\u043e\u0430\u0434\u0435\u0440 \u043a\u0432\u0435\u0440\u0438    expect(result.idea.title).toBe('Viewable')    expect(result.idea.author.id).toBe(user.id)  })})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/testing\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u0442\u0435\u0441\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435<\/a>.<\/p>\n<h2>\u0418 \u0444\u0443\u043b\u0441\u0442\u0435\u043a\u0430\u043c, \u0438 \u0431\u044d\u043a\u0435\u043d\u0434\u0435\u0440\u0430\u043c, \u0438 \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0435\u0440\u0430\u043c.<\/h2>\n<p>\u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e Point0 \u044d\u0442\u043e \u0444\u0443\u043b\u0441\u0442\u0435\u043a \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a, \u043d\u0438\u0447\u0435\u0433\u043e \u043d\u0435 \u043c\u0435\u0448\u0430\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0444\u0440\u043e\u043d\u0442\u0435\u043d\u0434 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a, \u0438\u043b\u0438 \u043a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0431\u044d\u043a\u0435\u043d\u0434 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a.<\/p>\n<p>\u0424\u0440\u043e\u043d\u0442\u0435\u043d\u0434\u0435\u0440\u044b \u043c\u043e\u0433\u0443\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044e, \u0438 <code>.with()<\/code> \u0445\u0435\u043b\u043f\u0435\u0440\u044b \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u0441\u0432\u043e\u0438\u0445 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u041c\u043e\u0433\u0443\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c BFF \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u043a\u0432\u0435\u0440\u0438\/\u043c\u0443\u0442\u0430\u0446\u0438\u0438, \u0438\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0435 \u043b\u043e\u0430\u0434\u0435\u0440\u044b \u0434\u043b\u044f \u0437\u0430\u043f\u0440\u043e\u0441\u0430 \u043a \u0441\u0442\u043e\u0440\u043e\u043d\u043d\u0435\u043c\u0443 \u0441\u0435\u0440\u0432\u0435\u0440\u0443.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u044b \u0431\u044d\u043a\u0435\u043d\u0434\u0435\u0440 \u0438 \u0432\u0430\u0441 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u0430\u043f\u0438, \u0442\u043e\u0433\u0434\u0430 \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u044d\u043a\u0448\u0435\u043d\u044b, \u0441 \u0443\u0434\u043e\u0431\u043d\u043e\u0439 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u0435\u0439 openapi, \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 <code>.ctx()<\/code>, \u0442\u0435\u0441\u0442\u044b \u0431\u0435\u0437 \u043f\u043e\u0434\u043d\u044f\u0442\u0438\u044f \u0441\u0435\u0440\u0432\u0435\u0440\u0430.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/points\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u043f\u043e\u0438\u043d\u0442\u044b<\/a>.<\/p>\n<h2>Bun \u0438\u043b\u0438 Vite<\/h2>\n<p>\u0421\u043d\u0430\u0447\u0430\u043b\u0430 \u044f \u0445\u043e\u0442\u0435\u043b \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0438\u043c\u0435\u043d\u043d\u043e Bun \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a. \u0418 \u043f\u043e\u043b\u0443\u0447\u0430\u043b\u043e\u0441\u044c \u0445\u043e\u0440\u043e\u0448\u043e. \u041f\u043e\u0442\u043e\u043c \u043d\u0430\u0447\u0430\u043b\u0438\u0441\u044c \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b \u0432\u0441\u044f\u043a\u043e\u0433\u043e \u0440\u043e\u0434\u0430, \u0438 \u044f \u043f\u043e\u0434\u0443\u043c\u0430\u043b, \u0447\u0442\u043e \u043d\u0430\u0432\u0435\u0440\u043d\u043e\u0435 \u043d\u0430\u0434\u043e \u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Vite \u043a\u0430\u043a \u043e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u0443\u044e \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c. \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043b Vite. \u041e\u043f\u044f\u0442\u044c \u0431\u044b\u043b\u0438 \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u044b, \u043d\u043e \u0432 \u0438\u0442\u043e\u0433\u0435 Vite \u0441\u0442\u0430\u043b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043b\u0443\u0447\u0448\u0435 \u0447\u0435\u043c \u0447\u0438\u0441\u0442\u044b\u0439 Bun \u0432\u043d\u0443\u0442\u0440\u0438 Point0. \u041f\u043e\u0442\u043e\u043c \u044f \u0441\u043e\u0431\u0440\u0430\u043b\u0441\u044f \u0441 \u0441\u0438\u043b\u0430\u043c\u0438 \u0438 \u0434\u043e\u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043b Bun. \u0418 \u0432 \u0438\u0442\u043e\u0433\u0435 Bun \u0441\u0442\u0430\u043b \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u043b\u0443\u0447\u0448\u0435, \u0447\u0435\u043c Vite \u0432\u043d\u0443\u0442\u0440\u0438 Point0. Bun \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u0435\u0435, HMR \u043b\u0443\u0447\u0448\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442. \u041a\u0430\u043a \u044f \u0431\u043e\u0440\u043e\u043b\u0441\u044f \u0441 Bun \u0438 Vite, \u044d\u0442\u043e \u0442\u0435\u043c\u0430 \u0434\u043b\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u043e\u0441\u0442\u0430.<\/p>\n<p>\u0412 \u0438\u0442\u043e\u0433\u0435 \u0434\u0438\u0437\u0430\u0439\u043d \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0441\u044f \u0442\u0430\u043a\u043e\u0439, \u0447\u0442\u043e \u0435\u0441\u043b\u0438 \u0432\u0430\u0441 \u0432\u0434\u0440\u0443\u0433 \u043d\u0435 \u0443\u0441\u0442\u0440\u043e\u0438\u0442 \u043e\u0434\u0438\u043d \u0438\u0437 \u0431\u0430\u043d\u0434\u043b\u0435\u0440\u043e\u0432, \u0432\u044b \u043c\u043e\u0436\u0435\u0442\u0435, \u0438\u0437\u043c\u0435\u043d\u0438\u0432 \u043f\u0430\u0440\u0443 \u0444\u0430\u0439\u043b\u043e\u0432, \u043f\u0435\u0440\u0435\u0441\u0435\u0441\u0442\u044c \u043d\u0430 \u0434\u0440\u0443\u0433\u043e\u0439, \u043f\u043e\u0432\u0435\u0434\u0435\u043d\u0438\u0435 \u0440\u0430\u043d\u0442\u0430\u0439\u043c\u0430 \u043e\u0441\u0442\u0430\u043d\u0435\u0442\u0441\u044f \u043f\u0440\u0435\u0436\u043d\u0438\u043c.<\/p>\n<p>\u0415\u0441\u043b\u0438 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0431\u0438\u043b\u0434 \u043e\u043f\u0446\u0438\u0438 \u0434\u043b\u044f bun, \u043f\u0440\u043e\u0441\u0442\u043e \u0434\u043e\u043f\u0438\u0448\u0438\u0442\u0435 \u0438\u0445 \u0432 engine.ts:<\/p>\n<pre><code>import { Engine } from '@point0\/engine'import react from '@vitejs\/plugin-react'import tailwindcss from 'tailwindcss\/vite'export const engine = Engine.create({  \/\/ ...  bunBuildConfig: ({ side, mode, scope }) =&gt; ({    \/\/ \u0441\u0442\u0430\u043d\u0434\u0440\u0430\u0442\u043d\u044b\u0439 Bun.buildConfig \u043c\u043e\u0436\u043d\u043e \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0437\u0434\u0435\u0441\u044c    \/\/ mode - production | development | test \u0432 \u0437\u0430\u0432\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 process.env.NODE_ENV    \/\/ side - server | client \u0432 \u0437\u0430\u0432\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0442\u043e\u0433\u043e, \u0431\u0438\u043b\u0434\u0438\u043c    \/\/ scope - \u044d\u0442\u043e \u0435\u0441\u043b\u0438 \u0443 \u0432\u0430\u0441 \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043a\u043b\u0438\u0435\u043d\u0442\u043e\u0432, \u0442\u043e \u0437\u0434\u0435\u0441\u044c \u0431\u0443\u0434\u0435\u0442 \u0438\u043c\u044f \u0440\u0443\u0442\u0430 \u043a\u043b\u0438\u0435\u043d\u0442\u0430\/\u0441\u0435\u0440\u0432\u0435\u0440\u0430  }),  client: {    \/\/ bunBuildConfig: {}    \/\/ \u043c\u043e\u0436\u043d\u043e \u0438 \u0437\u0434\u0435\u0441\u044c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c  },  server: {    \/\/ bunBuildConfig: {}    \/\/ \u043c\u043e\u0436\u043d\u043e \u0438 \u0437\u0434\u0435\u0441\u044c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c  },})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0415\u0441\u043b\u0438 \u0437\u0430\u0445\u043e\u0442\u0438\u0442\u0435 \u043f\u0435\u0440\u0435\u0441\u0435\u0441\u0442\u044c \u0441 bun \u043d\u0430 vite, \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0434\u043f\u0440\u043e\u043a\u0438\u043d\u0443\u0442\u044c <code>viteConfig<\/code> \u0432 <code>engine.ts<\/code>. \u042d\u0442\u043e \u0437\u0430\u043c\u0435\u043d\u0438\u0442 bun \u043d\u0430 vite \u0438 \u0432 build, \u0438 \u0432 dev \u0440\u0435\u0436\u0438\u043c\u0435.<\/p>\n<pre><code>import { Engine } from '@point0\/engine'import react from '@vitejs\/plugin-react'import tailwindcss from 'tailwindcss\/vite'export const engine = Engine.create({  \/\/ ...  viteConfig: ({ plugins, side, mode }) =&gt; ({    \/\/ \u043d\u0438\u043a\u0430\u043a\u0438\u0445 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a \u043d\u0435 \u043d\u0443\u0436\u043d\u043e, \u043e\u043d\u0438 \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438    \/\/ \u0438\u0441\u0445\u043e\u0434\u044f \u0438\u0437 \u043f\u0440\u043e\u0447\u0438\u0445 \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a engine, \u043d\u043e \u043c\u043e\u0433\u0443\u0442 \u0431\u044b\u0442\u044c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u044b \u0437\u0434\u0435\u0441\u044c.    \/\/ \u042d\u0442\u043e \u043e\u0431\u044a\u0435\u043a\u0442 \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e \u0432\u0430\u0439\u0442 \u043a\u043e\u043d\u0444\u0438\u0433\u0430.    plugins: [      ...plugins, \/\/ \u043f\u043b\u0430\u0433\u0438\u043d \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 Point0 \u0443\u0436\u0435 \u0437\u0434\u0435\u0441\u044c      react(),      tailwindcss(),    ],    \/\/ \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f side (client|server) \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438    \/\/ \u0434\u043b\u044f \u043a\u043b\u0438\u0435\u043d\u0442\u0430 \u0438\u043b\u0438 \u0441\u0435\u0440\u0432\u0435\u0440\u0430  }),  client: {    \/\/ viteConfig: {}    \/\/ \u043c\u043e\u0436\u043d\u043e \u0438 \u0437\u0434\u0435\u0441\u044c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c  },  server: {    \/\/ viteConfig: {}    \/\/ \u043c\u043e\u0436\u043d\u043e \u0438 \u0437\u0434\u0435\u0441\u044c \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c  },})<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/bun-vs-vite\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e Bun \u0438\u043b\u0438 Vite<\/a>.<\/p>\n<h2>Deploy<\/h2>\n<p><code>point0 build<\/code> \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442 \u0432\u0441\u0451 \u0432 <code>dist\/<\/code>: <code>dist\/server<\/code> (\u0441\u0435\u0440\u0432\u0435\u0440) \u0438 <code>dist\/client<\/code> (\u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u0431\u0430\u043d\u0434\u043b, \u0441\u0442\u0430\u0442\u0438\u043a\u0430). \u0417\u0430\u0442\u0435\u043c \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0441\u0435\u0440\u0432\u0435\u0440: <code>bun run .\/dist\/server\/index.server.js<\/code> \u043e\u043d \u0436\u0435 \u0440\u0430\u0437\u0434\u0430\u0451\u0442 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442.<\/p>\n<pre><code>FROM oven\/bun:1WORKDIR \/appCOPY . .RUN bun install &amp;&amp; bun run buildCMD [\"bun\", \"run\", \".\/dist\/server\/index.server.js\"]<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c \u043c\u043e\u0436\u043d\u043e \u0434\u0435\u043f\u043b\u043e\u0438\u0442\u044c\u0441\u044f \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u043a\u0443\u0434\u0430 \u0443\u0433\u043e\u0434\u043d\u043e, \u043d\u0438\u0447\u0435\u0433\u043e \u0441\u043f\u0435\u0446\u0438\u0444\u0438\u0447\u0435\u0441\u043a\u043e\u0433\u043e \u0437\u0434\u0435\u0441\u044c \u043d\u0435\u0442.<\/p>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/deploy\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u0434\u0435\u043f\u043b\u043e\u0439<\/a>.<\/p>\n<h2>Size<\/h2>\n<p>\u0420\u0430\u0437\u043c\u0435\u0440 \u0444\u0430\u0439\u043b\u043e\u0432 Point0 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u043e\u0433\u043e \u0431\u0430\u043d\u0434\u043b\u0430.<\/p>\n<ul>\n<li>\n<p>\u0421\u0430\u043c <code>@point0\/core<\/code>: raw 143.4 KB, gzip 40.9 KB, brotli 36.2 KB<\/p>\n<\/li>\n<li>\n<p>\u041f\u0438\u0440 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c <code>@1gr14\/route0<\/code>: raw 15.0 KB, gzip 4.7 KB, brotli 4.2 KB<\/p>\n<\/li>\n<li>\n<p>\u041f\u0438\u0440 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c <code>@1gr14\/error0<\/code>: raw 3.6 KB, gzip 1.4 KB, brotli 1.3 KB<\/p>\n<\/li>\n<li>\n<p>\u041f\u0438\u0440 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u044c <code>@tanstack\/react-query<\/code>: raw 38.2 KB, gzip 15.9 KB, brotli 14.2<\/p>\n<\/li>\n<\/ul>\n<h2>Examples<\/h2>\n<p>\u0412 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u0435\u0441\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432:<\/p>\n<ul>\n<li>\n<p><strong>basic<\/strong> \u2014 \u043a\u043e\u043b\u043b\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0431\u043b\u043e\u0433 \u0438\u0434\u0435\u0439: SSR, Prisma + SQLite, Tailwind, \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044f, \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b\/\u043b\u044d\u0439\u0430\u0443\u0442\u044b\/\u043a\u0432\u0435\u0440\u0438\/\u043c\u0443\u0442\u0430\u0446\u0438\u0438\/\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430 \u043d\u0430 MDX, \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0430 \u0444\u0430\u0439\u043b\u0430, OpenAPI<\/p>\n<\/li>\n<li>\n<p><strong>vite<\/strong> \u2014 \u0442\u043e \u0436\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u043d\u043e \u043a\u043b\u0438\u0435\u043d\u0442 \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0447\u0435\u0440\u0435\u0437 Vite \u0432\u043c\u0435\u0441\u0442\u043e Bun.<\/p>\n<\/li>\n<li>\n<p><strong>better-auth<\/strong> \u2014 \u0442\u043e\u0442 \u0436\u0435 \u043a\u043e\u043b\u043b\u0435\u043a\u0442\u0438\u0432\u043d\u044b\u0439 \u0431\u043b\u043e\u0433, \u043d\u043e \u0441 \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0451\u043d\u043d\u043e\u0439 \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u0430\u0446\u0438\u0435\u0439 \u0447\u0435\u0440\u0435\u0437 better-auth<\/p>\n<\/li>\n<li>\n<p><strong>capacitor<\/strong> \u2014 \u0443\u043f\u0430\u043a\u043e\u0432\u043a\u0430 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0432 \u043c\u043e\u0431\u0438\u043b\u044c\u043d\u043e\u0435 (iOS\/Android) \u0447\u0435\u0440\u0435\u0437 Capacitor. (\u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0435)<\/p>\n<\/li>\n<li>\n<p><strong>expo<\/strong> \u2014 React Native \u0447\u0435\u0440\u0435\u0437 Expo: \u043e\u0434\u0438\u043d \u0441\u0435\u0440\u0432\u0435\u0440 \u043d\u0430 Bun, \u043e\u0431\u0449\u0438\u0439 \u043a\u043e\u0434 \u043a\u0432\u0435\u0440\u0438\/\u043c\u0443\u0442\u0430\u0446\u0438\u0439, \u0430 \u043a\u043b\u0438\u0435\u043d\u0442 \u2014 \u043d\u0430\u0442\u0438\u0432\u043d\u044b\u0439, \u0441 \u0440\u043e\u0443\u0442\u0435\u0440\u043e\u043c Expo. \u0421\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u0434 \u0432\u044b\u043f\u0438\u043b\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0438\u0437 \u0431\u0430\u043d\u0434\u043b\u0430 \u0447\u0435\u0440\u0435\u0437 Babel-\u043f\u043b\u0430\u0433\u0438\u043d \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430. (\u044d\u043a\u0441\u043f\u0435\u0440\u0438\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e\u0435)<\/p>\n<\/li>\n<\/ul>\n<p>\u041d\u043e \u0447\u0442\u043e\u0431\u044b \u0432\u0430\u043c \u0434\u0430\u043b\u0435\u043a\u043e \u043d\u0435 \u0445\u043e\u0434\u0438\u0442\u044c, \u043f\u043e\u043a\u0430\u0436\u0443 \u0435\u0449\u0451 \u0447\u0430\u0441\u0442\u044c \u043a\u043e\u0434\u0430 \u043f\u0440\u044f\u043c\u043e \u0437\u0434\u0435\u0441\u044c, \u0438\u0437 \u043c\u043e\u0435\u0433\u043e \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d \u0440\u0435\u0434\u0438 \u0431\u043e\u0439\u043b\u0435\u0440\u043f\u043b\u0435\u0439\u0442\u0430 Start0, \u0447\u0442\u043e\u0431\u044b \u0432\u044b \u043c\u043e\u0433\u043b\u0438 \u043f\u043e\u0447\u0443\u0432\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u0434 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<pre><code>\/\/ src\/features\/idea\/api.tsimport { paginateCursor } from '@\/components\/blocks\/pagination'import { AppError } from '@\/lib\/error'import { root } from '@\/lib\/root'import { zz } from '@\/lib\/schema'import { authorizedOnlyPlugin } from '@\/modules\/auth\/plugins'import { prisma } from '@\/modules\/prisma'import { ideaSelect, normalizeIdeaPayload } from '@\/features\/idea\/server'import { z } from 'zod'export const ideaListQuery = root.lets  .infiniteQuery()  .input(    z.object({      ...zz.shape.paginationCursor,      authorSn: zz.sn.optional(),    }),  )  .loader(async ({ input: { limit = 20, cursor, authorSn } }) =&gt; {    const items = await prisma.idea.findMany({      select: ideaSelect,      orderBy: { sn: 'desc' },      take: limit + 1,      where: {        ...(authorSn ? { author: { sn: authorSn } } : {}),        ...(cursor ? { sn: { lte: cursor } } : {}),      },    })    return paginateCursor({      items: items.map(normalizeIdeaPayload),      limit,      cursorKey: 'sn',    })  })  .infiniteQuery({    getNextPageParam: (lastPage) =&gt; lastPage.pagination.nextCursor,    initialPageParam: undefined,    pageParamFromInput: 'cursor',  })export const ideaViewQuery = root.lets  .query()  .input(zz.object.sn)  .loader(async ({ input: { sn } }) =&gt; {    const idea = await prisma.idea.findUniqueOrThrow({      select: ideaSelect,      where: { sn },    })    return { idea: normalizeIdeaPayload(idea) }  })  .query()export const ideaCreateMutationSchema = z.object({  title: z.string().min(1),  content: z.string().min(1),})export const ideaCreateMutation = root.lets  .mutation()  .use(authorizedOnlyPlugin)  .input(ideaCreateMutationSchema)  .loader(async ({ ctx, input: { title, content } }) =&gt; {    const idea = await prisma.idea.create({      select: ideaSelect,      data: { title, content, authorId: ctx.me.user.id },    })    return { idea: normalizeIdeaPayload(idea) }  })  .mutation()export const ideaUpdateMutationSchema = z.object({  sn: zz.sn,  title: z.string().min(1),  content: z.string().min(1),})export const ideaUpdateMutation = root.lets  .mutation()  .use(authorizedOnlyPlugin)  .input(ideaUpdateMutationSchema)  .loader(async ({ ctx, input: { sn, title, content } }) =&gt; {    const existing = await prisma.idea.findUniqueOrThrow({      select: { authorId: true },      where: { sn },    })    if (existing.authorId !== ctx.me.user.id) {      throw new AppError('Only the author can edit this idea', {        code: 'FORBIDDEN',      })    }    const idea = await prisma.idea.update({      select: ideaSelect,      where: { sn },      data: { title, content },    })    return { idea: normalizeIdeaPayload(idea) }  })  .mutation()<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>\/\/ src\/features\/idea\/pages\/list.tsximport { InfiniteScroll } from '@\/components\/blocks\/infinite-scroll'import { Section } from '@\/components\/ui\/section'import { generalLayout } from '@\/layouts\/general'import { IdeaCard } from '@\/features\/idea\/components\/idea-card'import { ideaListQuery } from '@\/features\/idea\/api'import { mePlugin } from '@\/modules\/auth\/plugins'export const ideaListPage = generalLayout.lets  .page('\/ideas')  .head('Ideas')  .use(mePlugin)  .page(({ props: { me } }) =&gt; {    const query = ideaListQuery.useInfiniteQuery()    return (      &lt;Section h1=\"Ideas\"&gt;        &lt;InfiniteScroll          query={query}          loadMoreOnReachEnd          getItemKey={(idea) =&gt; idea.sn}          empty=\"No ideas yet. Be the first to share one.\"          itemClassName=\"border-b border-border last:border-b-0\"          renderItem={(idea) =&gt; &lt;IdeaCard idea={idea} me={me} \/&gt;}        \/&gt;      &lt;\/Section&gt;    )  })<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>\/\/ src\/features\/idea\/pages\/view.tsximport { Button } from '@\/components\/ui\/button'import { Prose } from '@\/components\/ui\/prose'import { Section } from '@\/components\/ui\/section'import { routes } from '@\/generated\/point0\/routes'import { Link } from '@\/lib\/navigation'import { zz } from '@\/lib\/schema'import { formatDate } from '@\/utils\/date'import { generalLayout } from '@\/layouts\/general'import { ideaViewQuery } from '@\/features\/idea\/api'import { isMyIdea } from '@\/features\/idea\/shared'import { mePlugin } from '@\/modules\/auth\/plugins'export const ideaViewPage = generalLayout.lets  .page('\/ideas\/:sn')  .params(zz.object.sn)  .use(mePlugin)  .with(ideaViewQuery, ({ params }) =&gt; ({ sn: +params.sn }))  .head(({ params }) =&gt; `Idea #${params.sn}`)  .page(({ data: { idea }, props: { me } }) =&gt; {    return (      &lt;Section        h1={idea.title}        action={          isMyIdea(idea, me) ? (            &lt;Button              to={routes.ideaEdit({ sn: idea.sn })}              variant=\"outline-secondary\"            &gt;              Edit idea            &lt;\/Button&gt;          ) : undefined        }        description={          &lt;span className=\"flex flex-wrap items-center gap-2\"&gt;            &lt;Link              to={routes.userProfile({ sn: idea.author.sn })}              className=\"hover:text-foreground\"            &gt;              {idea.author.name}            &lt;\/Link&gt;            &lt;span&gt;\u00b7&lt;\/span&gt;            &lt;span&gt;{formatDate(idea.createdAt, 'date-time-nice')}&lt;\/span&gt;            {idea.updatedAt &gt; idea.createdAt ? (              &lt;span&gt;\u00b7 edited {formatDate(idea.updatedAt, 'date-nice')}&lt;\/span&gt;            ) : null}          &lt;\/span&gt;        }      &gt;        &lt;Prose&gt;          &lt;p className=\"whitespace-pre-wrap\"&gt;{idea.content}&lt;\/p&gt;        &lt;\/Prose&gt;      &lt;\/Section&gt;    )  })<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>\/\/ src\/features\/idea\/pages\/new.tsximport { Section } from '@\/components\/ui\/section'import { routes } from '@\/generated\/point0\/routes'import { navigate } from '@\/lib\/navigation'import { generalLayout } from '@\/layouts\/general'import { authorizedOnlyPlugin } from '@\/modules\/auth\/plugins'import { FButton } from '@\/modules\/form\/core\/button'import { FFields, FFooter } from '@\/modules\/form\/core\/layout'import { FForm } from '@\/modules\/form\/core\/provider'import { FInput } from '@\/modules\/form\/fields\/input'import { FTextarea } from '@\/modules\/form\/fields\/textarea'import {  ideaCreateMutation,  ideaCreateMutationSchema,  ideaViewQuery,  ideaListQuery,} from '@\/features\/idea\/api'export const ideaNewPage = generalLayout.lets  .page('\/ideas\/new')  .head('New Idea')  .use(authorizedOnlyPlugin)  .page(() =&gt; {    return (      &lt;Section h1=\"New Idea\"&gt;        &lt;FForm          schema={ideaCreateMutationSchema}          defaultValues={{ title: '', content: '' }}          onSubmit={async ({ title, content }) =&gt; {            const { idea } = await ideaCreateMutation.fetch({ title, content })            void ideaListQuery.invalidateInfiniteQuery(true)            ideaViewQuery.setQueryData({ sn: idea.sn }, { idea })            return { idea }          }}          onSuccess={({ idea }) =&gt; {            void navigate('ideaView', { sn: idea.sn }, { replace: true })          }}          toastOnSuccess=\"Idea published\"          size=\"sm\"        &gt;          &lt;FFields&gt;            &lt;FInput              name=\"title\"              label=\"Title\"              placeholder=\"A short, catchy title\"              inputSize=\"xl\"            \/&gt;            &lt;FTextarea              name=\"content\"              label=\"Content\"              placeholder=\"Share your idea\u2026\"              rows={10}            \/&gt;          &lt;\/FFields&gt;          &lt;FFooter&gt;            &lt;FButton type=\"submit\" size=\"2xl\"&gt;              Publish            &lt;\/FButton&gt;          &lt;\/FFooter&gt;        &lt;\/FForm&gt;      &lt;\/Section&gt;    )  })<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>\/\/ src\/features\/idea\/pages\/edit.tsximport { Button } from '@\/components\/ui\/button'import { Section } from '@\/components\/ui\/section'import {  ideaListQuery,  ideaUpdateMutation,  ideaUpdateMutationSchema,  ideaViewQuery,} from '@\/features\/idea\/api'import { routes } from '@\/generated\/point0\/routes'import { generalLayout } from '@\/layouts\/general'import { navigate } from '@\/lib\/navigation'import { zz } from '@\/lib\/schema'import { FButton } from '@\/modules\/form\/core\/button'import { FFields, FFooter } from '@\/modules\/form\/core\/layout'import { FForm } from '@\/modules\/form\/core\/provider'import { FInput } from '@\/modules\/form\/fields\/input'import { FTextarea } from '@\/modules\/form\/fields\/textarea'export const ideaEditPage = generalLayout.lets  .page('\/ideas\/:sn\/edit')  .params(zz.object.sn)  .with(ideaViewQuery, ({ params }) =&gt; ({ sn: +params.sn }))  .head(({ params }) =&gt; `Edit Idea #${params.sn}`)  .page(({ data: { idea } }) =&gt; {    return (      &lt;Section        h1=\"Edit Idea\"        action={          &lt;Button            to={routes.ideaView({ sn: idea.sn })}            variant=\"outline-secondary\"          &gt;            View idea          &lt;\/Button&gt;        }      &gt;        &lt;FForm          schema={ideaUpdateMutationSchema.pick({ title: true, content: true })}          defaultValues={{ title: idea.title, content: idea.content }}          onSubmit={async ({ title, content }) =&gt; {            const { idea: updated } = await ideaUpdateMutation.fetch({              sn: idea.sn,              title,              content,            })            ideaViewQuery.setQueryData({ sn: updated.sn }, { idea: updated })            void ideaListQuery.invalidateInfiniteQuery(true)            return { idea: updated }          }}          onSuccess={({ idea: updated }) =&gt; {            void navigate('ideaView', { sn: updated.sn }, { replace: true })          }}          toastOnSuccess=\"Idea updated\"          size=\"sm\"        &gt;          &lt;FFields&gt;            &lt;FInput name=\"title\" label=\"Title\" inputSize=\"xl\" \/&gt;            &lt;FTextarea name=\"content\" label=\"Content\" rows={10} \/&gt;          &lt;\/FFields&gt;          &lt;FFooter&gt;            &lt;FButton type=\"submit\" size=\"2xl\"&gt;              Save            &lt;\/FButton&gt;          &lt;\/FFooter&gt;        &lt;\/FForm&gt;      &lt;\/Section&gt;    )  })<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<pre><code>\/\/ src\/features\/idea\/pages\/my.tsximport { InfiniteScroll } from '@\/components\/blocks\/infinite-scroll'import { Section } from '@\/components\/ui\/section'import { ideaListQuery } from '@\/features\/idea\/api'import { IdeaCard } from '@\/features\/idea\/components\/idea-card'import { generalLayout } from '@\/layouts\/general'import { authorizedOnlyPlugin } from '@\/modules\/auth\/plugins'export const myIdeaListPage = generalLayout.lets  .page('\/my\/ideas')  .head('My Ideas')  .use(authorizedOnlyPlugin)  .with(ideaListQuery, ({ props: { me } }) =&gt; ({ authorSn: me.user.sn }))  .page(({ queries: [query], props: { me } }) =&gt; {    return (      &lt;Section h1=\"My Ideas\"&gt;        &lt;InfiniteScroll          query={query}          loadMoreOnReachEnd          getItemKey={(idea) =&gt; idea.sn}          empty=\"You haven't shared any ideas yet.\"          itemClassName=\"border-b border-border last:border-b-0\"          renderItem={(idea) =&gt; &lt;IdeaCard idea={idea} me={me} \/&gt;}        \/&gt;      &lt;\/Section&gt;    )  })<\/code><div class=\"code-explainer\"><a href=\"https:\/\/sourcecraft.dev\/\" class=\"tm-button code-explainer__link\" style=\"visibility: hidden;\"><img style=\"width:14px;height:14px;object-fit:cover;object-position:left;\"\/><\/a><\/div><\/pre>\n<p>\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 <a href=\"https:\/\/1gr14.dev\/point0\/latest\/example-basic\" rel=\"noopener noreferrer nofollow\">\u043f\u0440\u043e \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043f\u0440\u0438\u043c\u0435\u0440<\/a>.<\/p>\n<h2>\u041f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d<\/h2>\n<p>\u041d\u0430 \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u044b\u043f\u0443\u0441\u043a\u0430 \u0441\u0442\u0430\u0442\u044c\u0438 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442 \u0442\u043e\u043b\u044c\u043a\u043e \u043e\u0434\u0438\u043d \u043f\u0440\u043e\u0435\u043a\u0442 \u0432 \u043c\u0438\u0440\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a Point0. \u042d\u0442\u043e \u043c\u043e\u0439 \u0441\u0430\u0439\u0442 <a href=\"https:\/\/1gr14.dev\" rel=\"noopener noreferrer nofollow\">https:\/\/1gr14.dev<\/a><\/p>\n<p>\u042f \u043d\u0435 \u0441\u043e\u0431\u0438\u0440\u0430\u044e\u0441\u044c \u043c\u0435\u043d\u044f\u0442\u044c \u0434\u0438\u0437\u0430\u0439\u043d \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u044f \u0441 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u043c. \u042f \u0430\u0431\u0441\u043e\u043b\u044e\u0442\u043d\u043e \u0434\u043e\u0432\u043e\u043b\u0435\u043d \u0432\u0441\u0435\u043c, \u0447\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u0431\u0438\u043b\u0434\u0435\u0440\u0430 \u0441\u0430\u043c\u0438\u0445 \u043f\u043e\u0438\u043d\u0442\u043e\u0432. \u042f \u0440\u0435\u0444\u0430\u043a\u0442\u043e\u0440\u0438\u043b \u044d\u0442\u043e \u0434\u0435\u0441\u044f\u0442\u043a\u0438 \u0440\u0430\u0437, \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u043c\u043d\u043e\u0433\u0438\u0445 \u043c\u0435\u0441\u044f\u0446\u0435\u0432, \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u0440\u0438\u0448\u0451\u043b \u043a \u0442\u043e\u043c\u0443, \u0447\u0442\u043e \u043c\u044b \u0438\u043c\u0435\u0435\u043c \u0441\u0435\u0439\u0447\u0430\u0441.<\/p>\n<p>\u041d\u0435 \u0438\u0441\u043a\u043b\u044e\u0447\u0435\u043d\u043e, \u0447\u0442\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043f\u043e\u043c\u0435\u043d\u044f\u0435\u0442\u0441\u044f \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043a\u043e\u043d\u0444\u0438\u0433\u0430 <code>engine<\/code>, \u043d\u043e \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u043f\u0440\u043e\u0438\u0437\u043e\u0439\u0434\u0451\u0442, \u0442\u043e \u043f\u043e \u0441\u0443\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0432 \u0432\u0430\u0448\u0438\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430\u0445 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u044e\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0432 \u0444\u0430\u0439\u043b\u0435 <code>engine.ts<\/code>.<\/p>\n<p>\u042f \u043f\u043e\u043d\u044f\u0442\u0438\u044f \u043d\u0435 \u0438\u043c\u0435\u044e, \u043a\u043e\u0433\u0434\u0430 \u043c\u043e\u0436\u043d\u043e \u0441 \u0443\u0432\u0435\u0440\u0435\u043d\u043d\u043e\u0441\u0442\u044c\u044e \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u043e\u0432\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Point0 \u0432 \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d\u0435 \u0432\u0430\u043c. \u042f \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435 \u0437\u043d\u0430\u044e, \u043a\u0430\u043a\u0438\u0435 \u0437\u0434\u0435\u0441\u044c \u043a\u0440\u0438\u0442\u0435\u0440\u0438\u0438. \u042f \u0441\u0435\u0439\u0447\u0430\u0441 \u0431\u0443\u0434\u0443 \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0433\u043e \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432, \u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0434\u043b\u044f \u043c\u043e\u0438\u0445 \u0437\u0430\u043a\u0430\u0437\u0447\u0438\u043a\u043e\u0432.<\/p>\n<p>\u042f \u0441\u043e\u0437\u0434\u0430\u043b \u043f\u0440\u043e\u0434\u0430\u043a\u0448\u0435\u043d \u0440\u0435\u0434\u0438 \u0431\u043e\u0439\u043b\u0435\u0440\u043f\u043b\u0435\u0439\u0442 \u0434\u043b\u044f SaaS \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <a href=\"https:\/\/1gr14.dev\/start0\" rel=\"noopener noreferrer nofollow\">Start0<\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0441\u0442\u0440\u043e\u0435\u043d \u0432\u043e\u043a\u0440\u0443\u0433 Point0. \u041f\u043e\u0434\u043a\u043b\u044e\u0447\u0438\u043b \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043b \u0434\u043b\u044f \u043d\u0435\u0433\u043e \u0432\u0441\u0451 \u043d\u0443\u0436\u043d\u043e\u0435 \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432. \u0421\u0442\u0435\u043a \u0442\u0430\u043a\u043e\u0439:<\/p>\n<ul>\n<li>\n<p>Bun<\/p>\n<\/li>\n<li>\n<p>TypeScript<\/p>\n<\/li>\n<li>\n<p>Point0<\/p>\n<\/li>\n<li>\n<p>React<\/p>\n<\/li>\n<li>\n<p>Tailwind CSS<\/p>\n<\/li>\n<li>\n<p>shadcn\/ui<\/p>\n<\/li>\n<li>\n<p>PostgreSQL<\/p>\n<\/li>\n<li>\n<p>Prisma<\/p>\n<\/li>\n<li>\n<p>better-auth<\/p>\n<\/li>\n<li>\n<p>TanStack Query<\/p>\n<\/li>\n<li>\n<p>TanStack Table<\/p>\n<\/li>\n<li>\n<p>Zod<\/p>\n<\/li>\n<li>\n<p>React Hook Form<\/p>\n<\/li>\n<li>\n<p>Resend<\/p>\n<\/li>\n<li>\n<p>Sentry<\/p>\n<\/li>\n<li>\n<p>Mixpanel<\/p>\n<\/li>\n<li>\n<p>Axiom<\/p>\n<\/li>\n<li>\n<p>LogTape<\/p>\n<\/li>\n<li>\n<p>Playwright<\/p>\n<\/li>\n<li>\n<p>Testing Library<\/p>\n<\/li>\n<li>\n<p>ESLint<\/p>\n<\/li>\n<li>\n<p>Prettier<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0437\u0434\u0435\u0441\u044c: <a href=\"https:\/\/1gr14.dev\/start0\" rel=\"noopener noreferrer nofollow\">https:\/\/1gr14.dev\/start0<\/a><\/p>\n<p>\u041f\u043e \u043c\u0435\u0440\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043c\u043e\u0438\u0445 \u0441\u043e\u0431\u0441\u0442\u0432\u0435\u043d\u043d\u044b\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u043e\u0432 \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0439 \u0441\u0432\u044f\u0437\u0438 \u043e\u0442 \u0432\u0430\u0441, \u0431\u0443\u0434\u0443 \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 \u0431\u043e\u0439\u043b\u0435\u0440\u043f\u043b\u0435\u0439\u0442.<\/p>\n<h2>\u041f\u043b\u0430\u043d\u044b<\/h2>\n<p>\u0421\u0435\u0439\u0447\u0430\u0441 \u0444\u043e\u043a\u0443\u0441 \u043d\u0430 \u0441\u0442\u0430\u0431\u0438\u043b\u044c\u043d\u043e\u0441\u0442\u044c. \u042f \u0431\u0443\u0434\u0443 \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0431\u044b\u0441\u0442\u0440\u043e \u0440\u0435\u0430\u0433\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u0430 \u043b\u044e\u0431\u044b\u0435 <a href=\"https:\/\/github.com\/1gr14\/point0\" rel=\"noopener noreferrer nofollow\">issue \u0432 GitHub<\/a>.<\/p>\n<p>\u0421\u043e\u0431\u0438\u0440\u0430\u044e\u0441\u044c \u043d\u0430 \u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0439 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u0438\u0441\u0430\u0442\u044c \u0433\u0430\u0439\u0434-\u0441\u0442\u0430\u0442\u044c\u0438 \u043d\u0430 \u0445\u0430\u0431\u0440\u0435, \u0438 \u0437\u0430\u043f\u0438\u0441\u044b\u0432\u0430\u0442\u044c \u0432\u0438\u0434\u0435\u043e\u0440\u043e\u043b\u0438\u043a\u0438 \u043d\u0430 <a href=\"https:\/\/www.youtube.com\/@s_1gr14\" rel=\"noopener noreferrer nofollow\">YouTube<\/a> \u0438 <a href=\"https:\/\/vkvideo.ru\/@s_1gr14\" rel=\"noopener noreferrer nofollow\">VK Video<\/a>. \u0412\u0441\u0435 \u0430\u043d\u043e\u043d\u0441\u044b \u0431\u0443\u0434\u0443\u0442 \u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0435 \u0432 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c <a href=\"https:\/\/t.me\/s_1gr14\" rel=\"noopener noreferrer nofollow\">\u043a\u0430\u043d\u0430\u043b<\/a> \u0438 <a href=\"https:\/\/t.me\/s_1gr14_chat\" rel=\"noopener noreferrer nofollow\">\u0447\u0430\u0442<\/a> (\u0440\u0443\u0441\u0441\u043a\u0438\u0439 \u044f\u0437\u044b\u043a) \u0438 <a href=\"https:\/\/discord.gg\/hWgtn58FVv\" rel=\"noopener noreferrer nofollow\">\u0434\u0438\u0441\u043a\u043e\u0440\u0434\u0435<\/a> (\u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u0438\u0439 \u044f\u0437\u044b\u043a).<\/p>\n<p>\u0417\u0430\u0442\u0435\u043c \u044f \u0445\u043e\u0447\u0443 \u0434\u043e\u0434\u0435\u043b\u0430\u0442\u044c realtime \u043f\u043e\u0438\u043d\u0442\u044b \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0447\u0435\u0440\u0435\u0437 WebSocket, \u0432 \u0442\u0430\u043a\u043e\u043c \u0436\u0435 \u0441\u0442\u0438\u043b\u0435 \u043a\u0430\u043a \u0438 \u043e\u0431\u044b\u0447\u043d\u044b\u0435 \u043f\u043e\u0438\u043d\u0442\u044b. \u0422\u0430\u043a\u0436\u0435 \u0445\u043e\u0447\u0443 \u0434\u043e\u0434\u0435\u043b\u0430\u0442\u044c \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0445 \u0441\u0430\u0439\u0442\u043e\u0432.<\/p>\n<p>React Server Components \u043e\u0447\u0435\u043d\u044c \u043d\u0435 \u0445\u043e\u0447\u0443 \u0434\u0435\u043b\u0430\u0442\u044c, \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u044e \u043a\u0430\u043a\u0430\u044f \u0442\u0443\u0442 \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043e\u0442 \u043d\u0438\u0445 \u043f\u043e\u043b\u044c\u0437\u0430. \u041d\u043e \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u0431\u0443\u0434\u0443\u0442, \u0442\u043e \u043f\u043e \u0441\u0443\u0442\u0438 \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0430\u0437\u0440\u0435\u0448\u0443 \u0438\u0437 <code>.loader()<\/code> \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0442\u044c react \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b. \u041d\u043e \u043a\u0430\u043a\u0430\u044f \u0432 \u044d\u0442\u043e\u043c \u043f\u043e\u043b\u044c\u0437\u0430 \u044f \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u044e. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u044d\u0442\u043e \u043e\u0431\u0441\u0443\u0434\u0438\u043c \u0432 \u0434\u0440\u0443\u0433\u043e\u0439 \u0440\u0430\u0437.<\/p>\n<h2>P.S.<\/h2>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044e, \u0447\u0442\u043e \u043e\u0437\u043d\u0430\u043a\u043e\u043c\u0438\u043b\u0438\u0441\u044c \u0441 \u0443\u0441\u0442\u0440\u043e\u0439\u0441\u0442\u0432\u043e\u043c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 Point0. \u042f \u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u044d\u0442\u043e\u0442 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u043d\u0438\u043a\u043e\u043c\u0443 \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u0432\u0441\u0435\u0439 \u0435\u0433\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u043f\u043e\u043d\u044f\u0442\u0438\u044f \u043d\u0435 \u0438\u043c\u0435\u044e \u043a\u0430\u043a \u043e\u043d \u0432\u043e\u0441\u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0434\u0440\u0443\u0433\u0438\u043c\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c\u0438. \u0411\u0443\u0434\u0443 \u043f\u0440\u0438\u0437\u043d\u0430\u0442\u0435\u043b\u0435\u043d \u0432\u0430\u0448\u0435\u0439 \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u043a\u0435 \u0438 \u043e\u0431\u0440\u0430\u0442\u043d\u043e\u0439 \u0441\u0432\u044f\u0437\u0438:<\/p>\n<ul>\n<li>\n<p>\u041d\u0430\u043f\u0438\u0448\u0438\u0442\u0435 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445, \u0447\u0442\u043e \u0432\u0430\u043c \u043f\u0440\u0438\u0433\u043b\u044f\u043d\u0443\u043b\u043e\u0441\u044c \u0432\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0435, \u0438 \u043d\u0430\u0448\u043b\u0438 \u043b\u0438 \u0432 \u043d\u0451\u043c \u0447\u0442\u043e-\u0442\u043e \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0435 \u0434\u043b\u044f \u0441\u0435\u0431\u044f, \u0447\u0442\u043e\u0431\u044b \u044f \u043f\u043e\u0440\u0430\u0434\u043e\u0432\u0430\u043b\u0441\u044f \u0438 \u043f\u043e\u043d\u044f\u043b, \u0447\u0442\u043e \u0438\u043c\u0435\u043d\u043d\u043e \u0432\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f \u0432\u0430\u043c, \u0438 \u043c\u043e\u0433 \u0434\u043e\u043d\u043e\u0441\u0438\u0442\u044c \u0434\u043e \u0434\u0440\u0443\u0433\u0438\u0445.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u043f\u0438\u0448\u0438\u0442\u0435 \u0432 \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u044f\u0445, \u0447\u0442\u043e \u0432\u0430\u043c \u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u0442\u0441\u044f, \u0447\u0442\u043e \u0441\u043c\u0443\u0449\u0430\u0435\u0442 \u0432 \u0441\u0430\u043c\u043e\u043c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0435. \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435\u0434\u043e\u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u043e\u0431\u044a\u044f\u0441\u043d\u044e \u043a\u0430\u043a \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u043e. \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043f\u043e\u043f\u0440\u0430\u0432\u0438\u043c\u044b\u0439 \u043a\u043e\u0441\u044f\u043a, \u043f\u043e\u043f\u0440\u0430\u0432\u043b\u044e. \u0415\u0441\u043b\u0438 \u044d\u0442\u043e \u043e\u0433\u0440\u0430\u043d\u0438\u0447\u0435\u043d\u0438\u0435 \u0441\u0430\u043c\u043e\u0433\u043e \u0434\u0438\u0437\u0430\u0439\u043d\u0430, \u043e\u0442\u043c\u0435\u0447\u0443 \u0434\u043b\u044f \u0441\u0435\u0431\u044f, \u0447\u0442\u043e\u0431\u044b \u0437\u043d\u0430\u0442\u044c \u0438 \u0438\u043c\u0435\u0442\u044c \u0432 \u0432\u0438\u0434\u0443 \u0441\u043b\u0430\u0431\u044b\u0435 \u0441\u0442\u043e\u0440\u043e\u043d\u044b.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043c\u043e\u0433\u0438\u0442\u0435 \u043f\u043e\u043f\u0430\u0441\u0442\u044c \u0432 \u0442\u0440\u0435\u043d\u0434\u044b \u0433\u0438\u0442\u0445\u0430\u0431\u0430, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430. \u041f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u0437\u0432\u0435\u0437\u0434\u043e\u0447\u043a\u0443 \u043d\u0430 \u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430: <a href=\"https:\/\/github.com\/1gr14\/point0\" rel=\"noopener noreferrer nofollow\">https:\/\/github.com\/1gr14\/point0<\/a><\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u043c\u043e\u0433\u0438\u0442\u0435 \u0437\u0430\u0444\u043e\u0440\u0441\u0438\u0442\u044c \u0442\u0432\u0438\u0442\u0442\u0435\u0440 (X) \u0442\u0440\u0435\u0434, \u043f\u043e\u0436\u0430\u043b\u0443\u0439\u0441\u0442\u0430. \u041f\u043e\u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0443\u0439\u0442\u0435 \u0441 \u0442\u0440\u0435\u0434\u043e\u043c, \u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0439\u0442\u0435 \u043b\u0430\u0439\u043a\u0438, \u0440\u0435\u0442\u0432\u0438\u0442\u044b, \u043a\u043e\u043c\u043c\u0435\u043d\u0442\u0430\u0440\u0438\u0438, \u043f\u043e\u0434\u043f\u0438\u0441\u044b\u0432\u0430\u0439\u0442\u0435\u0441\u044c \u043d\u0430 \u0442\u0440\u0435\u0434: <a href=\"https:\/\/x.com\/s_1gr14\/status\/2072234966319051002\" rel=\"noopener noreferrer nofollow\">https:\/\/x.com\/s_1gr14\/status\/2072234966319051002<\/a><\/p>\n<\/li>\n<li>\n<p>\u041b\u0430\u0439\u043a\u043d\u0438\u0442\u0435 \u043f\u0435\u0440\u0435\u043a\u0440\u0451\u0441\u0442\u043d\u0443\u044e \u0430\u043d\u0433\u043b\u043e\u044f\u0437\u044b\u0447\u043d\u0443\u044e \u0441\u0442\u0430\u0442\u044c\u044e \u043d\u0430 dev.to \u0434\u043b\u044f \u043f\u0440\u0438\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u044f \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u044f \u0437\u0430\u0440\u0443\u0431\u0435\u0436\u043d\u043e\u0439 \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u0438: <a href=\"https:\/\/dev.to\/1gr14\/point0-the-fullstack-typescript-framework-on-bun-and-react-mjm\" rel=\"noopener noreferrer nofollow\">https:\/\/dev.to\/1gr14\/point0-the-fullstack-typescript-framework-on-bun-and-react-mjm<\/a><\/p>\n<\/li>\n<li>\n<p>\u0412\u0441\u0442\u0443\u043f\u0430\u0439\u0442\u0435 \u0432 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e. \u0412 \u0442\u0435\u043b\u0435\u0433\u0440\u0430\u043c \u043e\u0431\u0449\u0430\u0435\u043c\u0441\u044f \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u043c: <a href=\"https:\/\/t.me\/s_1gr14\" rel=\"noopener noreferrer nofollow\">\u043c\u043e\u0439 \u043a\u0430\u043d\u0430\u043b<\/a>, \u043d\u0430\u0448 <a href=\"https:\/\/t.me\/s_1gr14_chat\" rel=\"noopener noreferrer nofollow\">\u0444\u043e\u0440\u0443\u043c<\/a>. \u0412\u0441\u0442\u0443\u043f\u0430\u0439\u0442\u0435 \u0432 <a href=\"https:\/\/discord.gg\/hWgtn58FVv\" rel=\"noopener noreferrer nofollow\">\u0434\u0438\u0441\u043a\u043e\u0440\u0434<\/a>, \u0442\u0430\u043c \u043f\u0435\u0440\u0435\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u043c\u0441\u044f \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c \u0442\u0435\u043a\u0441\u0442\u043e\u043c, \u043d\u043e \u0435\u0441\u0442\u044c \u0433\u043e\u043b\u043e\u0441\u043e\u0432\u043e\u0439 \u043a\u0430\u043d\u0430\u043b \u043d\u0430 \u0440\u0443\u0441\u0441\u043a\u043e\u043c. \u0412 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0435 \u043e\u0442\u0432\u0435\u0447\u0430\u044e \u043e\u043f\u0435\u0440\u0430\u0442\u0438\u0432\u043d\u043e, \u0442\u0430\u043a\u0436\u0435 \u0432\u0441\u0435 \u043f\u043e\u043c\u043e\u0433\u0430\u0435\u043c \u0434\u0440\u0443\u0433 \u0434\u0440\u0443\u0433\u0443 \u0432 \u0432\u043e\u043f\u0440\u043e\u0441\u0430\u0445 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p>\u041f\u043e\u0434\u043f\u0438\u0448\u0438\u0442\u0435\u0441\u044c \u043d\u0430 \u043c\u0435\u043d\u044f \u043d\u0430 \u0445\u0430\u0431\u0440\u0435, <a href=\"https:\/\/www.youtube.com\/@s_1gr14\" rel=\"noopener noreferrer nofollow\">\u044e\u0442\u0443\u0431\u0435<\/a>, <a href=\"https:\/\/vkvideo.ru\/@s_1gr14\" rel=\"noopener noreferrer nofollow\">\u0432\u043a \u0432\u0438\u0434\u0435\u043e<\/a>, <a href=\"https:\/\/x.com\/s_1gr14\" rel=\"noopener noreferrer nofollow\">\u0442\u0432\u0438\u0442\u0442\u0435\u0440\u0435<\/a>, \u0447\u0442\u043e\u0431\u044b \u043d\u0435 \u043f\u0440\u043e\u043f\u0443\u0441\u0442\u0438\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0433\u0430\u0439\u0434\u044b \u043f\u043e Point0, \u0438 \u043f\u0440\u043e\u0447\u0438\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0441\u0442\u0438 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0438.<\/p>\n<\/li>\n<\/ul>\n<p>\u0412\u0441\u0435\u043c \u0441\u043f\u0430\u0441\u0438\u0431\u043e!<\/p>\n<\/div>\n<p>\u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/1054310\/\">https:\/\/habr.com\/ru\/articles\/1054310\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0425\u043e\u0447\u0443 \u0430\u043d\u043e\u043d\u0441\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a Point0. \u042d\u0442\u043e \u043f\u0435\u0440\u0432\u044b\u0439 Bun FullStack \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0441\u043e\u043f\u043e\u0441\u0442\u0430\u0432\u0438\u043c\u044b\u0439 \u043f\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u0443 \u0441 Next.js \u0438 TanStack Start. \u041e\u0434\u043d\u0430\u043a\u043e, \u0438\u043c\u0435\u0435\u0442 \u043a\u0430\u0440\u0434\u0438\u043d\u0430\u043b\u044c\u043d\u043e \u0434\u0440\u0443\u0433\u043e\u0439 DX, \u0440\u0430\u0434\u0438 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0438 \u0431\u044b\u043b \u0441\u043e\u0437\u0434\u0430\u043d.\u041c\u043d\u0435 \u0432\u0441\u0435\u0433\u0434\u0430 \u043d\u0435 \u043d\u0440\u0430\u0432\u0438\u043b\u0438\u0441\u044c \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u044e\u0449\u0438\u0435 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438, \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e Next.js \u0438 Remix (React Router). \u041d\u043e \u044f \u0434\u0443\u043c\u0430\u043b, \u0447\u0442\u043e, \u0432\u0438\u0434\u0438\u043c\u043e, \u043f\u043e-\u0434\u0440\u0443\u0433\u043e\u043c\u0443 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435 \u043f\u043e\u043b\u0443\u0447\u0430\u044e\u0442\u0441\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0438 \u043d\u0435 \u0434\u0435\u043b\u0430\u044e\u0442. \u0410 \u0433\u0440\u043e\u043c\u043e\u0437\u0434\u043a\u043e\u0441\u0442\u044c, \u0447\u0443\u0436\u0438\u0435 \u0441\u0442\u0440\u043e\u0433\u0438\u0435 \u0441\u043e\u0433\u043b\u0430\u0448\u0435\u043d\u0438\u044f, \u043d\u0435\u043f\u043e\u0432\u043e\u0440\u043e\u0442\u043b\u0438\u0432\u043e\u0441\u0442\u044c \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b, \u044d\u0442\u043e \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0437\u043b\u043e, \u0441 \u043a\u043e\u0442\u043e\u0440\u044b\u043c \u044f \u0434\u043e\u043b\u0436\u0435\u043d \u0441\u043c\u0438\u0440\u0438\u0442\u044c\u0441\u044f.\u0412 \u043a\u0430\u043a\u043e\u0439-\u0442\u043e \u043c\u043e\u043c\u0435\u043d\u0442 \u0432\u043e \u043c\u043d\u0435 \u043d\u0430\u043a\u043e\u043f\u0438\u043b\u043e\u0441\u044c \u043a\u0440\u0438\u0442\u0438\u0447\u0435\u0441\u043a\u043e\u0435 \u043e\u0449\u0443\u0449\u0435\u043d\u0438\u0435, \u0447\u0442\u043e \u0432\u0441\u0451 \u0436\u0435 \u0434\u043e\u043b\u0436\u043d\u043e \u0431\u044b\u0442\u044c \u0441\u043e\u0432\u0435\u0440\u0448\u0435\u043d\u043d\u043e \u043f\u043e-\u0434\u0440\u0443\u0433\u043e\u043c\u0443. \u0418 \u044f \u043f\u043e\u0434\u0443\u043c\u0430\u043b, \u0430 \u043d\u0430\u043f\u0438\u0448\u0443-\u043a\u0430 \u044f \u043f\u0441\u0435\u0432\u0434\u043e\u043a\u043e\u0434 \u043d\u0430 \u0432\u043e\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u043e\u043c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0435, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0431\u044b \u043c\u0435\u043d\u044f \u0443\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u043b, \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u0432\u0437\u0438\u0440\u0430\u044f \u043d\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u041f\u0440\u043e\u0441\u0442\u043e \u0431\u0443\u0434\u0443 \u043f\u0438\u0441\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442, \u0431\u0443\u0434\u0442\u043e \u0431\u044b \u0438\u0434\u0435\u0430\u043b\u044c\u043d\u044b\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442.\u0418 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u043e\u0441\u044c \u0442\u0430\u043a \u0437\u0434\u043e\u0440\u043e\u0432\u043e, \u0447\u0442\u043e \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0437\u0430\u0431\u044b\u043b \u043e\u0431\u043e \u0432\u0441\u0451\u043c \u043d\u0430 \u0441\u0432\u0435\u0442\u0435 \u0438 10 \u043c\u0435\u0441\u044f\u0446\u0435\u0432 \u043f\u0438\u043b\u0438\u043b \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u044d\u0442\u043e\u0433\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430, \u0430 3 \u043c\u0435\u0441\u044f\u0446\u0430 \u043d\u0430\u0437\u0430\u0434 \u0434\u0430\u0436\u0435 \u0443\u0432\u043e\u043b\u0438\u043b\u0441\u044f \u0441 \u0440\u0430\u0431\u043e\u0442\u044b, \u0447\u0442\u043e\u0431\u044b \u0443\u0436\u0435 \u0441\u043a\u043e\u0440\u0435\u0435 \u0435\u0433\u043e \u0434\u043e\u0431\u0438\u0442\u044c. \u0418 \u0432\u043e\u0442 \u0434\u043e\u0431\u0438\u043b, \u0438 \u0445\u043e\u0447\u0443 \u043f\u043e\u0434\u0435\u043b\u0438\u0442\u044c\u0441\u044f \u0441 \u0432\u0430\u043c\u0438.\u0412\u0432\u0435\u0434\u0435\u043d\u0438\u0435\u0421\u0442\u0430\u0442\u044c\u044f \u0434\u043b\u0438\u043d\u043d\u0430\u044f, \u043e\u043f\u0438\u0441\u044b\u0432\u0430\u0435\u0442 \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 Point0, \u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u0430\u043c\u043e\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e\u0435 \u0438 \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 \u043f\u0440\u0438\u043c\u0435\u0440\u043e\u0432 \u043a\u043e\u0434\u0430. \u0411\u043e\u043b\u0435\u0435 \u0433\u043b\u0443\u0431\u043e\u043a\u043e\u0435 \u043e\u043f\u0438\u0441\u0430\u043d\u0438\u0435 \u0436\u0438\u0432\u0451\u0442 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u0445 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438. \u0422\u0430\u043a\u0436\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u0435\u043d \u0432\u0438\u0434\u0435\u043e \u043e\u0431\u0437\u043e\u0440 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u043d\u0430 YouTube https:\/\/www.youtube.com\/watch?v=lhZ6eWMXMdg \u0438 \u0432 \u0412\u041a \u0432\u0438\u0434\u0435\u043e https:\/\/vkvideo.ru\/video-227165132_456239210\u0414\u043e \u0440\u0430\u0437\u0434\u0435\u043b\u0430 \u201cRoot\u201d \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u0432\u0441\u0451, \u044d\u0442\u043e \u0441\u0430\u043c\u043e\u0435 \u0432\u0430\u0436\u043d\u043e\u0435, \u0438 \u0447\u0438\u0442\u0430\u0435\u0442\u0441\u044f \u0437\u0430 5 \u043c\u0438\u043d\u0443\u0442. \u0414\u0430\u043b\u0435\u0435, \u0435\u0441\u043b\u0438 \u0443\u0442\u043e\u043c\u0438\u0442\u0435\u0441\u044c, \u043b\u0438\u0441\u0442\u0430\u0439\u0442\u0435, \u043f\u043e\u0433\u043b\u044f\u0434\u044b\u0432\u0430\u044f \u043d\u0430 \u0437\u0430\u0433\u043e\u043b\u043e\u0432\u043a\u0438 \u0438 \u0437\u0430\u0446\u0435\u043f\u0438\u0432\u0448\u0438\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043a\u0443\u0441\u043a\u0438 \u043a\u043e\u0434\u0430. \u041f\u0440\u043e\u0447\u0438\u0442\u0430\u0439\u0442\u0435 \u201cEngine\u201d \u0438 \u201cCLI\u201d. \u041b\u0438\u0441\u0442\u0430\u0439\u0442\u0435 \u0434\u0430\u043b\u044c\u0448\u0435 \u0434\u043e \u201cDeploy\u201d, \u0438 \u0434\u043e\u0447\u0438\u0442\u044b\u0432\u0430\u0439\u0442\u0435 \u0434\u043e \u043a\u043e\u043d\u0446\u0430.\u0410 \u0435\u0441\u043b\u0438 \u043e\u0441\u0438\u043b\u0438\u0442\u0435 \u0432\u0441\u044e \u0441\u0442\u0430\u0442\u044c\u044e \u0446\u0435\u043b\u0438\u043a\u043e\u043c, \u0431\u0443\u0434\u0435\u0442\u0435 \u043e\u0431\u043b\u0430\u0434\u0430\u0442\u044c \u0432\u0441\u0435\u043c\u0438 \u043d\u0443\u0436\u043d\u044b\u043c\u0438 \u0437\u043d\u0430\u043d\u0438\u044f\u043c\u0438, \u0447\u0442\u043e\u0431\u044b \u0445\u043e\u0442\u044c \u0441\u0435\u0439\u0447\u0430\u0441 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442\u044b \u043d\u0430 Point0.\u0421\u043f\u0440\u0430\u0432\u043a\u0430\u0413\u0438\u0442\u0445\u0430\u0431: https:\/\/github.com\/1gr14\/point0\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f: https:\/\/1gr14.dev\/point0\u0412\u0438\u0434\u0435\u043e-\u043e\u0431\u0437\u043e\u0440 \u043d\u0430 YouTube: https:\/\/www.youtube.com\/watch?v=lhZ6eWMXMdg\u0412\u0438\u0434\u0435\u043e-\u043e\u0431\u0437\u043e\u0440 \u043d\u0430 \u0412\u041a \u0432\u0438\u0434\u0435\u043e: https:\/\/vkvideo.ru\/video-227165132_456239210\u0421\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0443\u0441\u0442\u043e\u0439 \u043f\u0440\u043e\u0435\u043a\u0442: bun create point0-app\u0414\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u044f \u043f\u043e \u0441\u0442\u0430\u043d\u0434\u0430\u0440\u0442\u0443 llmstxt.org: https:\/\/1gr14.dev\/llms.txt \u0441\u043a\u043e\u0440\u043c\u0438\u0442\u0435 \u0435\u0451 \u0430\u0433\u0435\u043d\u0442\u0443, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u043e\u0442\u0432\u0435\u0442\u044b \u043d\u0430 \u043b\u044e\u0431\u044b\u0435 \u0432\u043e\u043f\u0440\u043e\u0441\u044b \u043f\u043e \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0443\u041f\u0430\u043f\u043a\u0430 \u0441 \u0442\u0435\u0441\u0442\u0430\u043c\u0438, \u0433\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u043f\u043e\u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044e \u0438 \u043f\u0440\u043e\u0432\u0435\u0440\u043a\u0443 \u0432\u0441\u0435\u0445 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u044b\u0445 \u043a\u0435\u0439\u0441\u043e\u0432 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430: https:\/\/github.com\/1gr14\/point0\/tree\/main\/packages\/engine\/tests \u0438 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440\u0430 https:\/\/github.com\/1gr14\/point0\/tree\/main\/packages\/engine\/tests\u042d\u0442\u0430 \u0441\u0442\u0430\u0442\u044c\u044f \u043d\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434, \u044f \u043f\u0438\u0441\u0430\u043b \u0435\u0451 \u0440\u0443\u043a\u0430\u043c\u0438 \u043d\u0435\u0434\u0435\u043b\u044e. \u041d\u0430 \u0441\u0430\u0439\u0442\u0435 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u0442\u0430\u0436\u0435 \u0441\u0442\u0430\u0442\u044c\u044f \u043d\u0430 \u0430\u043d\u0433\u043b\u0438\u0439\u0441\u043a\u043e\u043c, \u0432\u043e\u0442 \u043e\u043d\u0430 \u043c\u0430\u0448\u0438\u043d\u043d\u043d\u044b\u0439 \u043f\u0435\u0440\u0435\u0432\u043e\u0434. \u042d\u0442\u043e \u0441\u0442\u0430\u0442\u044c\u044f \u043d\u0435 \u201c\u043f\u0438\u0430\u0440\u201d, \u044d\u0442\u043e \u0430\u043d\u043e\u043d\u0441 \u043e\u043f\u0435\u043d\u0441\u043e\u0440\u0441 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0441 MIT \u043b\u0438\u0446\u0435\u043d\u0437\u0438\u0435\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0440\u0430\u043d\u0435\u0435 \u043d\u0438\u0433\u0434\u0435 \u043d\u0435 \u0431\u044b\u043b \u043e\u043f\u0443\u0431\u043b\u0438\u043a\u043e\u0432\u0430\u043d, \u0442\u043e \u0435\u0441\u0442\u044c \u044d\u0442\u043e \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u0442\u0430\u0442\u044c\u044f \u0441\u043f\u0435\u0446\u0438\u0430\u043b\u044c\u043d\u043e \u0434\u043b\u044f \u0445\u0430\u0431\u0440\u0430.Page\u0427\u0442\u043e \u044f \u0445\u043e\u0442\u0435\u043b \u043e\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b:\u041e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u043f\u0443\u0442\u044c \u043a \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435\u041e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u043a\u0430\u043a\u0438\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u043e\u043d\u0430 \u0433\u0440\u0443\u0437\u0438\u0442\u0427\u0442\u043e\u0431\u044b \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043b\u043e\u0430\u0434\u0438\u043d\u0433\u0430 \u0438 \u043f\u043e\u043a\u0430\u0437\u0430\u043d\u0438\u044f \u043e\u0448\u0438\u0431\u043a\u0438 \u043e\u0442\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u043b\u043e \u0441\u0430\u043c\u043e \u043f\u043e \u0441\u0435\u0431\u0435 \u0438 \u0431\u044b\u043b\u043e \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043a\u0430\u0441\u0442\u043e\u043c\u0438\u0437\u0438\u0440\u0443\u0435\u043c\u044b\u043c\u0427\u0442\u043e\u0431\u044b \u0445\u043e\u0442\u044c \u0441 SSR, \u0445\u043e\u0442\u044c \u0431\u0435\u0437 SSR, \u043e\u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u043b\u0430, \u0438 \u044f \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u0431\u044b\u043b \u043e\u0431 \u044d\u0442\u043e\u043c \u0434\u0443\u043c\u0430\u0442\u044c\u0427\u0442\u043e\u0431\u044b \u044f \u043c\u043e\u0433 \u043e\u0431\u044a\u044f\u0432\u043b\u044f\u0442\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0432 \u043b\u044e\u0431\u044b\u0445 \u0444\u0430\u0439\u043b\u0430\u0445, \u0432 \u043b\u044e\u0431\u044b\u0445 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u0430\u0445 \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0434\u043d\u043e\u0433\u043e \u0444\u0430\u0439\u043b\u0430, \u0432 \u043b\u044e\u0431\u044b\u0445 \u043f\u0430\u043f\u043a\u0430\u0445 \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0438 \u0447\u0442\u043e\u0431\u044b \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a \u043d\u0435 \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u043b \u0433\u0434\u0435 \u044f \u0434\u043e\u043b\u0436\u0435\u043d \u044d\u0442\u043e \u0434\u0435\u043b\u0430\u0442\u044c \u0438 \u043a\u0430\u043a \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u0444\u0430\u0439\u043b\u044b \u0438 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435import { root } from &#8216;@\/lib\/root&#8217;export const ideaPage = root  .lets(&#8216;page&#8217;, &#8216;idea&#8217;, &#8216;\/ideas\/:id&#8217;)  .loader(({ params }) =&gt; {    \/\/ params \u0442\u0443\u0442 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 \u0441\u0442\u0440\u043e\u043a\u0435 \u0440\u043e\u0443\u0442\u0430 \u043c\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u043b\u0438 :id, \u0438 \u0442\u0430\u0439\u043f\u0441\u043a\u0440\u0438\u043f\u0442 \u0443\u043c\u0435\u0435\u0442 \u0442\u0430\u043a\u043e\u0435 \u043f\u0430\u0440\u0441\u0438\u0442\u044c    const idea = await prisma.idea.findUniqueOrThrow({      where: { id: params.id },    })    return { idea }  })  .head(({ data: { idea } }) =&gt; ({    \/\/ \u0442\u0443\u0442 \u0434\u0430\u043d\u043d\u044b\u0435 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0441\u0430\u043c\u0438 \u043f\u043e \u0441\u0435\u0431\u0435, \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043c\u044b \u0432\u0435\u0440\u043d\u0443\u043b\u0438 \u0438\u0445 \u0438\u0437 \u043b\u043e\u0430\u0434\u0435\u0440\u0430    title: idea.title,    description: idea.content.slice(0, 100),  }))  .page(({ data: { idea } }) =&gt; (    \/\/ \u0442\u0443\u0442 \u0442\u043e\u0436\u0435 \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435, \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e    &lt;div&gt;      &lt;h1&gt;{idea.title}&lt;\/h1&gt;      &lt;div&gt;{idea.content}&lt;\/div&gt;    &lt;\/div&gt;  ))\u0412\u043e\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043a\u0430. \u041a\u0430\u043a\u0438\u0435 \u043f\u0440\u0430\u0432\u0438\u043b\u0430 \u0442\u0443\u0442 \u044f \u0434\u043b\u044f \u0441\u0435\u0431\u044f \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043b, \u0447\u0442\u043e\u0431\u044b \u0440\u0430\u0437\u0432\u0438\u0432\u0430\u0442\u044c \u0434\u0438\u0437\u0430\u0439\u043d \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430 \u0434\u0430\u043b\u044c\u0448\u0435:\u0412\u0441\u0435 \u0441\u0443\u0449\u043d\u043e\u0441\u0442\u0438 \u0431\u0443\u0434\u0435\u043c \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u043f\u043e\u0438\u043d\u0442\u0430\u043c\u0438. \u0412\u043e\u0442 \u0442\u0443\u0442 \u0432\u044b \u0432\u0438\u0434\u0438\u0442\u0435 \u043f\u043e\u0438\u043d\u0442 \u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043a\u0438, \u0430 \u043f\u043e\u0442\u043e\u043c \u044f \u0432\u0430\u043c \u043f\u043e\u043a\u0430\u0436\u0443 \u043a\u0432\u0435\u0440\u0438, \u043c\u0443\u0442\u0430\u0446\u0438\u0438, \u043b\u044d\u0439\u043e\u0443\u0442\u044b, \u043f\u0440\u043e\u0432\u0430\u0439\u0434\u0435\u0440\u044b, \u0438 \u043f\u0440\u043e\u0447\u0435\u0435.\u0410\u043d\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u044f \u043f\u043e\u0438\u043d\u0442 \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u043c\u043e\u0447\u044c \u043f\u043e\u043d\u044f\u0442\u044c \u0432\u0441\u0451 \u0447\u0442\u043e \u043d\u0430 \u043d\u0435\u0433\u043e \u0432\u043b\u0438\u044f\u0435\u0442 \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430 \u043a\u043e\u0434 \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u043e\u0438\u043d\u0442\u0430, \u043d\u0435 \u0434\u0435\u0440\u0436\u0430 \u0432 \u0433\u043e\u043b\u043e\u0432\u0435 \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u043d\u0438\u0435 \u043a\u0430\u043a\u0438\u0445-\u0442\u043e \u043a\u043e\u043d\u0444\u0438\u0433\u043e\u0432 \u0432 \u0434\u0440\u0443\u0433\u0438\u0445 \u0444\u0430\u0439\u043b\u0430\u0445, \u0438\u043b\u0438 \u0434\u0430\u0436\u0435 \u0434\u0440\u0443\u0433\u0438\u0445 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0439 \u0432 \u044d\u0442\u043e\u043c \u0436\u0435 \u0444\u0430\u0439\u043b\u0435. \u0412 \u044d\u0442\u043e\u043c \u043f\u0440\u0438\u043c\u0435\u0440\u0435 \u043c\u044b \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u043c, \u0447\u0442\u043e \u0432\u0441\u0451 \u0447\u0442\u043e \u043a\u0430\u0441\u0430\u0435\u0442\u0441\u044f \u044d\u0442\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043e\u043f\u0438\u0441\u0430\u043d\u043e \u043f\u0440\u044f\u043c\u043e \u0432 \u043a\u043e\u0434\u0435 \u0441\u0430\u043c\u043e\u0433\u043e \u043f\u043e\u0438\u043d\u0442\u0430, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0447\u0442\u043e \u043d\u0430 \u043d\u0435\u0451 \u0432\u043b\u0438\u044f\u0435\u0442 \u043d\u0435\u043a\u0438\u0439 root, \u0438\u0437 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u043e\u043d\u0430 \u0440\u0430\u0441\u0442\u0451\u0442. root \u044d\u0442\u043e \u0442\u043e\u0436\u0435 \u043f\u043e\u0438\u043d\u0442, \u043f\u0440\u043e \u043d\u0438\u0445 \u0442\u043e\u0436\u0435 \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u0447\u0443\u0442\u044c \u0434\u0430\u043b\u044c\u0448\u0435.\u041f\u043e\u0438\u043d\u0442\u044b \u043c\u043e\u0433\u0443\u0442 \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u044b\u0432\u0430\u0442\u044c \u0446\u0435\u043f\u043e\u0447\u043a\u0438 \u0434\u043b\u044f \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u044f \u043a\u0430\u043a\u0438\u0445-\u0442\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043a. \u0412 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u044d\u0442\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u0432\u044b \u043d\u0435 \u0432\u0438\u0434\u0438\u0442\u0435 \u043a\u0430\u043a\u0443\u044e \u0432\u0451\u0440\u0441\u0442\u043a\u0443 \u0438\u043c\u0435\u044e\u0442 \u043c\u043e\u0438 \u043b\u043e\u0430\u0434\u0438\u043d\u0433 \u0438 \u044d\u0440\u0440\u043e\u0440 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043e\u043d\u0438 \u0432\u043a\u043b\u044e\u0447\u0435\u043d\u044b \u0432 root, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u044f \u0432\u0430\u043c \u043f\u043e\u043a\u0430 \u043d\u0435 \u043f\u043e\u043a\u0430\u0437\u0430\u043b. \u0418 \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u044d\u0442\u043e \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u043e \u0441\u0443\u0442\u0438 \u043c\u043d\u0435 \u0432\u0435\u0437\u0434\u0435 \u043d\u0430\u0434\u043e \u0438\u043c\u0435\u0442\u044c \u043e\u0434\u0438\u043d\u0430\u043a\u043e\u0432\u044b\u0439 \u0432\u0438\u0434 \u043b\u043e\u0430\u0434\u0438\u043d\u0433\u0430 \u0438 \u043e\u0448\u0438\u0431\u043a\u0438, \u0438 \u044f \u043d\u0435 \u0445\u043e\u0447\u0443 \u044d\u0442\u043e \u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0432 \u043f\u043e\u0438\u043d\u0442\u0435 \u043a\u0430\u0436\u0434\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b. \u0412 \u0442\u043e \u0436\u0435 \u0432\u0440\u0435\u043c\u044f \u044f \u043c\u043e\u0433\u0443 \u0437\u0430\u043f\u0440\u043e\u0441\u0442\u043e \u0438\u0445 \u043f\u0435\u0440\u0435\u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u0442\u044c \u0445\u043e\u0442\u044c \u0434\u043b\u044f \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b, \u0445\u043e\u0442\u044c \u0434\u043b\u044f \u0433\u0440\u0443\u043f\u043f\u044b \u0441\u0442\u0440\u0430\u043d\u0438\u0446, \u0441\u043e\u0437\u0434\u0430\u0432 \u0438\u043c \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u043f\u043e\u0438\u043d\u0442\u0430, \u0431\u0443\u0434\u0435\u0442 \u043d\u0430\u0437\u044b\u0432\u0430\u0442\u044c\u0441\u044f base \u043f\u043e\u0438\u043d\u0442, \u043d\u043e \u044d\u0442\u043e \u0442\u043e\u0436\u0435 \u043f\u043e\u0437\u0436\u0435.\u041b\u044e\u0431\u043e\u0439 \u043f\u043e\u0438\u043d\u0442 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0441 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 .lets, \u0447\u0442\u043e \u0437\u043d\u0430\u0447\u0438\u0442, \u201c\u0410 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443\/\u043a\u0432\u0435\u0440\u0438\/\u043c\u0443\u0442\u0430\u0446\u0438\u044e\/\u2026 \u0441 \u0438\u043c\u0435\u043d\u0435\u043c \u0442\u0430\u043a\u0438\u043c-\u0442\u043e\u201d, \u0434\u0430\u043b\u0435\u0435 \u0432 \u0438\u0434\u0435\u0430\u043b\u0435 \u0431\u044b \u043d\u0435 \u0438\u043c\u0435\u0442\u044c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u0432, \u043d\u043e \u043a\u0430\u043a\u0438\u0435-\u0442\u043e \u0432\u0441\u0451 \u0436\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b \u0434\u043b\u044f \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0442\u0438\u043f\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0435 \u0448\u0442\u0443\u043a\u0438, \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0439 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442 \u044d\u0442\u043e \u0435\u0451 \u043f\u0443\u0442\u044c, \u0447\u0442\u043e \u0432 \u0446\u0435\u043b\u043e\u043c \u043b\u043e\u0433\u0438\u0447\u043d\u043e\u041b\u044e\u0431\u043e\u0439 \u043f\u043e\u0438\u043d\u0442 \u0437\u0430\u043a\u0430\u043d\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0442\u0435\u043c, \u0447\u0442\u043e \u043c\u044b \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0438\u043b\u0438 \u0432 .lets. \u0421\u043a\u0430\u0437\u0430\u043b\u0438 .lets(&#8216;page&#8217;, &#8230;), \u0437\u043d\u0430\u0447\u0438\u0442 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0431\u0438\u043b\u0434\u0435\u0440\u0430 \u0431\u0443\u0434\u0435\u0442 .page(&#8230;). \u0421\u043a\u0430\u0437\u0430\u043b\u0438 .lets(&#8216;query&#8217;, &#8230;), \u0437\u043d\u0430\u0447\u0438\u0442 \u0432 \u043a\u043e\u043d\u0446\u0435 \u0431\u0443\u0434\u0435\u0442 .query(&#8230;). \u0415\u0441\u0442\u044c \u0432 \u044d\u0442\u043e\u043c \u043a\u0430\u043a\u0430\u044f-\u0442\u043e \u043f\u043e\u044d\u0437\u0438\u044f, \u0440\u0435\u0444\u0440\u0435\u043d \u0442\u0430\u043a \u0441\u043a\u0430\u0437\u0430\u0442\u044c.\u041c\u044b \u043d\u0435 \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u043c \u0442\u0438\u043f\u044b, \u0432 \u043e\u0442\u043b\u0438\u0447\u0438\u0435 \u043e\u0442 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0445 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u043e\u0432, \u0432\u0441\u0451 \u0441\u0438\u0434\u0438\u0442 \u043d\u0430 \u0433\u0435\u043d\u0435\u0440\u0438\u043a\u0430\u0445 \u0441\u0430\u043c\u043e\u0433\u043e \u0431\u0438\u043b\u0434\u0435\u0440\u0430 \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442 \u0441\u0430\u043c\u043e \u043f\u043e \u0441\u0435\u0431\u0435, \u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0438\u043f\u044b \u0441\u0430\u043c\u0438\u043c \u043d\u0435 \u043d\u0430\u0434\u043e\u0421\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u0438 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439 \u043a\u043e\u0434 \u0434\u043e\u043b\u0436\u043d\u044b \u043c\u043e\u0447\u044c \u0441\u043f\u043e\u043a\u043e\u0439\u043d\u043e \u0441\u043e\u0441\u0443\u0449\u0435\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0432 \u043e\u0434\u043d\u043e\u043c \u0444\u0430\u0439\u043b\u0435, \u0432 \u043e\u0434\u043d\u043e\u0439 \u043a\u043e\u043d\u0441\u0442\u0440\u0443\u043a\u0446\u0438\u0438 \u043f\u043e\u0438\u043d\u0442\u0430, \u0438 \u044f \u043d\u0435 \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u0431 \u044d\u0442\u043e\u043c \u043f\u0430\u0440\u0438\u0442\u044c\u0441\u044f. \u041e\u0431 \u044d\u0442\u043e\u043c \u0434\u043e\u043b\u0436\u0435\u043d \u043f\u0430\u0440\u0438\u0442\u044c\u0441\u044f \u0441\u0430\u043c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a, \u043a\u043e\u0434\u0441\u043f\u043b\u0438\u0442\u0438\u043d\u0433 \u0438\u043b\u0438 \u0447\u0442\u043e \u0442\u0430\u043c, \u044f \u043f\u0440\u043e\u0441\u0442\u043e \u0445\u043e\u0447\u0443 \u0431\u044b\u0442\u044c \u043e\u0431\u0435\u0437\u043e\u043f\u0430\u0448\u0435\u043d, \u0447\u0442\u043e \u0441\u0435\u0440\u0432\u0435\u0440\u043d\u044b\u0439 \u043a\u043e\u0434 \u043d\u0435 \u043f\u043e\u043f\u0430\u0434\u0451\u0442 \u0432 \u043a\u043b\u0438\u0435\u043d\u0442\u0441\u043a\u0438\u0439. \u0412 \u0438\u0442\u043e\u0433\u0435 \u044d\u0442\u0438\u043c \u0443 \u043d\u0430\u0441 \u0437\u0430\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u043a\u043e\u043c\u043f\u0438\u043b\u044f\u0442\u043e\u0440, \u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u0440\u0430\u0441\u0441\u043a\u0430\u0436\u0443 \u043f\u043e\u0437\u0436\u0435\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043f\u0440\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b.Mutation\u0427\u0442\u043e \u044f \u0445\u043e\u0442\u0435\u043b \u043e\u0442 \u043c\u0443\u0442\u0430\u0446\u0438\u0438:\u0427\u0442\u043e\u0431\u044b \u044f \u0435\u0451 \u043c\u043e\u0433 \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0432 \u0444\u0430\u0439\u043b\u0435 \u0433\u0434\u0435 \u043e\u043d\u0430 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f, \u0435\u0441\u043b\u0438 \u0437\u0430\u0445\u043e\u0447\u0443, \u0438 \u043e\u043d\u0430 \u0431\u044b \u043d\u0435 \u043b\u043e\u043c\u0430\u043b\u0430 HMR\u0427\u0442\u043e\u0431\u044b \u044f \u043c\u043e\u0433 \u0435\u0451 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043e\u0431\u0440\u0430\u0449\u0430\u044f\u0441\u044c \u043a \u043d\u0435\u0439 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e, \u0430 \u043d\u0435 \u0447\u0435\u0440\u0435\u0437 \u0438\u043d\u0434\u0435\u043a\u0441 \u0444\u0430\u0439\u043b \u043a\u0430\u043a \u0432 tRPC, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 tRPC \u043a\u043e\u0433\u0434\u0430 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u0432 \u043c\u043d\u043e\u0433\u043e \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u043a\u043e\u0434\u0430 \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442 \u0442\u043e\u0440\u043c\u043e\u0437\u0438\u0442\u044c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u043f\u0440\u0438 \u043e\u0431\u0440\u0430\u0449\u0435\u043d\u0438\u0438 \u043a \u0434\u0430\u0436\u0435 \u043e\u0434\u043d\u043e\u043c\u0443 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u0443 \u0442\u044f\u043d\u0443\u0442\u0441\u044f \u0442\u0438\u043f\u044b \u0432\u0441\u0435\u0445 \u044d\u043d\u0434\u043f\u043e\u0438\u043d\u0442\u043e\u0432\u0427\u0442\u043e\u0431\u044b \u0441\u0445\u0435\u043c\u0443 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0431\u044a\u044f\u0432\u0438\u0442\u044c \u0447\u0435\u0440\u0435\u0437 \u043b\u044e\u0431\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443. \u041c\u043d\u0435 \u0434\u043e\u0441\u0442\u0430\u0442\u043e\u0447\u043d\u043e \u0442\u043e\u043b\u044c\u043a\u043e zod. \u041d\u043e \u043c\u044b \u0436\u0435 \u0434\u0435\u043b\u0430\u0435\u043c \u0441\u0430\u043c\u044b\u0439 \u043b\u0443\u0447\u0448\u0438\u0439 \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a, \u0437\u043d\u0430\u0447\u0438\u0442 \u043d\u0443\u0436\u043d\u043e \u0432\u0441\u0435\u043c \u0440\u0430\u0437\u0440\u0435\u0448\u0438\u0442\u044c \u043b\u044e\u0434\u044f\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043b\u044e\u0431\u0443\u044e \u0441\u0445\u0435\u043c\u0443 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438\u0427\u0442\u043e\u0431\u044b \u0441\u0445\u0435\u043c\u0430 \u0432\u0430\u043b\u0438\u0434\u0430\u0446\u0438\u0438 \u043c\u043e\u0433\u043b\u0430 \u0431\u044b\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u0430 \u0432 \u0441\u043b\u0443\u0447\u0430\u0435 \u0447\u0435\u0439\u043d\u0438\u043d\u0433\u0430 \u043f\u043e\u0438\u043d\u0442\u043e\u0432. \u0422\u043e \u0435\u0441\u0442\u044c \u0447\u0430\u0441\u0442\u044c \u0441\u0445\u0435\u043c\u044b \u0434\u043e\u043b\u0436\u043d\u0430 \u043c\u043e\u0447\u044c \u0431\u044b\u0442\u044c \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u0430 \u0432 \u0440\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u043c \u043f\u043e\u0438\u043d\u0442\u0435\u0427\u0442\u043e\u0431\u044b \u044d\u0442\u043e \u0431\u044b\u043b\u0430 \u043e\u0431\u044b\u0447\u043d\u0430\u044f react-query \u043c\u0443\u0442\u0430\u0446\u0438\u044f \u043f\u043e \u0441\u0432\u043e\u0435\u0439 \u0441\u0443\u0442\u0438import { root } from &#8216;@\/lib\/root&#8217;import { z } from &#8216;zod&#8217;\/\/ \u0424\u043e\u0440\u043c\u0430 \u2014 \u043d\u0435 \u0447\u0430\u0441\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430. \u041f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u0438\u043c,\/\/ \u0447\u0442\u043e \u0443 \u0432\u0430\u0441 \u0435\u0441\u0442\u044c \u043a\u043b\u0430\u0441\u0441\u043d\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0444\u043e\u0440\u043c \u0432 \u0432\u0430\u0448\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435import { Form, Input, Textarea, Button } from &#8216;@\/lib\/form&#8217;\/\/ \u0410 \u0432\u043e\u0442 \u043d\u0430\u0432\u0438\u0433\u0430\u0446\u0438\u044f \u044d\u0442\u043e \u0447\u0430\u0441\u0442\u044c \u0444\u0440\u0435\u0439\u043c\u0432\u043e\u0440\u043a\u0430, \u043d\u043e \u043e\u0431 \u044d\u0442\u043e\u043c \u043f\u043e\u0437\u0436\u0435import { navigate } from &#8216;@\/lib\/navigation&#8217;export const ideaUpdateMutation = root  .lets(&#8216;mutation&#8217;, &#8216;ideaUpdate&#8217;)  .input(    z.object({      id: z.string().min(1),      title: z.string().min(1),      content: z.string().min(1),    }), \/\/ \u0442\u0443\u0442 \u043c\u043e\u0433 \u0431\u044b \u0431\u044b\u0442\u044c \u0438 \u043d\u0435 zod, \u0430 \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 TypeBox  )  .loader(async ({ input: { id, title, content } }) =&gt; {    const idea = await prisma.idea.update({      where: { id },      data: { title, content },    })    return { idea }  })  .mutation() \/\/ \u043c\u043e\u0436\u043d\u043e \u0442\u0443\u0442 \u043f\u0440\u043e\u043a\u0438\u043d\u0443\u0442\u044c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u043c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438,\/\/ \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u043e\u0439\u0434\u0443\u0442 \u0432 useMutation\/fetchMutation \u043e\u0431\u044b\u0447\u043d\u043e\u0433\u043e react-queryexport const ideaEditPage = root  .lets(&#8216;page&#8217;, &#8216;ideaEdit&#8217;, &#8216;\/ideas\/:id\/edit&#8217;)  .loader(({ params }) =&gt; {    const idea = await prisma.idea.findUniqueOrThrow({      where: { id: params.id },    })    return { idea }  })  .head(({ data: { idea } }) =&gt; `Edit: ${idea.title}`)  .page(({ data: { idea } }) =&gt; (    &lt;div&gt;      &lt;h1&gt;\u0420\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0438\u0434\u0435\u0438: {idea.title}&lt;\/h1&gt;      &lt;Form        defaultValues={{          title: idea.title,          content: idea.content,        }}        onSubmit={({ title, content }) =&gt; {          await ideaUpdateMutation.fetchMutation({            id: idea.id,            title,            content,          }) \/\/ \u0430 \u0442\u0443\u0442 \u0432\u0442\u043e\u0440\u044b\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c          \/\/  \u043c\u043e\u0436\u043d\u043e \u043f\u0440\u043e\u043a\u0438\u043d\u0443\u0442\u044c \u043b\u044e\u0431\u044b\u0435 \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0431\u0443\u0434\u0443\u0442 \u0441\u043c\u0435\u0440\u0436\u0435\u043d\u044b \u0441 \u0440\u0430\u043d\u0435\u0435 \u043e\u0431\u044a\u044f\u0432\u043b\u0435\u043d\u043d\u044b\u043c\u0438 \u0432 \u0441\u0430\u043c\u043e\u0439 \u043c\u0443\u0442\u0430\u0446\u0438\u0438          await navigate(&#8216;idea&#8217;, { id })        }}      &gt;        &lt;Input label=&#187;\u0417\u0430\u0433\u043e\u043b\u043e\u0432\u043e\u043a&#187; name=&#187;title&#187; \/&gt;        &lt;Textarea label=&#187;\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435&#187; name=&#187;content&#187; \/&gt;        &lt;Button&gt;\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c&lt;\/Button&gt;      &lt;\/Form&gt;    &lt;\/div&gt;  ))\u0412\u043e\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0430\u0441\u044c \u043c\u0443\u0442\u0430\u0446\u0438\u044f. \u042f \u043c\u043e\u0433\u0443 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0435\u0451 \u0445\u043e\u0442\u044c \u0432 \u044d\u0442\u043e\u043c \u0444\u0430\u0439\u043b\u0435, \u0445\u043e\u0442\u044c \u0432 \u0434\u0440\u0443\u0433\u043e\u043c, \u043f\u0440\u043e\u0441\u0442\u043e \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u044f \u0441\u0430\u043c\u0443 \u043c\u0443\u0442\u0430\u0446\u0438\u044e. \u0422\u0438\u043f\u044b \u0432\u043e\u043e\u0431\u0449\u0435 \u043d\u0435 \u043f\u0435\u0440\u0435\u0433\u0440\u0443\u0436\u0435\u043d\u044b, \u0440\u0435\u0434\u0430\u043a\u0442\u043e\u0440 \u043a\u043e\u0434\u0430 \u043d\u0435 \u0442\u043e\u0440\u043c\u043e\u0437\u0438\u0442, \u043e\u0449\u0443\u0449\u0430\u0435\u0442\u0441\u044f \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e. \u0412\u043e\u0442 \u044f \u043e\u0431\u044a\u044f\u0432\u0438\u043b \u043c\u0443\u0442\u0430\u0446\u0438\u044e, \u0432\u043e\u0442 \u044f \u0435\u0451 \u0432\u044b\u0437\u0432\u0430\u043b. \u041a\u0440\u0443\u0442\u043e!\u041f\u043e\u0441\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043c\u0443\u0442\u0430\u0446\u0438\u0438, \u0432 \u043d\u0435\u0439 \u0442\u0430\u043a\u0436\u0435 \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043c\u0435\u0442\u043e\u0434\u044b \u043a\u043b\u0430\u0441\u0441\u0438\u0447\u0435\u0441\u043a\u043e\u0439 \u043c\u0443\u0442\u0430\u0446\u0438\u0438 react-query:myMutation.getMutationKey(input, &#8230;)myMutation.getMutationOptions()myMutation.getMutationCache()myMutation.getMutationsCache()myMutation.useMutation()myMutation.fetchMutation()\u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435 \u043e\u0442\u043b\u0438\u0447\u0438\u0435, \u0447\u0442\u043e \u043f\u0435\u0440\u0432\u044b\u043c \u0430\u0440\u0433\u0443\u043c\u0435\u043d\u0442\u043e\u043c \u0437\u0434\u0435\u0441\u044c \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442\u0441\u044f \u0438\u043d\u043f\u0443\u0442, \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u0438 \u0444\u043e\u0440\u043c\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 \u0434\u043b\u044f \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0433\u043e \u044d\u0442\u043e\u0433\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0430 mutationKey, \u0430 \u0442\u0430\u043a\u0436\u0435 \u0442\u0435\u043b\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u0430\u043c\u043e\u0439 \u043c\u0443\u0442\u0430\u0446\u0438\u0438\u0427\u0438\u0442\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u0435\u0435 \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u043f\u0440\u043e \u043c\u0443\u0442\u0430\u0446\u0438\u0438.Query\u0412 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0447\u043a\u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u044f \u043e\u0431\u0440\u0430\u0442\u0438\u043b \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 \u0442\u043e, \u0447\u0442\u043e \u0443 \u043d\u0430\u0441 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u043f\u0440\u043e\u0434\u0443\u0431\u043b\u0438\u0440\u043e\u0432\u0430\u043d \u043a\u043e\u0434 \u043b\u043e\u0430\u0434\u0435\u0440\u0430 \u043d\u0430 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043f\u0440\u043e\u0441\u043c\u043e\u0442\u0440\u0430 \u0438 \u0440\u0435\u0434\u0430\u043a\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u044f \u0438\u0434\u0435\u0438. \u0418 \u043d\u0430 \u0441\u0430\u043c\u043e\u043c \u0434\u0435\u043b\u0435 \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0431\u044b \u0432\u044b\u043d\u0435\u0441\u0442\u0438 \u0441\u0430\u043c \u043a\u043e\u0434 \u043b\u043e\u0430\u0434\u0435\u0440\u0430 \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438 \u0435\u0451 \u043f\u0435\u0440\u0435\u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c. \u041d\u043e \u044d\u0442\u043e \u043d\u0435 \u0442\u043e. \u041f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-485770","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/485770","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=485770"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/485770\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=485770"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=485770"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=485770"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}