{"_id":"@aiaiai-pt/widget-system","_rev":"4-77a7928a686f03f639a9e9edc8e0b65e","name":"@aiaiai-pt/widget-system","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@aiaiai-pt/widget-system","version":"0.1.0","license":"MIT","_id":"@aiaiai-pt/widget-system@0.1.0","maintainers":[{"name":"colivetree","email":"carlos@nomadriver.co"}],"homepage":"https://github.com/aiaiai-pt/sistema#readme","bugs":{"url":"https://github.com/aiaiai-pt/sistema/issues"},"dist":{"shasum":"2c12e2f18640e2b4ab223389fcd53fd3883ed8cb","tarball":"https://registry.npmjs.org/@aiaiai-pt/widget-system/-/widget-system-0.1.0.tgz","fileCount":14,"integrity":"sha512-lEq1svL/fIacZ84dgFWwNy1+QUhvvt0CEkGZ1J7iPaDHZsQGECRAQWPmiPNfNUCif+09MwSIFDSGfMXU58c4Qw==","signatures":[{"sig":"MEUCIQCO5X8YOS5ROo26FAvr3oJ41ypXYJTGfwuV+tNPfaXXAwIgPOyilfxP7cz3h5KUe3QP505jyoDHmVY21SFXYp/XML4=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":45694},"type":"module","exports":{"./core":{"types":"./src/core/index.ts","default":"./src/core/index.ts"},"./svelte":{"types":"./src/svelte/index.ts","svelte":"./src/svelte/index.ts","default":"./src/svelte/index.ts"},"./widgets":{"types":"./src/widgets/index.ts","svelte":"./src/widgets/index.ts","default":"./src/widgets/index.ts"}},"gitHead":"c4b6cb251ef5b7127b8f5ff088658ef34c024dce","scripts":{"test":"vitest run","typecheck":"tsc --noEmit"},"_npmUser":{"name":"colivetree","email":"carlos@nomadriver.co"},"repository":{"url":"git+https://github.com/aiaiai-pt/sistema.git","type":"git","directory":"packages/widget-system"},"_npmVersion":"11.4.2","description":"Generic widget registry, dispatch, display transforms, and transport-neutral widgets for aiaiai products","directories":{},"_nodeVersion":"22.17.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^29.1.1","svelte":"^5.55.3","vitest":"^3.2.6","echarts":"^6.1.0","@sveltejs/vite-plugin-svelte":"^6.2.4"},"peerDependencies":{"svelte":"^5.0.0","echarts":"^6.1.0","@aiaiai-pt/design-system":"^0.47.0"},"peerDependenciesMeta":{"svelte":{"optional":true},"echarts":{"optional":true},"@aiaiai-pt/design-system":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/widget-system_0.1.0_1785082568408_0.41187890662328974","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@aiaiai-pt/widget-system","version":"0.2.0","license":"MIT","_id":"@aiaiai-pt/widget-system@0.2.0","maintainers":[{"name":"colivetree","email":"carlos@nomadriver.co"}],"homepage":"https://github.com/aiaiai-pt/sistema#readme","bugs":{"url":"https://github.com/aiaiai-pt/sistema/issues"},"dist":{"shasum":"ce6bf0feaa1d0f4783abb3b156963093f0ad8485","tarball":"https://registry.npmjs.org/@aiaiai-pt/widget-system/-/widget-system-0.2.0.tgz","fileCount":16,"integrity":"sha512-bGPGo5vznvd8m/7sper9QvM6JXNAGlduxx/rnaA3XJs8pCIJoFMgrmFzswVs2dJ8VMG81znWoBvWTHW+mz0wqA==","signatures":[{"sig":"MEQCIAkMNwg+4AUFFQBtgiQYU2rt8hwp/A+2Ko4p8x1w0iWSAiBo6wjR0boIIUkZiVjXRkdsvmg4W1DvGXPwa3vGl0gShQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":58077},"type":"module","exports":{"./core":{"types":"./src/core/index.ts","default":"./src/core/index.ts"},"./svelte":{"types":"./src/svelte/index.ts","svelte":"./src/svelte/index.ts","default":"./src/svelte/index.ts"},"./widgets":{"types":"./src/widgets/index.ts","svelte":"./src/widgets/index.ts","default":"./src/widgets/index.ts"},"./fixtures":{"types":"./src/fixtures/index.ts","default":"./src/fixtures/index.ts"}},"gitHead":"f9e726c27752c0ccc0d6d8ede43cda7c3a2d0fe8","scripts":{"test":"vitest run","typecheck":"tsc --noEmit"},"_npmUser":{"name":"colivetree","email":"carlos@nomadriver.co"},"repository":{"url":"git+https://github.com/aiaiai-pt/sistema.git","type":"git","directory":"packages/widget-system"},"_npmVersion":"11.4.2","description":"Generic widget registry, dispatch, display transforms, and transport-neutral widgets for aiaiai products","directories":{},"_nodeVersion":"22.17.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^29.1.1","svelte":"^5.55.3","vitest":"^3.2.6","echarts":"^6.1.0","@sveltejs/vite-plugin-svelte":"^6.2.4"},"peerDependencies":{"svelte":"^5.0.0","echarts":"^6.1.0","@aiaiai-pt/design-system":">=0.47.0 <1"},"peerDependenciesMeta":{"svelte":{"optional":true},"echarts":{"optional":true},"@aiaiai-pt/design-system":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/widget-system_0.2.0_1785244451773_0.722630299894278","host":"s3://npm-registry-packages-npm-production"}},"0.2.1":{"name":"@aiaiai-pt/widget-system","version":"0.2.1","license":"MIT","_id":"@aiaiai-pt/widget-system@0.2.1","maintainers":[{"name":"colivetree","email":"carlos@nomadriver.co"}],"homepage":"https://github.com/aiaiai-pt/sistema#readme","bugs":{"url":"https://github.com/aiaiai-pt/sistema/issues"},"dist":{"shasum":"efcee42c9725327713e56cf3ca8321de3db67ddd","tarball":"https://registry.npmjs.org/@aiaiai-pt/widget-system/-/widget-system-0.2.1.tgz","fileCount":17,"integrity":"sha512-PwK3bsuTGUaFn0PLAC1GEfRi7qkk1BMXPkxhhKOqAASTquzYBIL3kVLCmT4eImNbzbaPo1OjQK1e4ZOXuhQBYg==","signatures":[{"sig":"MEUCIEGC6ylZoxtWue4ABbI5mnGuRwWatyRKQUbJ0sKFK604AiEArseb5qxxqGD5h1UxO7Dk4UEM7Bpv82dvodV5qWwnzBE=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":63666},"type":"module","exports":{"./core":{"types":"./src/core/index.ts","default":"./src/core/index.ts"},"./svelte":{"types":"./src/svelte/index.ts","svelte":"./src/svelte/index.ts","default":"./src/svelte/index.ts"},"./widgets":{"types":"./src/widgets/index.ts","svelte":"./src/widgets/index.ts","default":"./src/widgets/index.ts"},"./fixtures":{"types":"./src/fixtures/index.ts","default":"./src/fixtures/index.ts"}},"gitHead":"0bc49d89eea6e11fc68224e64b8c72e96e404af9","scripts":{"test":"vitest run","typecheck":"tsc --noEmit"},"_npmUser":{"name":"colivetree","email":"carlos@nomadriver.co"},"repository":{"url":"git+https://github.com/aiaiai-pt/sistema.git","type":"git","directory":"packages/widget-system"},"_npmVersion":"11.4.2","description":"Generic widget registry, dispatch, display transforms, and transport-neutral widgets for aiaiai products","directories":{},"_nodeVersion":"22.17.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"jsdom":"^29.1.1","svelte":"^5.55.3","vitest":"^3.2.6","echarts":"^6.1.0","@sveltejs/vite-plugin-svelte":"^6.2.4"},"peerDependencies":{"svelte":"^5.0.0","echarts":"^6.1.0","@aiaiai-pt/design-system":">=0.47.0 <1"},"peerDependenciesMeta":{"svelte":{"optional":true},"echarts":{"optional":true},"@aiaiai-pt/design-system":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/widget-system_0.2.1_1785324304790_0.18557880027188212","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@aiaiai-pt/widget-system","version":"0.3.0","description":"Generic widget registry, dispatch, display transforms, and transport-neutral widgets for aiaiai products","license":"MIT","type":"module","repository":{"type":"git","url":"git+https://github.com/aiaiai-pt/sistema.git","directory":"packages/widget-system"},"publishConfig":{"access":"public"},"exports":{"./core":{"types":"./src/core/index.ts","default":"./src/core/index.ts"},"./svelte":{"types":"./src/svelte/index.ts","svelte":"./src/svelte/index.ts","default":"./src/svelte/index.ts"},"./widgets":{"types":"./src/widgets/index.ts","svelte":"./src/widgets/index.ts","default":"./src/widgets/index.ts"},"./widgets/EntryStreamWidget":{"types":"./src/widgets/EntryStreamWidget.svelte","svelte":"./src/widgets/EntryStreamWidget.svelte","default":"./src/widgets/EntryStreamWidget.svelte"},"./widgets/IndicatorCardWidget":{"types":"./src/widgets/IndicatorCardWidget.svelte","svelte":"./src/widgets/IndicatorCardWidget.svelte","default":"./src/widgets/IndicatorCardWidget.svelte"},"./widgets/DefinitionMembersCardWidget":{"types":"./src/widgets/DefinitionMembersCardWidget.svelte","svelte":"./src/widgets/DefinitionMembersCardWidget.svelte","default":"./src/widgets/DefinitionMembersCardWidget.svelte"},"./widgets/ChartTileMockWidget":{"types":"./src/widgets/ChartTileMockWidget.svelte","svelte":"./src/widgets/ChartTileMockWidget.svelte","default":"./src/widgets/ChartTileMockWidget.svelte"},"./widgets/NativeChartWidget":{"types":"./src/widgets/NativeChartWidget.svelte","svelte":"./src/widgets/NativeChartWidget.svelte","default":"./src/widgets/NativeChartWidget.svelte"},"./widgets/EmbeddedAnalysisWidget":{"types":"./src/widgets/EmbeddedAnalysisWidget.svelte","svelte":"./src/widgets/EmbeddedAnalysisWidget.svelte","default":"./src/widgets/EmbeddedAnalysisWidget.svelte"},"./widgets/embed-url":{"types":"./src/widgets/embed-url.ts","default":"./src/widgets/embed-url.ts"},"./fixtures":{"types":"./src/fixtures/index.ts","default":"./src/fixtures/index.ts"}},"peerDependencies":{"svelte":"^5.0.0","echarts":"^6.1.0","@aiaiai-pt/design-system":">=0.51.0 <1"},"peerDependenciesMeta":{"svelte":{"optional":true},"echarts":{"optional":true},"@aiaiai-pt/design-system":{"optional":true}},"devDependencies":{"@aiaiai-pt/design-system":"file:../..","@sveltejs/vite-plugin-svelte":"^6.2.4","echarts":"^6.1.0","jsdom":"^29.1.1","svelte":"^5.55.3","vitest":"^3.2.6"},"scripts":{"test":"vitest run","typecheck":"tsc --noEmit"},"_id":"@aiaiai-pt/widget-system@0.3.0","gitHead":"260c6ce9e6ba9d84f36482b1cebd520fed4899c8","bugs":{"url":"https://github.com/aiaiai-pt/sistema/issues"},"homepage":"https://github.com/aiaiai-pt/sistema#readme","_nodeVersion":"22.17.0","_npmVersion":"11.4.2","dist":{"integrity":"sha512-s1ILYtGLDfFFeO0Q7YTzA87i8YK9HpLGcnloVkuhZeqkzLFra7Z/Zg6b+lyEwJR1yuvJbRpCbsWgLmzIuZJqBA==","shasum":"ff884d06916dbb276740d12032dff7387d2a740f","tarball":"https://registry.npmjs.org/@aiaiai-pt/widget-system/-/widget-system-0.3.0.tgz","fileCount":21,"unpackedSize":125905,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIFZ7CcqwY3KCcSWFCu9lZjZ8WYz56tG1S7Si4CUA5q+aAiB+cB/f83x8RmMpJUoXecLbfzrQf9Rv0Q+4gfRfkFSAgg=="}]},"_npmUser":{"name":"colivetree","email":"carlos@nomadriver.co"},"directories":{},"maintainers":[{"name":"colivetree","email":"carlos@nomadriver.co"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/widget-system_0.3.0_1786040102925_0.128883731123959"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-26T16:16:08.283Z","modified":"2026-08-06T18:15:03.298Z","0.1.0":"2026-07-26T16:16:08.551Z","0.2.0":"2026-07-28T13:14:11.910Z","0.2.1":"2026-07-29T11:25:04.948Z","0.3.0":"2026-08-06T18:15:03.124Z"},"bugs":{"url":"https://github.com/aiaiai-pt/sistema/issues"},"license":"MIT","homepage":"https://github.com/aiaiai-pt/sistema#readme","repository":{"type":"git","url":"git+https://github.com/aiaiai-pt/sistema.git","directory":"packages/widget-system"},"description":"Generic widget registry, dispatch, display transforms, and transport-neutral widgets for aiaiai products","maintainers":[{"name":"colivetree","email":"carlos@nomadriver.co"}],"readme":"# @aiaiai-pt/widget-system\n\nGeneric widget registry, dispatch, and transport-neutral widgets for aiaiai products.\n\n## Subpath exports\n\n| Import | Contents |\n|--------|----------|\n| `@aiaiai-pt/widget-system/core` | `WidgetMatchContext`, `WidgetRenderRequest`, registry factory, dispatch helpers. Zero runtime imports — safe for any environment. |\n| `@aiaiai-pt/widget-system/svelte` | Svelte `WidgetRenderer` integration component (S1.3). |\n| `@aiaiai-pt/widget-system/widgets` | Pre-built Svelte widgets + `registerBaseWidgets` preload helper. |\n\nNo root `\".\"` export. Always import from a subpath.\n\n## Quick start\n\n```ts\nimport { createRegistry } from '@aiaiai-pt/widget-system/core';\nimport { registerBaseWidgets } from '@aiaiai-pt/widget-system/widgets';\n\n// Create an isolated registry and populate it at startup.\nconst registry = createRegistry();\nregisterBaseWidgets(registry);\n\n// Selection: pass only kind/type — no data, no props.\nconst match = registry.resolve({ kind: 'kpi', type: 'stat-grid' });\n\n// Render: the widget receives the data separately.\nif (match) renderWidget(match.payload, { data, props, locale });\n```\n\nSelection and rendering use two separate objects (`WidgetMatchContext` and\n`WidgetRenderRequest`). The registry dispatches on `{ kind, type }`; the\nmatched widget receives `{ data, props, locale }`. Neither object carries the\nother's fields — this matches the JSONForms pattern: testers see the descriptor,\nthe control sees data.\n\n## Optional peers\n\n`svelte`, `echarts`, and `@aiaiai-pt/design-system` are declared as **optional**\npeer dependencies. This means:\n\n- A consumer importing only `/core` (e.g. a headless adapter or test suite) will\n  **not** have svelte or echarts force-installed by pnpm's `autoInstallPeers`.\n- A consumer importing `/widgets` must have all three available at runtime.\n  They will not be auto-installed; if missing, you will get a runtime resolve\n  error rather than an install-time warning.\n\nEvery real `/widgets` consumer is a Svelte host that already carries these\npackages — the optional flag changes only the install-time behaviour, not the\nruntime requirement.\n\n## /core purity guarantee\n\nNothing reachable from `/core` imports svelte, echarts, or\n`@aiaiai-pt/design-system` at runtime. This is enforced by a source-level\nstructural guard test (`tests/core/structural-guard.test.ts`). If you add a\nnew file under `src/core/`, the test will fail if it contains a forbidden\nruntime import.\n\n## Svelte rendering (`/svelte`)\n\n`WidgetRenderer` is the Svelte integration (S1.3). It receives its registry,\nmatch context, and observable state **explicitly as props** — there is no\nmodule-global registry or host state, so two renderers (two hosts, two SSR\nrequests, two tests) never observe each other.\n\n```svelte\n<script lang=\"ts\">\n  import { createRegistry } from '@aiaiai-pt/widget-system/core';\n  import { registerBaseWidgets } from '@aiaiai-pt/widget-system/widgets';\n  import { WidgetRenderer, type WidgetState } from '@aiaiai-pt/widget-system/svelte';\n\n  const registry = createRegistry();\n  registerBaseWidgets(registry);\n\n  // The host resolves its own transport/policy and reports the OUTCOME as a\n  // WidgetState. The widget-system never fetches, authorises, or times anything.\n  let state: WidgetState = { status: 'ready', request: { data, props, locale } };\n</script>\n\n<WidgetRenderer\n  {registry}\n  context={{ kind: 'chart' }}\n  {state}\n  importance=\"structural\"\n  messages={{ loading: t('loading'), empty: t('empty'), error: t('error') }}\n/>\n```\n\n### Observable states\n\n`WidgetState` is a discriminated union of every state a slot can report:\n`loading`, `ready`, `stale`, `empty`, `error`, `unauthorized`, `timeout`,\n`unsupported`, `overflow`. `ready`/`stale` carry the `WidgetRenderRequest`; the\nrest are terminal status states.\n\nThe renderer's decision is **fail-closed** (pure `resolveWidgetState`, unit-\ntestable without a DOM):\n\n- `ready`/`stale` + a matched widget → render the widget (`stale` is flagged).\n- `ready`/`stale` with **no** matching registration → corrected to `unsupported`\n  (the registry, not the host, is the authority on whether a widget exists).\n- `loading` is always shown (transient busy affordance).\n- every terminal status is **visible on a `structural` slot** (it must not\n  silently vanish) and **soft-empty on an `optional` slot** (it collapses to\n  nothing) — the same posture as `decideRender`.\n\n### Error isolation\n\nAn optional widget that throws at runtime is caught by a Svelte error boundary:\na `structural` slot surfaces a visible error, an `optional` slot fails soft to\nnothing, and **the failure never propagates to the rest of the surface**.\n\n### SSR\n\n`WidgetRenderer` renders deterministically on the server and touches no\nbrowser-only globals; the only client-only work lives inside the mounted\nwidgets' own effects (e.g. `NativeChartWidget` lazy-loads echarts in an effect).\n\n### String-free (D9)\n\nThe package ships no translatable copy. Every user-visible label is caller-\nsupplied via `messages`; a status with no supplied message still carries its\nARIA role and `data-widget-state` token for assistive tech and tests.\n\n## Generic widgets (`/widgets`)\n\n`registerBaseWidgets(registry)` populates a registry with the two transport-\nneutral widgets (S1.4). They register under **distinct kinds** with distinct\ntesters — there is no shared tester and **no heuristic fallback** between them:\n\n| Key | Kind | Contract |\n|-----|------|----------|\n| `native-chart` | `chart` | Renders an **already-resolved** `{ category, series }` chart model over the Sistema `EChart` primitive, with its accessible data table. It reads no rows, view, BFF path, ontology schema, or tenant — the host resolves; the widget renders. |\n| `embedded-analysis` | `embed` | Renders an `<iframe>` from an **already-authorized, sanitised, short-lived URL** the caller supplies as `props.src`. It knows no signer, grant, resource id, or tenant. `safeEmbedSrc` admits only http(s)/root-relative URLs as defence in depth; an absent or unsafe `src` renders the empty state, never a broken frame. |\n\nThe Atelier renderer's coupled `MetabaseEmbedWidget` is **not** moved or replaced\nby `embedded-analysis` — it stays until the BFF-resolved trusted-embed seam\nexists (BD-META-01, Atelier-owned).\n\nOverflow is a host budget decision surfaced via `WidgetState.overflow`, not\ninferred by the widgets: `native-chart` always renders every resolved\ncategory/series into its accessible table (no silent truncation).\n\n## TH-08: key provenance\n\nThe `type` field in `WidgetMatchContext` is **untrusted** (operator-authored).\nIt only influences tester scoring; the resolved `key` always comes from the\nmatched entry's literal `key` field — never from the `type` hint. This prevents\nan operator from redirecting dispatch to an unregistered or arbitrary component.\n","readmeFilename":"README.md"}