@cratis/pi 2.22.0 → 2.23.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/package/corpus/agents/backend-developer.md +6 -5
- package/package/corpus/agents/code-reviewer.md +7 -7
- package/package/corpus/agents/coordinator.md +5 -4
- package/package/corpus/agents/frontend-developer.md +34 -40
- package/package/corpus/agents/orchestrator.md +5 -4
- package/package/corpus/agents/performance-reviewer.md +5 -4
- package/package/corpus/agents/planner.md +5 -4
- package/package/corpus/agents/repository-investigation-reviewer.md +2 -1
- package/package/corpus/agents/repository-investigator.md +2 -1
- package/package/corpus/agents/security-reviewer.md +5 -4
- package/package/corpus/agents/slice-implementer.md +8 -2
- package/package/corpus/agents/spec-writer.md +6 -4
- package/package/corpus/harnesses/pi/extensions/subagent/agents.ts +52 -7
- package/package/corpus/harnesses/pi/extensions/subagent/index.ts +14 -0
- package/package/corpus/hooks/README.md +29 -27
- package/package/corpus/hooks/agent-stop.md +1 -5
- package/package/corpus/hooks/scripts/cratis-patterns.json +1 -1
- package/package/corpus/hooks/scripts/validate-package-subpaths.sh +1 -2
- package/package/corpus/prompts/verify-ai-setup.prompt.md +17 -7
- package/package/corpus/rules/ai-distribution.md +58 -0
- package/package/corpus/rules/components.md +77 -44
- package/package/corpus/rules/dialogs.md +24 -20
- package/package/corpus/rules/efcore.md +35 -187
- package/package/corpus/rules/framework.md +1 -1
- package/package/corpus/rules/frontend-quality.md +1 -1
- package/package/corpus/rules/frontend-testing.md +4 -4
- package/package/corpus/rules/general.md +29 -105
- package/package/corpus/rules/new-repository-intake.md +34 -0
- package/package/corpus/rules/orleans.md +13 -27
- package/package/corpus/rules/react.md +12 -12
- package/package/corpus/rules/reactors.md +28 -5
- package/package/corpus/rules/specs.scenarios.csharp.md +18 -3
- package/package/corpus/rules/specs.typescript.md +1 -1
- package/package/corpus/rules/storybook.md +2 -2
- package/package/corpus/rules/typescript.md +1 -0
- package/package/corpus/rules/vertical-slices.md +20 -15
- package/package/corpus/rules/writing-correct-examples.md +1 -0
- package/package/corpus/skills/cratis-application-react-specifications/SKILL.md +4 -4
- package/package/corpus/skills/cratis-application-slice-specifications/SKILL.md +16 -8
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/SKILL.md +6 -4
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authentication.md +1 -1
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authorization.md +1 -1
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/frontend.md +1 -1
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/local-development.md +1 -1
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/tenancy.md +7 -4
- package/package/corpus/skills/cratis-arc-command/SKILL.md +9 -7
- package/package/corpus/skills/cratis-arc-command/references/command-result.md +1 -1
- package/package/corpus/skills/cratis-arc-command/references/handler-shapes.md +2 -2
- package/package/corpus/skills/cratis-arc-command/references/proxy-generation.md +6 -3
- package/package/corpus/skills/cratis-arc-command/references/read-model-injection.md +1 -1
- package/package/corpus/skills/cratis-arc-command-execution/SKILL.md +12 -2
- package/package/corpus/skills/cratis-arc-command-validation/SKILL.md +5 -3
- package/package/corpus/skills/cratis-arc-ef-core-migration/SKILL.md +7 -4
- package/package/corpus/skills/cratis-arc-observable-query-http/SKILL.md +10 -3
- package/package/corpus/skills/cratis-arc-query-paging/SKILL.md +13 -8
- package/package/corpus/skills/cratis-arc-react-page/SKILL.md +27 -24
- package/package/corpus/skills/cratis-arc-react-page/references/data-page.md +15 -11
- package/package/corpus/skills/cratis-arc-react-page/references/data-tables.md +9 -2
- package/package/corpus/skills/cratis-arc-react-page/references/dialogs.md +11 -9
- package/package/corpus/skills/cratis-arc-react-page/references/queries-and-commands.md +26 -2
- package/package/corpus/skills/cratis-chronicle-cli-operations/SKILL.md +19 -13
- package/package/corpus/skills/cratis-chronicle-client-dotnet/SKILL.md +17 -15
- package/package/corpus/skills/cratis-chronicle-client-elixir/SKILL.md +24 -20
- package/package/corpus/skills/cratis-chronicle-client-kotlin/SKILL.md +26 -15
- package/package/corpus/skills/cratis-chronicle-client-typescript/SKILL.md +15 -11
- package/package/corpus/skills/cratis-chronicle-compliance/SKILL.md +14 -3
- package/package/corpus/skills/cratis-chronicle-event-constraints/SKILL.md +13 -6
- package/package/corpus/skills/cratis-chronicle-event-modeling/SKILL.md +2 -2
- package/package/corpus/skills/cratis-chronicle-event-specifications/SKILL.md +11 -5
- package/package/corpus/skills/cratis-chronicle-event-type-migration/SKILL.md +2 -2
- package/package/corpus/skills/cratis-chronicle-multi-tenancy/SKILL.md +2 -2
- package/package/corpus/skills/cratis-chronicle-projection/SKILL.md +23 -4
- package/package/corpus/skills/cratis-chronicle-projection/references/fluent-builder.md +1 -1
- package/package/corpus/skills/cratis-chronicle-projection/references/model-bound-attributes.md +2 -2
- package/package/corpus/skills/cratis-chronicle-reactor/SKILL.md +22 -8
- package/package/corpus/skills/cratis-chronicle-read-model/SKILL.md +1 -1
- package/package/corpus/skills/cratis-chronicle-read-model/references/queries.md +1 -1
- package/package/corpus/skills/cratis-chronicle-read-model-specifications/SKILL.md +3 -1
- package/package/corpus/skills/cratis-chronicle-reducer/SKILL.md +1 -1
- package/package/corpus/skills/cratis-chronicle-web-workbench/SKILL.md +19 -11
- package/package/corpus/skills/cratis-cli-terminal-workbench/SKILL.md +11 -6
- package/package/corpus/skills/cratis-code-review/SKILL.md +8 -6
- package/package/corpus/skills/cratis-components-accessibility/SKILL.md +112 -82
- package/package/corpus/skills/cratis-components-schema-editor/SKILL.md +12 -10
- package/package/corpus/skills/cratis-components-stepper-command-dialog/SKILL.md +11 -12
- package/package/corpus/skills/cratis-components-styling/SKILL.md +204 -170
- package/package/corpus/skills/cratis-components-toolbar/SKILL.md +32 -26
- package/package/corpus/skills/cratis-event-model-diagram/SKILL.md +1 -1
- package/package/corpus/skills/cratis-fundamentals-concept/SKILL.md +2 -2
- package/package/corpus/skills/cratis-fundamentals-type-discovery/SKILL.md +2 -2
- package/package/corpus/skills/cratis-lens-browser-extension/SKILL.md +4 -2
- package/package/corpus/skills/cratis-performance-review/SKILL.md +4 -2
- package/package/corpus/skills/cratis-screenplay-model-authoring/SKILL.md +15 -5
- package/package/corpus/skills/cratis-security-review/SKILL.md +20 -3
- package/package/corpus/skills/cratis-specifications-csharp/SKILL.md +3 -3
- package/package/corpus/skills/cratis-specifications-csharp/references/application-scenarios.md +12 -8
- package/package/corpus/skills/cratis-specifications-csharp/references/csharp-patterns.md +1 -1
- package/package/corpus/skills/cratis-specifications-csharp/references/integration-specs.md +7 -3
- package/package/corpus/skills/cratis-specifications-typescript/SKILL.md +6 -3
- package/package/corpus/skills/cratis-specifications-typescript/references/typescript-patterns.md +21 -4
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +29 -17
- package/package.json +1 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Tenancy
|
|
2
2
|
|
|
3
|
-
Verified against `Cratis.Arc.Core` `22.
|
|
3
|
+
Verified against `Cratis.Arc.Core` `22.16.0`. Types are in `Cratis.Arc.Tenancy`.
|
|
4
4
|
|
|
5
5
|
Arc tenancy is **request-scoped tenant resolution**. It answers "which tenant is
|
|
6
6
|
this request for". It is not Chronicle's tenant namespace isolation, and it does
|
|
@@ -61,9 +61,12 @@ the configured value.
|
|
|
61
61
|
|
|
62
62
|
`ITenantIdAccessor.Current` gives the current `TenantId`, cached into an
|
|
63
63
|
`AsyncLocal`. An empty resolution is `TenantId.NotSet`, whose value is the
|
|
64
|
-
literal string `"[NotSet]"`. `TenantId.Default` is `"Default"
|
|
65
|
-
|
|
66
|
-
|
|
64
|
+
literal string `"[NotSet]"`. `TenantId.Default` is `"Default"`. ⚠️ `IsDefault`
|
|
65
|
+
is `this == NotSet || this == Default` — it is true for an **unresolved** tenant
|
|
66
|
+
as well, so it cannot tell "single-tenant default" from "nothing resolved".
|
|
67
|
+
Compare against `TenantId.NotSet` explicitly, or use
|
|
68
|
+
`CurrentTenantIdIsNotSet.ThrowIfNotSet(...)`, wherever an unresolved tenant must
|
|
69
|
+
be refused.
|
|
67
70
|
|
|
68
71
|
⚠️ `NotSet` is a real string, not `null`. A check like
|
|
69
72
|
`string.IsNullOrEmpty(tenantId)` never fires for an unresolved tenant. Compare
|
|
@@ -14,12 +14,14 @@ whatever `Handle()` returns into appended events, a response, or both.
|
|
|
14
14
|
|
|
15
15
|
| Package | Version | Purpose |
|
|
16
16
|
| --- | --- | --- |
|
|
17
|
-
| `Cratis.Arc.Core` | `22.
|
|
18
|
-
| `Cratis.Arc.Chronicle` | `22.
|
|
19
|
-
| `Cratis.Arc.ProxyGenerator.Build` | `22.
|
|
20
|
-
| `Cratis.Fundamentals` | `7.
|
|
21
|
-
| `Cratis.Chronicle` | `
|
|
22
|
-
| `@cratis/arc` | `22.
|
|
17
|
+
| `Cratis.Arc.Core` | `22.16.0` | `Cratis.Arc.Commands.ModelBound.CommandAttribute`, `CommandResult`, `CommandValidator<T>` |
|
|
18
|
+
| `Cratis.Arc.Chronicle` | `22.16.0` | event append handling, `Cratis.Arc.Chronicle.Commands.NotAuditedAttribute` |
|
|
19
|
+
| `Cratis.Arc.ProxyGenerator.Build` | `22.16.0` | `CratisProxiesOutputPath` MSBuild integration |
|
|
20
|
+
| `Cratis.Fundamentals` | `7.19.2` | `Cratis.Monads.Result<TResult, TError>` |
|
|
21
|
+
| `Cratis.Chronicle` | `18.3.0` | `EventTypeAttribute`, `EventForEventSourceId`, `ICanProvideEventSourceId` |
|
|
22
|
+
| `@cratis/arc` | `22.16.0` | `ICommand`, `CommandResult`, `ValidationResult` |
|
|
23
|
+
|
|
24
|
+
> Re-verified at the versions above by **symbol and signature**: every type, attribute and member this skill names exists at that tag, and the public surface it describes is unchanged since the previous verification (Chronicle 16.45.x / Arc 22.10.4 — the Chronicle 16→18 client diff is converters, options and doc comments; no type was removed or renamed). Behavior claims were verified at the earlier tag unless a section says otherwise.
|
|
23
25
|
|
|
24
26
|
Reverify before claiming support for another version. Arc without Chronicle is a
|
|
25
27
|
supported setup; everything on this page that appends events needs Chronicle.
|
|
@@ -214,7 +216,7 @@ either way, so the reading is all a reviewer has to go on.
|
|
|
214
216
|
## Generate the TypeScript proxy
|
|
215
217
|
|
|
216
218
|
```xml
|
|
217
|
-
<PackageReference Include="Cratis.Arc.ProxyGenerator.Build" Version="22.
|
|
219
|
+
<PackageReference Include="Cratis.Arc.ProxyGenerator.Build" Version="22.16.0" />
|
|
218
220
|
|
|
219
221
|
<PropertyGroup>
|
|
220
222
|
<CratisProxiesOutputPath>$(MSBuildThisFileDirectory)../<Web>/src/api</CratisProxiesOutputPath>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Handler shapes and how Arc dispatches them
|
|
2
2
|
|
|
3
|
-
Verified against `Cratis.Arc.Core` and `Cratis.Arc.Chronicle` `22.
|
|
4
|
-
`Cratis.Chronicle` `
|
|
3
|
+
Verified against `Cratis.Arc.Core` and `Cratis.Arc.Chronicle` `22.16.0` with
|
|
4
|
+
`Cratis.Chronicle` `18.3.0`.
|
|
5
5
|
|
|
6
6
|
## The pipeline around `Handle`
|
|
7
7
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Proxy generation
|
|
2
2
|
|
|
3
|
-
Verified against `Cratis.Arc.ProxyGenerator.Build` `22.
|
|
3
|
+
Verified against `Cratis.Arc.ProxyGenerator.Build` `22.16.0`.
|
|
4
4
|
|
|
5
5
|
## Wiring
|
|
6
6
|
|
|
@@ -8,7 +8,7 @@ Reference the build package from the project that contains the commands,
|
|
|
8
8
|
queries and read models, and set an output path:
|
|
9
9
|
|
|
10
10
|
```xml
|
|
11
|
-
<PackageReference Include="Cratis.Arc.ProxyGenerator.Build" Version="22.
|
|
11
|
+
<PackageReference Include="Cratis.Arc.ProxyGenerator.Build" Version="22.16.0" />
|
|
12
12
|
|
|
13
13
|
<PropertyGroup>
|
|
14
14
|
<CratisProxiesOutputPath>$(MSBuildThisFileDirectory)../<Web>/src/api</CratisProxiesOutputPath>
|
|
@@ -27,7 +27,7 @@ Output folders mirror the C# **namespace**, not the file path. A command in
|
|
|
27
27
|
|
|
28
28
|
## MSBuild properties
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
The first nine properties below are declared with the default shown in the package's `.props`; the last three are read by the `.targets` only when set to `true` (absent means off).
|
|
31
31
|
|
|
32
32
|
| Property | Default | Effect |
|
|
33
33
|
| --- | --- | --- |
|
|
@@ -40,6 +40,9 @@ Every property below is declared by the package with the default shown.
|
|
|
40
40
|
| `CratisProxiesSkipQueryNameInRoute` | `false` | Leaves the query name out of the generated route |
|
|
41
41
|
| `CratisProxiesApiPrefix` | `api` | Route prefix |
|
|
42
42
|
| `CratisProxiesSkipFileIndexTracking` | `false` | Disables tracking which files the generator owns |
|
|
43
|
+
| `CratisProxiesSkipIndexGeneration` | `false` | Does not write the per-folder `index.ts` barrels |
|
|
44
|
+
| `CratisProxiesUseSourceFileAsOutputFile` | `false` | Names the generated file after the C# source file rather than the type |
|
|
45
|
+
| `CratisProxiesEmitInterfaces` | off | **Arc ≥ 22.15.0** (the underlying `--emit-interfaces` flag exists from 22.14.0; the MSBuild property from 22.15.0). Emits plain TypeScript `interface`s instead of `@field`-decorated classes — no `@cratis/fundamentals` import in the output. Only for consumers that never reconstruct instances from JSON; command and query proxies need the classes |
|
|
43
46
|
|
|
44
47
|
⚠️ `CratisProxiesSkipOutputDeletion` defaults to `true`. Guidance that tells you
|
|
45
48
|
to set it to `true` "so the generator does not delete your hand-written files"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Injecting a read model into a command
|
|
2
2
|
|
|
3
|
-
Verified against `Cratis.Arc.Core` `22.
|
|
3
|
+
Verified against `Cratis.Arc.Core` `22.16.0` and `Cratis.Chronicle` `18.3.0`.
|
|
4
4
|
|
|
5
5
|
A read model can be injected into a `CommandValidator<T>` constructor, into
|
|
6
6
|
`Provide()`, or into `Handle()`. Arc resolves it through an
|
|
@@ -15,8 +15,10 @@ dispatch.
|
|
|
15
15
|
|
|
16
16
|
| Package | Version | Purpose |
|
|
17
17
|
| --- | --- | --- |
|
|
18
|
-
| `Cratis.Arc.Core` | `22.
|
|
19
|
-
| `Cratis.Arc.Chronicle` | `22.
|
|
18
|
+
| `Cratis.Arc.Core` | `22.16.0` | `Cratis.Arc.Commands.ICommandPipeline`, `CommandResult`, `ValidationResultSeverity` |
|
|
19
|
+
| `Cratis.Arc.Chronicle` | `22.16.0` | analyzer `ARCCHR0006` for reactor replay |
|
|
20
|
+
|
|
21
|
+
> Re-verified at the versions above by **symbol and signature**: every type, attribute and member this skill names exists at that tag, and the public surface it describes is unchanged since the previous verification (Chronicle 16.45.x / Arc 22.10.4 — the Chronicle 16→18 client diff is converters, options and doc comments; no type was removed or renamed). Behavior claims were verified at the earlier tag unless a section says otherwise.
|
|
20
22
|
|
|
21
23
|
Reverify before claiming support for another version.
|
|
22
24
|
|
|
@@ -29,6 +31,14 @@ inject `IEventLog` (`ARCCHR0007`).
|
|
|
29
31
|
|
|
30
32
|
## Inject and execute
|
|
31
33
|
|
|
34
|
+
> **Reactors have a declarative alternative.** With the Arc Chronicle integration a
|
|
35
|
+
> reactor handler can **return** the `[Command]` (or a collection of commands) and
|
|
36
|
+
> Arc executes it; a denied or invalid result fails the partition instead of being
|
|
37
|
+
> discarded, and `[ExecuteCommandsAsSystem]` on the reactor class supplies a
|
|
38
|
+
> principal for those returned commands. That attribute does **not** cover manual
|
|
39
|
+
> `Execute` calls — the form below needs its own execution context. See the
|
|
40
|
+
> **cratis-chronicle-reactor** skill.
|
|
41
|
+
|
|
32
42
|
```csharp
|
|
33
43
|
public class <Name>Reactor(ICommandPipeline pipeline) : IReactor
|
|
34
44
|
{
|
|
@@ -23,11 +23,13 @@ rejection on it.)
|
|
|
23
23
|
|
|
24
24
|
| Package | Version | Purpose |
|
|
25
25
|
| --- | --- | --- |
|
|
26
|
-
| `Cratis.Arc.Core` | `22.
|
|
27
|
-
| `Cratis.Fundamentals` | `7.
|
|
28
|
-
| `Cratis.Chronicle` | `
|
|
26
|
+
| `Cratis.Arc.Core` | `22.16.0` | `CommandValidator<T>`, `ConceptValidator<T>`, `ValidationResult`, `CommandResult`, the command pipeline, `ARC0004`–`ARC0013` |
|
|
27
|
+
| `Cratis.Fundamentals` | `7.19.2` | `Cratis.Monads.Result<TResult, TError>` |
|
|
28
|
+
| `Cratis.Chronicle` | `18.3.0` | Read-model resolution for command-side injection |
|
|
29
29
|
| `FluentValidation` | `12.1.1` | `RuleFor(...)`, `.WithMessage(...)` |
|
|
30
30
|
|
|
31
|
+
> Re-verified at the versions above by **symbol and signature**: every type, attribute and member this skill names exists at that tag, and the public surface it describes is unchanged since the previous verification (Chronicle 16.45.x / Arc 22.10.4 — the Chronicle 16→18 client diff is converters, options and doc comments; no type was removed or renamed). Behavior claims were verified at the earlier tag unless a section says otherwise.
|
|
32
|
+
|
|
31
33
|
Reverify against the owning product repository before claiming support for
|
|
32
34
|
another version.
|
|
33
35
|
|
|
@@ -15,10 +15,12 @@ Everything else is ordinary EF Core.
|
|
|
15
15
|
|
|
16
16
|
| Package | Version | Purpose |
|
|
17
17
|
| --- | --- | --- |
|
|
18
|
-
| `Cratis.Arc.EntityFrameworkCore` | `22.
|
|
19
|
-
| `Cratis.Arc.Core` | `22.
|
|
18
|
+
| `Cratis.Arc.EntityFrameworkCore` | `22.16.0` | `BaseDbContext`, `ReadOnlyDbContext`, `WithEntityFrameworkCore`, column helpers, `EntityFrameworkReadModelForCommandResolver` |
|
|
19
|
+
| `Cratis.Arc.Core` | `22.16.0` | `Cratis.Arc.Queries.ModelBound.ReadModelAttribute`, `ICanResolveReadModelForCommand` |
|
|
20
20
|
| `Microsoft.EntityFrameworkCore` | `10.0.11` | EF Core itself, including all migration tooling |
|
|
21
21
|
|
|
22
|
+
> Re-verified at the versions above by **symbol and signature**: every type, attribute and member this skill names exists at that tag, and the public surface it describes is unchanged since the previous verification (Chronicle 16.45.x / Arc 22.10.4 — the Chronicle 16→18 client diff is converters, options and doc comments; no type was removed or renamed). Behavior claims were verified at the earlier tag unless a section says otherwise.
|
|
23
|
+
|
|
22
24
|
Reverify before claiming support for another version.
|
|
23
25
|
|
|
24
26
|
⚠️ **Arc ships no migration tooling of its own.** There is no design-time
|
|
@@ -148,8 +150,9 @@ migrationBuilder.CreateTable(
|
|
|
148
150
|
`StringColumn`, `NumberColumn<T>`, `BoolColumn`, `AutoIncrementColumn`,
|
|
149
151
|
`GuidColumn` and `DateTimeOffsetColumn` all take the `MigrationBuilder` as their
|
|
150
152
|
first argument — that is how they learn which database they are generating for.
|
|
151
|
-
All of them default `nullable` to **`true`**, so a
|
|
152
|
-
`nullable: false` explicitly
|
|
153
|
+
All of them except `AutoIncrementColumn` default `nullable` to **`true`**, so a
|
|
154
|
+
required column has to say `nullable: false` explicitly; `AutoIncrementColumn`
|
|
155
|
+
has no `nullable` parameter and is always `NOT NULL`.
|
|
153
156
|
|
|
154
157
|
On `MigrationBuilder`, for an existing table:
|
|
155
158
|
|
|
@@ -13,7 +13,9 @@ request is made. Choose the transport first, then the command.
|
|
|
13
13
|
|
|
14
14
|
| Package | Version | Purpose |
|
|
15
15
|
| --- | --- | --- |
|
|
16
|
-
| `Cratis.Arc.Core` | `22.
|
|
16
|
+
| `Cratis.Arc.Core` | `22.16.0` | `ObservableQueryHttp`, `ObservableQueryHandler`, the demultiplexer routes |
|
|
17
|
+
|
|
18
|
+
> Re-verified at the versions above by **symbol and signature**: every type, attribute and member this skill names exists at that tag, and the public surface it describes is unchanged since the previous verification (Chronicle 16.45.x / Arc 22.10.4 — the Chronicle 16→18 client diff is converters, options and doc comments; no type was removed or renamed). Behavior claims were verified at the earlier tag unless a section says otherwise.
|
|
17
19
|
|
|
18
20
|
Reverify before claiming support for another version. This skill is read-only
|
|
19
21
|
inspection of an endpoint the user already has; it neither implements the query
|
|
@@ -29,7 +31,12 @@ handler decides in this order:
|
|
|
29
31
|
(case-insensitive);
|
|
30
32
|
3. **plain HTTP** — everything else, answered once and closed.
|
|
31
33
|
|
|
32
|
-
A plain `curl` sends neither, so it always lands on the third case
|
|
34
|
+
A plain `curl` sends neither, so it always lands on the third case — and there
|
|
35
|
+
the two result shapes part ways: an **`ISubject<T>`** query answers with one
|
|
36
|
+
`QueryResult` as described below, while an **`IAsyncEnumerable<T>`** query
|
|
37
|
+
answers **HTTP 400** with `{ "message": "AsyncEnumerable queries require WebSocket connection" }`
|
|
38
|
+
and never a `QueryResult`. Everything that follows on this page is about
|
|
39
|
+
`ISubject<T>`; inspect an `IAsyncEnumerable<T>` query over WebSocket.
|
|
33
40
|
|
|
34
41
|
## Snapshot: the current value, once
|
|
35
42
|
|
|
@@ -37,7 +44,7 @@ A plain `curl` sends neither, so it always lands on the third case.
|
|
|
37
44
|
curl "https://<host>/<api-prefix>/<route>"
|
|
38
45
|
```
|
|
39
46
|
|
|
40
|
-
The response is one JSON `QueryResult
|
|
47
|
+
The response is one JSON `QueryResult` (for an `ISubject<T>` query — see above).
|
|
41
48
|
|
|
42
49
|
⚠️ **When the observable has not produced its first value yet, this returns HTTP
|
|
43
50
|
202 Accepted with a not-ready result** — no exception, no data. That is a normal
|
|
@@ -13,10 +13,12 @@ the query string — you choose a **return shape** that the framework can narrow
|
|
|
13
13
|
|
|
14
14
|
| Package | Version | Purpose |
|
|
15
15
|
| --- | --- | --- |
|
|
16
|
-
| `Cratis.Arc.Core` | `22.
|
|
17
|
-
| `Cratis.Arc.MongoDB` | `22.
|
|
18
|
-
| `Cratis.Arc.EntityFrameworkCore` | `22.
|
|
19
|
-
| `@cratis/arc.react` | `22.
|
|
16
|
+
| `Cratis.Arc.Core` | `22.16.0` | `QueryableQueryRenderer`, `Paging`, `Sorting`, `PagingInfo` |
|
|
17
|
+
| `Cratis.Arc.MongoDB` | `22.16.0` | `Observe` helpers that page at the source |
|
|
18
|
+
| `Cratis.Arc.EntityFrameworkCore` | `22.16.0` | `DbSet<T>` observe helpers that page at the source |
|
|
19
|
+
| `@cratis/arc.react` | `22.16.0` | `useWithPaging`, `useSuspenseWithPaging` |
|
|
20
|
+
|
|
21
|
+
> Re-verified at the versions above by **symbol and signature**: every type, attribute and member this skill names exists at that tag, and the public surface it describes is unchanged since the previous verification (Chronicle 16.45.x / Arc 22.10.4 — the Chronicle 16→18 client diff is converters, options and doc comments; no type was removed or renamed). Behavior claims were verified at the earlier tag unless a section says otherwise.
|
|
20
22
|
|
|
21
23
|
Reverify before claiming support for another version. A small, bounded result
|
|
22
24
|
set does not need any of this — `IEnumerable<T>` is fine.
|
|
@@ -25,7 +27,7 @@ set does not need any of this — `IEnumerable<T>` is fine.
|
|
|
25
27
|
|
|
26
28
|
| Query-string key | Effect |
|
|
27
29
|
| --- | --- |
|
|
28
|
-
| `pageSize` | **Required to page at all
|
|
30
|
+
| `pageSize` | **Required to page at all** on the query string; any parseable integer is accepted (`0` yields an empty page, negatives are clamped by `Skip`) — the JSON body reader, by contrast, treats `pageSize <= 0` as not paged |
|
|
29
31
|
| `page` | Zero-based. Defaults to `0` when `pageSize` is present |
|
|
30
32
|
| `sortby` | Field name; PascalCased before use, so `?sortby=name` sorts on `Name` |
|
|
31
33
|
| `sortDirection` | `desc` (case-insensitive) sorts descending; **anything else, including a missing value, is ascending** |
|
|
@@ -36,9 +38,12 @@ Two consequences that surprise people:
|
|
|
36
38
|
- **Sorting needs both keys.** `sortby` without `sortDirection` is ignored
|
|
37
39
|
entirely.
|
|
38
40
|
|
|
39
|
-
Paging is validated
|
|
40
|
-
|
|
41
|
-
|
|
41
|
+
Paging is **not** validated on the request path at 22.16.0: `PageNumber`/`PageSize`
|
|
42
|
+
concept validators exist (`page >= 0`, `pageSize > 0`) but nothing feeds the
|
|
43
|
+
query-string paging into them, so an out-of-range value produces an empty or
|
|
44
|
+
clamped page rather than a validation failure. Validate paging arguments in the
|
|
45
|
+
frontend, or expose them as explicit query arguments if the rule must be
|
|
46
|
+
enforced.
|
|
42
47
|
|
|
43
48
|
## Which return shapes page
|
|
44
49
|
|
|
@@ -15,21 +15,20 @@ This skill is verified against these exact package contracts:
|
|
|
15
15
|
|
|
16
16
|
| Package | Version | Verified from |
|
|
17
17
|
| --- | --- | --- |
|
|
18
|
-
| `@cratis/components` | `
|
|
19
|
-
| `@cratis/arc` | `>=20.3.1 <23` | peer range declared by `@cratis/components@
|
|
20
|
-
| `@cratis/arc.react` | `>=20.3.1 <23` | peer range declared by `@cratis/components@
|
|
21
|
-
| `
|
|
22
|
-
| `primeicons` | `^8.0.0` | peer of `@cratis/components@3.0.0` |
|
|
23
|
-
| `react` | `^19.0.0` | peer of `@cratis/components@3.0.0` |
|
|
18
|
+
| `@cratis/components` | `4.6.0` | its package manifest (`exports`, peers), `Source/DataPage/*`, `Source/DataTables/*`, `Source/Dialogs/*`, `Source/CommandDialog/*`, `Source/MIGRATION.md` |
|
|
19
|
+
| `@cratis/arc` | `>=20.3.1 <23` | peer range declared by `@cratis/components@4.6.0` |
|
|
20
|
+
| `@cratis/arc.react` | `>=20.3.1 <23` | peer range declared by `@cratis/components@4.6.0` |
|
|
21
|
+
| `react` | `^19.0.0` | peer of `@cratis/components@4.6.0` |
|
|
24
22
|
|
|
25
23
|
`@cratis/arc.react.mvvm` ships with `@cratis/arc.react` and is an explicit
|
|
26
24
|
application dependency. Reverify before claiming another version.
|
|
27
25
|
|
|
28
26
|
## Import from subpaths, never the root barrel
|
|
29
27
|
|
|
30
|
-
The root `@cratis/components` entry
|
|
31
|
-
`import { DataPage } from '@cratis/components'`
|
|
32
|
-
|
|
28
|
+
The root `@cratis/components` entry is **setup-only** — `CratisComponentsProvider`
|
|
29
|
+
and its configuration types. `import { DataPage } from '@cratis/components'` is a
|
|
30
|
+
compile error; the Components 3 root namespaces are gone. Always import from the
|
|
31
|
+
subpath:
|
|
33
32
|
|
|
34
33
|
```tsx
|
|
35
34
|
import { DataPage, MenuItem, Column } from '@cratis/components/DataPage';
|
|
@@ -45,18 +44,21 @@ import { DialogProps, DialogResult, useDialog } from '@cratis/arc.react/dialogs'
|
|
|
45
44
|
regenerated the TypeScript proxies. Generated proxies carry a
|
|
46
45
|
`**DO NOT EDIT** - This file is an automatically generated file.` header —
|
|
47
46
|
fix the C# source and rebuild instead of editing one.
|
|
48
|
-
- The app must mount `CratisComponentsProvider` (from
|
|
49
|
-
`@cratis/components
|
|
50
|
-
|
|
51
|
-
- The app must import the stylesheets explicitly; components
|
|
47
|
+
- The app must mount `CratisComponentsProvider` (from the package root,
|
|
48
|
+
`@cratis/components`) above every Cratis component — it carries the locale,
|
|
49
|
+
the Components-owned labels and the toast region (`toaster`).
|
|
50
|
+
- The app must import the stylesheets explicitly; components do not import
|
|
52
51
|
their own CSS:
|
|
53
52
|
|
|
54
53
|
```ts
|
|
55
|
-
import '@cratis/components/tokens'; // the --cratis-* token
|
|
56
|
-
import '@cratis/components/styles'; // every component
|
|
57
|
-
import '@cratis/components/theme'; // optional
|
|
54
|
+
import '@cratis/components/tokens'; // the --cratis-* token seam
|
|
55
|
+
import '@cratis/components/styles'; // structural rules for every component
|
|
56
|
+
import '@cratis/components/theme'; // optional: the maintained baseline look
|
|
58
57
|
```
|
|
59
58
|
|
|
59
|
+
Components has no vendor UI dependency — do not install PrimeReact or an icon
|
|
60
|
+
font for it. Menu icons are React component types (`react-icons` works).
|
|
61
|
+
|
|
60
62
|
See the **cratis-components-styling** skill for the full theming contract.
|
|
61
63
|
|
|
62
64
|
## Step 2 — The DataPage shell
|
|
@@ -81,9 +83,9 @@ export const AccountsPage = () => (
|
|
|
81
83
|
);
|
|
82
84
|
```
|
|
83
85
|
|
|
84
|
-
|
|
85
|
-
`MenuItem` and `Column` are **named exports**
|
|
86
|
-
|
|
86
|
+
`DataPage.Columns`, `DataPage.MenuItems` and `DataPage.MenuItem` are the
|
|
87
|
+
compound members; `MenuItem` and `Column` are also **named exports** of the
|
|
88
|
+
subpath (there is no `DataPage.Column`). Pass `dataKey` whenever the read model has an
|
|
87
89
|
identity.
|
|
88
90
|
|
|
89
91
|
See [data-page.md](references/data-page.md) for every prop, and
|
|
@@ -97,6 +99,7 @@ Menu items go in `<DataPage.MenuItems>`. `MenuItem` takes `command`, not
|
|
|
97
99
|
string. `disableOnUnselected` greys the item out until a row is selected.
|
|
98
100
|
|
|
99
101
|
```tsx
|
|
102
|
+
import { FaPencil, FaPlus } from 'react-icons/fa6';
|
|
100
103
|
import { DataPage, MenuItem } from '@cratis/components/DataPage';
|
|
101
104
|
import { useDialog } from '@cratis/arc.react/dialogs';
|
|
102
105
|
import { CreateAccountDialog } from './CreateAccountDialog';
|
|
@@ -105,8 +108,8 @@ const [CreateAccountWrapper, showCreateAccount] = useDialog(CreateAccountDialog)
|
|
|
105
108
|
|
|
106
109
|
<DataPage title='Accounts' query={AllAccounts} emptyMessage='No accounts yet.'>
|
|
107
110
|
<DataPage.MenuItems>
|
|
108
|
-
<MenuItem label='Add account' icon={
|
|
109
|
-
<MenuItem label='Edit account' icon={
|
|
111
|
+
<MenuItem label='Add account' icon={FaPlus} command={() => showCreateAccount()} />
|
|
112
|
+
<MenuItem label='Edit account' icon={FaPencil} command={() => showEditAccount()} disableOnUnselected />
|
|
110
113
|
</DataPage.MenuItems>
|
|
111
114
|
<DataPage.Columns>
|
|
112
115
|
<Column field='name' header='Name' />
|
|
@@ -146,9 +149,9 @@ export const CreateAccountDialog = () => {
|
|
|
146
149
|
};
|
|
147
150
|
```
|
|
148
151
|
|
|
149
|
-
Never put a raw
|
|
150
|
-
|
|
151
|
-
stays disabled. Seed values that must be present for validity with
|
|
152
|
+
Never put a raw control (a `Common` `TextInput`, a native `<input>`) inside a
|
|
153
|
+
command dialog for a command value — it is not bound to the command, so
|
|
154
|
+
validation never re-runs and the submit button stays disabled. Seed values that must be present for validity with
|
|
152
155
|
`initialValues`, not `onBeforeExecute`.
|
|
153
156
|
|
|
154
157
|
## Step 5 — Confirming, and showing that work is in progress
|
|
@@ -5,19 +5,21 @@ optional details pane in one component. Import from
|
|
|
5
5
|
`@cratis/components/DataPage`.
|
|
6
6
|
|
|
7
7
|
```tsx
|
|
8
|
+
import { FaPlus } from 'react-icons/fa6';
|
|
8
9
|
import { Column, DataPage, MenuItem } from '@cratis/components/DataPage';
|
|
9
10
|
import type { IDetailsComponentProps } from '@cratis/components/DataPage';
|
|
10
11
|
```
|
|
11
12
|
|
|
12
13
|
## Compound members
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
Three static members exist:
|
|
15
16
|
|
|
16
17
|
- `DataPage.Columns` — wraps the `Column` elements.
|
|
17
18
|
- `DataPage.MenuItems` — wraps the `MenuItem` elements.
|
|
19
|
+
- `DataPage.MenuItem` — the same component as the named `MenuItem` export.
|
|
18
20
|
|
|
19
21
|
`Column` and `MenuItem` are named exports of the same subpath. There is no
|
|
20
|
-
`DataPage.Column
|
|
22
|
+
`DataPage.Column`.
|
|
21
23
|
|
|
22
24
|
## `DataPageProps`
|
|
23
25
|
|
|
@@ -37,9 +39,10 @@ Exactly two static members exist:
|
|
|
37
39
|
| `onRefresh` | `() => void` | invoked to re-fetch a snapshot query |
|
|
38
40
|
| `actionsAriaLabel` | `string` | accessible name of the actions menubar, default `'Actions'` |
|
|
39
41
|
| `tableClassName` | `string` | class on the inner table |
|
|
40
|
-
| `tablePt`
|
|
42
|
+
| `tablePt` | `DataTableParts` | per-part attributes on the inner data table (`tablePtOptions`/`tableUnstyled` are accepted no-ops) |
|
|
41
43
|
| `menubarClassName` | `string` | class on the action menubar |
|
|
42
|
-
| `menubarPt`
|
|
44
|
+
| `menubarPt` | `ButtonParts` | per-part attributes on the action buttons (`menubarPtOptions`/`menubarUnstyled` are accepted no-ops) |
|
|
45
|
+
| `paginatorPt` | `TablePaginatorParts` | per-part attributes on the paginator |
|
|
43
46
|
| `clientFiltering` | `boolean` | **deprecated and a no-op** — do not use in new code |
|
|
44
47
|
|
|
45
48
|
## Snapshot versus observable
|
|
@@ -64,7 +67,7 @@ after a command succeeds.
|
|
|
64
67
|
reads. Icons are usually a small inline component:
|
|
65
68
|
|
|
66
69
|
```tsx
|
|
67
|
-
<MenuItem label='Add account' icon={
|
|
70
|
+
<MenuItem label='Add account' icon={FaPlus} command={() => showCreate()} />
|
|
68
71
|
```
|
|
69
72
|
|
|
70
73
|
## `IDetailsComponentProps<TDataType>`
|
|
@@ -99,7 +102,8 @@ declaration the table reads.
|
|
|
99
102
|
| `showFilterMatchModes` | `boolean` |
|
|
100
103
|
| `filterElement` | `(options: ColumnFilterElementOptions) => ReactNode` |
|
|
101
104
|
| `filterLabels` | `Partial<ColumnFilterMenuLabels>` |
|
|
102
|
-
| `
|
|
105
|
+
| `filterPt` | `ColumnFilterMenuParts` — parts of the filter popup |
|
|
106
|
+
| `selectionMode` | `'single'` — the only implemented value; there is no checkbox multi-selection |
|
|
103
107
|
| `style` / `className` | `React.CSSProperties` / `string` |
|
|
104
108
|
| `headerStyle` / `headerClassName` | `React.CSSProperties` / `string` |
|
|
105
109
|
| `bodyStyle` / `bodyClassName` | `React.CSSProperties` / `string` |
|
|
@@ -112,11 +116,11 @@ Use `body` for a computed or formatted cell:
|
|
|
112
116
|
|
|
113
117
|
## Type name caution
|
|
114
118
|
|
|
115
|
-
`@cratis/components/DataPage`
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
`@cratis/components/DataTables` when you
|
|
119
|
-
|
|
119
|
+
`ColumnProps` from `@cratis/components/DataPage` is the **column declaration**
|
|
120
|
+
type re-exported from `DataTables` (the explicit named re-export shadows the
|
|
121
|
+
`DataPage.Columns` wrapper's own `ColumnProps`, which is not reachable from the
|
|
122
|
+
subpath). Import it from `@cratis/components/DataTables` when you want the
|
|
123
|
+
reference to say so.
|
|
120
124
|
|
|
121
125
|
## Layout
|
|
122
126
|
|
|
@@ -40,7 +40,8 @@ Both components take the same prop names:
|
|
|
40
40
|
| `globalFilterFields` | `string[] \| undefined` | enables the search box |
|
|
41
41
|
| `defaultFilters` | `DataTableFilterMeta` | initial filter state |
|
|
42
42
|
| `className` | `string` | |
|
|
43
|
-
| `pt`
|
|
43
|
+
| `pt` | `DataTableParts` | per-part attributes (`ptOptions`/`unstyled` are accepted no-ops) |
|
|
44
|
+
| `paginatorPt` | `TablePaginatorParts` | per-part attributes on the paginator |
|
|
44
45
|
| `paginatorClassName` | `string` | |
|
|
45
46
|
| `paginatorAriaLabels` | paginator label overrides | localize the paginator |
|
|
46
47
|
| `clientFiltering` | `boolean` | **deprecated and a no-op** |
|
|
@@ -58,7 +59,13 @@ Both components take the same prop names:
|
|
|
58
59
|
</DataTableForQuery>
|
|
59
60
|
```
|
|
60
61
|
|
|
61
|
-
## Paging
|
|
62
|
+
## Paging, sorting and filtering scope
|
|
63
|
+
|
|
64
|
+
Column sorting and filtering — and the search box — apply to the **currently
|
|
65
|
+
loaded page**, not the complete result. Complete-result filtering and sorting
|
|
66
|
+
belong in the query's arguments and in the server-side query, before paging;
|
|
67
|
+
`clientFiltering` does not change this and is a deprecated no-op. Server totals
|
|
68
|
+
remain authoritative for the paginator.
|
|
62
69
|
|
|
63
70
|
Both tables page server-side through the Arc paging hooks with a fixed page
|
|
64
71
|
size of 20 rows starting at page 0. The paginator renders only when the result
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# Dialogs reference
|
|
2
2
|
|
|
3
3
|
The Cratis dialog wrappers own command execution, validation timing, busy
|
|
4
|
-
state, and footer buttons. Never
|
|
4
|
+
state, and footer buttons. Never use a vendor or hand-rolled modal — dialogs are Components-owned.
|
|
5
5
|
|
|
6
6
|
The **components** live in `@cratis/components`; the **hooks, enums, and
|
|
7
7
|
context** live in `@cratis/arc.react/dialogs`. `@cratis/components` exports no
|
|
@@ -41,10 +41,11 @@ first two is the normal case. `showDialog(input?)` resolves to
|
|
|
41
41
|
`[DialogResult, TResponse?]` when the dialog closes.
|
|
42
42
|
|
|
43
43
|
Inside the dialog, prefer plain typed props for input and take `closeDialog`
|
|
44
|
-
from `useDialogContext<TResponse>()
|
|
44
|
+
from `useDialogContext<TRequest, TResponse>()` — the **first** type parameter is
|
|
45
|
+
the request the dialog was shown with, the second the response it closes with:
|
|
45
46
|
|
|
46
47
|
```tsx
|
|
47
|
-
const { request, closeDialog } = useDialogContext<AccountCreated>();
|
|
48
|
+
const { request, closeDialog } = useDialogContext<object, AccountCreated>();
|
|
48
49
|
closeDialog(DialogResult.Ok, response);
|
|
49
50
|
```
|
|
50
51
|
|
|
@@ -86,7 +87,7 @@ The most-used props:
|
|
|
86
87
|
| `validateOnInit` | validate on mount so pre-filled invalid values show immediately |
|
|
87
88
|
| `initialFocus` | which control receives focus when the dialog opens |
|
|
88
89
|
| `dismissable` | X, Escape, and backdrop dismissal |
|
|
89
|
-
| `pt`
|
|
90
|
+
| `pt` | `DialogParts` — per-part attributes (`backdrop`, `positioner`, `root`, `header`, `title`, `close`, `content`, `footer`, `confirm`, `cancel`); `ptOptions`/`unstyled` are accepted no-ops |
|
|
90
91
|
|
|
91
92
|
`CommandDialog.Column` exists for multi-column layouts:
|
|
92
93
|
|
|
@@ -132,8 +133,8 @@ wrapper close. Do not use `onConfirm` as a result handler.
|
|
|
132
133
|
|
|
133
134
|
Every user-entered command value must be bound through a `CommandForm` field
|
|
134
135
|
from `@cratis/components/CommandForm` (also published as
|
|
135
|
-
`@cratis/components/CommandForm/fields`, the same module). A raw
|
|
136
|
-
|
|
136
|
+
`@cratis/components/CommandForm/fields`, the same module). A raw control (a
|
|
137
|
+
`Common` `TextInput`, a native `<input>`) is not bound to the command, so validation never re-runs and the submit
|
|
137
138
|
button stays disabled.
|
|
138
139
|
|
|
139
140
|
The full catalog: `InputTextField`, `PasswordField`, `NumberField`,
|
|
@@ -173,7 +174,7 @@ property descriptors, with `exclude` for the ones you do not want:
|
|
|
173
174
|
|
|
174
175
|
```tsx
|
|
175
176
|
export const RenameDialog = () => {
|
|
176
|
-
const { closeDialog } = useDialogContext<{ name: string }>();
|
|
177
|
+
const { closeDialog } = useDialogContext<object, { name: string }>();
|
|
177
178
|
const [name, setName] = useState('');
|
|
178
179
|
|
|
179
180
|
return (
|
|
@@ -197,9 +198,10 @@ when omitted, `isBusy` `false`, `okLabel` `'Ok'`, `cancelLabel` `'Cancel'`,
|
|
|
197
198
|
Two behaviors worth knowing:
|
|
198
199
|
|
|
199
200
|
- `resizable` is accepted for compatibility but has **no effect** — the
|
|
200
|
-
|
|
201
|
+
Components dialog has no resize.
|
|
201
202
|
- Passing a custom node to `buttons` instead of a `DialogButtons` member
|
|
202
|
-
removes the header close control
|
|
203
|
+
removes the header close control and disables Escape/backdrop dismissal
|
|
204
|
+
(unless you also pass `dismissable` explicitly), and means `onClose`,
|
|
203
205
|
`onCancel`, and `onConfirm` are never invoked. Close through
|
|
204
206
|
`useDialogContext().closeDialog(...)`, or set `dismissable` explicitly.
|
|
205
207
|
|
|
@@ -48,6 +48,30 @@ Guard rendering with `hasData` rather than checking `data.length` — a
|
|
|
48
48
|
conditional query that has not fired returns an empty result with
|
|
49
49
|
`hasData: false`.
|
|
50
50
|
|
|
51
|
+
### Command success is not projection convergence
|
|
52
|
+
|
|
53
|
+
A successful `CommandResult` means the events were **appended**. The read model a
|
|
54
|
+
query reads is built by an observer that runs *after* that, so for a moment the
|
|
55
|
+
command has succeeded and the query still answers from before it. Model the
|
|
56
|
+
states separately instead of collapsing them into "loaded or not":
|
|
57
|
+
|
|
58
|
+
| State | Signal | Render |
|
|
59
|
+
| --- | --- | --- |
|
|
60
|
+
| Not asked yet | `.when(false)` / `!isReady` | nothing, or the previous content |
|
|
61
|
+
| Pending | `isPerforming`, or `hasData: false` **right after a command you just issued succeeded** | a skeleton — **never** "not found" |
|
|
62
|
+
| Converged, empty | `hasData` with an empty `data` and no recent command | the designed empty state |
|
|
63
|
+
| Converged, populated | `hasData` with items | the content |
|
|
64
|
+
| Failed | `!isSuccess` / `hasExceptions` / `!isAuthorized` | the matching error affordance |
|
|
65
|
+
| Stale refresh | `isPerforming` while `data` still holds the previous result | keep the old content, indicate refresh |
|
|
66
|
+
|
|
67
|
+
Two consequences. After a create command, take the **window action on the
|
|
68
|
+
command's success** (close the dialog, navigate to the new id) and let the list
|
|
69
|
+
catch up — do not wait for the query to show the row before closing. And for a
|
|
70
|
+
detail page opened on an id you just created, `hasData: false` is *pending*, not
|
|
71
|
+
*missing*: an observable query (`ISubject<T>` on the backend, `.use()` here)
|
|
72
|
+
resolves it the moment the projection lands, which is why observable reads are
|
|
73
|
+
the default for anything a user changes and then looks at.
|
|
74
|
+
|
|
51
75
|
### Paging
|
|
52
76
|
|
|
53
77
|
```ts
|
|
@@ -196,5 +220,5 @@ query transport. Its props include `microservice`, `origin`, `basePath`,
|
|
|
196
220
|
`apiBasePath`, `httpHeadersCallback` (merged into every request — bearer and
|
|
197
221
|
tenant headers), `detailsType`, `queryTransportMethod`, `queryConnectionCount`,
|
|
198
222
|
`queryDirectMode`, `observableQueryTransferMode`, and `queryCacheRetentionMs`.
|
|
199
|
-
`QueryTransportMethod`
|
|
200
|
-
`@cratis/arc`; `Arc` imports from `@cratis/arc.react`.
|
|
223
|
+
`QueryTransportMethod` imports from `@cratis/arc/queries`,
|
|
224
|
+
`ObservableQueryTransferMode` from `@cratis/arc`; `Arc` imports from `@cratis/arc.react`.
|