@cratis/scene.components 3.5.0 → 3.7.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.
- package/README.md +56 -5
- package/bindings/bindingRegistry.ts +52 -4
- package/bindings/for_bindingRegistry/when_registering_query_identities.ts +81 -0
- package/bindings/for_requireArcProxy/when_mounting_bound_adapters.tsx +4 -2
- package/cratisComponents.ts +2 -0
- package/cratisComponentsPackage.ts +2 -1
- package/data/SingleResultRuntime.tsx +17 -3
- package/data/for_SceneDataTable/when_forwarding_query_arguments.tsx +19 -0
- package/dist/cjs/bindings/bindingRegistry.js +52 -4
- package/dist/cjs/bindings/bindingRegistry.js.map +1 -1
- package/dist/cjs/cratisComponents.js +2 -0
- package/dist/cjs/cratisComponents.js.map +1 -1
- package/dist/cjs/cratisComponentsPackage.js +2 -1
- package/dist/cjs/cratisComponentsPackage.js.map +1 -1
- package/dist/cjs/data/SingleResultRuntime.js +16 -1
- package/dist/cjs/data/SingleResultRuntime.js.map +1 -1
- package/dist/cjs/forms/CommandFormRuntime.js +81 -0
- package/dist/cjs/forms/CommandFormRuntime.js.map +1 -0
- package/dist/cjs/forms/CommandFormSubmit.js +19 -0
- package/dist/cjs/forms/CommandFormSubmit.js.map +1 -0
- package/dist/cjs/forms/ExplicitCommandField.js +109 -0
- package/dist/cjs/forms/ExplicitCommandField.js.map +1 -0
- package/dist/cjs/forms/SceneCommandForm.js +26 -21
- package/dist/cjs/forms/SceneCommandForm.js.map +1 -1
- package/dist/cjs/forms/SceneQueryInputForm.js +141 -0
- package/dist/cjs/forms/SceneQueryInputForm.js.map +1 -0
- package/dist/cjs/forms/commandInputs.js +35 -0
- package/dist/cjs/forms/commandInputs.js.map +1 -0
- package/dist/cjs/forms/queryInputs.js +50 -0
- package/dist/cjs/forms/queryInputs.js.map +1 -0
- package/dist/cjs/index.js +6 -0
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/bindings/bindingRegistry.d.ts +4 -0
- package/dist/esm/bindings/bindingRegistry.d.ts.map +1 -1
- package/dist/esm/bindings/bindingRegistry.js +49 -5
- package/dist/esm/bindings/bindingRegistry.js.map +1 -1
- package/dist/esm/bindings/for_bindingRegistry/when_registering_query_identities.d.ts +2 -0
- package/dist/esm/bindings/for_bindingRegistry/when_registering_query_identities.d.ts.map +1 -0
- package/dist/esm/bindings/for_bindingRegistry/when_registering_query_identities.js +73 -0
- package/dist/esm/bindings/for_bindingRegistry/when_registering_query_identities.js.map +1 -0
- package/dist/esm/bindings/for_requireArcProxy/when_mounting_bound_adapters.js +2 -2
- package/dist/esm/bindings/for_requireArcProxy/when_mounting_bound_adapters.js.map +1 -1
- package/dist/esm/cratisComponents.d.ts.map +1 -1
- package/dist/esm/cratisComponents.js +2 -0
- package/dist/esm/cratisComponents.js.map +1 -1
- package/dist/esm/cratisComponentsPackage.d.ts.map +1 -1
- package/dist/esm/cratisComponentsPackage.js +2 -1
- package/dist/esm/cratisComponentsPackage.js.map +1 -1
- package/dist/esm/data/SingleResultRuntime.d.ts +2 -1
- package/dist/esm/data/SingleResultRuntime.d.ts.map +1 -1
- package/dist/esm/data/SingleResultRuntime.js +16 -1
- package/dist/esm/data/SingleResultRuntime.js.map +1 -1
- package/dist/esm/data/for_SceneDataTable/when_forwarding_query_arguments.js +17 -0
- package/dist/esm/data/for_SceneDataTable/when_forwarding_query_arguments.js.map +1 -1
- package/dist/esm/for_cratisComponentsPackage/when_declaring_command_form_peers.d.ts +2 -0
- package/dist/esm/for_cratisComponentsPackage/when_declaring_command_form_peers.d.ts.map +1 -0
- package/dist/esm/for_cratisComponentsPackage/when_declaring_command_form_peers.js +16 -0
- package/dist/esm/for_cratisComponentsPackage/when_declaring_command_form_peers.js.map +1 -0
- package/dist/esm/for_cratisComponentsPackage/when_describing_query_input_form.d.ts +2 -0
- package/dist/esm/for_cratisComponentsPackage/when_describing_query_input_form.d.ts.map +1 -0
- package/dist/esm/for_cratisComponentsPackage/when_describing_query_input_form.js +14 -0
- package/dist/esm/for_cratisComponentsPackage/when_describing_query_input_form.js.map +1 -0
- package/dist/esm/forms/CommandFormRuntime.d.ts +11 -0
- package/dist/esm/forms/CommandFormRuntime.d.ts.map +1 -0
- package/dist/esm/forms/CommandFormRuntime.js +77 -0
- package/dist/esm/forms/CommandFormRuntime.js.map +1 -0
- package/dist/esm/forms/CommandFormSubmit.d.ts +6 -0
- package/dist/esm/forms/CommandFormSubmit.d.ts.map +1 -0
- package/dist/esm/forms/CommandFormSubmit.js +17 -0
- package/dist/esm/forms/CommandFormSubmit.js.map +1 -0
- package/dist/esm/forms/ExplicitCommandField.d.ts +5 -0
- package/dist/esm/forms/ExplicitCommandField.d.ts.map +1 -0
- package/dist/esm/forms/ExplicitCommandField.js +107 -0
- package/dist/esm/forms/ExplicitCommandField.js.map +1 -0
- package/dist/esm/forms/SceneCommandForm.d.ts.map +1 -1
- package/dist/esm/forms/SceneCommandForm.js +27 -22
- package/dist/esm/forms/SceneCommandForm.js.map +1 -1
- package/dist/esm/forms/SceneQueryInputForm.d.ts +3 -0
- package/dist/esm/forms/SceneQueryInputForm.d.ts.map +1 -0
- package/dist/esm/forms/SceneQueryInputForm.js +139 -0
- package/dist/esm/forms/SceneQueryInputForm.js.map +1 -0
- package/dist/esm/forms/commandInputs.d.ts +7 -0
- package/dist/esm/forms/commandInputs.d.ts.map +1 -0
- package/dist/esm/forms/commandInputs.js +33 -0
- package/dist/esm/forms/commandInputs.js.map +1 -0
- package/dist/esm/forms/for_SceneCommandForm/given/RecordNote.d.ts +22 -0
- package/dist/esm/forms/for_SceneCommandForm/given/RecordNote.d.ts.map +1 -0
- package/dist/esm/forms/for_SceneCommandForm/given/RecordNote.js +30 -0
- package/dist/esm/forms/for_SceneCommandForm/given/RecordNote.js.map +1 -0
- package/dist/esm/forms/for_SceneCommandForm/given/StartProject.d.ts +32 -0
- package/dist/esm/forms/for_SceneCommandForm/given/StartProject.d.ts.map +1 -0
- package/dist/esm/forms/for_SceneCommandForm/given/StartProject.js +32 -0
- package/dist/esm/forms/for_SceneCommandForm/given/StartProject.js.map +1 -0
- package/dist/esm/forms/for_SceneCommandForm/when_forwarding_to_the_lazy_runtime.d.ts +2 -0
- package/dist/esm/forms/for_SceneCommandForm/when_forwarding_to_the_lazy_runtime.d.ts.map +1 -0
- package/dist/esm/forms/for_SceneCommandForm/when_forwarding_to_the_lazy_runtime.js +66 -0
- package/dist/esm/forms/for_SceneCommandForm/when_forwarding_to_the_lazy_runtime.js.map +1 -0
- package/dist/esm/forms/for_SceneCommandForm/when_native_custom_field_errors_block_submission.d.ts +2 -0
- package/dist/esm/forms/for_SceneCommandForm/when_native_custom_field_errors_block_submission.d.ts.map +1 -0
- package/dist/esm/forms/for_SceneCommandForm/when_native_custom_field_errors_block_submission.js +26 -0
- package/dist/esm/forms/for_SceneCommandForm/when_native_custom_field_errors_block_submission.js.map +1 -0
- package/dist/esm/forms/for_SceneCommandForm/when_preserving_guid_error_ownership.d.ts +2 -0
- package/dist/esm/forms/for_SceneCommandForm/when_preserving_guid_error_ownership.d.ts.map +1 -0
- package/dist/esm/forms/for_SceneCommandForm/when_preserving_guid_error_ownership.js +44 -0
- package/dist/esm/forms/for_SceneCommandForm/when_preserving_guid_error_ownership.js.map +1 -0
- package/dist/esm/forms/for_SceneCommandForm/when_rendering_submit_in_native_context.d.ts +2 -0
- package/dist/esm/forms/for_SceneCommandForm/when_rendering_submit_in_native_context.d.ts.map +1 -0
- package/dist/esm/forms/for_SceneCommandForm/when_rendering_submit_in_native_context.js +49 -0
- package/dist/esm/forms/for_SceneCommandForm/when_rendering_submit_in_native_context.js.map +1 -0
- package/dist/esm/forms/for_SceneCommandForm/when_submitting_explicit_inputs.d.ts +2 -0
- package/dist/esm/forms/for_SceneCommandForm/when_submitting_explicit_inputs.d.ts.map +1 -0
- package/dist/esm/forms/for_SceneCommandForm/when_submitting_explicit_inputs.js +176 -0
- package/dist/esm/forms/for_SceneCommandForm/when_submitting_explicit_inputs.js.map +1 -0
- package/dist/esm/forms/for_SceneCommandForm/when_submitting_the_native_form.d.ts +2 -0
- package/dist/esm/forms/for_SceneCommandForm/when_submitting_the_native_form.d.ts.map +1 -0
- package/dist/esm/forms/for_SceneCommandForm/when_submitting_the_native_form.js +110 -0
- package/dist/esm/forms/for_SceneCommandForm/when_submitting_the_native_form.js.map +1 -0
- package/dist/esm/forms/for_SceneQueryInputForm/ProjectLookup.d.ts +26 -0
- package/dist/esm/forms/for_SceneQueryInputForm/ProjectLookup.d.ts.map +1 -0
- package/dist/esm/forms/for_SceneQueryInputForm/ProjectLookup.js +44 -0
- package/dist/esm/forms/for_SceneQueryInputForm/ProjectLookup.js.map +1 -0
- package/dist/esm/forms/for_SceneQueryInputForm/when_submitting_generated_guid_parameters.d.ts +2 -0
- package/dist/esm/forms/for_SceneQueryInputForm/when_submitting_generated_guid_parameters.d.ts.map +1 -0
- package/dist/esm/forms/for_SceneQueryInputForm/when_submitting_generated_guid_parameters.js +175 -0
- package/dist/esm/forms/for_SceneQueryInputForm/when_submitting_generated_guid_parameters.js.map +1 -0
- package/dist/esm/forms/for_SceneQueryInputForm/when_submitting_native_queries.d.ts +2 -0
- package/dist/esm/forms/for_SceneQueryInputForm/when_submitting_native_queries.d.ts.map +1 -0
- package/dist/esm/forms/for_SceneQueryInputForm/when_submitting_native_queries.js +413 -0
- package/dist/esm/forms/for_SceneQueryInputForm/when_submitting_native_queries.js.map +1 -0
- package/dist/esm/forms/index.d.ts +2 -0
- package/dist/esm/forms/index.d.ts.map +1 -1
- package/dist/esm/forms/index.js +1 -0
- package/dist/esm/forms/index.js.map +1 -1
- package/dist/esm/forms/queryInputs.d.ts +10 -0
- package/dist/esm/forms/queryInputs.d.ts.map +1 -0
- package/dist/esm/forms/queryInputs.js +47 -0
- package/dist/esm/forms/queryInputs.js.map +1 -0
- package/dist/esm/index.js +2 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/tsconfig.tsbuildinfo +1 -1
- package/for_cratisComponentsPackage/when_declaring_command_form_peers.ts +26 -0
- package/for_cratisComponentsPackage/when_describing_query_input_form.ts +17 -0
- package/forms/CommandFormRuntime.tsx +71 -0
- package/forms/CommandFormSubmit.tsx +16 -0
- package/forms/ExplicitCommandField.tsx +86 -0
- package/forms/SceneCommandForm.tsx +30 -27
- package/forms/SceneQueryInputForm.tsx +79 -0
- package/forms/commandInputs.ts +29 -0
- package/forms/for_SceneCommandForm/given/RecordNote.ts +37 -0
- package/forms/for_SceneCommandForm/given/StartProject.ts +41 -0
- package/forms/for_SceneCommandForm/when_forwarding_to_the_lazy_runtime.tsx +69 -0
- package/forms/for_SceneCommandForm/when_native_custom_field_errors_block_submission.tsx +33 -0
- package/forms/for_SceneCommandForm/when_preserving_guid_error_ownership.tsx +50 -0
- package/forms/for_SceneCommandForm/when_rendering_submit_in_native_context.tsx +56 -0
- package/forms/for_SceneCommandForm/when_submitting_explicit_inputs.tsx +189 -0
- package/forms/for_SceneCommandForm/when_submitting_the_native_form.tsx +120 -0
- package/forms/for_SceneQueryInputForm/ProjectLookup.ts +54 -0
- package/forms/for_SceneQueryInputForm/when_submitting_generated_guid_parameters.tsx +188 -0
- package/forms/for_SceneQueryInputForm/when_submitting_native_queries.tsx +423 -0
- package/forms/index.ts +2 -0
- package/forms/queryInputs.ts +50 -0
- package/package.json +17 -13
package/README.md
CHANGED
|
@@ -73,7 +73,7 @@ unbound table costs one dashed box, not the whole screen.
|
|
|
73
73
|
|
|
74
74
|
`@cratis/arc`, `@cratis/arc.react` and `@cratis/fundamentals` are peer dependencies of `@cratis/components`
|
|
75
75
|
that the *host* supplies. This package also declares Arc and Arc React as optional peers and pins
|
|
76
|
-
22.
|
|
76
|
+
22.19.1 as development dependencies for native integration tests. A design surface is not a host.
|
|
77
77
|
|
|
78
78
|
Every adapter that reaches them does so through a dynamic `import()` inside `React.lazy`, wrapped in
|
|
79
79
|
`ArcRuntimeBoundary` (`Suspense` + the library's own `ErrorBoundary`). A screen built only from the library's
|
|
@@ -88,6 +88,22 @@ This splits the library cleanly, and the split is the library's own:
|
|
|
88
88
|
The Storybook build externalizes the Arc packages (`.storybook/main.ts`) so the lazy chunk can be emitted
|
|
89
89
|
with its imports left bare. No story loads that chunk, because no story registers a binding.
|
|
90
90
|
|
|
91
|
+
## Actionable command forms
|
|
92
|
+
|
|
93
|
+
`commandForm` supplies a native submit button via `AutoCommandForm`'s optional `footer` ReactNode seam.
|
|
94
|
+
`submitLabel` is an optional string, defaulting to `Submit`. A private lazy runtime keeps Arc out of unbound
|
|
95
|
+
previews; its footer child reads the actual native form context for execution and authorization state.
|
|
96
|
+
Validity does not disable submission: native validation must be able to show errors on untouched forms.
|
|
97
|
+
Scene neither executes the command directly nor creates another form or command context.
|
|
98
|
+
|
|
99
|
+
Optional explicit `inputs` use exact native proxy descriptor names and types (`string`/`guid`) in one
|
|
100
|
+
Arc CommandForm; missing, ambiguous, uncovered required or unsupported declarations block the form. Auto
|
|
101
|
+
mode is fields-only and only supports String/Number/Boolean/Date providers, so required Guid does not silently
|
|
102
|
+
disappear. The content slot is not connected to either mode. A valid Guid draft becomes a typed Guid; Guid
|
|
103
|
+
JSON canonicalizes textual case without changing identity. No ID is generated. The declared peers require
|
|
104
|
+
published Components >=4.13.0 for the footer and Arc/Arc React >=22.19.1 for native custom-error gating.
|
|
105
|
+
Arc peers remain optional so unbound previews stay Arc-free.
|
|
106
|
+
|
|
91
107
|
## Optional single-result view (read-only)
|
|
92
108
|
|
|
93
109
|
`Cratis.Components:singleResult` is a narrow adapter for an optional **single model**, not a collection.
|
|
@@ -132,9 +148,44 @@ view rather than an invented retry protocol. Enumerable proxies are rejected bef
|
|
|
132
148
|
|
|
133
149
|
Tests use a real `QueryFor` subclass with unmodified `perform`, native validation and only the HTTP
|
|
134
150
|
boundary replaced. Separate lazy-boundary doubles test Arc-free gating, not native client correctness.
|
|
135
|
-
They do not prove a generated server route
|
|
136
|
-
|
|
137
|
-
|
|
151
|
+
They do not prove a generated server route or backend persistence. The opt-in `queryInputForm` below
|
|
152
|
+
adds form-local editable input/commit semantics; Scene #39 remains open for broader binding and acceptance.
|
|
153
|
+
No default profile, generator or schema changed.
|
|
154
|
+
|
|
155
|
+
## Query input form (opt-in)
|
|
156
|
+
|
|
157
|
+
`Cratis.Components:queryInputForm` composes controlled native web string inputs with the **existing**
|
|
158
|
+
`SingleResultRuntime`. Its package-local `QueryInput` declarations name exact parameters, labels,
|
|
159
|
+
required state and optional whole-string patterns. It validates on submit, freezes a fresh committed
|
|
160
|
+
snapshot, cancels/hides obsolete results on edit and supports repeat submit. There is no query while
|
|
161
|
+
editing, fake command context, new executor, core schema, default identifier or inferred route.
|
|
162
|
+
|
|
163
|
+
Published Components `InputTextField` is wrapped with `asCommandFormField` and consumes command context;
|
|
164
|
+
it is not an exported independent controlled input. Native labelled text inputs are deliberately used
|
|
165
|
+
instead. The existing command-field adapters and command-slot behavior are unchanged.
|
|
166
|
+
|
|
167
|
+
`registerQueryIdentity(name, sourceIdentity, proxy)` is the explicit opt-in collision-aware API:
|
|
168
|
+
identical identities replace on hot reload; different sources with the same name are ambiguous.
|
|
169
|
+
`queryInputForm` subscribes to exact-binding changes. Legacy `registerQuery` keeps its last-write-wins
|
|
170
|
+
semantics and is authoritative for legacy `resolveQuery` when present. Otherwise a unique identity-only
|
|
171
|
+
registration also serves existing tables and `singleResult`; multiple identities show their unresolved
|
|
172
|
+
placeholder without selecting a candidate. Existing adapters re-resolve on host render.
|
|
173
|
+
`registeredQueryNames` includes the sorted union of both namespaces. Strict `resolveExactQuery` still
|
|
174
|
+
counts mixed candidates as ambiguous: Stage should emit one identity registration per source, not also
|
|
175
|
+
register the same name through `registerQueries`.
|
|
176
|
+
|
|
177
|
+
At the existing lazy runtime boundary, form declarations must map exactly to scalar `String` or `Guid`
|
|
178
|
+
proxy descriptors. Unsupported/missing/duplicate descriptors fail before HTTP; no coercion is performed.
|
|
179
|
+
The canonical generated Guid proxy shape is tested unchanged. Native Arc validates required arguments
|
|
180
|
+
and proxy rules, but does not automatically validate GUID format: declare an explicit pattern if needed.
|
|
181
|
+
The lazy runtime uses the optional Fundamentals peer already required by Arc; no Components peer-floor
|
|
182
|
+
change is required.
|
|
183
|
+
|
|
184
|
+
The [public contract](../../../Documentation/components-package/query-input-form.md) documents the exact
|
|
185
|
+
payload and Stage consumption pattern. Tests render through real `SceneElementView`, unmodified native
|
|
186
|
+
Arc `QueryFor.perform` and only substituted HTTP, including validation, stale requests and unmount.
|
|
187
|
+
They are not generated/browser acceptance; the DOM suite dispatches submit rather than simulating a
|
|
188
|
+
browser's implicit Enter algorithm.
|
|
138
189
|
|
|
139
190
|
## Naming and shadowing
|
|
140
191
|
|
|
@@ -199,7 +250,7 @@ both packages write themes in one language: `primary.color`, `primary.contrastCo
|
|
|
199
250
|
bindings/ the registry, BindingKind, BoundConstructor, MissingBinding, ArcRuntimeBoundary
|
|
200
251
|
pages/ page, dataPage, formElement
|
|
201
252
|
data/ dataTable, table, observableDataTable, singleResult
|
|
202
|
-
forms/ commandForm; forms/fields/ the twelve field types
|
|
253
|
+
forms/ commandForm, queryInputForm; forms/fields/ the twelve field types
|
|
203
254
|
dialogs/ dialog, confirmationDialog, busyIndicatorDialog, commandDialog, stepperCommandDialog
|
|
204
255
|
common/ icon, tooltip, dropdown, errorBoundary
|
|
205
256
|
editors/ objectContentEditor, objectNavigationalBar, schemaEditor, timeMachine, filterPanel
|
|
@@ -5,6 +5,47 @@ import { BoundConstructor } from './BoundConstructor';
|
|
|
5
5
|
|
|
6
6
|
const queries = new Map<string, BoundConstructor>();
|
|
7
7
|
const commands = new Map<string, BoundConstructor>();
|
|
8
|
+
// Opt-in identities are separate from the legacy last-registration-wins namespace.
|
|
9
|
+
const queryIdentities = new Map<string, Map<string, BoundConstructor>>();
|
|
10
|
+
const queryBindingListeners = new Set<() => void>();
|
|
11
|
+
|
|
12
|
+
function notifyQueryBindings(): void {
|
|
13
|
+
for (const listener of queryBindingListeners) listener();
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Subscribe to exact-binding changes. Existing adapters retain their render-time lookup contract. */
|
|
17
|
+
export function subscribeQueryBindings(listener: () => void): () => void {
|
|
18
|
+
queryBindingListeners.add(listener);
|
|
19
|
+
return () => { queryBindingListeners.delete(listener); };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Registers one source identity for an exact query name. The same identity replaces on hot reload;
|
|
24
|
+
* different identities remain distinct candidates, even when their constructors happen to match.
|
|
25
|
+
* Legacy resolution also accepts a unique identity when no legacy registration exists.
|
|
26
|
+
*/
|
|
27
|
+
export function registerQueryIdentity(name: string, identity: string, queryClass: BoundConstructor): void {
|
|
28
|
+
const candidates = queryIdentities.get(name) ?? new Map<string, BoundConstructor>();
|
|
29
|
+
candidates.set(identity, queryClass);
|
|
30
|
+
queryIdentities.set(name, candidates);
|
|
31
|
+
notifyQueryBindings();
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/** Removes a source identity when a generated module is removed or renamed. */
|
|
35
|
+
export function unregisterQueryIdentity(name: string, identity: string): void {
|
|
36
|
+
const candidates = queryIdentities.get(name);
|
|
37
|
+
candidates?.delete(identity);
|
|
38
|
+
if (candidates?.size === 0) queryIdentities.delete(name);
|
|
39
|
+
notifyQueryBindings();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Exact binding: a legacy registration counts as one candidate alongside opt-in identities. */
|
|
43
|
+
export function resolveExactQuery(name: string): BoundConstructor | 'ambiguous' | undefined {
|
|
44
|
+
const legacy = queries.get(name);
|
|
45
|
+
const candidates = queryIdentities.get(name);
|
|
46
|
+
if ((legacy ? 1 : 0) + (candidates?.size ?? 0) > 1) return 'ambiguous';
|
|
47
|
+
return legacy ?? candidates?.values().next().value;
|
|
48
|
+
}
|
|
8
49
|
|
|
9
50
|
/**
|
|
10
51
|
* Registers an Arc query proxy under the name screens refer to it by.
|
|
@@ -24,6 +65,7 @@ const commands = new Map<string, BoundConstructor>();
|
|
|
24
65
|
*/
|
|
25
66
|
export function registerQuery(name: string, queryClass: BoundConstructor): void {
|
|
26
67
|
queries.set(name, queryClass);
|
|
68
|
+
notifyQueryBindings();
|
|
27
69
|
}
|
|
28
70
|
|
|
29
71
|
/**
|
|
@@ -40,14 +82,18 @@ export function registerQueries(bindings: Record<string, BoundConstructor>): voi
|
|
|
40
82
|
}
|
|
41
83
|
|
|
42
84
|
/**
|
|
43
|
-
*
|
|
85
|
+
* Legacy registrations are authoritative. Otherwise resolve a unique source identity, or `undefined`
|
|
86
|
+
* when absent or ambiguous (existing adapters display their unresolved-binding placeholder).
|
|
44
87
|
*
|
|
45
88
|
* `undefined` rather than a throw: design-time preview in Studio normally has nothing registered at all,
|
|
46
89
|
* and a screen still has to render so its layout can be worked on. Every adapter turns `undefined` into
|
|
47
90
|
* a visible placeholder naming the binding it wanted.
|
|
48
91
|
*/
|
|
49
92
|
export function resolveQuery(name: string): BoundConstructor | undefined {
|
|
50
|
-
|
|
93
|
+
const legacy = queries.get(name);
|
|
94
|
+
if (legacy) return legacy;
|
|
95
|
+
const candidates = queryIdentities.get(name);
|
|
96
|
+
return candidates?.size === 1 ? candidates.values().next().value : undefined;
|
|
51
97
|
}
|
|
52
98
|
|
|
53
99
|
/**
|
|
@@ -75,14 +121,14 @@ export function resolveCommand(name: string): BoundConstructor | undefined {
|
|
|
75
121
|
}
|
|
76
122
|
|
|
77
123
|
/**
|
|
78
|
-
*
|
|
124
|
+
* The sorted union of legacy and identity query names, including ambiguous names.
|
|
79
125
|
*
|
|
80
126
|
* A design-time tool uses this to offer the names a screen can actually bind to, and a diagnostics
|
|
81
127
|
* surface uses it to explain a placeholder - "this screen wants `AllInvoices`, and here is what is
|
|
82
128
|
* registered" is a far more useful message than the placeholder alone.
|
|
83
129
|
*/
|
|
84
130
|
export function registeredQueryNames(): string[] {
|
|
85
|
-
return [...queries.keys()].sort();
|
|
131
|
+
return [...new Set([...queries.keys(), ...queryIdentities.keys()])].sort();
|
|
86
132
|
}
|
|
87
133
|
|
|
88
134
|
/**
|
|
@@ -102,4 +148,6 @@ export function registeredCommandNames(): string[] {
|
|
|
102
148
|
export function clearBindings(): void {
|
|
103
149
|
queries.clear();
|
|
104
150
|
commands.clear();
|
|
151
|
+
queryIdentities.clear();
|
|
152
|
+
notifyQueryBindings();
|
|
105
153
|
}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
3
|
+
|
|
4
|
+
import { expect } from 'vitest';
|
|
5
|
+
import { clearBindings, registerQuery, registerQueryIdentity, registeredQueryNames, resolveExactQuery, resolveQuery, unregisterQueryIdentity } from '../bindingRegistry';
|
|
6
|
+
|
|
7
|
+
class First {}
|
|
8
|
+
class Replacement {}
|
|
9
|
+
|
|
10
|
+
describe('when opting into collision-aware query identities', () => {
|
|
11
|
+
beforeEach(() => clearBindings());
|
|
12
|
+
afterEach(() => clearBindings());
|
|
13
|
+
|
|
14
|
+
it('replaces the same source identity on hot reload', () => {
|
|
15
|
+
registerQueryIdentity('Lookup', 'source/Lookup', First);
|
|
16
|
+
registerQueryIdentity('Lookup', 'source/Lookup', Replacement);
|
|
17
|
+
expect(resolveExactQuery('Lookup')).toBe(Replacement);
|
|
18
|
+
expect(resolveQuery('Lookup')).toBe(Replacement);
|
|
19
|
+
expect(registeredQueryNames()).toEqual(['Lookup']);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it('counts different source identities even for the same constructor', () => {
|
|
23
|
+
registerQueryIdentity('Lookup', 'one/Lookup', First);
|
|
24
|
+
registerQueryIdentity('Lookup', 'two/Lookup', First);
|
|
25
|
+
expect(resolveExactQuery('Lookup')).toBe('ambiguous');
|
|
26
|
+
expect(resolveQuery('Lookup')).toBeUndefined();
|
|
27
|
+
expect(registeredQueryNames()).toEqual(['Lookup']);
|
|
28
|
+
unregisterQueryIdentity('Lookup', 'one/Lookup');
|
|
29
|
+
expect(resolveExactQuery('Lookup')).toBe(First);
|
|
30
|
+
expect(resolveQuery('Lookup')).toBe(First);
|
|
31
|
+
unregisterQueryIdentity('Lookup', 'two/Lookup');
|
|
32
|
+
expect(resolveExactQuery('Lookup')).toBeUndefined();
|
|
33
|
+
expect(resolveQuery('Lookup')).toBeUndefined();
|
|
34
|
+
expect(registeredQueryNames()).toEqual([]);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
it('keeps legacy replacement authoritative while exact resolution counts mixed candidates', () => {
|
|
38
|
+
registerQuery('Lookup', First);
|
|
39
|
+
registerQuery('Lookup', Replacement);
|
|
40
|
+
expect(resolveQuery('Lookup')).toBe(Replacement);
|
|
41
|
+
expect(resolveExactQuery('Lookup')).toBe(Replacement);
|
|
42
|
+
registerQueryIdentity('Lookup', 'source/Lookup', First);
|
|
43
|
+
expect(resolveQuery('Lookup')).toBe(Replacement);
|
|
44
|
+
expect(resolveExactQuery('Lookup')).toBe('ambiguous');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('bridges a unique identity to legacy consumers with exact case-sensitive names and clears both maps', () => {
|
|
48
|
+
registerQueryIdentity('Lookup', 'source/Lookup', First);
|
|
49
|
+
expect(resolveQuery('Lookup')).toBe(First);
|
|
50
|
+
expect(resolveQuery('lookup')).toBeUndefined();
|
|
51
|
+
expect(resolveExactQuery('lookup')).toBeUndefined();
|
|
52
|
+
clearBindings();
|
|
53
|
+
expect(resolveQuery('Lookup')).toBeUndefined();
|
|
54
|
+
expect(resolveExactQuery('Lookup')).toBeUndefined();
|
|
55
|
+
expect(registeredQueryNames()).toEqual([]);
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
it('lists the sorted union without duplicates, retaining legacy names after identity removal', () => {
|
|
59
|
+
registerQueryIdentity('Zed', 'source/Zed', First);
|
|
60
|
+
registerQueryIdentity('Lookup', 'source/Lookup', First);
|
|
61
|
+
registerQuery('Lookup', Replacement);
|
|
62
|
+
registerQuery('Alpha', First);
|
|
63
|
+
expect(registeredQueryNames()).toEqual(['Alpha', 'Lookup', 'Zed']);
|
|
64
|
+
unregisterQueryIdentity('Lookup', 'source/Lookup');
|
|
65
|
+
unregisterQueryIdentity('Zed', 'source/Zed');
|
|
66
|
+
unregisterQueryIdentity('Missing', 'source/Missing');
|
|
67
|
+
expect(registeredQueryNames()).toEqual(['Alpha', 'Lookup']);
|
|
68
|
+
expect(resolveQuery('Lookup')).toBe(Replacement);
|
|
69
|
+
expect(resolveExactQuery('Lookup')).toBe(Replacement);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
it('gives an existing legacy registration precedence even over multiple identities and later replacements', () => {
|
|
73
|
+
registerQueryIdentity('Lookup', 'one/Lookup', First);
|
|
74
|
+
registerQueryIdentity('Lookup', 'two/Lookup', First);
|
|
75
|
+
registerQuery('Lookup', First);
|
|
76
|
+
registerQuery('Lookup', Replacement);
|
|
77
|
+
registerQueryIdentity('Lookup', 'one/Lookup', Replacement);
|
|
78
|
+
expect(resolveQuery('Lookup')).toBe(Replacement);
|
|
79
|
+
expect(resolveExactQuery('Lookup')).toBe('ambiguous');
|
|
80
|
+
});
|
|
81
|
+
});
|
|
@@ -55,7 +55,9 @@ describe('when mounting bound adapters', () => {
|
|
|
55
55
|
await act(async () => {
|
|
56
56
|
render(<SceneDataTable element={externalComponent('Cratis.Components:dataTable', { query: 'wrong' })} slots={{}} />);
|
|
57
57
|
});
|
|
58
|
-
|
|
58
|
+
// The published Components boundary sanitizes exception text; assert visible failure, not
|
|
59
|
+
// its former raw-error presentation. requireArcProxy's specs cover the precise diagnostic.
|
|
60
|
+
expect(screen.getByRole('alert')).toBeTruthy();
|
|
59
61
|
expect(received).not.toHaveBeenCalled();
|
|
60
62
|
});
|
|
61
63
|
|
|
@@ -65,7 +67,7 @@ describe('when mounting bound adapters', () => {
|
|
|
65
67
|
<Boundary><BoundCommandDialog command={proxies.Snapshot} title='' visible /></Boundary>
|
|
66
68
|
<Boundary><BoundStepperCommandDialog command={proxies.Live} title='' visible /></Boundary>
|
|
67
69
|
<Boundary><BoundDataPage query={proxies.Save} title='' emptyMessage='' children={undefined} /></Boundary></>);
|
|
68
|
-
expect(screen.
|
|
70
|
+
expect(screen.getAllByRole('alert')).toHaveLength(4);
|
|
69
71
|
expect(received).not.toHaveBeenCalled();
|
|
70
72
|
});
|
|
71
73
|
});
|
package/cratisComponents.ts
CHANGED
|
@@ -10,6 +10,7 @@ import {
|
|
|
10
10
|
SceneChipsField,
|
|
11
11
|
SceneColorPickerField,
|
|
12
12
|
SceneCommandForm,
|
|
13
|
+
SceneQueryInputForm,
|
|
13
14
|
SceneDropdownField,
|
|
14
15
|
SceneInputTextField,
|
|
15
16
|
SceneMultiSelectField,
|
|
@@ -54,6 +55,7 @@ export const cratisComponents: ComponentRegistry = {
|
|
|
54
55
|
[componentRegistryKey(cratisComponentsPackageName, 'table')]: SceneDataTable,
|
|
55
56
|
[componentRegistryKey(cratisComponentsPackageName, 'observableDataTable')]: SceneObservableDataTable,
|
|
56
57
|
|
|
58
|
+
[componentRegistryKey(cratisComponentsPackageName, 'queryInputForm')]: SceneQueryInputForm,
|
|
57
59
|
[componentRegistryKey(cratisComponentsPackageName, 'commandForm')]: SceneCommandForm,
|
|
58
60
|
[componentRegistryKey(cratisComponentsPackageName, 'inputTextField')]: SceneInputTextField,
|
|
59
61
|
[componentRegistryKey(cratisComponentsPackageName, 'numberField')]: SceneNumberField,
|
|
@@ -37,6 +37,7 @@ export const cratisComponentsPackageManifest: ScenePackage = {
|
|
|
37
37
|
'dataPage',
|
|
38
38
|
'formElement',
|
|
39
39
|
'singleResult',
|
|
40
|
+
'queryInputForm',
|
|
40
41
|
'dataTable',
|
|
41
42
|
'table',
|
|
42
43
|
'observableDataTable',
|
|
@@ -89,7 +90,7 @@ export const cratisComponentsPackageManifest: ScenePackage = {
|
|
|
89
90
|
themes: [],
|
|
90
91
|
|
|
91
92
|
displayName: 'Cratis Components',
|
|
92
|
-
description: "Cratis' Arc-bound data, form and dialog composites, built on PrimeReact and Tailwind. dataTable and table accept optional object-valued queryArguments for collection queries. singleResult displays one read-only scalar own resultField of an optional model using an explicit query, object queryArguments and enabled: true.",
|
|
93
|
+
description: "Cratis' Arc-bound data, form and dialog composites, built on PrimeReact and Tailwind. dataTable and table accept optional object-valued queryArguments for collection queries. singleResult displays one read-only scalar own resultField of an optional model using an explicit query, object queryArguments and enabled: true. queryInputForm commits explicit string inputs on submit to the same optional-single runtime; drafts never execute a query.",
|
|
93
94
|
module: '@cratis/scene.components',
|
|
94
95
|
license: 'MIT',
|
|
95
96
|
licenseUrl: 'https://github.com/Cratis/Scene/blob/main/LICENSE',
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import { useContext, useEffect, useMemo, useState } from 'react';
|
|
5
5
|
import { ArcContext } from '@cratis/arc.react';
|
|
6
6
|
import type { QueryFor } from '@cratis/arc/queries';
|
|
7
|
+
import { Guid } from '@cratis/fundamentals';
|
|
7
8
|
import type { BoundConstructor } from '../bindings/BoundConstructor';
|
|
8
9
|
import { SingleResultStatus } from './SingleResultStatus';
|
|
9
10
|
|
|
@@ -11,6 +12,8 @@ interface Props {
|
|
|
11
12
|
query: BoundConstructor;
|
|
12
13
|
queryArguments: Record<string, unknown>;
|
|
13
14
|
resultField: string;
|
|
15
|
+
/** queryInputForm alone opts into scalar String/Guid descriptor mapping; no value conversion. */
|
|
16
|
+
stringInputs?: boolean;
|
|
14
17
|
}
|
|
15
18
|
|
|
16
19
|
type Outcome = { state: 'failure' | 'notFound' } | { state: 'success'; value: string };
|
|
@@ -19,12 +22,12 @@ type Outcome = { state: 'failure' | 'notFound' } | { state: 'success'; value: st
|
|
|
19
22
|
* Private execution owner. Arc owns validation, routing, HTTP and deserialization; this component
|
|
20
23
|
* owns only request lifetime and presentation. No shared cache can hand B the result belonging to A.
|
|
21
24
|
*/
|
|
22
|
-
export default function SingleResultRuntime({ query, queryArguments, resultField }: Props) {
|
|
25
|
+
export default function SingleResultRuntime({ query, queryArguments, resultField, stringInputs = false }: Props) {
|
|
23
26
|
const arc = useContext(ArcContext);
|
|
24
27
|
const { microservice, apiBasePath, origin, httpHeadersCallback, queryVersion } = arc;
|
|
25
28
|
// Identity is deliberate: hosts replace immutable committed arguments rather than mutating them.
|
|
26
|
-
const request = useMemo(() => ({ query, queryArguments, resultField, microservice, apiBasePath, origin, httpHeadersCallback, queryVersion }),
|
|
27
|
-
[query, queryArguments, resultField, microservice, apiBasePath, origin, httpHeadersCallback, queryVersion]);
|
|
29
|
+
const request = useMemo(() => ({ query, queryArguments, resultField, stringInputs, microservice, apiBasePath, origin, httpHeadersCallback, queryVersion }),
|
|
30
|
+
[query, queryArguments, resultField, stringInputs, microservice, apiBasePath, origin, httpHeadersCallback, queryVersion]);
|
|
28
31
|
const [settled, setSettled] = useState<{ request: typeof request; outcome: Outcome }>();
|
|
29
32
|
|
|
30
33
|
useEffect(() => {
|
|
@@ -42,6 +45,17 @@ export default function SingleResultRuntime({ query, queryArguments, resultField
|
|
|
42
45
|
publish({ state: 'failure' });
|
|
43
46
|
return;
|
|
44
47
|
}
|
|
48
|
+
// Arc perform does not validate argument-to-descriptor types. The form supports only
|
|
49
|
+
// scalar String/Guid inputs, matched by exact name and constructor, never by naming
|
|
50
|
+
// convention. This check is lazy and form-only; singleResult's host contract is intact.
|
|
51
|
+
if (request.stringInputs && !Object.entries(request.queryArguments).every(([name, value]) => {
|
|
52
|
+
const descriptors = instance!.parameterDescriptors.filter(descriptor => descriptor.name === name);
|
|
53
|
+
return typeof value === 'string' && descriptors.length === 1 && !descriptors[0].isEnumerable
|
|
54
|
+
&& (descriptors[0].type === String || descriptors[0].type === Guid);
|
|
55
|
+
})) {
|
|
56
|
+
publish({ state: 'failure' });
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
45
59
|
instance.setMicroservice(request.microservice);
|
|
46
60
|
instance.setApiBasePath(request.apiBasePath ?? '');
|
|
47
61
|
instance.setOrigin(request.origin ?? '');
|
|
@@ -57,6 +57,25 @@ describe('when forwarding query arguments', () => {
|
|
|
57
57
|
properties.should.have.property('queryArguments').that.deep.equals({ projectId: suppliedId });
|
|
58
58
|
});
|
|
59
59
|
|
|
60
|
+
it('should bridge an identity-only query to an existing table without a second legacy registration', async () => {
|
|
61
|
+
bindings.clearBindings();
|
|
62
|
+
bindings.registerQueryIdentity('InvoicesForProject', 'Invoices/ForProject', InvoicesForProject);
|
|
63
|
+
const queryArguments = { projectId: suppliedId };
|
|
64
|
+
await renderTable({ query: 'InvoicesForProject', queryArguments });
|
|
65
|
+
await screen.findByTestId('query-table');
|
|
66
|
+
(received.mock.lastCall![0].query === InvoicesForProject).should.equal(true);
|
|
67
|
+
(received.mock.lastCall![0].queryArguments === queryArguments).should.equal(true);
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
it('should visibly reject ambiguous identity-only tables without selecting either native proxy', async () => {
|
|
71
|
+
bindings.clearBindings();
|
|
72
|
+
bindings.registerQueryIdentity('InvoicesForProject', 'One/ForProject', InvoicesForProject);
|
|
73
|
+
bindings.registerQueryIdentity('InvoicesForProject', 'Two/ForProject', AnotherQuery);
|
|
74
|
+
await renderTable({ query: 'InvoicesForProject' });
|
|
75
|
+
(screen.getByText("Unresolved query binding 'InvoicesForProject' on Cratis.Components:dataTable") !== null).should.equal(true);
|
|
76
|
+
received.mock.calls.should.have.lengthOf(0);
|
|
77
|
+
});
|
|
78
|
+
|
|
60
79
|
it('should preserve all supplied keys and values without normalization or defaults', async () => {
|
|
61
80
|
const queryArguments = { projectId: suppliedId, ProjectID: 'distinct', limit: 0, enabled: false, optional: null, filter: { names: ['one'] } };
|
|
62
81
|
await renderTable({ query: 'InvoicesForProject', queryArguments });
|
|
@@ -4,6 +4,40 @@
|
|
|
4
4
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
|
5
5
|
const queries = new Map();
|
|
6
6
|
const commands = new Map();
|
|
7
|
+
// Opt-in identities are separate from the legacy last-registration-wins namespace.
|
|
8
|
+
const queryIdentities = new Map();
|
|
9
|
+
const queryBindingListeners = new Set();
|
|
10
|
+
function notifyQueryBindings() {
|
|
11
|
+
for (const listener of queryBindingListeners)listener();
|
|
12
|
+
}
|
|
13
|
+
/** Subscribe to exact-binding changes. Existing adapters retain their render-time lookup contract. */ function subscribeQueryBindings(listener) {
|
|
14
|
+
queryBindingListeners.add(listener);
|
|
15
|
+
return ()=>{
|
|
16
|
+
queryBindingListeners.delete(listener);
|
|
17
|
+
};
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Registers one source identity for an exact query name. The same identity replaces on hot reload;
|
|
21
|
+
* different identities remain distinct candidates, even when their constructors happen to match.
|
|
22
|
+
* Legacy resolution also accepts a unique identity when no legacy registration exists.
|
|
23
|
+
*/ function registerQueryIdentity(name, identity, queryClass) {
|
|
24
|
+
const candidates = queryIdentities.get(name) ?? new Map();
|
|
25
|
+
candidates.set(identity, queryClass);
|
|
26
|
+
queryIdentities.set(name, candidates);
|
|
27
|
+
notifyQueryBindings();
|
|
28
|
+
}
|
|
29
|
+
/** Removes a source identity when a generated module is removed or renamed. */ function unregisterQueryIdentity(name, identity) {
|
|
30
|
+
const candidates = queryIdentities.get(name);
|
|
31
|
+
candidates?.delete(identity);
|
|
32
|
+
if (candidates?.size === 0) queryIdentities.delete(name);
|
|
33
|
+
notifyQueryBindings();
|
|
34
|
+
}
|
|
35
|
+
/** Exact binding: a legacy registration counts as one candidate alongside opt-in identities. */ function resolveExactQuery(name) {
|
|
36
|
+
const legacy = queries.get(name);
|
|
37
|
+
const candidates = queryIdentities.get(name);
|
|
38
|
+
if ((legacy ? 1 : 0) + (candidates?.size ?? 0) > 1) return 'ambiguous';
|
|
39
|
+
return legacy ?? candidates?.values().next().value;
|
|
40
|
+
}
|
|
7
41
|
/**
|
|
8
42
|
* Registers an Arc query proxy under the name screens refer to it by.
|
|
9
43
|
*
|
|
@@ -21,6 +55,7 @@ const commands = new Map();
|
|
|
21
55
|
* the previous run.
|
|
22
56
|
*/ function registerQuery(name, queryClass) {
|
|
23
57
|
queries.set(name, queryClass);
|
|
58
|
+
notifyQueryBindings();
|
|
24
59
|
}
|
|
25
60
|
/**
|
|
26
61
|
* Registers several query proxies at once, keyed by the name screens refer to each by.
|
|
@@ -34,13 +69,17 @@ const commands = new Map();
|
|
|
34
69
|
}
|
|
35
70
|
}
|
|
36
71
|
/**
|
|
37
|
-
*
|
|
72
|
+
* Legacy registrations are authoritative. Otherwise resolve a unique source identity, or `undefined`
|
|
73
|
+
* when absent or ambiguous (existing adapters display their unresolved-binding placeholder).
|
|
38
74
|
*
|
|
39
75
|
* `undefined` rather than a throw: design-time preview in Studio normally has nothing registered at all,
|
|
40
76
|
* and a screen still has to render so its layout can be worked on. Every adapter turns `undefined` into
|
|
41
77
|
* a visible placeholder naming the binding it wanted.
|
|
42
78
|
*/ function resolveQuery(name) {
|
|
43
|
-
|
|
79
|
+
const legacy = queries.get(name);
|
|
80
|
+
if (legacy) return legacy;
|
|
81
|
+
const candidates = queryIdentities.get(name);
|
|
82
|
+
return candidates?.size === 1 ? candidates.values().next().value : undefined;
|
|
44
83
|
}
|
|
45
84
|
/**
|
|
46
85
|
* Registers an Arc command proxy under the name screens refer to it by. The command half of
|
|
@@ -61,14 +100,17 @@ const commands = new Map();
|
|
|
61
100
|
return commands.get(name);
|
|
62
101
|
}
|
|
63
102
|
/**
|
|
64
|
-
*
|
|
103
|
+
* The sorted union of legacy and identity query names, including ambiguous names.
|
|
65
104
|
*
|
|
66
105
|
* A design-time tool uses this to offer the names a screen can actually bind to, and a diagnostics
|
|
67
106
|
* surface uses it to explain a placeholder - "this screen wants `AllInvoices`, and here is what is
|
|
68
107
|
* registered" is a far more useful message than the placeholder alone.
|
|
69
108
|
*/ function registeredQueryNames() {
|
|
70
109
|
return [
|
|
71
|
-
...
|
|
110
|
+
...new Set([
|
|
111
|
+
...queries.keys(),
|
|
112
|
+
...queryIdentities.keys()
|
|
113
|
+
])
|
|
72
114
|
].sort();
|
|
73
115
|
}
|
|
74
116
|
/**
|
|
@@ -87,6 +129,8 @@ const commands = new Map();
|
|
|
87
129
|
*/ function clearBindings() {
|
|
88
130
|
queries.clear();
|
|
89
131
|
commands.clear();
|
|
132
|
+
queryIdentities.clear();
|
|
133
|
+
notifyQueryBindings();
|
|
90
134
|
}
|
|
91
135
|
|
|
92
136
|
exports.clearBindings = clearBindings;
|
|
@@ -94,8 +138,12 @@ exports.registerCommand = registerCommand;
|
|
|
94
138
|
exports.registerCommands = registerCommands;
|
|
95
139
|
exports.registerQueries = registerQueries;
|
|
96
140
|
exports.registerQuery = registerQuery;
|
|
141
|
+
exports.registerQueryIdentity = registerQueryIdentity;
|
|
97
142
|
exports.registeredCommandNames = registeredCommandNames;
|
|
98
143
|
exports.registeredQueryNames = registeredQueryNames;
|
|
99
144
|
exports.resolveCommand = resolveCommand;
|
|
145
|
+
exports.resolveExactQuery = resolveExactQuery;
|
|
100
146
|
exports.resolveQuery = resolveQuery;
|
|
147
|
+
exports.subscribeQueryBindings = subscribeQueryBindings;
|
|
148
|
+
exports.unregisterQueryIdentity = unregisterQueryIdentity;
|
|
101
149
|
//# sourceMappingURL=bindingRegistry.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bindingRegistry.js","sources":["../../../bindings/bindingRegistry.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { BoundConstructor } from './BoundConstructor';\n\nconst queries = new Map<string, BoundConstructor>();\nconst commands = new Map<string, BoundConstructor>();\n\n/**\n * Registers an Arc query proxy under the name screens refer to it by.\n *\n * This is the seam that makes the Arc-bound half of `@cratis/components` usable from Scene at all. A\n * screen says `data Invoices via query AllInvoices`, and by the time that reaches a renderer it is an\n * `ExternalComponent` whose `properties` bag holds the *string* `'AllInvoices'` - a property bag carries\n * plain values and named slots, and there is no way to put a TypeScript class into one. `DataTableForQuery`\n * needs the class. The name is the only thing that survives the trip, so the name is what the lookup has\n * to be keyed on, and a host that owns the generated proxies is the only party that can supply the class\n * behind it.\n *\n * A host - Stage's generated application, or Studio's preview when it is wired to a real backend -\n * registers every proxy a screen can name, once, during startup. Registering the same name twice\n * replaces the earlier registration, so a host can re-register on hot reload without having to unwind\n * the previous run.\n */\nexport function registerQuery(name: string, queryClass: BoundConstructor): void {\n queries.set(name, queryClass);\n}\n\n/**\n * Registers several query proxies at once, keyed by the name screens refer to each by.\n *\n * Stage generates a module that exports every proxy it produced; handing that module's exports straight\n * to this is the whole of a generated host's registration step, and it stays correct as proxies are\n * added and removed without anyone editing a list.\n */\nexport function registerQueries(bindings: Record<string, BoundConstructor>): void {\n for (const [name, queryClass] of Object.entries(bindings)) {\n registerQuery(name, queryClass);\n }\n}\n\n/**\n * The query proxy registered under a name, or `undefined` when nothing is registered under it.\n *\n * `undefined` rather than a throw: design-time preview in Studio normally has nothing registered at all,\n * and a screen still has to render so its layout can be worked on. Every adapter turns `undefined` into\n * a visible placeholder naming the binding it wanted.\n */\nexport function resolveQuery(name: string): BoundConstructor | undefined {\n return queries.get(name);\n}\n\n/**\n * Registers an Arc command proxy under the name screens refer to it by. The command half of\n * {@link registerQuery}, with the same contract.\n */\nexport function registerCommand(name: string, commandClass: BoundConstructor): void {\n commands.set(name, commandClass);\n}\n\n/**\n * Registers several command proxies at once, keyed by the name screens refer to each by.\n */\nexport function registerCommands(bindings: Record<string, BoundConstructor>): void {\n for (const [name, commandClass] of Object.entries(bindings)) {\n registerCommand(name, commandClass);\n }\n}\n\n/**\n * The command proxy registered under a name, or `undefined` when nothing is registered under it.\n */\nexport function resolveCommand(name: string): BoundConstructor | undefined {\n return commands.get(name);\n}\n\n/**\n * Every registered query name, sorted.\n *\n * A design-time tool uses this to offer the names a screen can actually bind to, and a diagnostics\n * surface uses it to explain a placeholder - \"this screen wants `AllInvoices`, and here is what is\n * registered\" is a far more useful message than the placeholder alone.\n */\nexport function registeredQueryNames(): string[] {\n return [...queries.keys()].sort();\n}\n\n/**\n * Every registered command name, sorted.\n */\nexport function registeredCommandNames(): string[] {\n return [...commands.keys()].sort();\n}\n\n/**\n * Forgets every registered query and command.\n *\n * The registry is module-level state, which is right for a host that registers once at startup but wrong\n * for anything that switches between applications - Studio previewing a different project, or a spec\n * that must not inherit what the previous one registered. Both need a way back to empty.\n */\nexport function clearBindings(): void {\n queries.clear();\n commands.clear();\n}\n"],"names":["queries","Map","commands","registerQuery","name","queryClass","set","registerQueries","bindings","Object","entries","resolveQuery","get","registerCommand","commandClass","registerCommands","resolveCommand","registeredQueryNames","keys","sort","registeredCommandNames","clearBindings","clear"],"mappings":";;AAAA;AACA;AAIA,MAAMA,UAAU,IAAIC,GAAAA,EAAAA;AACpB,MAAMC,WAAW,IAAID,GAAAA,EAAAA;AAErB;;;;;;;;;;;;;;;AAeC,IACM,SAASE,aAAAA,CAAcC,IAAY,EAAEC,UAA4B,EAAA;IACpEL,OAAAA,CAAQM,GAAG,CAACF,IAAAA,EAAMC,UAAAA,CAAAA;AACtB;AAEA;;;;;;IAOO,SAASE,eAAAA,CAAgBC,QAA0C,EAAA;IACtE,KAAK,MAAM,CAACJ,IAAAA,EAAMC,UAAAA,CAAW,IAAII,MAAAA,CAAOC,OAAO,CAACF,QAAAA,CAAAA,CAAW;AACvDL,QAAAA,aAAAA,CAAcC,IAAAA,EAAMC,UAAAA,CAAAA;AACxB,IAAA;AACJ;AAEA;;;;;;IAOO,SAASM,YAAAA,CAAaP,IAAY,EAAA;IACrC,OAAOJ,OAAAA,CAAQY,GAAG,CAACR,IAAAA,CAAAA;AACvB;AAEA;;;AAGC,IACM,SAASS,eAAAA,CAAgBT,IAAY,EAAEU,YAA8B,EAAA;IACxEZ,QAAAA,CAASI,GAAG,CAACF,IAAAA,EAAMU,YAAAA,CAAAA;AACvB;AAEA;;IAGO,SAASC,gBAAAA,CAAiBP,QAA0C,EAAA;IACvE,KAAK,MAAM,CAACJ,IAAAA,EAAMU,YAAAA,CAAa,IAAIL,MAAAA,CAAOC,OAAO,CAACF,QAAAA,CAAAA,CAAW;AACzDK,QAAAA,eAAAA,CAAgBT,IAAAA,EAAMU,YAAAA,CAAAA;AAC1B,IAAA;AACJ;AAEA;;IAGO,SAASE,cAAAA,CAAeZ,IAAY,EAAA;IACvC,OAAOF,QAAAA,CAASU,GAAG,CAACR,IAAAA,CAAAA;AACxB;AAEA;;;;;;AAMC,IACM,SAASa,oBAAAA,GAAAA;IACZ,OAAO;AAAIjB,QAAAA,GAAAA,OAAAA,CAAQkB,IAAI;AAAG,KAAA,CAACC,IAAI,EAAA;AACnC;AAEA;;AAEC,IACM,SAASC,sBAAAA,GAAAA;IACZ,OAAO;AAAIlB,QAAAA,GAAAA,QAAAA,CAASgB,IAAI;AAAG,KAAA,CAACC,IAAI,EAAA;AACpC;AAEA;;;;;;AAMC,IACM,SAASE,aAAAA,GAAAA;AACZrB,IAAAA,OAAAA,CAAQsB,KAAK,EAAA;AACbpB,IAAAA,QAAAA,CAASoB,KAAK,EAAA;AAClB;;;;;;;;;;"}
|
|
1
|
+
{"version":3,"file":"bindingRegistry.js","sources":["../../../bindings/bindingRegistry.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { BoundConstructor } from './BoundConstructor';\n\nconst queries = new Map<string, BoundConstructor>();\nconst commands = new Map<string, BoundConstructor>();\n// Opt-in identities are separate from the legacy last-registration-wins namespace.\nconst queryIdentities = new Map<string, Map<string, BoundConstructor>>();\nconst queryBindingListeners = new Set<() => void>();\n\nfunction notifyQueryBindings(): void {\n for (const listener of queryBindingListeners) listener();\n}\n\n/** Subscribe to exact-binding changes. Existing adapters retain their render-time lookup contract. */\nexport function subscribeQueryBindings(listener: () => void): () => void {\n queryBindingListeners.add(listener);\n return () => { queryBindingListeners.delete(listener); };\n}\n\n/**\n * Registers one source identity for an exact query name. The same identity replaces on hot reload;\n * different identities remain distinct candidates, even when their constructors happen to match.\n * Legacy resolution also accepts a unique identity when no legacy registration exists.\n */\nexport function registerQueryIdentity(name: string, identity: string, queryClass: BoundConstructor): void {\n const candidates = queryIdentities.get(name) ?? new Map<string, BoundConstructor>();\n candidates.set(identity, queryClass);\n queryIdentities.set(name, candidates);\n notifyQueryBindings();\n}\n\n/** Removes a source identity when a generated module is removed or renamed. */\nexport function unregisterQueryIdentity(name: string, identity: string): void {\n const candidates = queryIdentities.get(name);\n candidates?.delete(identity);\n if (candidates?.size === 0) queryIdentities.delete(name);\n notifyQueryBindings();\n}\n\n/** Exact binding: a legacy registration counts as one candidate alongside opt-in identities. */\nexport function resolveExactQuery(name: string): BoundConstructor | 'ambiguous' | undefined {\n const legacy = queries.get(name);\n const candidates = queryIdentities.get(name);\n if ((legacy ? 1 : 0) + (candidates?.size ?? 0) > 1) return 'ambiguous';\n return legacy ?? candidates?.values().next().value;\n}\n\n/**\n * Registers an Arc query proxy under the name screens refer to it by.\n *\n * This is the seam that makes the Arc-bound half of `@cratis/components` usable from Scene at all. A\n * screen says `data Invoices via query AllInvoices`, and by the time that reaches a renderer it is an\n * `ExternalComponent` whose `properties` bag holds the *string* `'AllInvoices'` - a property bag carries\n * plain values and named slots, and there is no way to put a TypeScript class into one. `DataTableForQuery`\n * needs the class. The name is the only thing that survives the trip, so the name is what the lookup has\n * to be keyed on, and a host that owns the generated proxies is the only party that can supply the class\n * behind it.\n *\n * A host - Stage's generated application, or Studio's preview when it is wired to a real backend -\n * registers every proxy a screen can name, once, during startup. Registering the same name twice\n * replaces the earlier registration, so a host can re-register on hot reload without having to unwind\n * the previous run.\n */\nexport function registerQuery(name: string, queryClass: BoundConstructor): void {\n queries.set(name, queryClass);\n notifyQueryBindings();\n}\n\n/**\n * Registers several query proxies at once, keyed by the name screens refer to each by.\n *\n * Stage generates a module that exports every proxy it produced; handing that module's exports straight\n * to this is the whole of a generated host's registration step, and it stays correct as proxies are\n * added and removed without anyone editing a list.\n */\nexport function registerQueries(bindings: Record<string, BoundConstructor>): void {\n for (const [name, queryClass] of Object.entries(bindings)) {\n registerQuery(name, queryClass);\n }\n}\n\n/**\n * Legacy registrations are authoritative. Otherwise resolve a unique source identity, or `undefined`\n * when absent or ambiguous (existing adapters display their unresolved-binding placeholder).\n *\n * `undefined` rather than a throw: design-time preview in Studio normally has nothing registered at all,\n * and a screen still has to render so its layout can be worked on. Every adapter turns `undefined` into\n * a visible placeholder naming the binding it wanted.\n */\nexport function resolveQuery(name: string): BoundConstructor | undefined {\n const legacy = queries.get(name);\n if (legacy) return legacy;\n const candidates = queryIdentities.get(name);\n return candidates?.size === 1 ? candidates.values().next().value : undefined;\n}\n\n/**\n * Registers an Arc command proxy under the name screens refer to it by. The command half of\n * {@link registerQuery}, with the same contract.\n */\nexport function registerCommand(name: string, commandClass: BoundConstructor): void {\n commands.set(name, commandClass);\n}\n\n/**\n * Registers several command proxies at once, keyed by the name screens refer to each by.\n */\nexport function registerCommands(bindings: Record<string, BoundConstructor>): void {\n for (const [name, commandClass] of Object.entries(bindings)) {\n registerCommand(name, commandClass);\n }\n}\n\n/**\n * The command proxy registered under a name, or `undefined` when nothing is registered under it.\n */\nexport function resolveCommand(name: string): BoundConstructor | undefined {\n return commands.get(name);\n}\n\n/**\n * The sorted union of legacy and identity query names, including ambiguous names.\n *\n * A design-time tool uses this to offer the names a screen can actually bind to, and a diagnostics\n * surface uses it to explain a placeholder - \"this screen wants `AllInvoices`, and here is what is\n * registered\" is a far more useful message than the placeholder alone.\n */\nexport function registeredQueryNames(): string[] {\n return [...new Set([...queries.keys(), ...queryIdentities.keys()])].sort();\n}\n\n/**\n * Every registered command name, sorted.\n */\nexport function registeredCommandNames(): string[] {\n return [...commands.keys()].sort();\n}\n\n/**\n * Forgets every registered query and command.\n *\n * The registry is module-level state, which is right for a host that registers once at startup but wrong\n * for anything that switches between applications - Studio previewing a different project, or a spec\n * that must not inherit what the previous one registered. Both need a way back to empty.\n */\nexport function clearBindings(): void {\n queries.clear();\n commands.clear();\n queryIdentities.clear();\n notifyQueryBindings();\n}\n"],"names":["queries","Map","commands","queryIdentities","queryBindingListeners","Set","notifyQueryBindings","listener","subscribeQueryBindings","add","delete","registerQueryIdentity","name","identity","queryClass","candidates","get","set","unregisterQueryIdentity","size","resolveExactQuery","legacy","values","next","value","registerQuery","registerQueries","bindings","Object","entries","resolveQuery","undefined","registerCommand","commandClass","registerCommands","resolveCommand","registeredQueryNames","keys","sort","registeredCommandNames","clearBindings","clear"],"mappings":";;AAAA;AACA;AAIA,MAAMA,UAAU,IAAIC,GAAAA,EAAAA;AACpB,MAAMC,WAAW,IAAID,GAAAA,EAAAA;AACrB;AACA,MAAME,kBAAkB,IAAIF,GAAAA,EAAAA;AAC5B,MAAMG,wBAAwB,IAAIC,GAAAA,EAAAA;AAElC,SAASC,mBAAAA,GAAAA;IACL,KAAK,MAAMC,YAAYH,qBAAAA,CAAuBG,QAAAA,EAAAA;AAClD;AAEA,uGACO,SAASC,sBAAAA,CAAuBD,QAAoB,EAAA;AACvDH,IAAAA,qBAAAA,CAAsBK,GAAG,CAACF,QAAAA,CAAAA;IAC1B,OAAO,IAAA;AAAQH,QAAAA,qBAAAA,CAAsBM,MAAM,CAACH,QAAAA,CAAAA;AAAW,IAAA,CAAA;AAC3D;AAEA;;;;AAIC,IACM,SAASI,qBAAAA,CAAsBC,IAAY,EAAEC,QAAgB,EAAEC,UAA4B,EAAA;AAC9F,IAAA,MAAMC,UAAAA,GAAaZ,eAAAA,CAAgBa,GAAG,CAACJ,SAAS,IAAIX,GAAAA,EAAAA;IACpDc,UAAAA,CAAWE,GAAG,CAACJ,QAAAA,EAAUC,UAAAA,CAAAA;IACzBX,eAAAA,CAAgBc,GAAG,CAACL,IAAAA,EAAMG,UAAAA,CAAAA;AAC1BT,IAAAA,mBAAAA,EAAAA;AACJ;AAEA,gFACO,SAASY,uBAAAA,CAAwBN,IAAY,EAAEC,QAAgB,EAAA;IAClE,MAAME,UAAAA,GAAaZ,eAAAA,CAAgBa,GAAG,CAACJ,IAAAA,CAAAA;AACvCG,IAAAA,UAAAA,EAAYL,MAAAA,CAAOG,QAAAA,CAAAA;AACnB,IAAA,IAAIE,UAAAA,EAAYI,IAAAA,KAAS,CAAA,EAAGhB,eAAAA,CAAgBO,MAAM,CAACE,IAAAA,CAAAA;AACnDN,IAAAA,mBAAAA,EAAAA;AACJ;AAEA,iGACO,SAASc,iBAAAA,CAAkBR,IAAY,EAAA;IAC1C,MAAMS,MAAAA,GAASrB,OAAAA,CAAQgB,GAAG,CAACJ,IAAAA,CAAAA;IAC3B,MAAMG,UAAAA,GAAaZ,eAAAA,CAAgBa,GAAG,CAACJ,IAAAA,CAAAA;AACvC,IAAA,IAAI,CAACS,MAAAA,GAAS,CAAA,GAAI,CAAA,KAAMN,UAAAA,EAAYI,IAAAA,IAAQ,CAAA,CAAA,GAAK,CAAA,EAAG,OAAO,WAAA;IAC3D,OAAOE,MAAAA,IAAUN,UAAAA,EAAYO,MAAAA,EAAAA,CAASC,IAAAA,EAAAA,CAAOC,KAAAA;AACjD;AAEA;;;;;;;;;;;;;;;AAeC,IACM,SAASC,aAAAA,CAAcb,IAAY,EAAEE,UAA4B,EAAA;IACpEd,OAAAA,CAAQiB,GAAG,CAACL,IAAAA,EAAME,UAAAA,CAAAA;AAClBR,IAAAA,mBAAAA,EAAAA;AACJ;AAEA;;;;;;IAOO,SAASoB,eAAAA,CAAgBC,QAA0C,EAAA;IACtE,KAAK,MAAM,CAACf,IAAAA,EAAME,UAAAA,CAAW,IAAIc,MAAAA,CAAOC,OAAO,CAACF,QAAAA,CAAAA,CAAW;AACvDF,QAAAA,aAAAA,CAAcb,IAAAA,EAAME,UAAAA,CAAAA;AACxB,IAAA;AACJ;AAEA;;;;;;;IAQO,SAASgB,YAAAA,CAAalB,IAAY,EAAA;IACrC,MAAMS,MAAAA,GAASrB,OAAAA,CAAQgB,GAAG,CAACJ,IAAAA,CAAAA;AAC3B,IAAA,IAAIS,QAAQ,OAAOA,MAAAA;IACnB,MAAMN,UAAAA,GAAaZ,eAAAA,CAAgBa,GAAG,CAACJ,IAAAA,CAAAA;IACvC,OAAOG,UAAAA,EAAYI,SAAS,CAAA,GAAIJ,UAAAA,CAAWO,MAAM,EAAA,CAAGC,IAAI,EAAA,CAAGC,KAAK,GAAGO,SAAAA;AACvE;AAEA;;;AAGC,IACM,SAASC,eAAAA,CAAgBpB,IAAY,EAAEqB,YAA8B,EAAA;IACxE/B,QAAAA,CAASe,GAAG,CAACL,IAAAA,EAAMqB,YAAAA,CAAAA;AACvB;AAEA;;IAGO,SAASC,gBAAAA,CAAiBP,QAA0C,EAAA;IACvE,KAAK,MAAM,CAACf,IAAAA,EAAMqB,YAAAA,CAAa,IAAIL,MAAAA,CAAOC,OAAO,CAACF,QAAAA,CAAAA,CAAW;AACzDK,QAAAA,eAAAA,CAAgBpB,IAAAA,EAAMqB,YAAAA,CAAAA;AAC1B,IAAA;AACJ;AAEA;;IAGO,SAASE,cAAAA,CAAevB,IAAY,EAAA;IACvC,OAAOV,QAAAA,CAASc,GAAG,CAACJ,IAAAA,CAAAA;AACxB;AAEA;;;;;;AAMC,IACM,SAASwB,oBAAAA,GAAAA;IACZ,OAAO;AAAI,QAAA,GAAA,IAAI/B,GAAAA,CAAI;AAAIL,YAAAA,GAAAA,OAAAA,CAAQqC,IAAI,EAAA;AAAOlC,YAAAA,GAAAA,eAAAA,CAAgBkC,IAAI;AAAG,SAAA;AAAE,KAAA,CAACC,IAAI,EAAA;AAC5E;AAEA;;AAEC,IACM,SAASC,sBAAAA,GAAAA;IACZ,OAAO;AAAIrC,QAAAA,GAAAA,QAAAA,CAASmC,IAAI;AAAG,KAAA,CAACC,IAAI,EAAA;AACpC;AAEA;;;;;;AAMC,IACM,SAASE,aAAAA,GAAAA;AACZxC,IAAAA,OAAAA,CAAQyC,KAAK,EAAA;AACbvC,IAAAA,QAAAA,CAASuC,KAAK,EAAA;AACdtC,IAAAA,eAAAA,CAAgBsC,KAAK,EAAA;AACrBnC,IAAAA,mBAAAA,EAAAA;AACJ;;;;;;;;;;;;;;"}
|
|
@@ -8,6 +8,7 @@ var SceneSingleResult = require('./data/SceneSingleResult.js');
|
|
|
8
8
|
var SceneDataTable = require('./data/SceneDataTable.js');
|
|
9
9
|
var SceneObservableDataTable = require('./data/SceneObservableDataTable.js');
|
|
10
10
|
var SceneCommandForm = require('./forms/SceneCommandForm.js');
|
|
11
|
+
var SceneQueryInputForm = require('./forms/SceneQueryInputForm.js');
|
|
11
12
|
require('react/jsx-runtime');
|
|
12
13
|
require('./bindings/resolveElementBinding.js');
|
|
13
14
|
require('react');
|
|
@@ -70,6 +71,7 @@ var SceneToolbarSeparator = require('./toolbar/SceneToolbarSeparator.js');
|
|
|
70
71
|
[scene_react.componentRegistryKey(cratisComponentsPackageName, 'dataTable')]: SceneDataTable.SceneDataTable,
|
|
71
72
|
[scene_react.componentRegistryKey(cratisComponentsPackageName, 'table')]: SceneDataTable.SceneDataTable,
|
|
72
73
|
[scene_react.componentRegistryKey(cratisComponentsPackageName, 'observableDataTable')]: SceneObservableDataTable.SceneObservableDataTable,
|
|
74
|
+
[scene_react.componentRegistryKey(cratisComponentsPackageName, 'queryInputForm')]: SceneQueryInputForm.SceneQueryInputForm,
|
|
73
75
|
[scene_react.componentRegistryKey(cratisComponentsPackageName, 'commandForm')]: SceneCommandForm.SceneCommandForm,
|
|
74
76
|
[scene_react.componentRegistryKey(cratisComponentsPackageName, 'inputTextField')]: SceneInputTextField.SceneInputTextField,
|
|
75
77
|
[scene_react.componentRegistryKey(cratisComponentsPackageName, 'numberField')]: SceneNumberField.SceneNumberField,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cratisComponents.js","sources":["../../cratisComponents.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ComponentRegistry, componentRegistryKey } from '@cratis/scene.react';\nimport { SceneDataPage, SceneFormElement, ScenePage } from './pages';\nimport { SceneDataTable, SceneObservableDataTable, SceneSingleResult } from './data';\nimport {\n SceneCalendarField,\n SceneCheckboxField,\n SceneChipsField,\n SceneColorPickerField,\n SceneCommandForm,\n SceneDropdownField,\n SceneInputTextField,\n SceneMultiSelectField,\n SceneNumberField,\n SceneRadioButtonField,\n SceneRadioGroupField,\n SceneSliderField,\n SceneTextAreaField,\n} from './forms';\nimport { SceneBusyIndicatorDialog, SceneCommandDialog, SceneConfirmationDialog, SceneDialog, SceneStepperCommandDialog } from './dialogs';\nimport { SceneDropdown, SceneErrorBoundary, SceneIcon, SceneTooltip } from './common';\nimport { SceneFilterPanel, SceneObjectContentEditor, SceneObjectNavigationalBar, SceneSchemaEditor, SceneTimeMachine } from './editors';\nimport { SceneToolbar, SceneToolbarButton, SceneToolbarGroup, SceneToolbarSeparator } from './toolbar';\n\n/**\n * The package name every component here is registered under, and the one a screen writes when it\n * qualifies a name explicitly (`Cratis.Components.table`).\n */\nexport const cratisComponentsPackageName = 'Cratis.Components';\n\n/**\n * The `Cratis.Components` package's component registry - the abstract names a screen can resolve to a\n * real `@cratis/components` component.\n *\n * Names are `lowerCamelCase` and deliberately *abstract*: a screen names `dataTable`, not\n * `DataTableForQuery`, so the same screen resolves against whichever package a profile ranks highest.\n * Two of them - `table` and `dialog` - are names `core` and `PrimeReact` also declare, and that overlap\n * is the point: a profile listing `core`, `PrimeReact`, `Cratis.Components` in that order resolves both\n * here and records the others as shadowed, which is override priority doing exactly what it exists for.\n *\n * `table` and `dataTable` are the same component under two names. `dataTable` says what it is; `table`\n * is what a screen written against the base vocabulary already says, and both should land on the\n * query-aware implementation.\n */\nexport const cratisComponents: ComponentRegistry = {\n [componentRegistryKey(cratisComponentsPackageName, 'page')]: ScenePage,\n [componentRegistryKey(cratisComponentsPackageName, 'dataPage')]: SceneDataPage,\n [componentRegistryKey(cratisComponentsPackageName, 'formElement')]: SceneFormElement,\n\n [componentRegistryKey(cratisComponentsPackageName, 'singleResult')]: SceneSingleResult,\n [componentRegistryKey(cratisComponentsPackageName, 'dataTable')]: SceneDataTable,\n [componentRegistryKey(cratisComponentsPackageName, 'table')]: SceneDataTable,\n [componentRegistryKey(cratisComponentsPackageName, 'observableDataTable')]: SceneObservableDataTable,\n\n [componentRegistryKey(cratisComponentsPackageName, 'commandForm')]: SceneCommandForm,\n [componentRegistryKey(cratisComponentsPackageName, 'inputTextField')]: SceneInputTextField,\n [componentRegistryKey(cratisComponentsPackageName, 'numberField')]: SceneNumberField,\n [componentRegistryKey(cratisComponentsPackageName, 'checkboxField')]: SceneCheckboxField,\n [componentRegistryKey(cratisComponentsPackageName, 'textAreaField')]: SceneTextAreaField,\n [componentRegistryKey(cratisComponentsPackageName, 'dropdownField')]: SceneDropdownField,\n [componentRegistryKey(cratisComponentsPackageName, 'sliderField')]: SceneSliderField,\n [componentRegistryKey(cratisComponentsPackageName, 'calendarField')]: SceneCalendarField,\n [componentRegistryKey(cratisComponentsPackageName, 'colorPickerField')]: SceneColorPickerField,\n [componentRegistryKey(cratisComponentsPackageName, 'multiSelectField')]: SceneMultiSelectField,\n [componentRegistryKey(cratisComponentsPackageName, 'chipsField')]: SceneChipsField,\n [componentRegistryKey(cratisComponentsPackageName, 'radioButtonField')]: SceneRadioButtonField,\n [componentRegistryKey(cratisComponentsPackageName, 'radioGroupField')]: SceneRadioGroupField,\n\n [componentRegistryKey(cratisComponentsPackageName, 'dialog')]: SceneDialog,\n [componentRegistryKey(cratisComponentsPackageName, 'confirmationDialog')]: SceneConfirmationDialog,\n [componentRegistryKey(cratisComponentsPackageName, 'busyIndicatorDialog')]: SceneBusyIndicatorDialog,\n [componentRegistryKey(cratisComponentsPackageName, 'commandDialog')]: SceneCommandDialog,\n [componentRegistryKey(cratisComponentsPackageName, 'stepperCommandDialog')]: SceneStepperCommandDialog,\n\n [componentRegistryKey(cratisComponentsPackageName, 'icon')]: SceneIcon,\n [componentRegistryKey(cratisComponentsPackageName, 'tooltip')]: SceneTooltip,\n [componentRegistryKey(cratisComponentsPackageName, 'dropdown')]: SceneDropdown,\n [componentRegistryKey(cratisComponentsPackageName, 'errorBoundary')]: SceneErrorBoundary,\n\n [componentRegistryKey(cratisComponentsPackageName, 'objectContentEditor')]: SceneObjectContentEditor,\n [componentRegistryKey(cratisComponentsPackageName, 'objectNavigationalBar')]: SceneObjectNavigationalBar,\n [componentRegistryKey(cratisComponentsPackageName, 'schemaEditor')]: SceneSchemaEditor,\n [componentRegistryKey(cratisComponentsPackageName, 'timeMachine')]: SceneTimeMachine,\n [componentRegistryKey(cratisComponentsPackageName, 'filterPanel')]: SceneFilterPanel,\n\n [componentRegistryKey(cratisComponentsPackageName, 'toolbar')]: SceneToolbar,\n [componentRegistryKey(cratisComponentsPackageName, 'toolbarButton')]: SceneToolbarButton,\n [componentRegistryKey(cratisComponentsPackageName, 'toolbarGroup')]: SceneToolbarGroup,\n [componentRegistryKey(cratisComponentsPackageName, 'toolbarSeparator')]: SceneToolbarSeparator,\n};\n"],"names":["cratisComponentsPackageName","cratisComponents","componentRegistryKey","ScenePage","SceneDataPage","SceneFormElement","SceneSingleResult","SceneDataTable","SceneObservableDataTable","SceneCommandForm","SceneInputTextField","SceneNumberField","SceneCheckboxField","SceneTextAreaField","SceneDropdownField","SceneSliderField","SceneCalendarField","SceneColorPickerField","SceneMultiSelectField","SceneChipsField","SceneRadioButtonField","SceneRadioGroupField","SceneDialog","SceneConfirmationDialog","SceneBusyIndicatorDialog","SceneCommandDialog","SceneStepperCommandDialog","SceneIcon","SceneTooltip","SceneDropdown","SceneErrorBoundary","SceneObjectContentEditor","SceneObjectNavigationalBar","SceneSchemaEditor","SceneTimeMachine","SceneFilterPanel","SceneToolbar","SceneToolbarButton","SceneToolbarGroup","SceneToolbarSeparator"],"mappings":"
|
|
1
|
+
{"version":3,"file":"cratisComponents.js","sources":["../../cratisComponents.ts"],"sourcesContent":["// Copyright (c) Cratis. All rights reserved.\n// Licensed under the MIT license. See LICENSE file in the project root for full license information.\n\nimport { ComponentRegistry, componentRegistryKey } from '@cratis/scene.react';\nimport { SceneDataPage, SceneFormElement, ScenePage } from './pages';\nimport { SceneDataTable, SceneObservableDataTable, SceneSingleResult } from './data';\nimport {\n SceneCalendarField,\n SceneCheckboxField,\n SceneChipsField,\n SceneColorPickerField,\n SceneCommandForm,\n SceneQueryInputForm,\n SceneDropdownField,\n SceneInputTextField,\n SceneMultiSelectField,\n SceneNumberField,\n SceneRadioButtonField,\n SceneRadioGroupField,\n SceneSliderField,\n SceneTextAreaField,\n} from './forms';\nimport { SceneBusyIndicatorDialog, SceneCommandDialog, SceneConfirmationDialog, SceneDialog, SceneStepperCommandDialog } from './dialogs';\nimport { SceneDropdown, SceneErrorBoundary, SceneIcon, SceneTooltip } from './common';\nimport { SceneFilterPanel, SceneObjectContentEditor, SceneObjectNavigationalBar, SceneSchemaEditor, SceneTimeMachine } from './editors';\nimport { SceneToolbar, SceneToolbarButton, SceneToolbarGroup, SceneToolbarSeparator } from './toolbar';\n\n/**\n * The package name every component here is registered under, and the one a screen writes when it\n * qualifies a name explicitly (`Cratis.Components.table`).\n */\nexport const cratisComponentsPackageName = 'Cratis.Components';\n\n/**\n * The `Cratis.Components` package's component registry - the abstract names a screen can resolve to a\n * real `@cratis/components` component.\n *\n * Names are `lowerCamelCase` and deliberately *abstract*: a screen names `dataTable`, not\n * `DataTableForQuery`, so the same screen resolves against whichever package a profile ranks highest.\n * Two of them - `table` and `dialog` - are names `core` and `PrimeReact` also declare, and that overlap\n * is the point: a profile listing `core`, `PrimeReact`, `Cratis.Components` in that order resolves both\n * here and records the others as shadowed, which is override priority doing exactly what it exists for.\n *\n * `table` and `dataTable` are the same component under two names. `dataTable` says what it is; `table`\n * is what a screen written against the base vocabulary already says, and both should land on the\n * query-aware implementation.\n */\nexport const cratisComponents: ComponentRegistry = {\n [componentRegistryKey(cratisComponentsPackageName, 'page')]: ScenePage,\n [componentRegistryKey(cratisComponentsPackageName, 'dataPage')]: SceneDataPage,\n [componentRegistryKey(cratisComponentsPackageName, 'formElement')]: SceneFormElement,\n\n [componentRegistryKey(cratisComponentsPackageName, 'singleResult')]: SceneSingleResult,\n [componentRegistryKey(cratisComponentsPackageName, 'dataTable')]: SceneDataTable,\n [componentRegistryKey(cratisComponentsPackageName, 'table')]: SceneDataTable,\n [componentRegistryKey(cratisComponentsPackageName, 'observableDataTable')]: SceneObservableDataTable,\n\n [componentRegistryKey(cratisComponentsPackageName, 'queryInputForm')]: SceneQueryInputForm,\n [componentRegistryKey(cratisComponentsPackageName, 'commandForm')]: SceneCommandForm,\n [componentRegistryKey(cratisComponentsPackageName, 'inputTextField')]: SceneInputTextField,\n [componentRegistryKey(cratisComponentsPackageName, 'numberField')]: SceneNumberField,\n [componentRegistryKey(cratisComponentsPackageName, 'checkboxField')]: SceneCheckboxField,\n [componentRegistryKey(cratisComponentsPackageName, 'textAreaField')]: SceneTextAreaField,\n [componentRegistryKey(cratisComponentsPackageName, 'dropdownField')]: SceneDropdownField,\n [componentRegistryKey(cratisComponentsPackageName, 'sliderField')]: SceneSliderField,\n [componentRegistryKey(cratisComponentsPackageName, 'calendarField')]: SceneCalendarField,\n [componentRegistryKey(cratisComponentsPackageName, 'colorPickerField')]: SceneColorPickerField,\n [componentRegistryKey(cratisComponentsPackageName, 'multiSelectField')]: SceneMultiSelectField,\n [componentRegistryKey(cratisComponentsPackageName, 'chipsField')]: SceneChipsField,\n [componentRegistryKey(cratisComponentsPackageName, 'radioButtonField')]: SceneRadioButtonField,\n [componentRegistryKey(cratisComponentsPackageName, 'radioGroupField')]: SceneRadioGroupField,\n\n [componentRegistryKey(cratisComponentsPackageName, 'dialog')]: SceneDialog,\n [componentRegistryKey(cratisComponentsPackageName, 'confirmationDialog')]: SceneConfirmationDialog,\n [componentRegistryKey(cratisComponentsPackageName, 'busyIndicatorDialog')]: SceneBusyIndicatorDialog,\n [componentRegistryKey(cratisComponentsPackageName, 'commandDialog')]: SceneCommandDialog,\n [componentRegistryKey(cratisComponentsPackageName, 'stepperCommandDialog')]: SceneStepperCommandDialog,\n\n [componentRegistryKey(cratisComponentsPackageName, 'icon')]: SceneIcon,\n [componentRegistryKey(cratisComponentsPackageName, 'tooltip')]: SceneTooltip,\n [componentRegistryKey(cratisComponentsPackageName, 'dropdown')]: SceneDropdown,\n [componentRegistryKey(cratisComponentsPackageName, 'errorBoundary')]: SceneErrorBoundary,\n\n [componentRegistryKey(cratisComponentsPackageName, 'objectContentEditor')]: SceneObjectContentEditor,\n [componentRegistryKey(cratisComponentsPackageName, 'objectNavigationalBar')]: SceneObjectNavigationalBar,\n [componentRegistryKey(cratisComponentsPackageName, 'schemaEditor')]: SceneSchemaEditor,\n [componentRegistryKey(cratisComponentsPackageName, 'timeMachine')]: SceneTimeMachine,\n [componentRegistryKey(cratisComponentsPackageName, 'filterPanel')]: SceneFilterPanel,\n\n [componentRegistryKey(cratisComponentsPackageName, 'toolbar')]: SceneToolbar,\n [componentRegistryKey(cratisComponentsPackageName, 'toolbarButton')]: SceneToolbarButton,\n [componentRegistryKey(cratisComponentsPackageName, 'toolbarGroup')]: SceneToolbarGroup,\n [componentRegistryKey(cratisComponentsPackageName, 'toolbarSeparator')]: SceneToolbarSeparator,\n};\n"],"names":["cratisComponentsPackageName","cratisComponents","componentRegistryKey","ScenePage","SceneDataPage","SceneFormElement","SceneSingleResult","SceneDataTable","SceneObservableDataTable","SceneQueryInputForm","SceneCommandForm","SceneInputTextField","SceneNumberField","SceneCheckboxField","SceneTextAreaField","SceneDropdownField","SceneSliderField","SceneCalendarField","SceneColorPickerField","SceneMultiSelectField","SceneChipsField","SceneRadioButtonField","SceneRadioGroupField","SceneDialog","SceneConfirmationDialog","SceneBusyIndicatorDialog","SceneCommandDialog","SceneStepperCommandDialog","SceneIcon","SceneTooltip","SceneDropdown","SceneErrorBoundary","SceneObjectContentEditor","SceneObjectNavigationalBar","SceneSchemaEditor","SceneTimeMachine","SceneFilterPanel","SceneToolbar","SceneToolbarButton","SceneToolbarGroup","SceneToolbarSeparator"],"mappings":"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"}
|