@cratis/stage.runtime 0.0.0 → 4.157.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,69 @@
1
+ import type { DestinationReference, Screen } from '@cratis/scene.model';
2
+ /** The contribution point the application's navigation is contributed to. */
3
+ export declare const navigationContributionPoint = "Navigation";
4
+ /** One authored navigation entry: what it is called, the screen it opens and where in the application it was declared. */
5
+ export interface NavigationEntry {
6
+ label: string;
7
+ targetScreen: string;
8
+ /** The module and features, outermost first, the entry was declared in. */
9
+ hierarchy: string[];
10
+ order?: number;
11
+ /** The icon the entry was authored with. */
12
+ icon?: string;
13
+ /** How chrome shows the entry - `icon`, `text` or `both`; any other value is a hint the theme may read. */
14
+ presentation?: string;
15
+ /** Where the entry opens when that is not simply the screen: an outlet, a dialog or an external route. */
16
+ destination?: DestinationReference;
17
+ }
18
+ /** A node of the navigation tree: a group (module or feature) with children, or an entry that opens a screen. */
19
+ export interface NavigationNode {
20
+ label: string;
21
+ /** The screen the node opens; absent on a group. */
22
+ screen?: string;
23
+ icon?: string;
24
+ presentation?: string;
25
+ destination?: DestinationReference;
26
+ children: NavigationNode[];
27
+ }
28
+ /**
29
+ * The navigation the model authored: every `Navigation` contribution on any screen, once.
30
+ *
31
+ * A feature's contribution is attached to every screen of the feature, so the same entry arrives several times;
32
+ * an entry is the same when it opens the same screen from the same place under the same label.
33
+ *
34
+ * @param screens The scene's screens.
35
+ * @returns The authored entries, in the order the model gave them (ordered ones first, by `order`).
36
+ */
37
+ export declare function authoredNavigationEntries(screens: Screen[]): NavigationEntry[];
38
+ /**
39
+ * Lays the entries out as the application hierarchy the model declared: a group per module and per feature,
40
+ * nested as deep as the model nests them, with each entry under the feature it was declared in. Groups and
41
+ * entries keep the order of the entries, so an ordered entry orders the group it sits in.
42
+ *
43
+ * @param entries The authored entries.
44
+ * @returns The top-level nodes.
45
+ */
46
+ export declare function navigationTree(entries: NavigationEntry[]): NavigationNode[];
47
+ /**
48
+ * The labels leading to a screen in the tree - each group, then the entry - for the breadcrumb.
49
+ *
50
+ * @param nodes The navigation tree.
51
+ * @param screen The screen to find.
52
+ * @returns The labels from the outermost group to the entry, or an empty list when no entry opens the screen.
53
+ */
54
+ export declare function navigationPathTo(nodes: NavigationNode[], screen: string): string[];
55
+ /** Whether an entry opens somewhere a plain link to its screen does not reach: an outlet, a dialog or an external route. */
56
+ export declare function opensElsewhere(destination: DestinationReference): boolean;
57
+ /**
58
+ * The hierarchy the screens declare, for the screens no navigation entry lists.
59
+ *
60
+ * A screen records the modules and features it was declared in, so one the model gave no entry still has a place:
61
+ * under its own module and feature, beside the entries that do list screens there. A screen declared outside any
62
+ * module has no place to be under, and goes with the other screens that have none.
63
+ *
64
+ * @param screens The scene's screens.
65
+ * @param listed The names of the screens an authored entry opens.
66
+ * @param fallback The group a screen with no recorded place goes under.
67
+ * @returns One entry for every unlisted screen, labelled with its own name.
68
+ */
69
+ export declare function unlistedNavigationEntries(screens: Screen[], listed: ReadonlySet<string>, fallback: string): NavigationEntry[];
@@ -0,0 +1,31 @@
1
+ import type { ExternalComponent, SceneElement } from '@cratis/scene.model';
2
+ import type { InteractionHandlers } from '@cratis/scene.react';
3
+ import type { ComponentType, ReactNode } from 'react';
4
+ import { StageCommandForm } from './StageCommandForm';
5
+ export declare const stageCommandFormComponent = "Stage:commandForm";
6
+ interface RegisteredProps {
7
+ element: ExternalComponent;
8
+ slots: Record<string, ReactNode[]>;
9
+ interactions?: InteractionHandlers;
10
+ }
11
+ /**
12
+ * Reads a slice's read model through the query the Stage registered for it.
13
+ *
14
+ * A table the model says navigates on a row click (`navigate to WorkItemDetails by workItemId`) carries that
15
+ * parameter in the address: clicking a row on another screen navigates there with the row's identity, clicking a
16
+ * row on the target screen itself updates the parameter in place, and opening an address that already carries it
17
+ * selects the row it names. The parameter is then what every query and command on the screen is scoped by.
18
+ */
19
+ export declare function StageTable({ element, slots }: RegisteredProps): import("react").JSX.Element;
20
+ /** Renders an authored screen form bound to a modeled command. */
21
+ export { StageCommandForm };
22
+ /** Executes a modeled command against the route the Stage registered for it. */
23
+ export declare function StageAction({ element, interactions, slots }: RegisteredProps): import("react").JSX.Element;
24
+ /**
25
+ * The components the Stage renders a scene with: Scene's own core vocabulary, with the two that have to reach
26
+ * this running application - the table that reads a modeled query, and the action that executes a modeled
27
+ * command - replaced by versions that do.
28
+ */
29
+ export declare const stageComponents: Record<string, ComponentType<RegisteredProps>>;
30
+ /** Whether an element tree contains anything the Stage can act on. */
31
+ export declare function isActionable(element: SceneElement): boolean;
@@ -0,0 +1,72 @@
1
+ import type React from 'react';
2
+ import type { BindingExpression } from '@cratis/scene.model';
3
+ import type { StageRoutes } from './stageRoutes';
4
+ interface QueryState {
5
+ name?: string;
6
+ route: string;
7
+ rows: Record<string, unknown>[];
8
+ loading: boolean;
9
+ error: string;
10
+ arguments: Record<string, unknown>;
11
+ }
12
+ export interface StageQueryRequest {
13
+ scope: string;
14
+ name?: string;
15
+ route?: string;
16
+ arguments?: Record<string, unknown>;
17
+ ready?: boolean;
18
+ /**
19
+ * Whether the result is published to the screen's bindings. A query read only to decide something - the item a
20
+ * guard is evaluated against - is not, so it does not show up twice where the screen reads the same query.
21
+ */
22
+ publish?: boolean;
23
+ }
24
+ export interface StageQueryResult {
25
+ rows: Record<string, unknown>[];
26
+ loading: boolean;
27
+ error: string;
28
+ refresh: () => void;
29
+ }
30
+ export interface StageDataState {
31
+ locale: string;
32
+ locales: string[];
33
+ screen: string;
34
+ routes: StageRoutes | undefined;
35
+ routesReady: boolean;
36
+ parameters: Record<string, string>;
37
+ queries: Record<string, QueryState>;
38
+ selected: Record<string, unknown> | undefined;
39
+ selections: Record<string, Record<string, unknown> | undefined>;
40
+ selectRow: (scope: string, row: Record<string, unknown> | undefined) => void;
41
+ clearSelection: (scope: string) => void;
42
+ setState: (key: string, value: unknown) => void;
43
+ setComponentOutput: (componentId: string, path: string, value: unknown) => void;
44
+ refreshQuery: (query?: string) => void;
45
+ refreshAfterCommand: () => void;
46
+ resolveBinding: (binding: BindingExpression | string | undefined) => unknown;
47
+ /**
48
+ * Resolves a command argument source the way Scene does: `component.<id>.<output>` reads what another
49
+ * element publishes - such as the `value` an input holds or a table's `selectedItem` - and any other
50
+ * source is a data-context path.
51
+ */
52
+ resolveArgument: (source: string | undefined) => unknown;
53
+ registerQueryResult: (scope: string, state: QueryState | undefined) => void;
54
+ refreshVersion: number;
55
+ refreshQueryName?: string;
56
+ }
57
+ /** When, after a command's own refresh, its queries are read again so an asynchronous projection has caught up. */
58
+ export declare const commandSettleDelays: number[];
59
+ export interface StageDataProviderProps {
60
+ routes: StageRoutes | undefined;
61
+ routesReady?: boolean;
62
+ parameters?: Record<string, string>;
63
+ locale: string;
64
+ locales: string[];
65
+ screen: string;
66
+ children: React.ReactNode;
67
+ }
68
+ export declare function StageDataProvider({ routes, routesReady, parameters, locale, locales, screen, children }: StageDataProviderProps): React.JSX.Element;
69
+ export declare const useStageData: () => StageDataState;
70
+ export declare function useStageQuery(request: StageQueryRequest): StageQueryResult;
71
+ export declare function dataChanged(): void;
72
+ export {};
@@ -0,0 +1,17 @@
1
+ import type { SceneElement } from '@cratis/scene.model';
2
+ /** The component a modeled `data` declaration is rendered as. */
3
+ export declare const dataComponent = "core:data";
4
+ /**
5
+ * Connects every table to the modeled `data` declaration that feeds it.
6
+ *
7
+ * A screen declares its data once - `data CommentsForWorkItem by workItemId` - and the table that follows it in
8
+ * the same section, or any section nested after it, shows that read model. The table itself only names the read
9
+ * model type, so without this it would read the unfiltered collection: every comment of every work item. This
10
+ * carries the declaration's query and its `by` parameter onto the table, bound to the screen parameter of the
11
+ * same name, so the table reads only what the declaration asked for and reads nothing while that parameter has
12
+ * no value.
13
+ *
14
+ * @param element The composed screen.
15
+ * @returns The screen with every fed table bound to its declaration.
16
+ */
17
+ export declare function bindDataSources(element: SceneElement): SceneElement;
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Evaluates the guards a Screenplay `when ... otherwise` carries.
3
+ *
4
+ * A guard compares a field of the subject - `item`, the record the nearest `data` declaration reads, or the row an
5
+ * interaction happened on - with a literal, and combines comparisons with `and` and `or`. That is the whole guard
6
+ * language Screenplay admits, and the same shape Stage emits into the Scene for a guarded action and for a guarded
7
+ * interaction. Anything else is not evaluable: the answer is then `undefined`, never `true`, so a guard the runtime
8
+ * does not understand can never let a command through.
9
+ */
10
+ /** The binding path a guarded interaction binding's condition carries; its `value` is a {@link GuardSelection}. */
11
+ export declare const guardPath = "$guard";
12
+ /** One condition of a guard. */
13
+ export type GuardCondition = ComparisonCondition | LogicalCondition;
14
+ /**
15
+ * A field of the guard's subject, such as `{ subject: 'item.status' }`.
16
+ *
17
+ * It is deliberately not a binding: Scene resolves every `{ path }` object in a component's properties against the
18
+ * data context before the component renders, which would replace the reference with a value. A `path` is still read,
19
+ * for guards written directly as Scene JSON or carried where Scene does not resolve them.
20
+ */
21
+ export interface SubjectReference {
22
+ subject?: string;
23
+ path?: string;
24
+ }
25
+ /**
26
+ * Reads the subject path a reference names.
27
+ * @param reference The reference.
28
+ * @returns The path, or `undefined` when it names none.
29
+ */
30
+ export declare function subjectPath(reference: unknown): string | undefined;
31
+ /** Compares a field of the subject with a literal. */
32
+ export interface ComparisonCondition {
33
+ kind: 'comparison';
34
+ left: SubjectReference;
35
+ operator: string;
36
+ right: unknown;
37
+ /** The members of the enumeration the field is, in declared order, when it is one. */
38
+ enumeration?: string[];
39
+ }
40
+ /** Combines two conditions. */
41
+ export interface LogicalCondition {
42
+ kind: 'logical';
43
+ left: GuardCondition;
44
+ operator: string;
45
+ right: GuardCondition;
46
+ }
47
+ /**
48
+ * Which branch of an ordered first-match guard a binding is: alternative `index`, or the `otherwise` that runs when
49
+ * there is a subject and no alternative holds.
50
+ */
51
+ export interface GuardSelection {
52
+ kind: 'firstMatch' | 'otherwise';
53
+ index?: number;
54
+ alternatives: unknown[];
55
+ }
56
+ /** The diagnostic a guard the runtime cannot evaluate is reported with. */
57
+ export declare const unevaluableGuardCode = "STAGE-SCENE-ACTION-001";
58
+ /**
59
+ * Evaluates one condition against a subject.
60
+ *
61
+ * A missing or null field does not match - `item.status == "open"` is false for an item without a status - because
62
+ * that is what Screenplay specifies and because the alternative, matching on absence, would run a command against
63
+ * data that never said it could.
64
+ *
65
+ * @param condition The condition as the Scene carries it.
66
+ * @param subject The record the condition is about.
67
+ * @returns Whether it holds, or `undefined` when it is not a condition this runtime can evaluate.
68
+ */
69
+ export declare function evaluateCondition(condition: unknown, subject: Record<string, unknown>): boolean | undefined;
70
+ /** Whether every condition can be evaluated, independently of any subject. */
71
+ export declare function canEvaluate(conditions: unknown[]): boolean;
72
+ /**
73
+ * Picks the first alternative whose condition holds.
74
+ * @param conditions The alternatives' conditions, in authored order.
75
+ * @param subject The record they are about.
76
+ * @returns The index of the first that holds, -1 when none does, or `undefined` when any is not evaluable.
77
+ */
78
+ export declare function firstMatch(conditions: unknown[], subject: Record<string, unknown>): number | undefined;
79
+ /**
80
+ * Resolves a guarded interaction binding's condition: whether its branch is the one that runs for this subject.
81
+ * @param selection The {@link GuardSelection} the binding carries.
82
+ * @param subject The record the interaction is about, when there is one.
83
+ * @returns Whether the branch runs, or `undefined` when there is no subject or the guard is not evaluable - which
84
+ * the interaction engine reports and treats as not running.
85
+ */
86
+ export declare function resolveGuard(selection: unknown, subject: unknown): boolean | undefined;
87
+ /** Resolves a binding path against a subject, for paths that start with `item.`. */
88
+ export declare function subjectValue(path: string, subject: unknown): unknown;
@@ -0,0 +1,33 @@
1
+ /**
2
+ * The parameters a screen was navigated to with, read from the hash (`#/WorkItemDetails?workItemId=...`).
3
+ *
4
+ * A modeled table that navigates on a row click names the parameter it navigates by. Keeping that parameter in
5
+ * the address is what makes the selection a deep link: reloading, sharing or reopening the address selects the
6
+ * same row and re-runs the queries that depend on it.
7
+ *
8
+ * @param hash The location hash.
9
+ * @returns The parameters, by name.
10
+ */
11
+ export declare function screenParameters(hash: string): Record<string, string>;
12
+ /**
13
+ * The hash addressing a screen with the given parameters.
14
+ *
15
+ * @param screen The screen name.
16
+ * @param parameters The parameters to carry; empty values are left out.
17
+ * @returns The hash.
18
+ */
19
+ export declare function screenHashWith(screen: string, parameters?: Record<string, string>): string;
20
+ /**
21
+ * Navigates to a screen with parameters through the address, so the application, history and a reload agree.
22
+ *
23
+ * @param screen The screen name.
24
+ * @param parameters The parameters to carry.
25
+ */
26
+ export declare function navigateToScreen(screen: string, parameters?: Record<string, string>): void;
27
+ /**
28
+ * Turns an interaction's navigation arguments into screen parameters: every argument with a value, as text, the way
29
+ * it appears in the address. An argument without a value is left out rather than written as `undefined`.
30
+ * @param args The arguments the navigation was given.
31
+ * @returns The screen parameters.
32
+ */
33
+ export declare function screenArguments(args: Record<string, unknown> | undefined): Record<string, string>;
@@ -0,0 +1,22 @@
1
+ import type { ApplicationStructure, NavigationModel, Screen } from '@cratis/scene.model';
2
+ import type { EffectiveNavItem } from '@cratis/scene.engine';
3
+ import type { SceneNavigationModel } from '@cratis/scene.react';
4
+ /** Whether the model declares navigation regions of its own - the application's or a module's. */
5
+ export declare function declaresRegions(navigation: NavigationModel | undefined): boolean;
6
+ /**
7
+ * The screen a navigation item opens: the screen declared in the feature the item resolves to (a screen's `path` is the modules and
8
+ * features it was declared in), the first screen declared beneath it, or the screen named like the feature - which is how the
9
+ * application structure names a feature's screen.
10
+ */
11
+ export declare function stageScreenFor(screens: Screen[]): (item: EffectiveNavItem) => string | undefined;
12
+ /** The module a screen was declared in - the first of its `path` - which decides whose sidebar the page shows. */
13
+ export declare function stageModuleOf(screens: Screen[]): (screen: string | undefined) => string | undefined;
14
+ /**
15
+ * What Scene's navigation regions read: the model's structure and navigation, and the two hooks that are the host's - where an item
16
+ * goes and which items the user may see. Hidden is hidden, never disabled, so nothing about an item the user may not see leaks.
17
+ */
18
+ export declare function stageNavigationModel(scene: {
19
+ screens: Screen[];
20
+ navigation?: NavigationModel;
21
+ structure?: ApplicationStructure;
22
+ }, isVisible?: (item: EffectiveNavItem) => boolean): SceneNavigationModel;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Where the running application registered its modeled commands and queries.
3
+ */
4
+ export interface StageRoutes {
5
+ commands: Record<string, string>;
6
+ queries: Record<string, string>;
7
+ /** Live-host metadata for route-synthesized proxies. Generated apps register their real proxies instead. */
8
+ commandSchemas?: Record<string, string>;
9
+ }
10
+ export interface StageRouteState {
11
+ routes: StageRoutes | undefined;
12
+ ready: boolean;
13
+ }
14
+ export declare const stageRoutes: string;
15
+ /**
16
+ * Reads the routes the Stage registered and says when that lookup has finished.
17
+ *
18
+ * An element carries the route it is backed by, but an interaction only names a command - so running one needs
19
+ * this lookup. Readiness is separate from the routes object because an empty or failed route lookup is a real
20
+ * loaded state; guessing a URL while it is still pending would turn a valid command into a transient 404.
21
+ */
22
+ export declare function useStageRouteState(): StageRouteState;
23
+ /** Reads the routes the Stage registered. */
24
+ export declare function useStageRoutes(): StageRoutes | undefined;
@@ -0,0 +1,26 @@
1
+ import type { ExternalComponent } from '@cratis/scene.model';
2
+ /** How long a row waits for a second click before treating the first as a single click. */
3
+ export declare const doubleClickWindow = 250;
4
+ /** What a table does with clicks on its rows. */
5
+ export interface RowInteractions {
6
+ /** Handles a click: at once, or after the double-click window when the table also handles double clicks. */
7
+ click: (row: Record<string, unknown>, single: () => void) => void;
8
+ /** Handles a double click, when the table declares one; otherwise `undefined`. */
9
+ doubleClick?: (row: Record<string, unknown>) => void;
10
+ }
11
+ /**
12
+ * Runs a table's `on double click` bindings for the row that was double clicked.
13
+ *
14
+ * The bindings are the table's own, resolved and run by the Scene interaction engine - the same engine that runs
15
+ * every other interaction - with `item` meaning the row. A guarded `when ... otherwise` arrives as one binding per
16
+ * branch whose condition the engine resolves through this context, so exactly the first branch that holds for the
17
+ * row runs, and the `otherwise` branch runs when none does.
18
+ *
19
+ * A row's single click (selection, or navigation to the row) would otherwise always win the race with a double
20
+ * click, because a double click starts with a click. When the table declares a double click, a single click waits
21
+ * out the double-click window first and is cancelled by the double click.
22
+ *
23
+ * @param element The table.
24
+ * @returns The row handlers.
25
+ */
26
+ export declare function useRowInteractions(element: ExternalComponent): RowInteractions;
@@ -0,0 +1,55 @@
1
+ import { type Theme, type UiProfile } from '@cratis/scene.model';
2
+ import { type EffectiveShell } from '@cratis/scene.engine';
3
+ import { ColorScheme, LayoutMode, MenuTheme } from '@cratis/scene.blueprint.default';
4
+ /** What the profile's root template, shell options and appearance ask of the running shell. */
5
+ export interface StageShellSettings {
6
+ /** The sidebar mode the profile's `navigationMode` option names. */
7
+ mode?: LayoutMode;
8
+ /** How the sidebar is tinted, when the profile's `menuTheme` option names one. */
9
+ menuTheme?: MenuTheme;
10
+ /** Whether the shell draws its footer; the `showFooter` option, drawn unless it is `false`. */
11
+ showFooter: boolean;
12
+ /** The theme the colour scheme selects, by name. */
13
+ themeName?: string;
14
+ /** The colour scheme the sidebar and the page follow. */
15
+ colorScheme?: ColorScheme;
16
+ /** Whether the profile follows the operating system's scheme instead of fixing one. */
17
+ followsSystem: boolean;
18
+ /** The accent colour, as the profile wrote it. */
19
+ accent?: string;
20
+ /** Options and values the shell does not understand: stated, never silently dropped. */
21
+ problems: string[];
22
+ }
23
+ /** The shell options the default blueprint's shells expose; any other name is stated as a problem. */
24
+ export declare const knownShellOptions: readonly string[];
25
+ /**
26
+ * Reads the profile's shell options and appearance into what the running shell is told to do.
27
+ *
28
+ * The effective shell is the engine's answer (`resolveEffectiveShell`); this only maps its options and the profile's
29
+ * appearance onto the blueprint's layout configuration, so the Stage and the Scene preview start a shell the same way.
30
+ *
31
+ * @param profile The profile the application renders with.
32
+ * @param shell The effective shell the engine resolved for it.
33
+ * @param prefersDark Whether the operating system prefers a dark scheme, for a profile that follows the system.
34
+ * @returns The settings, with every option or value that could not be applied.
35
+ */
36
+ export declare function stageShellSettings(profile: UiProfile | undefined, shell: EffectiveShell, prefersDark?: boolean): StageShellSettings;
37
+ /**
38
+ * What stops an application starting with the root template its profile names: the template is unknown, its blueprint is not
39
+ * installed, its version pin is not satisfied or it cannot be a shell. A page that cannot be drawn in the shell it asked for
40
+ * is stated, not drawn in a different one.
41
+ *
42
+ * @param profile The profile the application renders with.
43
+ * @param shell The effective shell the engine resolved for it.
44
+ * @returns The problems, empty when the root template resolved or the profile names none.
45
+ */
46
+ export declare function shellStartupProblems(profile: UiProfile | undefined, shell: EffectiveShell): string[];
47
+ /**
48
+ * The themes with the profile's accent set as their primary colour. Without an accent the themes are returned as they are, so
49
+ * the theme keeps its own.
50
+ *
51
+ * @param themes The themes the shell offers.
52
+ * @param accent The accent colour, `#rgb` or `#rrggbb`.
53
+ * @returns The themes to give the shell.
54
+ */
55
+ export declare function themesWithAccent(themes: Theme[], accent: string | undefined): Theme[];
@@ -0,0 +1,21 @@
1
+ import type { SliceCommandField, SliceInvoker } from '@cratis/scene.react';
2
+ import type { StageCommandOutcome } from './StageCommandOutcome';
3
+ /**
4
+ * The fields of a command, for the task dialog a toolbar slice button opens. They are what the command's schema declares -
5
+ * the same reading the native command form uses - so the dialog asks for exactly what the command takes. A property the form
6
+ * cannot present (a collection, an object) is left out rather than shown as a field that cannot be filled.
7
+ *
8
+ * @param schemas The JSON schema of every modeled command, by command name.
9
+ * @returns The fields of a command; none for a command the application does not describe.
10
+ */
11
+ export declare function sliceFieldsFrom(schemas: Record<string, string> | undefined): (command: string) => SliceCommandField[];
12
+ /**
13
+ * The invoker the running application submits a task dialog through: the command is posted to the route the Stage registered for
14
+ * it, exactly as an action or a form posts it, and the application's own validation results come back to the dialog against the
15
+ * fields they name. A successful command refreshes what the screen shows.
16
+ *
17
+ * @param executeCommand Executes a registered Arc proxy with the host's configuration.
18
+ * @param routesReady Whether the lookup has finished, so a command with no route is not-registered rather than not-yet.
19
+ * @param refreshAfterCommand Called after a command succeeds.
20
+ */
21
+ export declare function createStageSliceInvoker(executeCommand: (name: string, values: Record<string, unknown>) => Promise<StageCommandOutcome>, routesReady: boolean, refreshAfterCommand: () => void): SliceInvoker;
@@ -0,0 +1,33 @@
1
+ import { type ReactNode } from 'react';
2
+ import type { StringsDictionary } from '@cratis/scene.engine';
3
+ import type { StageRoutes } from './stageRoutes';
4
+ import type { StageSceneApplication } from './App';
5
+ /** The content supplied by the host of a Stage application. */
6
+ export interface StageSource {
7
+ scene(signal: AbortSignal): Promise<StageSceneApplication>;
8
+ routes(signal: AbortSignal): Promise<StageRoutes | undefined>;
9
+ locales(signal: AbortSignal): Promise<string[]>;
10
+ strings(locale: string, signal: AbortSignal): Promise<StringsDictionary>;
11
+ }
12
+ /** What a generated application already holds when it is built. */
13
+ export interface StageStaticContent {
14
+ scene: StageSceneApplication;
15
+ routes: StageRoutes;
16
+ strings: Record<string, StringsDictionary>;
17
+ }
18
+ /** Serves the document, routes and dictionaries built into an application. */
19
+ export declare function staticStageSource(content: StageStaticContent): StageSource;
20
+ /** Relative endpoint names shared with the live host's transport. */
21
+ export declare const stageEndpoints: {
22
+ scene: string;
23
+ routes: string;
24
+ locales: string;
25
+ strings: (locale: string) => string;
26
+ };
27
+ /** Supplies the source the runtime below reads from. Transport belongs to the host. */
28
+ export declare function StageSourceProvider({ source, children }: {
29
+ source: StageSource;
30
+ children?: ReactNode;
31
+ }): import("react").FunctionComponentElement<import("react").ProviderProps<StageSource | undefined>>;
32
+ /** The source the runtime reads from. */
33
+ export declare function useStageSource(): StageSource;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The selector that puts PrimeReact in its dark scheme: the colour scheme the active blueprint theme sets on
3
+ * the document root (see `ColorSchemeMirror`), so a dialog portalled to `body` follows the shell.
4
+ */
5
+ export declare const stageDarkSelector = "[data-scene-color-scheme='dark']";
6
+ /**
7
+ * The PrimeReact theme a Stage application renders with.
8
+ *
9
+ * PrimeReact 11 ships no CSS of its own: a component is styled only when the provider above it is handed a
10
+ * theme preset, from which it injects its styles at runtime. Without one, every component still renders its
11
+ * markup - a dialog included - but with nothing positioning or painting it, so a command's dialog opened as
12
+ * unstyled content below the screen and a user saw nothing happen when they clicked the command's button.
13
+ */
14
+ export declare const stageTheme: {
15
+ preset: import("@primeuix/themes/types").Preset<import("@primeuix/themes/types/base").BaseDesignTokens>;
16
+ options: {
17
+ darkModeSelector: string;
18
+ };
19
+ };
@@ -0,0 +1,21 @@
1
+ import type { StringsDictionary } from '@cratis/scene.engine';
2
+ export interface Strings {
3
+ /** Every locale at least one `.strings` file next to the model declares. */
4
+ locales: string[];
5
+ /** The active locale, or an empty string before the first `/stage/locales` fetch resolves. */
6
+ locale: string;
7
+ /** Switches the active locale, triggering a fetch of its dictionary. */
8
+ setLocale: (locale: string) => void;
9
+ /** The active locale's merged dictionary - empty until its fetch resolves. */
10
+ dictionary: StringsDictionary;
11
+ }
12
+ /**
13
+ * Fetches the locales a running Stage's `.strings` files declare, then the active one's dictionary -
14
+ * resolution itself (turning a dictionary and a tree into a resolved one) is `resolveStringsInElement`
15
+ * from `@cratis/scene.engine`; this only owns getting a dictionary from the network in the first place.
16
+ *
17
+ * The first locale `/stage/locales` reports becomes the default - there is no configured "default locale"
18
+ * concept yet, so the model deciding which `.strings` file exists first (alphabetically, since
19
+ * `IStringsFiles.FindIn` orders by relative path) is what a running Stage actually offers today.
20
+ */
21
+ export declare function useStrings(): Strings;
@@ -0,0 +1,23 @@
1
+ import type { Plugin } from 'vite';
2
+ /**
3
+ * Serves PrimeReact's styled components wherever its unstyled primitives are imported.
4
+ *
5
+ * `primereact/<component>` is PrimeReact 11's headless layer: it renders the markup but carries no styles, so
6
+ * nothing positions or paints it. The styled components - the same API with their style modules applied - live
7
+ * in `@primereact/ui/<component>`. The Scene components Stage renders with (`@cratis/scene.primereact`) import
8
+ * the primitives, which left a Stage application's buttons as bare text and a command's dialog rendered as plain
9
+ * content below the screen, where the user never saw it open.
10
+ *
11
+ * An import of a primitive from outside PrimeReact therefore gets a module that re-exports everything the
12
+ * primitive does, with every name `@primereact/ui` also exports taken from there instead. The styled package
13
+ * does not cover every helper a primitive exports, which is why it cannot simply replace the primitive.
14
+ * PrimeReact's own packages are built on the primitives - `@primereact/ui` wraps them and the primitives import
15
+ * one another - so imports from inside PrimeReact are left alone.
16
+ */
17
+ export declare function styledPrimeReact(): Plugin;
18
+ /**
19
+ * Reads the names a bundled ES module exports from its `export { ... }` statements.
20
+ * @param source The module source.
21
+ * @returns The exported names.
22
+ */
23
+ export declare function exportedNames(source: string): string[];
@@ -0,0 +1,30 @@
1
+ import { readFile as e } from "node:fs/promises";
2
+ //#region styledPrimeReact.ts
3
+ var t = /^primereact\/([a-z]+)$/, n = "\0stage-styled-primereact:";
4
+ function r() {
5
+ return {
6
+ name: "stage-styled-primereact",
7
+ enforce: "pre",
8
+ resolveId(e, r) {
9
+ let i = t.exec(e);
10
+ return !i || !r || r.startsWith(n) || /\/node_modules\/(primereact|@primereact)\//.test(r) ? null : `${n}${i[1]}`;
11
+ },
12
+ async load(t) {
13
+ if (!t.startsWith(n)) return null;
14
+ let r = t.slice(25), a = await this.resolve(`@primereact/ui/${r}`, void 0, { skipSelf: !0 });
15
+ if (!a) return `export * from 'primereact/${r}';`;
16
+ let o = i(await e(a.id, "utf8"));
17
+ return [`export * from 'primereact/${r}';`, o.length > 0 ? `export { ${o.join(", ")} } from '@primereact/ui/${r}';` : ""].join("\n");
18
+ }
19
+ };
20
+ }
21
+ function i(e) {
22
+ let t = /* @__PURE__ */ new Set();
23
+ for (let n of e.matchAll(/export\s*\{([^}]*)\}/g)) for (let e of n[1].split(",")) {
24
+ let n = e.trim().split(/\s+as\s+/).pop()?.trim();
25
+ n && n !== "default" && t.add(n);
26
+ }
27
+ return [...t];
28
+ }
29
+ //#endregion
30
+ export { i as exportedNames, r as styledPrimeReact };