You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
and re-exported again from the Notifications barrel. So import { toast } from '@cratis/components/Notifications' hands the consumer PrimeReact's imperative toast API under a Cratis name.
This is the only PrimeReact runtime value in Components' public surface — every other public leak is a type.
Evidence
Measured against the published @cratis/components@3.4.0 artifact with primereact@11.1.0.
Of 27 distinct PrimeReact symbols reachable from Components' public entry points, 26 are types (18 of them only via pt/ptOptions). toast is the single runtime value, which makes it categorically different: a type leak costs a consumer a commercial type import, whereas this one means the behavior itself is PrimeReact's, including its options shape, its dismissal semantics and its store.
Two consequences already visible in the issue tracker:
A custom toast render silently removes the toast's dismiss control, and Toaster exposes no pt #156 — a custom toast.render silently removes the toast's dismiss control, and Toaster exposes no pt. That is PrimeReact's rendering contract surfacing through a Cratis-named API, and the workaround (mint the id up front, render your own close button inside the custom body) is a consumer working around PrimeReact through a seam that does not admit to being PrimeReact.
toastCommandResult — genuinely Cratis-owned behavior, mapping an Arc ICommandResult to a severity — is built on top of that re-export, so the one piece that is Cratis's differentiator sits on a foundation the consumer cannot substitute.
What it costs a consumer
Small but real, and structurally awkward out of proportion to its size.
The whole notification surface is unsubstitutable. An application that has its own toast system (ours does not, but many do) cannot supply it while keeping toastCommandResult, because the Cratis-authored part depends on the PrimeReact-authored part rather than on a contract.
It is a licence-surface item with no opt-out. Unlike pt, a consumer cannot decline to use it and still get command-result notifications.
Honest limit: this has caused no defect in our application beyond #156, which is already filed. Filing this for the shape, not for a failure.
Suggested fix — the seam
Put a thin Cratis-owned dispatch in front of it:
Define a Cratis toast API — success / info / warn / error / promise / dismiss with a Cratis-owned options type — and have the PrimeReact implementation satisfy it, rather than re-exporting PrimeReact's function directly.
Let toastCommandResult depend on that contract, so the Arc-binding logic (result → severity → message) becomes independent of who renders the toast. This is the piece worth making headless; the renderer is not.
Optionally, allow a consumer-supplied dispatch so an application with an existing notification system can receive command-result notifications through it.
(1) alone is nearly free — a wrapper function and an options type — and is what makes (2) possible.
What is explicitly not being asked for
Not removing PrimeReact's toaster as the default implementation, or requiring anyone to supply their own.
What happens
toast— a PrimeReact runtime value, not a type — is re-exported verbatim as Cratis public API:and re-exported again from the
Notificationsbarrel. Soimport { toast } from '@cratis/components/Notifications'hands the consumer PrimeReact's imperative toast API under a Cratis name.This is the only PrimeReact runtime value in Components' public surface — every other public leak is a type.
Evidence
Measured against the published
@cratis/components@3.4.0artifact withprimereact@11.1.0.Of 27 distinct PrimeReact symbols reachable from Components' public entry points, 26 are types (18 of them only via
pt/ptOptions).toastis the single runtime value, which makes it categorically different: a type leak costs a consumer a commercial type import, whereas this one means the behavior itself is PrimeReact's, including its options shape, its dismissal semantics and its store.Two consequences already visible in the issue tracker:
toast.rendersilently removes the toast's dismiss control, andToasterexposes nopt. That is PrimeReact's rendering contract surfacing through a Cratis-named API, and the workaround (mint the id up front, render your own close button inside the custom body) is a consumer working around PrimeReact through a seam that does not admit to being PrimeReact.toastCommandResult— genuinely Cratis-owned behavior, mapping an ArcICommandResultto a severity — is built on top of that re-export, so the one piece that is Cratis's differentiator sits on a foundation the consumer cannot substitute.What it costs a consumer
Small but real, and structurally awkward out of proportion to its size.
toastCommandResult, because the Cratis-authored part depends on the PrimeReact-authored part rather than on a contract.pt, a consumer cannot decline to use it and still get command-result notifications.toastCommandResultis exactly the kind of Arc-binding behavior Prove a renderer-neutral Arc React query/table state seam #109 argues should live headlessly — it maps a command result to a severity and message, which is pure logic — but it cannot move while its dispatch is a PrimeReact re-export.Honest limit: this has caused no defect in our application beyond #156, which is already filed. Filing this for the shape, not for a failure.
Suggested fix — the seam
Put a thin Cratis-owned dispatch in front of it:
success/info/warn/error/promise/dismisswith a Cratis-owned options type — and have the PrimeReact implementation satisfy it, rather than re-exporting PrimeReact's function directly.toastCommandResultdepend on that contract, so the Arc-binding logic (result → severity → message) becomes independent of who renders the toast. This is the piece worth making headless; the renderer is not.(1) alone is nearly free — a wrapper function and an options type — and is what makes (2) possible.
What is explicitly not being asked for
renderto compose inside the toast frame and forptonToaster; this asks that the dispatch function be Cratis's rather than a verbatim re-export. A custom toast render silently removes the toast's dismiss control, and Toaster exposes no pt #156 stands on its own and would still be worth fixing.toast.*call sites consumers already have — a wrapper can preserve today's signatures.