@stealthscale/sdk-host 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"$schema":"http://cyclonedx.org/schema/bom-1.7.schema.json","bomFormat":"CycloneDX","specVersion":"1.7","version":1,"metadata":{"lifecycles":[{"phase":"build"}],"tools":{"components":[{"type":"application","name":"rolldown","version":"1.2.11"},{"type":"application","name":"vite","version":"8.3.1"},{"type":"library","name":"core","group":"@arethetypeswrong","version":"0.18.5","bom-ref":"pkg:npm/%40arethetypeswrong/core@0.18.5","author":"Andrew Branch","description":"The API behind arethetypeswrong.github.io","hashes":[{"alg":"SHA-512","content":"f72b63cc6c318e6f54cfb23d6af7dbb79be542deae93db914444b3263aabce797a58abc8e9dc184e8faf277534d96aeafe64778aa97f3f386f1e129d2480230d"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40arethetypeswrong/core@0.18.5","externalReferences":[{"url":"https://github.com/arethetypeswrong/arethetypeswrong.github.io.git#packages/core","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=20"}]},{"type":"library","name":"component-actions","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/component-actions@0.1.0","description":"Renders what a person presses: a button, a toggle group, a swap, a color mode toggle, a clipboard and a download trigger.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/component-actions@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#components/actions","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/components/actions#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"component-feedback","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/component-feedback@0.1.0","description":"Draws the system reporting on itself: what is loading, what went wrong, what state a thing is in.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/component-feedback@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#components/feedback","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/components/feedback#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"component-forms","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/component-forms@0.1.0","description":"Composes controls into something a person submits, and reports what is wrong with it.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/component-forms@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#components/forms","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/components/forms#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"component-layout","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/component-layout@0.1.0","description":"Arranges what is already there: the boxes, the stacks, the rules between them and the surfaces under them.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/component-layout@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#components/layout","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/components/layout#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"component-modals","group":"@stealthscale","version":"0.0.1","bom-ref":"pkg:npm/%40stealthscale/component-modals@0.0.1","description":"Draws what the page waits for: a dialog, a drawer, a palette, a tour.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/component-modals@0.0.1","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#components/modals","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/components/modals#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"component-navigation","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/component-navigation@0.1.0","description":"Draws the ways a person moves between places: links, tabs, breadcrumbs and rails.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/component-navigation@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#components/navigation","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/components/navigation#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"component-screen","group":"@stealthscale","version":"0.0.1","bom-ref":"pkg:npm/%40stealthscale/component-screen@0.0.1","description":"Lays an application out on whatever screen it is opened on: the shell, the page, the toolbar and the sidebar, each folding on its own as the screen narrows.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/component-screen@0.0.1","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#components/screen","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/components/screen#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"component-typography","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/component-typography@0.1.0","description":"Draws the components that are text: a heading, a paragraph, a snippet of code, a key a reader is asked to press.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/component-typography@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#components/typography","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/components/typography#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"hooks","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/hooks@0.1.0","description":"The React hooks a component uses to read the page it draws into: how the page is read, what it measures, and what a value was on the previous render.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/hooks@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#foundations/hooks","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/foundations/hooks#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"provider-color-mode","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/provider-color-mode@0.1.0","description":"Puts a colour mode in scope, remembers what a person chose, and settles the first paint before the page draws.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/provider-color-mode@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#foundations/providers/color-mode","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/foundations/providers/color-mode#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"provider-data","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/provider-data@0.1.0","description":"Reads and changes an application's data through the operations its gateway publishes: the transport, the query client, invalidation by record, route loaders and server rendering.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/provider-data@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#foundations/providers/data","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/foundations/providers/data#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"provider-environment","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/provider-environment@0.1.0","description":"Names the document a subtree lives in, which a portal attaches to and a measurement is taken against.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/provider-environment@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#foundations/providers/environment","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/foundations/providers/environment#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"provider-form","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/provider-form@0.1.0","description":"Publishes the foundation every form is built on: the contexts a bound field and a bound form share, the engine that evaluates a JSON Schema, the provider, and the draft kept across a refresh.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/provider-form@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#foundations/providers/form","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/foundations/providers/form#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"provider-hotkeys","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/provider-hotkeys@0.1.0","description":"Publishes the keyboard shortcuts a page answers to, under this design system's own name.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/provider-hotkeys@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#foundations/providers/hotkeys","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/foundations/providers/hotkeys#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"provider-i18n","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/provider-i18n@0.1.0","description":"Puts the words an application is read in into scope, in the locale it is given.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/provider-i18n@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#foundations/providers/i18n","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/foundations/providers/i18n#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"provider-locale","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/provider-locale@0.1.0","description":"Decides which locale a page is read in, remembers the choice, and writes the direction that follows.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/provider-locale@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#foundations/providers/locale","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/foundations/providers/locale#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"provider-router","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/provider-router@0.1.0","description":"Publishes the routes an application navigates by, and the options every router starts from.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/provider-router@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#foundations/providers/router","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/foundations/providers/router#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"provider-shell","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/provider-shell@0.1.0","description":"Composes every provider an application renders, in the order each depends on the one before.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/provider-shell@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#foundations/providers/shell","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/foundations/providers/shell#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"provider-viewport","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/provider-viewport@0.1.0","description":"Lays a subtree out for a stated width rather than the window's, and answers which breakpoint it is at.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/provider-viewport@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#foundations/providers/viewport","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/foundations/providers/viewport#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"sdk-plugin","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/sdk-plugin@0.1.0","description":"Renders what plugins contribute to a product's slots, and reads the host's sessions, access, flags, commands, events, settings and data in a plugin's components.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/sdk-plugin@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#sdk/plugin","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/sdk/plugin#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"settings","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/settings@0.1.0","description":"Remembers one named setting a person made, per application, held to the values it is allowed to take and kept where the reader chooses.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/settings@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#foundations/settings","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/foundations/settings#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"testing-config","group":"@stealthscale","version":"0.5.0","bom-ref":"pkg:npm/%40stealthscale/testing-config@0.5.0","description":"Lists every part of the house contract a config, plugin or library package breaks.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/testing-config@0.5.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#packages/testing-config","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/packages/testing-config#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"theme","group":"@stealthscale","version":"0.3.0","bom-ref":"pkg:npm/%40stealthscale/theme@0.3.0","description":"Publishes the foundation every recipe is written against, the runtime every component binds its recipe with, and the vocabulary a theme is written in.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/theme@0.3.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#foundations/theme","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/foundations/theme#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"vite-config-i18n","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/vite-config-i18n@0.1.0","description":"Configures a package or an application with words: the catalogue plugin, and the words in scope for its specifications.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/vite-config-i18n@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#packages/vite-config-i18n","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/packages/vite-config-i18n#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"vite-config-react","group":"@stealthscale","version":"0.8.0","bom-ref":"pkg:npm/%40stealthscale/vite-config-react@0.8.0","description":"Adds the JSX transform, the React lint rules, a test document and an MDX compiler to a package that renders.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/vite-config-react@0.8.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#packages/vite-config-react","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/packages/vite-config-react#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"vite-config-typescript","group":"@stealthscale","version":"0.3.0","bom-ref":"pkg:npm/%40stealthscale/vite-config-typescript@0.3.0","description":"Sets the TypeScript options every stealthscale package compiles with.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/vite-config-typescript@0.3.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#packages/vite-config-typescript","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/packages/vite-config-typescript#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"vite-config","group":"@stealthscale","version":"0.6.0","bom-ref":"pkg:npm/%40stealthscale/vite-config@0.6.0","description":"Configures a package from five Vite+ tiers and a named layer for every block.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/vite-config@0.6.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#packages/vite-config","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/packages/vite-config#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}]},{"type":"library","name":"react-form","group":"@tanstack","version":"1.33.5","bom-ref":"pkg:npm/%40tanstack/react-form@1.33.5","author":"tannerlinsley","description":"Powerful, type-safe forms for React.","hashes":[{"alg":"SHA-512","content":"2e5441dbca89c0efd0086687bd69db761e216818131626559b3036bb3c52052dd803bfc8aab43a1ce04aef40a4150f836df959ecd6b0b264a59f5de1e6221d4c"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40tanstack/react-form@1.33.5","externalReferences":[{"url":"git+https://github.com/TanStack/form.git#packages/react-form","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://tanstack.com/form","type":"website","comment":"as detected from PackageJson property \"homepage\""}]},{"type":"library","name":"react-hotkeys","group":"@tanstack","version":"0.12.0","bom-ref":"pkg:npm/%40tanstack/react-hotkeys@0.12.0","author":"Tanner Linsley","description":"React adapter for TanStack Hotkeys","hashes":[{"alg":"SHA-512","content":"b0a0ae3cca49e3ab07fc07b1b36663e21e9dfc28780356b02338d30f509b2a04f06f5f03c119ad07fcd32780f841e41d57a068c33752c37cedcf71812e83758c"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40tanstack/react-hotkeys@0.12.0","externalReferences":[{"url":"git+https://github.com/TanStack/hotkeys.git#packages/react-hotkeys","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://tanstack.com/hotkeys","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=20"}]},{"type":"library","name":"react-query","group":"@tanstack","version":"5.104.0","bom-ref":"pkg:npm/%40tanstack/react-query@5.104.0","author":"tannerlinsley","description":"Hooks for managing, caching and syncing asynchronous and remote data in React","hashes":[{"alg":"SHA-512","content":"7b54d99830909d621f88356bc881de03a21d8fe2dfc7584e44b3a15d2fe5e70720bed543e3262a6d30e5dfbf2c1902888b671281bd1310c0bd70a2bc186a0913"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40tanstack/react-query@5.104.0","externalReferences":[{"url":"git+https://github.com/TanStack/query.git#packages/react-query","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://tanstack.com/query","type":"website","comment":"as detected from PackageJson property \"homepage\""}]},{"type":"library","name":"react-router-ssr-query","group":"@tanstack","version":"1.167.3","bom-ref":"pkg:npm/%40tanstack/react-router-ssr-query@1.167.3","author":"Tanner Linsley","description":"Modern and scalable routing for React applications","hashes":[{"alg":"SHA-512","content":"1c0d29c6e3ee854fabc287becf55dc6f2b6ea28e996dc44ea603603529b7f2cdff8462e68333812f30e0f95cb1e9ec76e908a59cf6d9fb96297ade662269bd6d"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40tanstack/react-router-ssr-query@1.167.3","externalReferences":[{"url":"git+https://github.com/TanStack/router.git#packages/react-router-ssr-query","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://tanstack.com/router","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=20.19"}]},{"type":"library","name":"react-router","group":"@tanstack","version":"1.170.40","bom-ref":"pkg:npm/%40tanstack/react-router@1.170.40","author":"Tanner Linsley","description":"Modern and scalable routing for React applications","hashes":[{"alg":"SHA-512","content":"bd5af7bdaf4c72ad39ad946b0d93c6a29b400a544c287bde90b6e983619c7d7bc002d395856e90f77b4ecf876f4bc8f4def4d5ad4db954ceb078fd522071847b"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40tanstack/react-router@1.170.40","externalReferences":[{"url":"git+https://github.com/TanStack/router.git#packages/react-router","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://tanstack.com/router","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=20.19"}]},{"type":"library","name":"react","group":"@testing-library","version":"16.3.3","bom-ref":"pkg:npm/%40testing-library/react@16.3.3","author":"Kent C. Dodds <me@kentcdodds.com> (https://kentcdodds.com)","description":"Simple and complete React DOM testing utilities that encourage good testing practices.","hashes":[{"alg":"SHA-512","content":"528d7ddcd8106cf333ea5aeb86d45040570c0ba45efc42cb15b6ee54bdf4583959c65a597fdfe53074c05713d12f0d6ad62bbd389991d5cd812e210d46cb5d06"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40testing-library/react@16.3.3","externalReferences":[{"url":"https://github.com/testing-library/react-testing-library/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs.url\""},{"url":"https://github.com/testing-library/react-testing-library","type":"vcs","comment":"as detected from PackageJson property \"repository.url\""},{"url":"https://github.com/testing-library/react-testing-library#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=18"}]},{"type":"library","name":"react-dom","group":"@types","version":"19.3.0","bom-ref":"pkg:npm/%40types/react-dom@19.3.0","description":"TypeScript definitions for react-dom","hashes":[{"alg":"SHA-512","content":"648edb538da66575ca1e7fea34b130d88adb888354ed7e7ebdf81d8b10479023696165e32a07d0fcffaec866f90a338b07d51c9d37a0debca542d5768729b8e1"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40types/react-dom@19.3.0","externalReferences":[{"url":"https://github.com/DefinitelyTyped/DefinitelyTyped.git#types/react-dom","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/react-dom","type":"website","comment":"as detected from PackageJson property \"homepage\""}]},{"type":"library","name":"react","group":"@types","version":"19.3.0","bom-ref":"pkg:npm/%40types/react@19.3.0","description":"TypeScript definitions for react","hashes":[{"alg":"SHA-512","content":"374ac50ae1fd628c46f7f9bad65f4c7e924a7e62ce554d1e9bb8a9233e9346049292f45e2c1f6f2fce4607ecabf01b3995eaa9be0f7a252c05e194b5b38be242"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40types/react@19.3.0","externalReferences":[{"url":"https://github.com/DefinitelyTyped/DefinitelyTyped.git#types/react","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/react","type":"website","comment":"as detected from PackageJson property \"homepage\""}]},{"type":"library","name":"coverage-v8","group":"@vitest","version":"5.0.1","bom-ref":"pkg:npm/%40vitest/coverage-v8@5.0.1","author":"Anthony Fu <anthonyfu117@hotmail.com>","description":"V8 coverage provider for Vitest","hashes":[{"alg":"SHA-512","content":"1510bc0028ae742ddd23a313a65cd14985870d19c8bf620f7dbcece0576824db0c6a5ff7e6c595f21c087d5f1972acd23f2fae5c778c54e36df4212ab4e535ef"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40vitest/coverage-v8@5.0.1","externalReferences":[{"url":"https://github.com/vitest-dev/vitest/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs.url\""},{"url":"git+https://github.com/vitest-dev/vitest.git#packages/coverage-v8","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://vitest.dev/guide/coverage","type":"website","comment":"as detected from PackageJson property \"homepage\""}]},{"type":"library","name":"happy-dom","version":"20.14.5","bom-ref":"pkg:npm/happy-dom@20.14.5","author":"David Ortner","description":"Happy DOM is a JavaScript implementation of a web browser without its graphical user interface. It includes many web standards from WHATWG DOM and HTML.","hashes":[{"alg":"SHA-512","content":"c7f47392958ee346d38c8a13df4890b6deb814b2e61ff89171408dd97fff6cbc7b1f789f91d7cf5f2aacae8fce62dab32008622cc300ee69a2391f42dcd38a8d"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/happy-dom@20.14.5","externalReferences":[{"url":"https://github.com/capricorn86/happy-dom","type":"vcs","comment":"as detected from PackageJson property \"repository\""},{"url":"https://github.com/capricorn86/happy-dom","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=20.0.0"}]},{"type":"library","name":"i18next","version":"26.4.2","bom-ref":"pkg:npm/i18next@26.4.2","author":"Jan Mühlemann <jan.muehlemann@gmail.com> (https://github.com/jamuhl)","description":"i18next internationalization framework","hashes":[{"alg":"SHA-512","content":"457f91d152e0d7721bbd1b894b19eaca45054bdbd065397cc18a563c22140d656b4868ec432c01e58fa98f3ae46e8c4602e61f259547d489c54dd801771ababa"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/i18next@26.4.2","externalReferences":[{"url":"https://github.com/i18next/i18next/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"https://github.com/i18next/i18next.git","type":"vcs","comment":"as detected from PackageJson property \"repository.url\""},{"url":"https://www.i18next.com","type":"website","comment":"as detected from PackageJson property \"homepage\""}]},{"type":"library","name":"oxc-transform-react","version":"0.151.0","bom-ref":"pkg:npm/oxc-transform-react@0.151.0","author":"Boshen and oxc contributors","description":"Oxc React Compiler Node API","hashes":[{"alg":"SHA-512","content":"60ed7f62cdc5202fee060ca37b1bc6b084d05085c318d9b1272eafa906ddf1663b263ccc0f5faf095879f65cdaf7f3f4dbf4d135a517c94eceaf6c70c7f29b77"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/oxc-transform-react@0.151.0","externalReferences":[{"url":"https://github.com/oxc-project/oxc/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/oxc-project/oxc.git#napi/transform-react","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://oxc.rs","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":"^20.19.0 || >=22.12.0"}]},{"type":"library","name":"react-dom","version":"19.3.0","bom-ref":"pkg:npm/react-dom@19.3.0","description":"React package for working with the DOM.","hashes":[{"alg":"SHA-512","content":"24393c76089fe753a31680c4ef4f8e4fd202c98afeebd1e59a284dc29d7e36c7db9dadede6c22209af59264b43990e3fd5bfeb9f6ea1200476b985c332be6bd1"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/react-dom@19.3.0","externalReferences":[{"url":"https://github.com/react/react/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs.url\""},{"url":"https://github.com/react/react.git#packages/react-dom","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://react.dev/","type":"website","comment":"as detected from PackageJson property \"homepage\""}]},{"type":"library","name":"react-i18next","version":"17.0.15","bom-ref":"pkg:npm/react-i18next@17.0.15","author":"Jan Mühlemann <jan.muehlemann@gmail.com> (https://github.com/jamuhl)","description":"Internationalization for react done right. Using the i18next i18n ecosystem.","hashes":[{"alg":"SHA-512","content":"eee629c7fa0191eb0bb68edc3b33a67c84e55016971c201c15a8668044cc7d6afc9db6d64519d51afcfcc2c1ffc696cd732a07f8da4272739012a58f30eebf87"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/react-i18next@17.0.15","externalReferences":[{"url":"https://github.com/i18next/react-i18next/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"https://github.com/i18next/react-i18next.git","type":"vcs","comment":"as detected from PackageJson property \"repository.url\""},{"url":"https://github.com/i18next/react-i18next","type":"website","comment":"as detected from PackageJson property \"homepage\""}]},{"type":"library","name":"react","version":"19.3.0","bom-ref":"pkg:npm/react@19.3.0","description":"React is a JavaScript library for building user interfaces.","hashes":[{"alg":"SHA-512","content":"13c2d471bb415addb46db9766281dfc7864305dc554df38ab42667f5c0d227897afe7ba8029729201723e3bb76c19a155fc836647b8c1db892860091d53e52a2"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/react@19.3.0","externalReferences":[{"url":"https://github.com/react/react/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"https://github.com/react/react.git#packages/react","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://react.dev/","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=0.10.0"}]},{"type":"library","name":"typescript","version":"7.0.2","bom-ref":"pkg:npm/typescript@7.0.2","author":"Microsoft Corp.","description":"TypeScript is a language for application scale JavaScript development","hashes":[{"alg":"SHA-512","content":"f0561abbdea8dcd28e85b8ca8bfa8dbc6fd6e63873c646dd9b9b23f406d9ff94f9b16aa7de12602df1b1dbbb11299593bf2cc23fc74b4414dfe6d05349155434"}],"licenses":[{"license":{"id":"Apache-2.0"}}],"purl":"pkg:npm/typescript@7.0.2","externalReferences":[{"url":"https://github.com/microsoft/TypeScript/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs.url\""},{"url":"https://github.com/microsoft/TypeScript.git","type":"vcs","comment":"as detected from PackageJson property \"repository.url\""},{"url":"https://www.typescriptlang.org/","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=16.20.0"}]},{"type":"library","name":"vitest","version":"5.0.1","bom-ref":"pkg:npm/vitest@5.0.1","author":"Anthony Fu <anthonyfu117@hotmail.com>","description":"Next generation testing framework powered by Vite","hashes":[{"alg":"SHA-512","content":"880f799506ca124bebb5391d0209d66d77db8a95a28967bf8439763f9b4c8ba585c03efa1b43715c01a9fccf4439c62ea5e18946beb0a6931cec2a00e354d08e"}],"licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/vitest@5.0.1","externalReferences":[{"url":"https://github.com/vitest-dev/vitest/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs.url\""},{"url":"git+https://github.com/vitest-dev/vitest.git#packages/vitest","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://vitest.dev","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":"^22.12.0 || ^24.0.0 || >=26.0.0"}]}]},"component":{"type":"library","name":"sdk-host","group":"@stealthscale","version":"0.1.0","bom-ref":"pkg:npm/%40stealthscale/sdk-host@0.1.0","description":"Hosts a product composed from plugins: the state its plugins read, its routes, the parts of its frame, its palette and its settings pages.","licenses":[{"license":{"id":"MIT"}}],"purl":"pkg:npm/%40stealthscale/sdk-host@0.1.0","externalReferences":[{"url":"https://github.com/stealth-scale/scale/issues","type":"issue-tracker","comment":"as detected from PackageJson property \"bugs\""},{"url":"git+https://github.com/stealth-scale/scale.git#sdk/host","type":"vcs","comment":"as detected from PackageJson property \"repository.url\" and \"repository.directory\""},{"url":"https://github.com/stealth-scale/scale/tree/main/sdk/host#readme","type":"website","comment":"as detected from PackageJson property \"homepage\""}],"properties":[{"name":"cdx:npm:package:constraint:engine:node","value":">=26.0.0"}],"evidence":{"licenses":[{"license":{"name":"file: LICENSE","text":{"content":"TUlUIExpY2Vuc2UKCkNvcHlyaWdodCAoYykgMjAyNiBTdGVhbHRoIFNjYWxlIEIuVi4KClBlcm1pc3Npb24gaXMgaGVyZWJ5IGdyYW50ZWQsIGZyZWUgb2YgY2hhcmdlLCB0byBhbnkgcGVyc29uIG9idGFpbmluZyBhIGNvcHkKb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgIlNvZnR3YXJlIiksIHRvIGRlYWwKaW4gdGhlIFNvZnR3YXJlIHdpdGhvdXQgcmVzdHJpY3Rpb24sIGluY2x1ZGluZyB3aXRob3V0IGxpbWl0YXRpb24gdGhlIHJpZ2h0cwp0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vciBzZWxsCmNvcGllcyBvZiB0aGUgU29mdHdhcmUsIGFuZCB0byBwZXJtaXQgcGVyc29ucyB0byB3aG9tIHRoZSBTb2Z0d2FyZSBpcwpmdXJuaXNoZWQgdG8gZG8gc28sIHN1YmplY3QgdG8gdGhlIGZvbGxvd2luZyBjb25kaXRpb25zOgoKVGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UgYW5kIHRoaXMgcGVybWlzc2lvbiBub3RpY2Ugc2hhbGwgYmUgaW5jbHVkZWQgaW4gYWxsCmNvcGllcyBvciBzdWJzdGFudGlhbCBwb3J0aW9ucyBvZiB0aGUgU29mdHdhcmUuCgpUSEUgU09GVFdBUkUgSVMgUFJPVklERUQgIkFTIElTIiwgV0lUSE9VVCBXQVJSQU5UWSBPRiBBTlkgS0lORCwgRVhQUkVTUyBPUgpJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSwKRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQU5EIE5PTklORlJJTkdFTUVOVC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFCkFVVEhPUlMgT1IgQ09QWVJJR0hUIEhPTERFUlMgQkUgTElBQkxFIEZPUiBBTlkgQ0xBSU0sIERBTUFHRVMgT1IgT1RIRVIKTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSwKT1VUIE9GIE9SIElOIENPTk5FQ1RJT04gV0lUSCBUSEUgU09GVFdBUkUgT1IgVEhFIFVTRSBPUiBPVEhFUiBERUFMSU5HUyBJTiBUSEUKU09GVFdBUkUuCg==","contentType":"text/plain","encoding":"base64"}}}]}},"supplier":{"name":"Stealth Scale B.V.","url":["https://stealthscale.io"]}},"components":[],"dependencies":[{"ref":"pkg:npm/%40stealthscale/sdk-host@0.1.0"}]}
@@ -0,0 +1,288 @@
1
+ import { DataClientOptions, QueryClient } from "@stealthscale/provider-data";
2
+ import { AccessSource, FlagSource, Product, SessionSource, When } from "@stealthscale/sdk-core";
3
+ import { HostReport, HostStores, RenderTarget } from "@stealthscale/sdk-plugin";
4
+ import { SettingStore } from "@stealthscale/settings";
5
+ import { AnyRoute, AnyRouter, NotFoundRouteProps, RouteMap, RoutesContext } from "@stealthscale/provider-router";
6
+ import { ReactNode } from "react";
7
+ import { DataContext } from "@stealthscale/provider-data/router";
8
+ import { FormGlyphs } from "@stealthscale/component-forms/form";
9
+ //#region src/host/options.d.ts
10
+ /**
11
+ * Lists what a host is created from.
12
+ */
13
+ export interface HostOptions {
14
+ /**
15
+ * Source of decisions on single resources. Every decision is the tenant-wide one without it.
16
+ */
17
+ readonly access?: AccessSource | undefined;
18
+ /**
19
+ * The transport and the changes stream the host's data client runs on. A sampled transport over
20
+ * the contracts' samples where left out.
21
+ */
22
+ readonly data?: Pick<DataClientOptions, "changes" | "transport"> | undefined;
23
+ /**
24
+ * Source of flag values per session. Every flag has its product value or its default without
25
+ * one.
26
+ */
27
+ readonly flags?: FlagSource | undefined;
28
+ /**
29
+ * Milliseconds `ready` waits for the flag source's first `identify`. 1,000 by default.
30
+ */
31
+ readonly flagsTimeout?: number | undefined;
32
+ /**
33
+ * Glyphs the settings sections' forms render: the mark in a checked box, a select's chevron and
34
+ * the others the forms package names. A form renders no mark it has no glyph for.
35
+ */
36
+ readonly glyphs?: FormGlyphs | undefined;
37
+ /**
38
+ * Reads and writes flag overrides. On by default outside a production build.
39
+ */
40
+ readonly overrides?: boolean | undefined;
41
+ /**
42
+ * The resolved product with its plugins' manifests, from `virtual:product`.
43
+ */
44
+ readonly product: Product;
45
+ /**
46
+ * Failed renders in a row after which a route or an extension is quarantined. 3 by default.
47
+ */
48
+ readonly quarantineAfter?: number | undefined;
49
+ /**
50
+ * Receives every entry the host reports. Writes to the console by default.
51
+ */
52
+ readonly report?: ((entry: HostReport) => void) | undefined;
53
+ /**
54
+ * Source of the session.
55
+ */
56
+ readonly session: SessionSource;
57
+ /**
58
+ * Where the host keeps a person's switches, settings and placements.
59
+ */
60
+ readonly store: SettingStore;
61
+ }
62
+ /**
63
+ * Describes a host: the state of one page, or of one request on a server.
64
+ */
65
+ export interface Host {
66
+ /**
67
+ * The data client of the page or the request, which the router's context contains.
68
+ */
69
+ readonly data: QueryClient;
70
+ /**
71
+ * Stops listening to the session source, the flag source, the access source and the setting
72
+ * store, and cancels the data client's fetches.
73
+ */
74
+ readonly dispose: () => void;
75
+ /**
76
+ * Resolves once the eager plugins' modules are imported and the flag source has identified the
77
+ * session, or once the flag timeout passes.
78
+ */
79
+ readonly ready: () => Promise<void>;
80
+ /**
81
+ * Lifts a target's quarantine and forgets its failures.
82
+ */
83
+ readonly retry: (target: RenderTarget) => void;
84
+ /**
85
+ * The host's stores, which `HostProvider` provides and the hooks of `sdk-plugin` read.
86
+ */
87
+ readonly stores: HostStores;
88
+ }
89
+ //#endregion
90
+ //#region src/host/create-host.d.ts
91
+ /**
92
+ * Creates a host for one page, or for one request on a server.
93
+ *
94
+ * @remarks
95
+ * The host subscribes to the session source, the setting store, the flag source and the access
96
+ * source as it is created. It emits the session as `host/sessionChanged`, and starts the flag
97
+ * source's identification and the eager plugins' imports. The imports go through the runtime's
98
+ * product, whose importers measure each plugin's first import and recover from a chunk that no
99
+ * longer exists. `dispose` ends the subscriptions and cancels the data client's fetches.
100
+ * @throws {@link Error} Where the product's manifests lack code for a declared name.
101
+ */
102
+ export declare function createHost(options: HostOptions): Host;
103
+ //#endregion
104
+ //#region src/hydration/integration.d.ts
105
+ /**
106
+ * Lists what the host integration connects.
107
+ */
108
+ export interface HostIntegrationOptions {
109
+ /**
110
+ * The host of the request on a server, or of the page in the browser.
111
+ */
112
+ readonly host: Host;
113
+ /**
114
+ * The router whose context contains the host.
115
+ */
116
+ readonly router: AnyRouter;
117
+ }
118
+ /**
119
+ * Passes the host's state from a server render to the browser's first render.
120
+ *
121
+ * @remarks
122
+ * A product calls it where it calls `setupDataIntegration`: in the server's router factory for
123
+ * each request, and in the browser before the router hydrates. On a server the router's
124
+ * dehydrated state gains a snapshot of the host, taken once the render finished: the subject, the
125
+ * flags the render read and the decisions the host knew before it. In the browser the router
126
+ * awaits the snapshot before its first render, and the host reads the server's flags until
127
+ * `HostProvider` mounts, so the first render matches the server's. The host takes the decisions
128
+ * only where the browser's subject is the server's.
129
+ * @param options - The host and the router whose context contains it.
130
+ */
131
+ export declare function setupHostIntegration({ host, router }: HostIntegrationOptions): void;
132
+ //#endregion
133
+ //#region src/parts/content.d.ts
134
+ /**
135
+ * Renders the root route's outlet inside the `content` region, so the region's extensions decorate
136
+ * every page.
137
+ *
138
+ * @remarks
139
+ * The frame renders it where the page belongs. A frame that renders `Outlet` in its place renders
140
+ * pages without the region, and the extension statuses read the region as not mounted.
141
+ */
142
+ export declare function HostContent(): ReactNode;
143
+ //#endregion
144
+ //#region src/parts/not-found.d.ts
145
+ /**
146
+ * Renders the not-found page the router's data describes.
147
+ *
148
+ * @remarks
149
+ * A page whose plugin a switch turned off names the plugin and offers a button that turns it on.
150
+ * A page whose plugin a kill switch stopped names the plugin and offers nothing. A quarantined
151
+ * page offers a retry that lifts the quarantine. Data of another shape, or none, renders a plain
152
+ * not-found page, which states nothing about the address. The host runs the router's
153
+ * `beforeLoad` again after a switch or a retry, and the page renders again in this one's place.
154
+ */
155
+ export declare function HostNotFound({ data }: NotFoundRouteProps): ReactNode;
156
+ //#endregion
157
+ //#region src/parts/provider.d.ts
158
+ /**
159
+ * Describes the props of `HostProvider`.
160
+ */
161
+ export interface HostProviderProps {
162
+ /**
163
+ * The product's tree, which renders the router through `RouterProvider`.
164
+ */
165
+ readonly children?: ReactNode;
166
+ /**
167
+ * The host the router's context contains.
168
+ */
169
+ readonly host: Host;
170
+ /**
171
+ * The router whose context contains the host.
172
+ */
173
+ readonly router: AnyRouter;
174
+ }
175
+ /**
176
+ * Provides a host to the product's tree, once per render tree.
177
+ *
178
+ * @remarks
179
+ * The `root` region renders around the router, so its extensions render outside every route and
180
+ * read the router's matches through the router's context. The provider connects the host to the
181
+ * router (`useConnected`) and titles the document with the product's name as it mounts and as
182
+ * the language changes, before any page titles it. It renders the failure page in place of a
183
+ * tree that throws outside the router.
184
+ */
185
+ export declare function HostProvider({ children, host, router }: HostProviderProps): ReactNode;
186
+ //#endregion
187
+ //#region src/parts/root.d.ts
188
+ /**
189
+ * Describes the props of `HostRoot`.
190
+ */
191
+ export interface HostRootProps {
192
+ /**
193
+ * The product's frame.
194
+ */
195
+ readonly children?: ReactNode;
196
+ }
197
+ /**
198
+ * Renders the product's frame inside the `layout` region, the `overlay` region after it, and the
199
+ * keys of the product's commands.
200
+ *
201
+ * @remarks
202
+ * The router renders the root route's component inside a catch boundary of its own, so the
203
+ * component renders the host's last boundary around the frame, and an error in the frame
204
+ * renders the failure page and is reported with the target `host`.
205
+ */
206
+ export declare function HostRoot({ children }: HostRootProps): ReactNode;
207
+ //#endregion
208
+ //#region src/routes/context.d.ts
209
+ /**
210
+ * Lists what the router's context contains in a product.
211
+ */
212
+ export interface HostRouterContext extends DataContext, RoutesContext {
213
+ /**
214
+ * The host whose state every route condition reads.
215
+ */
216
+ readonly host: Host;
217
+ /**
218
+ * Every declared id, against the route compiled for it. The sign-in redirect resolves the sign-in
219
+ * route's path through it.
220
+ */
221
+ readonly routes: RouteMap;
222
+ }
223
+ /**
224
+ * Lists what a compiled plugin route's condition contains.
225
+ */
226
+ export interface HostCondition {
227
+ /**
228
+ * Id of the plugin that declared the route.
229
+ */
230
+ readonly pluginId: string;
231
+ /**
232
+ * Qualified id of the route.
233
+ */
234
+ readonly routeId: string;
235
+ /**
236
+ * The route's condition joined with the product's `when`. Absent where neither states one.
237
+ */
238
+ readonly when?: undefined | When;
239
+ }
240
+ /**
241
+ * Describes a page whose plugin is not on: the plugin whose state stops it, the page's own or one
242
+ * it requires, and that plugin's reason.
243
+ */
244
+ export interface PluginUnavailable {
245
+ /**
246
+ * Id of the plugin whose state stops the page.
247
+ */
248
+ readonly plugin: string;
249
+ /**
250
+ * `off` where a switch turned the plugin off, `unavailable` where its kill switch stopped it.
251
+ */
252
+ readonly reason: "off" | "unavailable";
253
+ }
254
+ /**
255
+ * Describes a page the host quarantined after it failed its renders.
256
+ */
257
+ export interface PageQuarantined {
258
+ /**
259
+ * The reason the page is not found.
260
+ */
261
+ readonly reason: "quarantined";
262
+ /**
263
+ * The quarantined target: `route:<id>`.
264
+ */
265
+ readonly target: RenderTarget;
266
+ }
267
+ /**
268
+ * Lists the data of a not-found error the route evaluator throws, which the not-found page reads.
269
+ */
270
+ export type NotFoundData = PageQuarantined | PluginUnavailable;
271
+ //#endregion
272
+ //#region src/routes/create-routes.d.ts
273
+ /**
274
+ * Returns a function of the product's root route that compiles every route of the product under
275
+ * it.
276
+ *
277
+ * @remarks
278
+ * The routes compile in one call, so the compiler sees every path at once. Each route loads its
279
+ * page with the modules of the plugins in its `loads`, loads its `data` through the data client
280
+ * in the router's context, validates its search with its contract's validator, and evaluates its
281
+ * condition against the host in the router's context. The settings route renders the settings
282
+ * frame, its index opens the first settings page, and each settings page renders its sections.
283
+ * The pages import through the manifests' importers as `instrumented` wraps them.
284
+ * @param product - The product, with each installed plugin's manifest.
285
+ * @returns The function that compiles the routes under the root, for the root's `addChildren`.
286
+ */
287
+ export declare function createHostRoutes(product: Product): (root: AnyRoute) => readonly AnyRoute[];
288
+ //#endregion
package/dist/index.js ADDED
@@ -0,0 +1,81 @@
1
+ import { a as HostContent, i as HostNotFound, n as HostRoot, o as createHost, r as HostProvider, s as internalsOf, t as createHostRoutes } from "./create-routes-CkgZV-dU.js";
2
+ import { subjectOf } from "@stealthscale/sdk-core";
3
+ //#region src/hydration/integration.ts
4
+ /**
5
+ * Returns true where a value is an object whose members can be read by name.
6
+ */
7
+ function isRecord(value) {
8
+ return typeof value === "object" && value !== null;
9
+ }
10
+ /**
11
+ * Returns true where a value has the snapshot's two lists.
12
+ */
13
+ function isSnapshot(value) {
14
+ return isRecord(value) && Array.isArray(value["decisions"]) && Array.isArray(value["flags"]);
15
+ }
16
+ /**
17
+ * Returns the subject of the host's session: the person and the tenant, or undefined for nobody.
18
+ */
19
+ function subjectIn(host) {
20
+ return subjectOf(host.stores.session.get().session);
21
+ }
22
+ /**
23
+ * Wraps the router's `dehydrate` on a server: the earlier function's result, plus `host`, a promise
24
+ * of the host's snapshot that resolves once the render finished.
25
+ */
26
+ function dehydrating(host, router) {
27
+ const { access, flags } = internalsOf(host);
28
+ const earlier = router.options.dehydrate;
29
+ router.options.dehydrate = async () => {
30
+ const dehydrated = await earlier?.();
31
+ const decisions = [...access.get().decisions];
32
+ const serverSsr = router.serverSsr;
33
+ const snapshot = new Promise((resolve) => {
34
+ serverSsr.onRenderFinished(() => {
35
+ resolve({
36
+ decisions,
37
+ flags: flags.snapshot(),
38
+ subject: subjectIn(host)
39
+ });
40
+ });
41
+ });
42
+ return {
43
+ ...isRecord(dehydrated) ? dehydrated : {},
44
+ host: snapshot
45
+ };
46
+ };
47
+ }
48
+ /**
49
+ * Wraps the router's `hydrate` in the browser: after the earlier function, it awaits the server's
50
+ * snapshot and hydrates the host from it.
51
+ */
52
+ function hydrating(host, router) {
53
+ const { access, flags } = internalsOf(host);
54
+ const earlier = router.options.hydrate;
55
+ router.options.hydrate = async (dehydrated) => {
56
+ await earlier?.(dehydrated);
57
+ const snapshot = isRecord(dehydrated) ? await dehydrated["host"] : void 0;
58
+ if (!isSnapshot(snapshot)) return;
59
+ flags.hydrate(snapshot.flags, snapshot.subject);
60
+ if (snapshot.subject === subjectIn(host)) access.hydrate(snapshot.decisions);
61
+ };
62
+ }
63
+ /**
64
+ * Passes the host's state from a server render to the browser's first render.
65
+ *
66
+ * @remarks
67
+ * A product calls it where it calls `setupDataIntegration`: in the server's router factory for
68
+ * each request, and in the browser before the router hydrates. On a server the router's
69
+ * dehydrated state gains a snapshot of the host, taken once the render finished: the subject, the
70
+ * flags the render read and the decisions the host knew before it. In the browser the router
71
+ * awaits the snapshot before its first render, and the host reads the server's flags until
72
+ * `HostProvider` mounts, so the first render matches the server's. The host takes the decisions
73
+ * only where the browser's subject is the server's.
74
+ * @param options - The host and the router whose context contains it.
75
+ */
76
+ function setupHostIntegration({ host, router }) {
77
+ if (router.isServer) dehydrating(host, router);
78
+ else hydrating(host, router);
79
+ }
80
+ //#endregion
81
+ export { HostContent, HostNotFound, HostProvider, HostRoot, createHost, createHostRoutes, setupHostIntegration };
@@ -0,0 +1,27 @@
1
+ import { FlagSource } from "@stealthscale/sdk-core";
2
+ //#region src/openfeature.d.ts
3
+ /**
4
+ * Lists the options of the OpenFeature adapter.
5
+ */
6
+ export interface OpenFeatureFlagsOptions {
7
+ /**
8
+ * Domain the host's client is bound to. `stealth.host` where left out.
9
+ */
10
+ readonly domain?: string | undefined;
11
+ }
12
+ /**
13
+ * Returns a flag source that evaluates the host's flags through the OpenFeature client of a domain.
14
+ *
15
+ * @remarks
16
+ * A product binds its provider to the domain with `OpenFeature.setProvider(domain, provider)`, so
17
+ * a product that runs OpenFeature elsewhere keeps its own default provider. `identify` sets the
18
+ * domain's evaluation context to the session and resolves once the provider reconciled it.
19
+ * `evaluate` returns no value where no provider is bound to the domain, so every flag takes the
20
+ * product's value. `subscribe` follows the provider's `Ready`, `ConfigurationChanged` and
21
+ * `ContextChanged` events, and OpenFeature calls a listener at once where the provider is
22
+ * ready. OpenFeature keeps one context per domain for the page, so a server passes a flag source
23
+ * per request instead.
24
+ * @param options - The domain the host's client is bound to.
25
+ */
26
+ export declare function openFeatureFlags({ domain }?: OpenFeatureFlagsOptions): FlagSource;
27
+ //#endregion
@@ -0,0 +1,80 @@
1
+ import { NOOP_PROVIDER, OpenFeature, ProviderEvents, StandardResolutionReasons } from "@openfeature/web-sdk";
2
+ //#region src/openfeature.ts
3
+ /**
4
+ * Adapts an OpenFeature client to the host's flag source, for a product whose flags run through
5
+ * OpenFeature in the browser.
6
+ */
7
+ /**
8
+ * Domain the host's client is bound to where the product states none.
9
+ */
10
+ const DOMAIN = "stealth.host";
11
+ /**
12
+ * The provider events after which the provider's values may differ.
13
+ */
14
+ const CHANGES = [
15
+ ProviderEvents.Ready,
16
+ ProviderEvents.ConfigurationChanged,
17
+ ProviderEvents.ContextChanged
18
+ ];
19
+ /**
20
+ * Returns a session as an evaluation context: the person as the targeting key, beside whether
21
+ * somebody is signed in, the tenant's entitlements, the person's roles and the tenant.
22
+ */
23
+ function contextOf(session) {
24
+ return {
25
+ authenticated: session.authenticated,
26
+ entitlements: [...session.entitlements],
27
+ roles: [...session.roles],
28
+ ...session.tenantId === void 0 ? {} : { tenantId: session.tenantId },
29
+ ...session.userId === void 0 ? {} : { targetingKey: session.userId }
30
+ };
31
+ }
32
+ /**
33
+ * Returns the value an evaluation resolved, or undefined where the provider stated none.
34
+ *
35
+ * @remarks
36
+ * A provider states no value where the evaluation reports an error code, such as for a flag it
37
+ * does not know, and where it disabled the flag: both return the default the adapter passed,
38
+ * which is not the product's.
39
+ */
40
+ function valueOf(details) {
41
+ return details.errorCode === void 0 && details.reason !== StandardResolutionReasons.DISABLED ? details.value : void 0;
42
+ }
43
+ /**
44
+ * Returns a flag source that evaluates the host's flags through the OpenFeature client of a domain.
45
+ *
46
+ * @remarks
47
+ * A product binds its provider to the domain with `OpenFeature.setProvider(domain, provider)`, so
48
+ * a product that runs OpenFeature elsewhere keeps its own default provider. `identify` sets the
49
+ * domain's evaluation context to the session and resolves once the provider reconciled it.
50
+ * `evaluate` returns no value where no provider is bound to the domain, so every flag takes the
51
+ * product's value. `subscribe` follows the provider's `Ready`, `ConfigurationChanged` and
52
+ * `ContextChanged` events, and OpenFeature calls a listener at once where the provider is
53
+ * ready. OpenFeature keeps one context per domain for the page, so a server passes a flag source
54
+ * per request instead.
55
+ * @param options - The domain the host's client is bound to.
56
+ */
57
+ function openFeatureFlags({ domain = DOMAIN } = {}) {
58
+ const client = OpenFeature.getClient(domain);
59
+ return {
60
+ evaluate: ({ id, type }) => {
61
+ const details = type === "boolean" ? client.getBooleanDetails(id, false) : client.getStringDetails(id, "");
62
+ return OpenFeature.getProvider(domain) === NOOP_PROVIDER ? void 0 : valueOf(details);
63
+ },
64
+ identify: (session) => OpenFeature.setContext(domain, contextOf(session)),
65
+ subscribe: (listener) => {
66
+ /**
67
+ * Calls the listener without the event's details.
68
+ */
69
+ const changed = () => {
70
+ listener();
71
+ };
72
+ for (const event of CHANGES) client.addHandler(event, changed);
73
+ return () => {
74
+ for (const event of CHANGES) client.removeHandler(event, changed);
75
+ };
76
+ }
77
+ };
78
+ }
79
+ //#endregion
80
+ export { openFeatureFlags };