Osy#betaRun it on Osyrin: osyrin.com

Reference / Local

Composing kits — what they give together, and what is left for you

osy compose <kits…> [--diff +<kit>] [--effects] [--offline] [--json] · osy compose [--app <dir>]

Before any code, shows what a set of kits gives together — the bridges that arrive by themselves, every event with its handlers in the order they run, slots and their contributions, records, actions, nav — and what is LEFT for your app: the policies to define, the settings to fill and the bases to derive, each with the kit's test app line that does it.

stablelocalclipackageskits

Summary#

osy compose answers the question to ask after choosing kits and before writing code: what do these give together, and what is left for me? Named kits are composed as a dry run — with every kit they use, and every bridge that completes a pair among them. Run inside an app (or with --app <dir>), it composes what the app uses together with the app's own code, so what is left is what the app has not done yet.

$ osy compose Osysharp.SatisfactionSurveys Osysharp.Notifications
Composing Osysharp.SatisfactionSurveys, Osysharp.Notifications — 8 kit(s) with what they use

kits      Osysharp.Identity · Osysharp.Ui · Osysharp.Workflow · Osysharp.TimeZone · Osysharp.EmailTemplates · Osysharp.Mail · Osysharp.SatisfactionSurveys (vertical) · Osysharp.Notifications

events — handlers in the order they run, after the commit
  heard by no handler of its own (1) — `[On] void H(TheEvent e) { … }` hears one: FeedbackAnswered (Osysharp.SatisfactionSurveys)

left for you
  define  policy ManagesFeedback (Osysharp.SatisfactionSurveys) — Who decides whether, when and for how long people are asked — the settings page.
          its test app: policy ManagesFeedback => IsOwner;
  define  policy ReadsFeedback (Osysharp.SatisfactionSurveys) — Who reads the answers and the results — the people who did the work, and whoever looks after how it goes.
          its test app: policy ReadsFeedback => IsMechanic;
  define  policy ReceivesNotifications (Osysharp.Notifications) — Who has a bell and notification preferences — the people the app tells things.
          its test app: policy ReceivesNotifications => IsWriter;
  may define  policy ManagesClock (Osysharp.TimeZone; has a default) — Who may move the app's clock — the app's admins, unless the app says otherwise: …
          its test app: policy ManagesClock => IsOwner;

Signature#

osy compose <kits…>          # a dry run over these kits, what they use, and the bridges among them
osy compose [--app <dir>]    # what this app uses, with its own code (the default inside an app)
  --diff +<kit>              # what one more kit adds
  --effects                  # what each handler can create, change, delete, raise or send (always on in an app)
  --project <dir>            # where to look for kits — the workspace above it, its lock
  --offline                  # only kits on this machine: no newest release from GitHub, no bridge search there
  --json                     # { composition: { packages, events, slots, extensions, records, actions, settings, nav, left } }

Description#

What it prints#

  • kits — every kit in the composition, a product kit marked (vertical), and each included bridge with why it arrived (completes Osysharp.WorkQueues + Osysharp.Notifications) and how to keep it out (without …;).
  • records — each record type with a title, the page that opens it and the actions offered on it.
  • events — each event with who raises it and its handlers in the order they run: [Order] (default 100), then the package — a kit before the kits built on it, your app last — then the name. The handlers that hear every event (automations, webhooks, a timeline) are said once. Events nothing hears specifically are listed on one line.
  • slots — each slot with its contributions in drawing order; a slot nothing fills is shown, not an error.
  • extension members — the members a bridge (or your app) adds to another kit's record.
  • nav and settings pages — the entries each kit adds.
  • left for you — what the composition still needs from your app: each policy a kit asks for and the app has not defined (with the kit's test app's line that defines it), each setting whose fields have no default, each abstract base with no type of your own.

Two kinds of account#

An app has ONE [Principal] (who signs in is one table), one [Role] enum, and one sign-in. A set of kits that brings two of any of them is said FIRST, before everything else, because it is not one app: the compile refuses the first two, and of two kits that each wire a sign-in only one is ever reached. The line names both declarers — and a kit you never named by the kit that brought it, so the use to drop is the one in your app. In an app that declares its own roles and uses the shop, whose roles are the shop's:

$ osy compose
⚠ two role vocabularies: `AppRole` (this app) and `ShopRole` (Osysharp.Shop). An app has only ONE `[Role]` enum — the roles a sign-in carries, counted across the app and every kit it uses, so this set does not compile as one app. Keep one kit's accounts: drop `Osysharp.Shop` (or your own) from the set, or use a kit that builds on the other's.

Kits that BUILD ON one another share one identity and are not a clash: the shop's ShopAccount is an Osysharp.UserAccounts User, itself an Osysharp.Identity Principal, so the shop composes with every kit on that identity — feedback, invitations, the people kit.

--diff +<kit> says it when the kit it adds is what brings the second; --json carries the lines as clashes.

What a handler can change#

--effects resolves the composition and prints, beside each handler, what it — and everything it calls — can create, change, delete, raise or send out. In an app it is always on. It is the review to make before a kit's handler runs on your data:

events — handlers in the order they run, after the commit
  every event is heard by RunRules (Osysharp.Automations, only what its [Interest] names), SendOut (Osysharp.Webhooks, only what its [Interest] names), InboxOnTheTimeline (this app, only what its [Interest] names)
    RunRules · creates AutomationFire; changes AutomationFire; and calls whose effects are not known here
    SendOut · creates WebhookDelivery; and calls whose effects are not known here
    InboxOnTheTimeline · creates ConversationEvent; changes Conversation
  FeedbackAnswered (Osysharp.SatisfactionSurveys raised by ApplyFeedbackReply)
    → TicketAnswered (this app) · creates ConversationEvent, Notification; changes Conversation, Ticket; Policy.CheckFor

One more kit#

--diff +<kit> composes once without the kit and once with it, and prints only what it adds: the kits (with any bridge it completes), the handlers it brings to events already there, contributions, nav, extension members, and the policies and settings it leaves for you.

The same data in osy model#

osy model --json carries the app's composition as composition — the same shape osy compose --app . --json prints — for a tool (Understanding your app).

See also#

Related

Connecting a kit — each seam with the code that connects it

Prints a kit's composition surface — every event, policy, setting, slot, contract, base, grant, extension member…

Finding a kit, and learning one from its tests

Lists the kits (packages) this project can build on — each one's contracts, the kits that implement them, and what this…

Bridges — a package that arrives when an app uses the two it completes

A bridge is a package whose manifest says `completes A@0, B@0;`. An app that uses every package it completes gets it…

[On] — hear an event, after the commit that raised it

`[On]` on a function makes it a HANDLER of the event its one parameter is. Every handler of an event — in the app and…

Slot (child content)

A `Slot` marks where a component renders the content block its caller wrapped around it. Writing `Card { Text("hi"); }`…

Understanding your app

Prints your app's RESOLVED model — field types bound to real types, relations wired to the entity they target, each…