{"_id":"@akynzhe/pash-js","_rev":"2-fd66e9957e5aa553ef3c1f0d5dd4d4af","name":"@akynzhe/pash-js","dist-tags":{"latest":"1.1.0"},"versions":{"1.0.0":{"name":"@akynzhe/pash-js","version":"1.0.0","_id":"@akynzhe/pash-js@1.0.0","maintainers":[{"name":"akynzhe","email":"zelzobaevakyn@gmail.com"}],"dist":{"shasum":"380ef88836fe9cdaacc9e94f42e2ea9a9b5846ca","tarball":"https://registry.npmjs.org/@akynzhe/pash-js/-/pash-js-1.0.0.tgz","fileCount":19,"integrity":"sha512-HqQFcGDHXjYnj+DiXSQSN9UIXGHL2cOdC0BdmeME9wfmAEXvH1O0SbWljZvCnGXejkT7J5Oy696APId4IkqUrg==","signatures":[{"sig":"MEUCIQDgQzyFqLXZwkCJ/332Xl0LgJ9dPvklxQraOwr+jA6EqQIgMbQTq49/Xa3GNqTEJFswXeguO3heIDlOws001cQmTFY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":76296},"gitHead":"4059633f85eb9dcb84c48bc70c2a6a542933ad97","private":false,"scripts":{"test":"jest --config jest.config.js --forceExit"},"_npmUser":{"name":"akynzhe","email":"zelzobaevakyn@gmail.com"},"_npmVersion":"11.7.0","description":"[![npm](https://img.shields.io/npm/v/pash-js)](https://www.npmjs.com/package/pash-js) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)","directories":{},"_nodeVersion":"24.9.0","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.0.0","react":"^18.0.0","ts-jest":"^29.0.0","typescript":"^5.0.0","@types/jest":"^29.0.0"},"_npmOperationalInternal":{"tmp":"tmp/pash-js_1.0.0_1780203819188_0.43789124345061925","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@akynzhe/pash-js","version":"1.1.0","private":false,"scripts":{"test":"jest --config jest.config.js --forceExit"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0","@pash/prompt":"^1.0.0"},"peerDependenciesMeta":{"react":{"optional":true},"react-dom":{"optional":true},"@pash/prompt":{"optional":false}},"devDependencies":{"jest":"^29.0.0","ts-jest":"^29.0.0","typescript":"^5.0.0","@types/jest":"^29.0.0","react":"^18.0.0"},"gitHead":"fa23a4d26804cad9f8739269dea9a2beb8633395","_id":"@akynzhe/pash-js@1.1.0","description":"[![npm](https://img.shields.io/npm/v/@akynzhe/pash-js)](https://www.npmjs.com/package/@akynzhe/pash-js) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)","_nodeVersion":"24.9.0","_npmVersion":"11.7.0","dist":{"integrity":"sha512-5QobFUA2PM8OYSaZnWWFTOaHOOVbGdPrLs+2ZGt6LRYQLCpoxQcKVWh01PTC4pJN3/9BrFDangIXJHHT5r413w==","shasum":"17a083b7028279725414ae447bee62a01ddad74e","tarball":"https://registry.npmjs.org/@akynzhe/pash-js/-/pash-js-1.1.0.tgz","fileCount":20,"unpackedSize":79048,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQDpKyVGC5n9/KTj9q0PB7Kwd2i92FC1QJrR0SyNCW7BcAIgDUdk4HTo08KrRDibxZHOdxRX4XJNHD/UstTxDPJf5Zc="}]},"_npmUser":{"name":"akynzhe","email":"zelzobaevakyn@gmail.com"},"directories":{},"maintainers":[{"name":"akynzhe","email":"zelzobaevakyn@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/pash-js_1.1.0_1780770704757_0.8251247138393292"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-31T05:03:38.988Z","modified":"2026-06-06T18:31:45.009Z","1.0.0":"2026-05-31T05:03:39.332Z","1.1.0":"2026-06-06T18:31:44.909Z"},"description":"[![npm](https://img.shields.io/npm/v/@akynzhe/pash-js)](https://www.npmjs.com/package/@akynzhe/pash-js) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)","maintainers":[{"name":"akynzhe","email":"zelzobaevakyn@gmail.com"}],"readme":"# pash-js\n\n[![npm](https://img.shields.io/npm/v/@akynzhe/pash-js)](https://www.npmjs.com/package/@akynzhe/pash-js)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE)\n\n**TypeScript/React SDK для PASH** — Protocol for Agentic Semantic Hypermedia.\n\nSupercharge your AI UI: вместо HTML-мусора от LLM — чистые компоненты из коробки.\n\n---\n\n## Быстрый старт\n\n```bash\nnpm install @akynzhe/pash-js\n```\n\n```tsx\nimport { PashClient, coreRegistry, PashRenderer } from '@akynzhe/pash-js';\n\n// 1. Создаём клиент с ядром из 24 компонентов (Tailwind-styled)\nconst pash = new PashClient({ registry: coreRegistry });\n\n// 2. Системный промпт — синхронизирован с реестром автоматически\nconst systemPrompt = pash.getSystemPrompt();\n\n// 3. Рендерим ответ ИИ\nfunction App() {\n  const [aiResponse, setAiResponse] = useState('');\n\n  return (\n    <div className=\"chat-window\">\n      <PashRenderer stream={aiResponse} client={pash} />\n    </div>\n  );\n}\n```\n\n---\n\n## Стриминг (компоненты появляются по мере генерации)\n\n```tsx\nimport { PashClient, coreRegistry, PashStream } from '@akynzhe/pash-js';\n\nconst pash = new PashClient({ registry: coreRegistry });\n\nfunction ChatWindow() {\n  const [stream, setStream] = useState<ReadableStream | null>(null);\n\n  async function ask(query: string) {\n    const response = await fetch('/api/ai', {\n      method: 'POST',\n      body: JSON.stringify({ query }),\n    });\n    setStream(response.body);\n  }\n\n  return (\n    <>\n      <button onClick={() => ask('Покажи мне карточку товара')}>\n        Спросить\n      </button>\n\n      {/* Компоненты рендерятся сразу, не дожидаясь конца ответа */}\n      <PashStream\n        readable={stream}\n        client={pash}\n        onComplete={(components) => console.log('Done:', components.length)}\n      />\n    </>\n  );\n}\n```\n\n---\n\n## OpenAI / Anthropic интеграция\n\n```tsx\nimport OpenAI from 'openai';\nimport { PashClient, coreRegistry, PashStream } from '@akynzhe/pash-js';\n\nconst openai = new OpenAI();\nconst pash   = new PashClient({ registry: coreRegistry });\n\nasync function* streamPash(query: string): AsyncIterable<string> {\n  const stream = openai.chat.completions.stream({\n    model:    'gpt-4o',\n    messages: [\n      { role: 'system', content: pash.getSystemPrompt() },\n      { role: 'user',   content: query },\n    ],\n    stream: true,\n  });\n\n  for await (const chunk of stream) {\n    yield chunk.choices[0]?.delta?.content ?? '';\n  }\n}\n\nfunction ProductSearch({ query }: { query: string }) {\n  const [aiStream, setAiStream] = useState<AsyncIterable<string> | null>(null);\n\n  useEffect(() => {\n    setAiStream(streamPash(query));\n  }, [query]);\n\n  return <PashStream readable={aiStream} client={pash} />;\n}\n```\n\n---\n\n## Core Registry — 24 компонента\n\n### UI (ID 1–11)\n\n| ID | Компонент    | Поля                                    |\n|----|-------------|------------------------------------------|\n| 1  | ProductCard | title\\* \\| desc \\| price \\| cta         |\n| 2  | Notification| level\\*(info\\|warn\\|error) \\| message\\* |\n| 3  | List        | title \\| items\\*                         |\n| 4  | Hero        | headline\\* \\| sub \\| cta               |\n| 5  | Article     | title\\* \\| author \\| date \\| summary    |\n| 6  | RichBlock   | content\\*[richtext]                      |\n| 7  | Badge       | text\\* \\| color                          |\n| 8  | UserCard    | name\\* \\| role \\| email \\| avatar        |\n| 9  | Rating      | score\\* \\| max \\| label                  |\n| 10 | PriceTag    | price\\* \\| original \\| badge             |\n| 11 | SearchResult| title\\* \\| url\\* \\| snippet[richtext]    |\n\n### PASH-Doc (ID 20–32)\n\n| ID | Блок        | ID | Блок         |\n|----|-------------|-----|-------------|\n| 20 | Heading     | 27  | OrderedList  |\n| 21 | Paragraph   | 28  | BulletList   |\n| 22 | Code        | 29  | Note         |\n| 23 | Blockquote  | 30  | Spoiler      |\n| 24 | Image       | 31  | Math         |\n| 25 | Divider     | 32  | Embed        |\n| 26 | Table       |     |              |\n\nВсе компоненты стилизованы **Tailwind CSS** и поддерживают **dark mode**.\n\n---\n\n## Добавить свой компонент\n\n```tsx\nimport { PashClient, coreRegistry, type ComponentRegistry } from '@akynzhe/pash-js';\nimport { createElement } from 'react';\n\nconst myRegistry: ComponentRegistry = {\n  40: {\n    schema: {\n      v: 1,\n      name: 'UserCard',\n      fields: [\n        { id: 0, type: 'string', label: 'name',  required: true },\n        { id: 1, type: 'string', label: 'email'                 },\n        { id: 2, type: 'string', label: 'role'                  },\n      ],\n    },\n    render: (f) => createElement(\n      'div',\n      { className: 'flex items-center gap-3 p-3 rounded-xl border' },\n      createElement('div', { className: 'font-semibold' }, f.name),\n      createElement('div', { className: 'text-sm text-gray-500' }, f.email),\n    ),\n  },\n};\n\n// Не мутируем coreRegistry — extend() возвращает новый экземпляр\nconst pash = new PashClient({ registry: coreRegistry }).extend(myRegistry);\n\n// ИИ теперь может генерировать: 40|Иван Петров|ivan@example.com|Разработчик\n```\n\n---\n\n## Локализация\n\n```tsx\n// ru-RU (по умолчанию): 69990 → \"69 990 ₽\"\nconst pash = new PashClient({ registry: coreRegistry, locale: 'ru-RU' });\n\n// en-US: 69990 → \"$69,990\"\nconst pash = new PashClient({ registry: coreRegistry, locale: 'en-US' });\n\n// de-DE: 69990 → \"69.990 €\"\nconst pash = new PashClient({ registry: coreRegistry, locale: 'de-DE' });\n```\n\n---\n\n## React Hooks\n\n```tsx\nimport { usePashStream, useDecodeStream, usePashClient } from '@akynzhe/pash-js';\n\n// Мемоизированный клиент\nconst pash = usePashClient({ registry: coreRegistry });\n\n// Статичный декод\nconst { components, version } = useDecodeStream(aiResponse, pash);\n\n// Стриминг с колбэками\nconst { components, streaming, error } = usePashStream(\n  response.body,\n  pash,\n  (component) => console.log('Получен:', component.type),\n);\n```\n\n---\n\n## Системный промпт\n\n```tsx\nconst pash = new PashClient({ registry: coreRegistry });\n\n// RU / mode: pash (по умолчанию)\npash.getSystemPrompt();\n\n// EN / mode: events\npash.getSystemPrompt({ lang: 'en', mode: 'events' });\n\n// RU / PASH+ID (максимальное сжатие)\npash.getSystemPrompt({ lang: 'ru', mode: 'pash+id' });\n```\n\nПромпт **автоматически синхронизирован** с реестром.  \nДобавил компонент через `extend()` — промпт обновится при следующем вызове.\n\n---\n\n## Требования\n\n- React 18+\n- Tailwind CSS (для стилей coreRegistry)\n- TypeScript 5+ (опционально)\n\n## License\n\nMIT — Copyright (c) 2026 Sergei\n","readmeFilename":"README.md"}