Този документ описва предназначението, структурата и архитектурните решения за платформата Lolly. Той отразява както визията за продукта, така и текущото състояние на кодовата база.
Статус: Lolly е пусната. Версия 1.0 излезе с отворен код под MPL-2.0 на 30 август 2026 г., а функциите, настройките по подразбиране и каталогът с инструменти все още се променят между версиите. Двигателят е детерминиран, с един път на рендиране зад всяка обвивка. Сигурността му още не е минавала през независим одит, а доказателствата за приемането са на няколко месеца. Виж Приемане и управление за текущото състояние и как се измерва приемането.
Как да четеш тази страница. Тя съдържа два вида материал, по ред. Първата половина е защо това съществува: проблемът, позиционирането и жизненият цикъл, през който преминава един актив. От Голямата картина нататък е как пасват слоевете: архитектурният документ за контрибутори, обхващащ разделянето engine/shell/pack, оформлението на хранилището, целите за доставка и ангажиментите, които ограничават всяка промяна в платформата. Ако си тук, за да промениш кодовата база, а не за да разбереш продукта, започни от голямата картина.
Два придружаващи документа навлизат по-надълбоко от тази страница.
engine/README.mdв хранилището е картата на двигателя модул по модул, с генерирана таблица за всеки модул и какво парсва или записва той. Модел на заплахите и граници на доверие е същата архитектура, прочетена като граници на доверие, и е правилната страница за всеки въпрос за това какво двигателят третира като недоверено.
Защо това съществува
Повтарящата се творческа работа е прекалено предвидима, за да оправдава ангажирането на опитни ръце всеки път, и прекалено чувствителна към качество, за да бъде прехвърлена без предпазни огради. Оставена сама на себе си, тя поема по един от три пътя: бавна, непоследователна, или заключена в шаблоните на доставчик.
Тази платформа е прекият отговор на това:
Програмно творчество и съдържание в мащаб - активи, генерирани от входове, с правила, зададени веднъж, за когото има нужда от тях.
Lolly не е мястото, където се изобретява дизайн система - той е мястото, където тя се произвежда. Мисли за него като за автомат за дизайн: правиш избор, получаваш резултат. Всеки път. Енджинът се стреми към най-високото качество, което всеки формат може да произведе на хардуера пред теб, и същият енджин прави същия файл на всяка платформа, на която се доставя.
Резултатът е изобилие: всяко събитие има правилни табели, всяко CVE предупреждение съответства на фирмения стил, всеки етикет се отпечатва чисто, всеки имейл подпис е актуален - всичко това от инструменти, които вече носят правилата. Платформата обработва повтарящото се, операционализирано творчество. Тя умишлено не е инструмент за индивидуален творчески дизайн - дизайнерите продължават да притежават флагманската работа.
Иновирай вероятностно, мащабирай детерминирано
Всеки спор за изкуствения интелект в творческия процес се заковава на един и същ въпрос: коя част от това е работа на машината? Това е стар въпрос с установен отговор. Писарите и илюминаторите отдавна са работили с два инструмента - свободната скица, където нищо не е фиксирано и всичко може да се пробва, и печатната преса, плашеща именно защото се обвързва. Скиците бяха мястото, където се раждаше изкуството. Пресата беше начинът, по който то достигаше до всеки. Никой не бъркаше двете, и двете продължаваха да напредват - нови мастила, нови шрифтове, нови преси - всяко подобрение вървеше в хармония с занаята и намерението, на което служеше.
Lolly прокарва същата линия. Изследвай вероятностно: модел, дизайнер, груба идея, промпт, който отива някъде, което никой не е планирал. После мащабирай детерминирано - това, което се превръща в много изходи, е инструмент, а инструментът се рендира по един и същ начин всеки път от входове, които можеш да прочетеш. Изследването остава свободно, защото нищо надолу по веригата не зависи от това дали ще се получи еднакво два пъти. Резултатът печели доверие, защото не е предположение. Превръщането на експериментирането с изкуствен интелект в предвидими, възпроизводими резултати не е нова дисциплина; това е същото разделение на труда, което направи печатната работа достойна за доверие още от самото начало.
Довери се на творческия процес, мащабирай с точност.
Спрямо алтернативите
Lolly includes lolly.work, the same project's separately deployed organisation service. Local creation needs no account; shared work and server rendering use the configured instance. Competitor scores: August 2026. Lolly coverage: 28 September 2026.
| Capability | Lolly+ lolly.work | Penpotopen design | CanvaAffinity Cavalry |
Adobedesktop pro | Brand DAMFrontify Bynder |
Cloudinarymedia pipeline | Figmaonline pro | Render APIsBannerbear Placid Creatomate |
|---|---|---|---|---|---|---|---|---|
| Overall completenessunweighted mean - weight rows for your own context · columns are sorted by this row | 84 | 70 | 57 | 48 | 41 | 41 | 41 | 34 |
Production maturity & track recordCanva, Adobe, Figma, Bynder/Frontify: a decade-plus at massive scale. Render APIs: years in production pipelines. Penpot: shipping, large community, younger at enterprise scale. Lolly: version 1.0 public since 30 August 2026 under MPL-2.0, and SUSE runs it as an internal deployment; no usage data is shared yet and there are no public case studies yet. Cloudinary: 2012, enterprise media infrastructure at global scale. |
25 | 75 | 100 | 100 | 100 | 100 | 100 | 75 |
Mass generation from data (CSV / API)Lolly: batch grid and CLI, plus lolly.work's recoverable server jobs and batches with retries, cancellation and retained outputs. Canva: Bulk Create + Autofill API - real, but Enterprise-gated, async, text/image fields only; Affinity Publisher adds desktop data merge. Adobe: InDesign data merge and scripting. Figma: Buzz fills templates from CSV or XLSX, free in beta (Aug 2026) - cloud- and account-gated, 50. Penpot: open API/MCP, not purpose-built. Render APIs: this is their entire product - account- and cloud-gated, so 75 under the method rule. DAM: Studio-style batch create and resize. Cloudinary: URL-driven overlays and named transforms derive variants at scale - account-gated, 75. |
100 | 50 | 50 | 50 | 75 | 75 | 50 | 75 |
Offline & air-gap operationLolly: standalone creation works offline once its assets are available; lolly.work's organisation services need a reachable instance, which can run on an internal network. The Canva column is scored on its best family member: Affinity (free since Oct 2025) runs offline as a desktop suite once a verified account activates it - 75, the same deduction Adobe takes. Canva's own Offline (2026) still edits pre-synced designs only, per device, in a 14-day window. Adobe: desktop apps run offline; licensing phones home. Figma: cached-file viewing and limited editing. Penpot: self-host on your infra behind a firewall (server required). Cloud APIs and DAM: none. |
100 | 75 | 75 | 75 | 0 | 0 | 25 | 0 |
On-device rendering - data never leavesLolly: local rendering and conversion in-browser or CLI need no upload. Choosing lolly.work's shared storage, work collabs or server rendering sends the relevant data to the configured instance. Adobe: local desktop rendering, but cloud services and telemetry in the suite. Figma: canvas renders locally, files live in Figma's cloud. Penpot: 90 - rendering happens in the browser and the save target is a server that can be your own sovereign private cloud, even your own laptop, with private export throughout; only the server hop separates it from Lolly. Canva itself is server-side by design; the column's 75 is Affinity - local desktop rendering, account activation and telemetry, the same shape as Adobe. Render APIs, DAM: server-side by design. |
100 | 90 | 75 | 75 | 0 | 0 | 25 | 0 |
Hard brand constraints (structural)Lolly: templates fix layout rules and expose permitted inputs. lolly.work adds group access, input policies, shared catalogues, approvals and audit records. Copy and usage rights can still need review. Canva: element locks - permission-based, admin-set and static: no template logic such as conditional logo switching or responsive recomposition at fill time, and Canva AI does not yet respect Brand Controls - 50. Render APIs: templates are fixed (only declared fields vary) but no governance layer. DAM: locked templates with restrictions. Figma: Buzz templates hold locked guidelines at fill time; the design surface stays review-enforced - 50. Penpot: tokens and systems enforced by review, not runtime. Adobe: libraries, little enforcement. Cloudinary: presets and Enterprise-gated transformation templates fix operations, not brand layout - 50. |
100 | 50 | 50 | 25 | 75 | 50 | 50 | 75 |
C2PA provenance, signed at creationAdobe: the broadest shipped implementation (Photoshop, Lightroom, Premiere, Firefly) - signing happens locally in the desktop apps and in the cloud for the Content Authenticity web app, and nothing signs without an Adobe account and an Adobe-provisioned identity, so it is account-gated end to end: 75 under the method rule. Lolly: optional on-device signing without an account, plus lolly.work server signing with a configured organisation identity. A verifier must trust the signer's root to show a trusted identity. Version 1.0 is public and SUSE runs it internally, but no usage data is shared yet, so 75. Penpot: 50 via the official Lolly Export plugin - the same on-device engine signing Lolly uses, opt-in, as in Lolly (and disclosed plainly: it is Lolly's own plugin). No evidence of C2PA writing in Canva, Figma, render APIs or DAM as of Aug 2026. Cloudinary: 50 - signs images on delivery (fl_c2pa, CAI member since 2020), attesting delivery by Cloudinary rather than creation by you. |
75 | 50 | 0 | 75 | 0 | 50 | 0 | 0 |
CLI, pipeline & AI-agent automationLolly: CLI, TUI, MCP server and URL mode, plus lolly.work's authenticated render API, recoverable batches and governed delivery. One engine across the local and server paths. Render APIs: API-first, webhooks, integrations - account- and cloud-gated, so 75 under the method rule. Penpot: open API, plugins, official MCP server. Canva: Connect API - Enterprise-gated, async, rate-limited. Adobe: UXP/ExtendScript plus Firefly APIs. Figma: strong REST/plugin API, no render pipeline. DAM: asset-management APIs. Cloudinary: API-first media pipeline - account-gated, 75. |
100 | 75 | 50 | 50 | 50 | 75 | 50 | 75 |
Live collaboration (real-time co-editing)Figma: the scale benchmark - 200 simultaneous editors, up to 500 people in a file - account and cloud required. Canva: mature real-time editing across the product, same precondition. Penpot: real-time multiplayer with live cursors; self-hosting lifts the vendor-account precondition, but a server is still required. Lolly: direct two-device private collabs without an account, plus authenticated work collabs through lolly.work with shared edits, cursors and saved team sessions. Partial reflects the current single-node work deployment and limited operating history. Private collabs work without internet on a shared network; work collabs need the organisation's instance. Adobe: Live Co-Editing in beta, cloud documents only. Render APIs: no editing surface. DAM: comments and approvals, not canvas co-editing. Cloudinary: DAM comments and workflows, no canvas co-editing. |
50 | 75 | 75 | 25 | 25 | 25 | 75 | 0 |
No design skill requiredCanva: the category benchmark for ease. DAM: fill a locked template. Lolly: fill in fields using an existing tool, or publish a tool from Design through Share with rules. lolly.work manages access and input policy for the team. Render APIs: swaps design skill for developer skill. Adobe, Figma, Penpot: professional tools. Cloudinary: the media library is easy; transformations are developer territory. |
100 | 25 | 100 | 25 | 100 | 50 | 25 | 50 |
Open source, self-hosted, no lock-inPenpot: MPL-licensed, 51k+ stars, self-host via Docker/K8s - fully verifiable today. Lolly and lolly.work: MPL-2.0 open source in separate repositories, both self-hostable. lolly.work provides the organisation services as part of the project. The current 75 reflects the young project and limited deployment history. Everything else is proprietary SaaS or proprietary desktop. |
75 | 100 | 0 | 0 | 0 | 0 | 0 | 0 |
Cost at production scaleLolly + lolly.work and Penpot: no per-seat software licence charge for the open-source self-hosted path; hardware, storage and operations remain costs. Render APIs: metered - roughly $0.005–0.049 per image, credits often expiring monthly. Canva/Figma: per-seat; Canva's automation needs Enterprise, though Affinity itself is free since Oct 2025. Adobe: premium per-seat suite. DAM: sales-led enterprise quotes, MAU or seat models. Cloudinary: credit-metered across transforms, storage and bandwidth - 25. |
100 | 100 | 50 | 25 | 25 | 25 | 50 | 25 |
Annual medium enterprise spendIndicative list-price arithmetic for a medium enterprise - think 500-5000 people - August 2026: a guess range, not a quote; deals vary and the seat mix dominates. Ring = how much of the board's largest annual spend (US$500k) you keep; the number in the ring is each range's upper bound. Canva (US$75k-400k; Affinity free since Oct 2025 pulls the design-seat share down), Adobe (US$100k-500k) and Figma (US$30k-250k) assume the realistic creative-seat share of an organisation this size - tens to hundreds of seats, not a licence for every employee. Render APIs price by usage (US$5k-60k). DAM is quote-only, commonly US$50k-250k and up. Penpot is hand-set at 99: "your server" can be your own laptop - a small technical hurdle at well under 1% of an Adobe-scale spend. Lolly + lolly.work: US$0 in software licence charges for self-hosting. The figure excludes devices, organisation hosting, storage, support and administration; these need a separate budget. Standalone Lolly does not need the organisation service. Cloudinary: US$30k-150k, credit-based; enterprise contracts commonly sit near US$82k. |
$0 | $0 | $400k | $500k | $250k+ | $150k | $250k | $60k |
Пълнота на възможностите в днешните творчески инструменти, проучени през август 2026. Скала: 0 липсва, 25 на ниво заобиколно решение, 50 реално, но ограничено или частично, 75 силно с уговорки, 100 основна компетентност.
signed by Lollypositioning-comparison.htmlHTMLpixels, not shapes40 KBAI generatedgenerated by GPT-6Провери самВземи подписания файлРазликата е ясна: нищо, което се предлага днес, не ни дава изход, ориентиран първо към ограниченията, способен да работи офлайн, с ниски изисквания за умения и вътрешно достъпен. Lolly дори включва отворено платно - Design - където цветовете, шрифтовете и активите се съобразяват с глобалните настройки на марката, така че свободното подреждане остава ориентирано първо към ограниченията. Това, което не е, е неограничен дизайнерски пакет: дизайнерите продължават да използват Illustrator и Figma за индивидуална флагманска работа. Пермутации могат да бъдат съставени с този инструмент.
signed by Lollyvector SVG367 paths~62k nodes773 groups3 images1453 KBПровери самВземи подписания файл
signed by Lollyvector SVG367 paths~62k nodes776 groups3 images1454 KBПровери самВземи подписания файл
Използвай го за: Бързо генериране на операционализирани творчески активи - плочки за събития, баджове с имена, подписи, CVE предупреждения, QR кодове, социални карти, етикети за пратки, структурирани отчети.
Не го използвай за: Индивидуално флагманско съдържание.
Жизненият цикъл на една кампания
Най-ясният начин да видиш какво е Lolly не е списък с функции - а да проследиш един-единствен актив, докато минава от ръка на ръка. Наблюдавай как една локализирана карта за кампания преминава през организацията:
- Творецът задава правилата. Дизайнер създава базовия шаблон в инструмента Design, вграждайки типографията и цветовите променливи на марката. Той не прави една карта - върши основната работа веднъж, за да не му се налага никога повече да я локализира ръчно.
- Разработчикът я мащабира. Същият шаблон е включен в нощен процес чрез CLI, така че нова диаграма или нов езиков вариант се генерира автоматично - никой дизайнер не отваря отново файла.
- Продуцентът просто го използва. Търговски представител, офлайн в самолет, отваря същия инструмент и генерира перфектно съобразена с марката презентация за среща с клиент. Без дизайнерски умения, без мрежа, без чакане.
„Новата диаграма" в стъпка две е рендиране като това тук, произведено от низ с данни и шепа параметри, без никой да отваря дизайнерски файл:
signed by Lollyvector SVG15 paths~1.3k nodes4 groups20 KBПровери самВземи подписания файл
signed by Lollyvector SVG15 paths~1.3k nodes4 groups20 KBПровери самВземи подписания файл
Смисълът не е, че Lolly е добър за дизайнери и добър за разработчици и добър за продажби, всеки във вакуум. Това е щафета: първоначалната работа на твореца се мащабира от разработчика, което на свой ред дава сила на продуцента. Безусилното изживяване за нетехническия представител в самолета е възможно само благодарение на точността, зададена от дизайнера и внедрена от разработчика.
Това е умножителят на сила. Lolly не е чекмедже с отделни инструменти за отделни роли - това е един детерминиран жизнен цикъл на активи, до който се докосва всяка роля, и всяка ръка, през която преминава, умножава стойността на предишната.
Един инструмент, много изходи
Правилата на бранда живеят в инструмента, а не във всеки файл, който той създава (виж Как се сравнява Lolly). Настрой инструмента правилно веднъж и всеки резултат наследява същия шрифт, цвят и разстояния, независимо дали това е една картичка или таблица с редове на дузина езици. Как проверяваш работата си и кой го прави, си остава твое решение; Lolly прави нещото, което си струва да се провери, по-малко, а резултата - по-бърз за създаване.
Един и същ детерминиран инструмент достига този мащаб по три начина, всички произвеждащи идентичен резултат:
- Човек, в приложението. Партидната мрежа
/pro: постави или импортирай редовете, получи по един готов актив на ред, изтегли zip файла. Без дизайнерски умения, без чакане. - Разработчик, от командния ред. CLI пуска същия двигател и същия път на рендиране без графичен интерфейс, така че инструментът може да бъде последователно приложен върху всеки ред в скрипт или нощен процес. Извикване
lolly <tool> --field=…в цикъл е цялата интеграция. - Система или AI агент, чрез MCP. Същият инструмент, управляван програмно, със същата точност, за колкото реда има задачата.
signed by Lollyvector SVG133 paths~15k nodes185 groups1 image195 KBПровери самВземи подписания файл
signed by Lollyvector SVG133 paths~15k nodes185 groups1 image195 KBПровери самВземи подписания файл
Един набор от ограничения на марката, зададен веднъж от дизайнер; три пътя до идентичния резултат.
Голямата картина: как пасват слоевете
Всичко оттук нататък е архитектура. Диаграмата е цялата система в един изглед: инструментите са данни най-отгоре, двигателят по средата не знае нищо за никоя платформа, обвивките под него имплементират един договор, а каталозите доставят съдържанието.
┌─────────────────────────────────────────────┐
│ Tools (data, not code) │
│ tool.json + template.html + hooks.js? │
└─────────────────────────────────────────────┘
▲
│ talks to via Capability Bridge v1
▼
┌─────────────────────────────────────────────┐
│ Engine │
│ loader · validator · runtime · template │
│ inputs · url-mode │
│ PLATFORM AGNOSTIC. Knows nothing of DOM, │
│ filesystem, or You. │
└─────────────────────────────────────────────┘
▲
│ implements HostV1
▼
┌──────────────┬──────────────┬──────────────┬──────────────┐
│ Web Shell │ Tauri Desktop│ Tauri Mobile │ CLI Shell │
│ (PWA) │ │ │ │
└──────────────┴──────────────┴──────────────┴──────────────┘
▲
│ fetches from
▼
┌─────────────────────────────────────────────┐
│ Catalogs │
│ catalog/tools/index.json + tool dirs │
│ catalog/assets/index.json + asset files │
└─────────────────────────────────────────────┘Оформление на хранилището
Lolly е едно хранилище. engine/, schemas/, scripts/, tests/, api/, docs/, community/, brands/lolly-start/, всеки shells/ и двата services/ са обикновени директории в него. Едно изключение е brands/suse - частен git подмодул, съдържащ пакета с инструменти на SUSE и каталога, по избор и отсъстващ от публичен клонинг. Кои пакети чете дадена версия (build) е въпрос на съдържателен профил (profiles.json), определян за всеки процес поотделно, а не превключван глобално. Виж Build Guide » Getting the source за командата за клониране и как се комитва промяна в частния пакет.
lolly/
├── engine/ # Platform-agnostic core. Open source (MPL-2.0).
│ └── src/
│ ├── index.ts # public surface - loader, runtime, template, inputs, url-mode
│ ├── loader.ts # fetches and validates tool files
│ ├── runtime.ts # orchestrates the 5-step lifecycle
│ ├── template.ts # Handlebars hydration + annotateTemplate
│ ├── inputs.ts # manifest → runtime input model
│ ├── url-mode.ts # URL ↔ input state round-trip
│ ├── validate.ts # JSON Schema validation of manifests
│ ├── compose.ts # resolve nested tool renders (composes)
│ ├── embed.ts # parse portable lolly.tools embed URLs
│ └── bridge/
│ └── host-v1.ts # type re-export of the @lolly-tools/core contract
│
├── shells/
│ ├── web/ # PWA - hosted online; primary distribution
│ │ └── src/
│ │ ├── main.ts # boot, routing
│ │ ├── theme.ts # theme apply/persist (FOUC prevention)
│ │ ├── bridge/ # web implementations of HostV1 APIs
│ │ │ ├── index.ts # compose all bridge pieces
│ │ │ ├── db.ts # IndexedDB setup
│ │ │ ├── state.ts # host.state - saved edits
│ │ │ ├── profile.ts # host.profile - user details
│ │ │ ├── assets.ts # host.assets - catalog + user uploads
│ │ │ ├── clipboard.ts # host.clipboard
│ │ │ ├── export.ts # host.export - rasterise/serialize
│ │ │ ├── net.ts # host.net - allowlisted fetch
│ │ │ └── media.ts # host.media - live camera frames (onFrame)
│ │ ├── catalog/
│ │ │ └── sync.ts # boot-time catalog sync + offline cache
│ │ ├── styles/ # app-wide CSS (app.css, picker.css, tokens.css)
│ │ └── views/
│ │ ├── gallery.ts # tool library listing + saved-state cards
│ │ ├── tool.ts # mounts one tool (inputs + canvas + actions)
│ │ ├── picker.ts # asset picker UI (invoked by host.assets)
│ │ ├── profile.ts # user details editor
│ │ ├── projects.ts # /p - folders of saved sessions (nested; folder/selection export)
│ │ └── free-canvas.ts # free-canvas editor overlay for render.layout:"editor" tools
│ │
│ ├── cli/ # Node.js CLI - same engine, headless jsdom
│ │ ├── bin/lolly.ts
│ │ └── src/
│ │ ├── run.ts # loadTool → createRuntime → export → write file
│ │ └── bridge.ts # CLI implementation of HostV1
│ │
│ ├── tui/ # Interactive terminal shell (Ink) - reuses the CLI bridge
│ │ └── src/
│ │ ├── main.tsx # full-screen app: Gallery / Projects / Profile / ToolView
│ │ └── bridge.ts # CLI bridge + on-disk state under ~/.lolly
│ │
│ ├── tauri-desktop/ # downloadable desktop app
│ └── tauri-mobile/ # iOS/Android app
│
├── community/ # the brand-agnostic tool pack - data, not code. Public (MPL-2.0).
│ # A SELECTION follows; a profile mounts these plus whatever
│ # tools the active brand pack carries of its own.
│ ├── qr-code/
│ ├── snippet/
│ ├── countdown-timer/
│ ├── color-palette/
│ ├── street-map/ # offline vector city-block maps
│ ├── url-shot/ # "URL Screenshot" (capture capability)
│ ├── strip-data/ # on-device metadata strip - JPEG/PNG/SVG/PDF (file in → clean file out)
│ ├── compress-pdf/ # on-device PDF compressor - recompresses images (file in → smaller file out)
│ ├── chart/ # SVG charts from structured data
│ ├── filter/ # photo effects in one tool - halftone/scanline/posterize/voronoi (vector), duotone/pixel-stretch/imperfections (raster)
│ ├── meeting-planner/ # global timezone meeting scheduler
│ ├── calendar-ics/ # event → .ics calendar file plus a card
│ ├── wayfinding-signage/ # event signage; directions blocks auto-fit label text
│ ├── text-helper/ # on-device text workbench (format/decode/hash/de-identify)
│ ├── design/ # "Design" - freeform WYSIWYG editor canvas (render.layout: editor)
│ ├── multi-page-pdf/ # multi-page PDF document - cover, flowing content blocks, back page
│ ├── diagram-builder/ # org / layercake / process / cycle / pyramid diagrams
│ ├── logo-wall/ # many logos → auto-packed grid
│ ├── icon/ # favicon .ico / png / svg from text + colours
│ └── lottie-digi-ad/ # animated Lottie ad banners
│
├── brands/ # brand packs - a catalog each, and optionally tools of their own
│ ├── lolly-start/ # the blank starter brand, owned here
│ │ └── catalog/
│ │ ├── tools/index.json # tool registry, generated per brand
│ │ └── assets/
│ │ ├── index.json # asset registry
│ │ └── lolly/... # logo, palette, tokens
│ └── suse/ # PRIVATE submodule - the SUSE tools and the SUSE catalog
│
├── schemas/ # JSON Schema for tool.json, asset entries, AssetRef
├── scripts/ # build-catalog-index.ts, checksum-assets.ts, validate-catalog.ts
├── tests/ # engine tests
└── docs/ # this file + authoring guides + positioningМодел на доставка на платформата
Платформата работи на няколко повърхности - уеб PWA, Tauri настолна/мобилна версия, скриптируемия CLI и интерактивния TUI. Всички те използват един и същ двигател и едни и същи файлове с инструменти.
Уеб (PWA) - основно разпространение
Хостван на URL, контролиран от SUSE. Работи офлайн, след като service worker-ът е кеширал инструментите и активите. Тук повечето служители, доставчици и партньори ще използват платформата. Не се изисква акаунт - състоянието се съхранява в IndexedDB на всяко устройство.
Уеб обвивката е адаптивна от едно единствено оформление. На настолен компютър инструментът е странична лента с контроли с променлив размер до сцена за преглед с навигация на платното, родна за тракпад (Cmd/Ctrl-колело или щипване за мащабиране около курсора, Space- или средно провлачване за преместване, клавиши 0/1/+/− и HUD за Fit/%). На мобилно устройство (≤640px) контролите стават лист, закачен отгоре, с плъзгаща дръжка, която прещраква между peek/half/full (докосването превключва) над статичен преглед на цял екран, а плаващ бутон Render отваря контролите за Export в изскачащ лист отдолу. Докосването получава щипване за мащаб и провлачване за преместване върху прегледа. Пътят на рендиране и контролите за експортиране са идентични и в двата случая - само хромът се преподрежда.
signed by Lollyvector SVG131 paths~6.1k nodes158 groups1 image142 KBПровери самВземи подписания файл
Същият инструмент при ширина на телефон, без втори layout за поддръжка: контролите стават лист в горната част, прегледът заема целия екран, а хапчето за рендиране плава над него.
signed by Lollyvector SVG97 paths~3.3k nodes113 groups99 KBПровери самВземи подписания файл
signed by Lollyvector SVG97 paths~3.3k nodes113 groups100 KBПровери самВземи подписания файл
Режим Batch (/pro). Уеб обвивката предлага и таблична batch мрежа (shells/web/src/pro/), която рендира много редове наведнъж през един или няколко инструмента. Тя поддържа кръгова обработка на CSV/TSV плюс поставяне от таблица, шаблон/формат/размер/мерна единица/dpi за всеки ред, страничен панел с редактор на блокове с преглед на живо, свиваеми колони за експорт, лента с етикети „relevance“ за всеки ред, преподреждане на редове чрез плъзгане с ляв манипулатор, двустъпково потвърждение за изтриване, запазени batch сесии и изтегляне на .zip. Това е повърхността „едно към много“ зад позиционирането „масово генериране на съдържание“.
Tauri desktop / mobile
Опакован нативен app (малък отпечатък чрез Tauri). Осигурява пълна офлайн наличност, достъп до файловата система за инструменти, зависими от CLI (PDF Smasher, Font Outliner), и достъп до камерата. Планирано подобрение на инструментите за средата на 2026.
CLI
lolly <tool-id> [--input=value ...] --output=file.png
Потребителите на десктоп могат да извикват много инструменти от терминала. CLI обвивката зарежда същия engine, създава jsdom DOM, изпълнява същия render път и записва файла. URL режимът е транспортът - CLI не е отделна реализация. Това гарантира, че изходите на CLI и GUI са идентични.
lolly qr-code --url=https://suse.com --output=qr.svg
lolly quotes --quote="Ship it." --output=quote.png
lolly # lists available tools
lolly qr-code # lists inputs for that toolTUI
pnpm run tui
Интерактивният аналог на CLI: терминален app на цял екран, ориентиран към клавиатурата (изграден върху Ink), за преглед на инструменти, попълване на входове, запазване на проекти и експортиране - всичко без GUI. Неговият host bridge преизползва реализацията на CLI за форматите без DOM (SVG/EMF/EPS/HTML + текст/данни) и добавя състояние на диска под ~/.lolly плюс изричен вграден преглед. Освен това има ниво за рендиране в браузър: обхванат headless Chromium (същият, който MCP сървърът инсталира), който произвежда растер/PDF/видео и заснемане на живи URL адреси при поискване - задвижвайки изградено копие на уеб обвивката, така че изходът е идентичен, и стартиращ само при първия ви експорт в такъв формат. Така url-shot (с изрязване + прецветяване + векторен PDF/SVG) и всеки растер/pdf инструмент работят и в терминала. Вижте ръководството за TUI.
На каквато и повърхност да сте, разделът Capabilities в таблото е пълната карта на това, което платформата декларира, че може да прави, групирана и четлива без да отваряте нито един инструмент.
Категории инструменти
Инструментите се маркират с category в манифеста си за групиране в галерията.
Редовете са изброени в реда на секциите в галерията. Секцията utility винаги се рендира последна в галерията (след всяка друга категория, включително бъдещи) - това е локалното (on-device) чекмедже „Offline Utilities“.
| Категория | Примери | Планирано |
|---|---|---|
everyone | QR Code Generator, Quote Card, Email Signature, Logo, Wordmark, Audiogram, Battlecards, Sequence, Record | Employee Image Stationery |
designer | Brand Lockup, Design, Chart, Darkroom, Filter, Pose Geeko, Booklet | Font Outliner |
event | Meeting Planner, Event Name Badge, Wayfinding Signage, Calendar ICS, Booth Studio | Event Stationery, Bulk Name Badges, Room Agenda Cards |
product | - | CVE Alert, Product Release Announcement, Blog OG Image |
utility | Strip Hidden Data, Text, Compress PDF, Convert Image, Convert Font, Redact, Run Web Code, Screen Capture, URL Screenshot | Unit/format converters, more on-device privacy utilities |
Тези клетки са примери, не пълен опис. Кои инструменти съществуват е свойство на профила, който сте монтирали, не на тази страница: пакет с марка добавя свои собствени и може да изключи инструмент от общността, който не желае да разпространява. catalog/tools/index.json - генериран от манифестите и регистърът, който галерията реално чете - е авторитетният списък; за да преброите какво монтира даден профил, преброете манифестите (ls community//tool.json brands//tools/*/tool.json), вместо да се доверявате на число, записано тук. (Идентификатор на инструмент, присъстващ в два пакета, се монтира само веднъж, от печелившия пакет.)
Инструментите се класифицират и по статус: official (одобрен от марката, без воден знак), community (принос от общността), experimental (експортите носят воден знак). По-голямата част от библиотеката е official; по-новите студиа и инструментите за заснемане обикновено се намират в community или experimental, докато се стабилизират. Всяка повърхност показва баджа, така че читателят знае какво получава, преди да го отвори - и, както при клетките с категории по-горе, принадлежността по статус се променя твърде бързо, за да бъде изброена тук. Проверете я в галерията или в генерирания индекс.
Design е първият инструмент, изграден върху режима на свободно платно render.layout: "editor" - повърхност без chrome, с директна манипулация, където плъзгате, преоразмерявате, завъртате и подравнявате чрез snap кутии с текст, форми и изображения, след което експортирате през същия render път като всеки друг инструмент.
Strip Hidden Data е първата услуга, изпълнявана на устройството (privacy: "on-device"): инструмент за трансформация на съдържание, който взема файл, предоставен от теб, обработва го изцяло в браузъра и връща чисто копие - никога не се качва, никога не се добавя воден знак, не се вгражда произход. Text е втората - работно пространство на устройството за ежедневни задачи от типа „постави в уебсайт" (форматиране на JSON, декодиране на JWT, Base64, URL кодиране/декодиране, SHA хеширане). Compress PDF е третата - тя намалява размера на PDF чрез прекомпресиране на изображенията в него, отново изцяло на устройството. Маркерът и текстът на неговия бадж „Работи на твоето устройство - нищо не се качва" вече покриват целия набор от трансформации: Strip Hidden Data, Text, Compress PDF, Convert Image (HEIC/TIFF/AVIF → WebP/JPG/PNG), Convert Font, Redact (унищожава области от изображение, SVG или PDF), Prompt Card и Rebrand (преоформя .pptx файл на място), където профилът го включва. Това е категория помощни инструменти за поверителност, която заменя предаването на поверителни файлове на сайтове с еднократно предназначение.
signed by Lollyvector SVG124 paths~29k nodes324 groups395 KBПровери самВземи подписания файл
signed by Lollyvector SVG124 paths~29k nodes324 groups396 KBПровери самВземи подписания файл
Забележка:
categoryиstatusса денормализирани вcatalog/tools/index.json(регистърът, който галерията чете) от всекиtool.json. Манифестът е първоизточникът на истината - индексът се генерира отpnpm run build:catalog, аpnpm run validate:catalogпроваля CI, ако комитнатият индекс се разминава с манифестите.
Архитектурни ангажименти
Тези решения са установени. Промяната на всяко от тях е мащабно начинание - те оформят всяко друго решение в кодовата база.
1. Декларативни инструменти, с императивен изход при нужда
Инструментът е манифест (tool.json) + шаблон (template.html) + по избор hooks.js.
Манифестът декларира входовете. Не шаблонът. Входовете не се извеждат от Handlebars токени. Манифестът е договорът; шаблонът консумира именувани променливи чрез {{id}}.
signed by Lollyvector SVG39 paths~2.6k nodes54 groups2 images43 KBПровери самВземи подписания файл
signed by Lollyvector SVG39 paths~2.6k nodes54 groups2 images43 KBПровери самВземи подписания файл
Hooks са по избор. Повечето инструменти са чисто декларативни - манифест + шаблон е достатъчно. Инструментите, нуждаещи се от изчислени стойности (QR кодиране, оформяне на данни за графики), предоставят hooks.js, който излага именувани функции от жизнения цикъл (onInit, onInput, onFrame - hook за всеки кадър при жива камера за реагиращи на движение инструменти - onLevel, beforeExport, afterExport, exportFile - пътят на трансформация файл-влиза/файл-излиза, използван от локални утилити като Strip Hidden Data - и exportStill, за инструмент, който притежава собствен дълбок растер). Host зарежда hooks чрез new Function('host', …), с инжектиран capability bridge като closure scope. Това е договор за преносимост, не защитна пясъчна кутия (sandbox): hooks все още се изпълняват в реалма на страницата и могат да достигнат до window/fetch/document в браузърна обвивка - host. е поддържаната, преносима повърхност, а не наложена граница. Резултатите от асинхронни hooks са ограничени във времето (onInit 5с, onInput 2с, beforeExport/afterExport 5с, exportFile/exportStill 10с), а закъснелите резултати се отхвърлят; неконтролируем синхронен* hook не може да бъде прекъснат. Затова изпълнението на недоверен hook код от трети страни не е безопасно, докато не се появи изолация чрез Worker.
Това има значение, защото: декларативните инструменти могат да се създават от хора без разработчически опит. Ако всеки инструмент беше уеб приложение, рисковата бележка „ограничени умения за създаване/поддръжка на работни шаблони“ се превръща в постоянно тясно място.
2. Инструментите и активите са данни, не пакетиран код
Уеб и Tauri приложенията извличат каталозите с инструменти и активи от известен URL адрес при стартиране, кешират ги локално и работят с каквото има там. Добавянето на нова плочка за събитие или сезонен актив не изисква release на приложението.
Байтовете на активите се контролно сумират с SHA-256, за да се предотврати CDN отравяне. id + version на актива задвижва обезсилването на кеша.
3. Capability Bridge е единственият API, който инструментите виждат
Инструментите никога не докосват DOM извън областта на своя шаблон, никога не викат fetch директно, никога не четат файловата система. Те викат версионирани методи host.*. Каноничната дефиниция на договора е packages/core/src/host-v1.ts - SDK за автори на инструменти @lolly-tools/core, така че трета страна може да разработва спрямо него без зависимост от engine; engine/src/bridge/host-v1.ts е type re-export на него, а кодът на engine/shell продължава да импортира от този път без промяна:
| Bridge API | Какво прави |
|---|---|
host.profile | Собствено име, имейл, снимка, град на потребителя и др. Предварително попълва входове чрез bindToProfile. |
host.assets | Заявки към каталога, разрешаване на активи, UI за избор, предоставен от host. |
host.state | Запазване / зареждане на входни слотове. IndexedDB в уеб, файлова система в Tauri, памет в CLI. |
host.clipboard | Записва текст или изображение в клипборда (с резервни варианти за платформата). |
host.export | Растеризира или сериализира целта на рендиране. Прилага воден знак за експериментални инструменти. |
host.net | Fetch с allowlist - достъпен само ако инструментът е декларирал capability "network". (Никой публикуван инструмент не го използва в момента.) |
Опционалните, добавъчни повърхности се появяват само когато обвивка ги предоставя. Някои са обвързани с capability - изложени само когато инструментът декларира съответния флаг: host.compose (вгражда рендирането на друг инструмент - compose), host.capture (заснемане на страница за URL Screenshot - capture) и host.recorder (заснемане от микрофон/камера/екран за инструментите за запис - microphone / camera / screen). Останалите се откриват по функционалност - присъстват, когато обвивката може да ги предостави, като инструментът пази резервен вариант за обвивки, които не могат.
Няколко водещи повърхности, за да покажем какво покрива - Host API документира всяка от тях, а packages/core/src/host-v1.ts е самият договор:
| Повърхност | От версия | Какво добавя |
|---|---|---|
host.tokens | 1.0 | DTCG дизайн токени - собствените примитиви на бранда |
host.text | 1.0 | Текст в път чрез HarfBuzz WASM (флагът за възможност wasm маркира инструментите, които разчитат на него) |
host.media | 1.4 | Живи кадри от камера, задвижващи хука onFrame. Прогресивно подобрение, съзнателно не ограничено от флага camera - такъв инструмент все още работи като обикновен инструмент за неподвижни изображения |
host.color | 1.40 | Перцептивна цветова математика: ΔEOK, контраст WCAG + APCA, OKLab рампи, разбивки на класове, категорийни палитри, хармонични схеми (1.60), смесване по CSS Color 4 и печене на градиенти (1.68). Чиста и синхронна - обвивките прикачват makeColorApi() на двигателя, вместо да реализират каквото и да е, затова не може да се разминат |
host.images | 1.60 | Декодиране/преоразмеряване/прекодиране на байтове на устройството - пътят за конвертиране (HEIC → JPEG, компресиране до WebP, намаляване на мащаба). Доставен в уеб обвивката като „мързелива“ фасада, затова HEIC декодерът никога не влиза в стартовия чънк |
host.geom | 1.64 | Точна векторна геометрия: булеви операции над пътища, отместване, преобразуване на щрих в заливка, снижаване на сплайни, опростяване, проверка за попадение. Също чиста, синхронна и прикачена от двигателя (makeGeomApi()); грешките се връщат, никога не се хвърлят |
Останалите следват същите правила и са документирани заедно с тях: pdf (1.8) и pptx (1.58) за локална хирургия на документи, audio (1.71) и speech (1.96) за анализ на клипове и локален TTS/транскрипция, viz (1.72) за договора-заместител на MilkDrop, codec (1.100) и layers (1.102) за изход с дълбок бит и слоести растерни изображения, upscale (1.101) и matte (1.103) за локалните модели, raster (1.105) за hooks, които вършат собствена пикселна работа, connectors (1.106) за безопасни за експорт стрелки и c2pa (1.85) за подписване на готови байтове. Броят расте; правилата - не.
Декларируемите capabilities са: network, filesystem, clipboard, camera, microphone, screen, ffmpeg, wasm, capture, compose. (screen, добавен в 1.54, е заснемане на екран чрез host.recorder - потребителят избира екран/прозорец/раздел в нативен за браузъра UI; отличава се от capture, който растеризира URL адрес, посочен от самия инструмент.)
Един и същ инструмент работи в браузър, Tauri и headless CLI, защото всяка обвивка имплементира този интерфейс - инструментът никога не знае в коя се намира.
Bridge-ът е версиониран. Добавянето на методи е минорна версия. Премахването или промяната на сигнатури е major версия. Когато излезе v2, v1 трябва да продължи да работи.
4. Идентификаторите на активи са завинаги
suse/logo/primary е договор. След публикуване:
- ID никога не се променя, никога не се преизползва.
- Промени в байтовете → повишете
versionв манифеста. - Заменен от нов актив → задайте
deprecated: trueи по изборreplacedBy. - Съществуващите препратки винаги се разрешават.
Това прави запазените състояния на инструменти и споделените чрез URL връзки трайни през годините.
5. URL режимът е първокласен
Всеки вход трябва да може да се изрази като URL параметър:
lolly.tools/#/tool/qr-code?url=https://suse.com&ecl=H signed by Lollyvector SVG55 paths~2.6k nodes38 groups60 KBПровери самВземи подписания файл
signed by Lollyvector SVG55 paths~2.6k nodes38 groups61 KBПровери самВземи подписания файл
Режимът CLI е URL режим под друг транспорт - CLI обвивката изгражда обект на URL състояние от argv и изпълнява същия engine pipeline. Има само един render път. CLI не може да се разминава с GUI, защото не е отделна реализация.
url-mode.ts управлява кръговата обработка (parse и serialize). Набор от резервирани параметри никога не се препращат към инструмента като входове: контролите за изхода (format, export, copy, filename, width/w, height/h, unit, dpi), регулаторите за печат и произход (bleed, marks, profile, password, c2pa, imprint, durable, meta, hdr, depth, cuts) и носителите на състояние (template, z - опакованият токен „Shortest link“ - и zx, същият, криптиран с парола). Наборът RESERVED в engine/src/url-mode.ts е авторитетният източник и е фиксиран с тест; URL Mode документира всеки от тях, включително няколкото, които не са изброени тук. Входовете от тип актив в URL режим се сериализират по своя id; runtime ги разрешава чрез host.assets.get() преди хидратация. width/height са стойности в unit (по подразбиране px, също mm/cm/in/pt/pc); при физическа единица dpi задава резолюцията за растер. Те задават размера на документа на платното и предварително попълват панела с размери за експорт.
Тъй като всеки вход пътува във връзката, промяна на параметър е различен готов актив. Цялата тази палитра е един начален цвят, хармония и брой стъпки:
signed by Lollyvector SVG10 groups25 KBПровери самВземи подписания файл
signed by Lollyvector SVG10 groups25 KBПровери самВземи подписания файл
6. Съхранението минава през моста, не директно
Уеб обвивка: IndexedDB. Tauri: файлова система. CLI: в паметта. Инструментите виждат само host.state.save(slot, data) и host.state.load(slot). localStorage не се използва - твърде малък е и не може да съхранява blob-ове.
Потребителите могат да записват няколко именувани слота за редакция на инструмент и да се връщат към всяка сесия по-късно. Не се изисква създаване на акаунт; състоянието е по устройство. Тъй като мостът е единствената точка на достъп, това състояние по устройство е и преносимо: shells/web/src/data-transfer.ts изчита всичко обратно през host.profile/host.state/host.assets в един zip lolly-backup, който се импортира на всяка друга инсталация - офлайн отговорът на "преминаване към ново устройство", без нужда от сървър (пълна спецификация: docs/data-transfer.md). Синхронизацията между устройства вече работи върху тази основа, изпращайки същия пакет към хранилището, което човек избере (docs/sync.md).
7. Етикетите за зрялост показват какво е инструментът
Всеки инструмент декларира status: official | community | experimental в манифеста си. Галерията сортира по статус. Експерименталните инструменти автоматично поставят воден знак на изнесеното съдържание - водният знак се прилага от host.export.render, не от инструмента, така че не може да бъде изключен от автор на неофициален инструмент.
Това е структурен отговор на риска от възприятие, че всеки инструмент в галерията носи еднаква тежест. Какъвто и процес да добави екип около каталога, той се надгражда върху това.
8. Входовете на инструментите се типизират чрез манифеста, включително активите
Входовете декларират type: text, longtext, number, boolean, color, select, asset, date, time, datetime-local, url, blocks, vector, table и file. Хостът рендира генеричен контрол за всеки тип от манифеста - инструментите не пишат код за контроли. (Предварителното попълване от профила на потребителя не е тип - всеки вход може да носи bindToProfile.) Три от тях носят повече тежест от останалите:
asset(сfilterиallowUpload) е мостът към глобалната система за активи;allowUpload: falseе лостът за налагане на бранда за неща като лога на спонсорски плочки, където се допускат само активи от библиотеката. Качванията от потребителя използват същата формаAssetRefкато активите от библиотеката, така че инструментите ги обработват еднакво.blocksе повтарящa се група от полета - мини-таблица вътре в един вход, редактирана в странична панел, с типизирано/дискриминирано меню за добавяне и полета за активи по блок. Кликването върху рендиран блок в канваса фокусира съответния ред. Използва се отmeeting-planner,chart-creator,event-name-badge,wayfinding-signage,color-blockиdigi-ad.vectorгрупира фиксиран набор от числа (напр. трансформация) в един съставен контрол;fileсъхранява собствения файл на потребителя като байтове в паметта за инструменти за трансформация на устройството (напр.strip-dataиcompress-pdf).
9. Шаблоните са без логика (Handlebars, не EJS)
Handlebars е избран пред EJS съзнателно:
- Без логика. Шаблоните могат да се създават от хора, които не са разработчици.
- Безопасен по подразбиране.
{{x}}escape-ва HTML;{{{x}}}е незадължителна суровина. - Липсата на произволен JS в шаблоните означава липса на повърхност за одит на XSS за всеки шаблон.
Логиката живее в hooks.js, където е явна и подлежаща на преглед. Налични помощници на Handlebars: {{default}}, {{upper}}, {{lower}}, {{eq}}, {{markdown}}, {{asset ref}}, {{asset ref "property"}} (плюс помощници за формат на данни icsStamp/rfcText/csvCell, използвани от съседните шаблони .ics/.vcf/.csv).
10. Инструментите съставят инструменти
Инструмент може да вгради рендера на друг инструмент без импорти между инструментите - композицията се разрешава от двигателя, никога от кода на инструмента. Има две повърхности:
- Декларативен манифест -
composes: [{ id, tool, inputs, format?, width?, height? }]. Двигателят рендира именувания дъщерен инструмент и поставя резултата в шаблона без логика като{{asset <id>}}.event-name-badgeсъставяqr-codeкато SVG днес. - Преносим вграден URL -
<img src="https://lolly.tools/tool/<id>.<ext>?<inputs>">. Обвивката рендира този дъщерен инструмент локално (плейсхолдър пиксел се показва, докато локалният рендер се разреши); нищо никога не се извлича отlolly.tools.
Съставяне на рендера на всеки инструмент: дъщерен SVG остава истински вектор, когато родителят изнася в SVG или PDF, и се растеризира чисто за PNG; дъщерни PNG/JPG/WEBP се вграждат като изображения. Изисква способността compose. Съставените дъщерни елементи са междинни - никога не носят воден знак или печат за произход - и композицията се деградира плавно: обвивка, която не може да рендира дъщерен елемент, просто пропуска слота, а родителят пак се рендира.
Какво съзнателно избрахме да не правим
- Без EJS / без произволен JS в шаблоните. Повърхността за XSS е нулева. Логиката живее в
hooks.js. - Без задължителна CMS за активи. Отделните хора внасят собствените си творчески файлове направо в Активи вътре в приложението (изгледът Активи и Brand Studio) - без сървър, без административна конзола. Работата се предава нататък като сесия: връзка за споделяне носи нейните входни данни и настройки (качените файлове пътуват в
.lolly), а същата сесия пътува в резервно копие или през сесия за съвместна работа. Който контролира внедряването, може после да заключи споделена сесия като шаблон - отваря връзката, записва стойностите ѝ като запис на шаблон в директорията на този инструмент в пакета за бранда и прави commit - след което тя се появява в избирача „New from template“ на инструмента и може да се достига чрез директна връзка като?template=<id>. Git е стъпката за заключване на собственика на внедряването, никога на автора. За споделен, управляван каталог, организация може да управлява директорията с активи по същия начин и да блокира актуализациите чрез PR преглед - наличен модел на управление, а не изискване на приложението. - Без наложен RBAC. Отвореното приложение е публично достъпно по подразбиране; рискът за бранда се управлява с етикети за зрялост + водни знаци. Организация, която иска по-строг контрол, наслагва собствена автентикация и прегледания в git каталог по-горе.
- Без централна база данни. Цялото потребителско състояние е на всяко устройство поотделно; незадължителната синхронизация го копира в хранилището, което човек избере, никога в база данни на Lolly.
- Без общ път на кода за инструменти/енджин. Енджинът е с отворен код, както и брандово-независимите инструменти в
community/; пакет за бранд като частнияbrands/suse/носи собствените си инструменти и каталог по свои собствени условия. И в двата случая разделянето е наложено (без кръстосани импорти отengine/в съдържанието на инструментите), така че разделението остава чисто.
Жизненият цикъл на едно рендиране
Потребител отваря lolly.tools/#/tool/qr-code?url=https://suse.com&ecl=H:
- Стартиране (Boot). Уеб обвивката отваря IndexedDB, изгражда моста на възможностите (capability bridge), синхронизира каталозите с инструменти и активи (или зарежда от кеша, когато няма връзка).
- Маршрутизиране (Route). URL хеш → изглед
tool, с извлечениqr-codeи URL параметри. - Зареждане (Load).
loadTool('qr-code', fetchFile)извличаtool.json, валидира го спрямо JSON схемата, извличаtemplate.html,styles.cssи изходния код наhooks.js. - Разбор на URL състоянието (Parse URL state).
parseUrlStateпревръща URL параметрите в начални стойности на входовете. Референциите към активи (?logo=suse/logo/primary) се разбират като леки обекти{ id, _unresolved: true }. - Runtime.
createRuntime(tool, host, initialValues)изгражда модела на входовете (обединявайки данните от профила, стойностите по подразбиране и началните стойности), разрешава референциите към активи чрезhost.assets.get(), зарежда хуковете (hostв обхват на затваряне, не в пясъчник), извикваhooks.onInit. - Рендиране (Render). Обвивката се абонира за runtime-а; при всяка промяна на състоянието получава
{ model, hydrated }. Тя рендира контролите за въвеждане от модела и записва хидратирания HTML на шаблона в#tool-canvas. - Взаимодействие (Interact). Потребителят въвежда в поле →
runtime.setInput(id, value)→ прилагат се ограничения → извиква сеhooks.onInput→ повторна хидратация → повторно рендиране. Платното се обновява на живо. - Експортиране (Export). Потребителят натиска Download(PNG) →
runtime.export(canvasNode, 'png')→host.export.render(растеризира чрез dom-to-image-more; SVG/PDF минават през специализирани векторизатори, обхождащи DOM-а) → blob →host.export.download. Диапазонът от формати, за които даден инструмент може да се включи, е широк, а изброяванетоrender.formatsвschemas/tool.schema.jsonе меродавно по въпроса - растери и растери с плаваща запетая, вектори и файлове за рязане, печат/CMYK, движение, редактируеми документи (pptx,docx,odt), палитра и изходи с данни/текст, аудио и файлове с шрифтове. URL Mode назовава всеки идентификатор и какво произвежда той. Аудиото е в това изброяване като всичко останало (wav,mp3,m4a,opus, декларирани от audiogram и инструментите за запис); отделно, режимътrender.captureна инструмент за запис задвижваhost.recorder, чийто резултат пристига като завършен Blob в контейнера, в който браузърът е записал. (Инструменти, които задаватrender.export: false- напр. Color Palette, Countdown Timer, Strip Hidden Data, Text, Compress PDF - скриват контролите за изтегляне/формат/размери.) Физическите единици се преобразуват тук според формата (PDF → истински точки на страницата, растер → пиксели при DPI с чънкpHYs). Метаданните за авторство/произход (автор, инструмент, източник - изградени отengine/src/metadata.ts) се вграждат според формата: PNG iTXt, JPEG EXIF, PDF info dict, SVG<metadata>, GIF коментар. Експерименталните инструменти получават воден знак, вмъкнат от хоста, не от инструмента.
signed by Lollyvector SVG77 paths~6.0k nodes87 groups3 images88 KBПровери самВземи подписания файл
signed by Lollyvector SVG77 paths~6.0k nodes87 groups3 images88 KBПровери самВземи подписания файл
Същият жизнен цикъл в Tauri. Същият жизнен цикъл в CLI - jsdom осигурява безглав DOM; изходът отива във файл или stdout.
Статус на отворения код
Кодът е MPL-2.0. engine/, shells/, services/, schemas/ и docs/*.ts са с отворен код под MPL-2.0 - вендор-неутрална платформа за скеле за брандирани инструменти, всичко в едно публично хранилище, lolly-tools/lolly.
Съдържанието на инструментите се доставя като бранд пакети, всеки със собствени условия (виж NOTICE.md на пакета). community/ е директория в това хранилище и нейните брандово-неутрални инструменти също са MPL-2.0. brands/suse/ е частният пакет suse-lolly, единственият подмодул: инструментите на SUSE и каталогът на SUSE, собственост на SUSE, включително лицензираната музика PremiumBeat. brands/lolly-start/ е празният начален бранд, притежаван от това хранилище. Шрифтовете се доставят вътре в пакет под SIL Open Font License 1.1 - пакетът на SUSE носи шрифтовете SUSE и SUSE Mono.
Няма директория tools/ или catalog/ в корена на хранилището. packages/node-shell/src/content-roots.ts отговаря на въпросите „къде живее инструментът <id>" и „къде е каталогът" от profiles.json по време на четене, така че профилът е отговор за всеки отделен процес, и не се налага дърво да бъде сглобявано предварително. Реална двойка tools/ + catalog/ се записва само в изходен резултат от компилация - dist/, RPM пакет, контейнерен образ - защото браузърът извлича тези два пътя през HTTP.
Разделянето е наложено - няма кръстосани импорти от engine/ в съдържанието на инструментите - така границата между платформа и съдържание остава чиста.
Къде свършва двигателят и започва хостът
Ако можеш да го опишеш с чисти данни + Handlebars → двигател. Ако засяга DOM, файловата система, мрежата или API на браузър/ОС → хост.
Границата е рязка нарочно. Двигателят е частта с отворен код. Всичко, което знае за SUSE, конкретни платформи или среди на изпълнение, остава извън него.
За следващото ниво на детайл, engine/README.md изброява всеки модул на двигателя и за какво отговаря, а Модел на заплахите и граници на доверие документира къде тази същата граница едновременно служи като граница на доверие.