@ngis/plugin-ui 0.4.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/LICENSE +13 -0
- package/README.md +25 -0
- package/dist/index.cjs +71 -0
- package/dist/index.d.ts +114 -0
- package/dist/index.mjs +69 -0
- package/dist/src/api/analysis.d.ts +140 -0
- package/dist/src/api/resources.d.ts +530 -0
- package/dist/src/api/scenes.d.ts +251 -0
- package/dist/src/api/users.d.ts +22 -0
- package/dist/src/api/workflows.d.ts +191 -0
- package/dist/src/components/plugin-ui/AttributeTable.d.ts +26 -0
- package/dist/src/components/plugin-ui/BatchTable.d.ts +47 -0
- package/dist/src/components/plugin-ui/ChartCanvas.d.ts +14 -0
- package/dist/src/components/plugin-ui/ExtentPicker.d.ts +22 -0
- package/dist/src/components/plugin-ui/FieldSelect.d.ts +23 -0
- package/dist/src/components/plugin-ui/Flow.d.ts +256 -0
- package/dist/src/components/plugin-ui/ModelSelect.d.ts +36 -0
- package/dist/src/components/plugin-ui/ParamForm.d.ts +63 -0
- package/dist/src/components/plugin-ui/PickerField.d.ts +52 -0
- package/dist/src/components/plugin-ui/ResourceSelect.d.ts +37 -0
- package/dist/src/components/plugin-ui/ResultActions.d.ts +48 -0
- package/dist/src/components/plugin-ui/RunButton.d.ts +49 -0
- package/dist/src/components/plugin-ui/StatChart.d.ts +66 -0
- package/dist/src/components/plugin-ui/TaskChrome.d.ts +35 -0
- package/dist/src/components/plugin-ui/TaskList.d.ts +29 -0
- package/dist/src/components/plugin-ui/TaskStatus.d.ts +55 -0
- package/dist/src/components/plugin-ui/batch-model.d.ts +442 -0
- package/dist/src/components/plugin-ui/flow-inputs.d.ts +61 -0
- package/dist/src/components/plugin-ui/flow-model.d.ts +303 -0
- package/dist/src/components/plugin-ui/flow-ports.d.ts +155 -0
- package/dist/src/components/plugin-ui/param-form-data.d.ts +122 -0
- package/dist/src/components/plugin-ui/param-form-model.d.ts +187 -0
- package/dist/src/components/plugin-ui/param-widgets.d.ts +88 -0
- package/dist/src/components/plugin-ui/picker-data.d.ts +141 -0
- package/dist/src/components/plugin-ui/picker-model.d.ts +150 -0
- package/dist/src/components/plugin-ui/recipe-model.d.ts +320 -0
- package/dist/src/components/plugin-ui/result-data.d.ts +112 -0
- package/dist/src/components/plugin-ui/result-model.d.ts +96 -0
- package/dist/src/components/plugin-ui/run-data.d.ts +118 -0
- package/dist/src/components/plugin-ui/run-model.d.ts +179 -0
- package/dist/src/components/plugin-ui/stat-chart-model.d.ts +168 -0
- package/dist/src/components/plugin-ui/validation-messages.d.ts +18 -0
- package/dist/src/components/plugin-ui/w2-contracts.d.ts +151 -0
- package/dist/src/components/plugin-ui/w3-contracts.d.ts +328 -0
- package/dist/src/components/plugin-ui/w4-contracts.d.ts +510 -0
- package/dist/src/components/ui/button.d.ts +12 -0
- package/dist/src/components/ui/checkbox.d.ts +4 -0
- package/dist/src/components/ui/column-resize-handle.d.ts +23 -0
- package/dist/src/components/ui/dropdown-menu.d.ts +25 -0
- package/dist/src/components/ui/input.d.ts +3 -0
- package/dist/src/components/ui/label.d.ts +4 -0
- package/dist/src/components/ui/popover.d.ts +10 -0
- package/dist/src/components/ui/select.d.ts +15 -0
- package/dist/src/components/ui/switch.d.ts +6 -0
- package/dist/src/domain/map/types.d.ts +128 -0
- package/dist/src/features/gis/components/GisAttributeTable.d.ts +56 -0
- package/dist/src/features/gis/hooks/useDatasetFeatureWindow.d.ts +51 -0
- package/dist/src/lib/api-error.d.ts +81 -0
- package/dist/src/lib/api.d.ts +82 -0
- package/dist/src/lib/auth-session.d.ts +22 -0
- package/dist/src/lib/hooks/useColumnResize.d.ts +57 -0
- package/dist/src/lib/raster-color-layer/RasterColorLayer.d.ts +48 -0
- package/dist/src/lib/raster-color-layer/TileGrid.d.ts +31 -0
- package/dist/src/lib/raster-color-layer/colorRamp.d.ts +18 -0
- package/dist/src/lib/raster-color-layer/shaders/raster-color.frag.d.ts +2 -0
- package/dist/src/lib/raster-color-layer/shaders/raster-color.vert.d.ts +2 -0
- package/dist/src/lib/raster-color-layer/zoomInterpolate.d.ts +2 -0
- package/dist/src/lib/utils.d.ts +2 -0
- package/dist/src/sdk/facets/types.d.ts +370 -0
- package/dist/src/sdk/host-api.d.ts +256 -0
- package/dist/src/sdk/map-api.d.ts +288 -0
- package/dist/src/sdk/panels.d.ts +130 -0
- package/dist/src/types/analysis.d.ts +205 -0
- package/dist/src/types/common.d.ts +17 -0
- package/dist/src/types/extensions.d.ts +560 -0
- package/dist/src/types/gis.d.ts +242 -0
- package/dist/src/types/market-social.d.ts +378 -0
- package/dist/src/types/workflow.d.ts +83 -0
- package/package.json +59 -0
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A flow graph, serialized — **recipe JSON, the `{graph,view}` envelope, and the
|
|
3
|
+
* publish payloads** (Stage 14 Y6, W4 — F14.6).
|
|
4
|
+
*
|
|
5
|
+
* Pure: no React, no host, no `src/lib/api.ts`, no DOM. The seam this stage has
|
|
6
|
+
* now used four times, and here it is load-bearing rather than stylistic — *"a
|
|
7
|
+
* recipe is data and not code"* is a claim a React-free serializer proves and a
|
|
8
|
+
* component-entangled one only asserts. The DTO types below are imported with
|
|
9
|
+
* `import type`, which is erased, so this module has no runtime dependency on
|
|
10
|
+
* `src/api/**` while still keeping **one** source of truth per DTO. Everything
|
|
11
|
+
* that touches the wire is `recipe-data.ts`.
|
|
12
|
+
*
|
|
13
|
+
* ## The one thing to understand before reading further
|
|
14
|
+
*
|
|
15
|
+
* A `<Flow>` scope holds **more nodes than a recipe has**. Eleven components
|
|
16
|
+
* declare ports; only one of them runs a tool with inputs the server can bind —
|
|
17
|
+
* `RunButton`, whose out port is the sole `task`-kind port in F14.5's table. A
|
|
18
|
+
* `ResourceSelect` is an *interactive control*, not a computation: it has no
|
|
19
|
+
* graph node, so a reference to it can never be an edge. That single fact is
|
|
20
|
+
* where four of this session's corrections come from, and
|
|
21
|
+
* {@link recipeToolNodes} is where it is decided once.
|
|
22
|
+
*
|
|
23
|
+
* ## Where each of F14.6's four value forms ends up
|
|
24
|
+
*
|
|
25
|
+
* | flow binding | recipe | `{graph,view}` |
|
|
26
|
+
* |---|---|---|
|
|
27
|
+
* | `"@otherToolNode"` | kept verbatim (form 4) | `edges[]` |
|
|
28
|
+
* | `"@picker"` on a file port | `{ $input }` (form 3) | `inputs.<key>: ""` + an input slot |
|
|
29
|
+
* | `"@picker"` on an option port | the resolved value (form 1) | `params.<key>` |
|
|
30
|
+
* | unbound file port | `{ $input }` (form 3) | `inputs.<key>: ""` + an input slot |
|
|
31
|
+
* | anything else that resolved | the resolved value (form 1) | `params.<key>` |
|
|
32
|
+
*
|
|
33
|
+
* Contract: F14.1 (the Pascal boundary), F14.4 (value forms, `fieldMap` never),
|
|
34
|
+
* F14.5 (ports), F14.6 (recipe JSON, the mapping, the publish sequence), F14.19
|
|
35
|
+
* (review posture), F14.21 (`recipeColumns`, which stays in the seam).
|
|
36
|
+
* `w4-contracts.ts` is the kickoff seam and is read by relative path only —
|
|
37
|
+
* public recipe names come through this file, never through the seam, exactly as
|
|
38
|
+
* `flow-model.ts` publishes W3's.
|
|
39
|
+
*/
|
|
40
|
+
import type { CreateWorkflowToolPayload, InvokeWorkflowToolPayload } from "../../api/workflows";
|
|
41
|
+
import type { NgisDataType } from "../../sdk/facets/types";
|
|
42
|
+
import type { CreateReferenceVersionRequest } from "../../types/extensions";
|
|
43
|
+
import type { WorkflowDagConfig } from "../../types/workflow";
|
|
44
|
+
import { type NgisFlowNode, type NgisFlowSnapshot } from "./w3-contracts";
|
|
45
|
+
import { type NgisRecipe, type NgisRecipeOutput, type NgisToolInputSlot, type NgisToolOutputSlot } from "./w4-contracts";
|
|
46
|
+
export { NGIS_RECIPE_VERSION } from "./w4-contracts";
|
|
47
|
+
export type { NgisRecipe, NgisRecipeInput, NgisRecipeNode, NgisRecipeOutput, NgisToolInputSlot, NgisToolOutputSlot, } from "./w4-contracts";
|
|
48
|
+
export { recipeColumns } from "./w4-contracts";
|
|
49
|
+
/**
|
|
50
|
+
* The `view` key the recipe JSON is stored under.
|
|
51
|
+
*
|
|
52
|
+
* **Not a preference — the only place it can go.** `normalizeNode` rebuilds
|
|
53
|
+
* every graph node from scratch and keeps exactly fifteen keys
|
|
54
|
+
* (`NGIS_GRAPH_NODE_KEYS`), and the lossless presentation capture that would
|
|
55
|
+
* otherwise stash the original runs **only for a non-envelope payload**
|
|
56
|
+
* (`WorkflowGraphNormalizer.java:70-77`). Y6 sends an envelope, so anything a
|
|
57
|
+
* recipe knows that the graph does not — `recipeVersion`, promoted-input ids,
|
|
58
|
+
* labels, declared `dataTypes` — is dropped on save with no error unless it is
|
|
59
|
+
* also in `view`, which the backend stores verbatim and never reads.
|
|
60
|
+
*
|
|
61
|
+
* `view` already carries `nodes`/`edges`/`viewport` for the Stage-11 canvas, so
|
|
62
|
+
* this is a sibling key rather than the whole object.
|
|
63
|
+
*/
|
|
64
|
+
export declare const NGIS_RECIPE_VIEW_KEY = "ngisRecipe";
|
|
65
|
+
/**
|
|
66
|
+
* What a snapshot cannot tell you, and therefore what the author supplies.
|
|
67
|
+
*
|
|
68
|
+
* `outputs` is here rather than derived because a recipe output is a *decision*:
|
|
69
|
+
* F14.5 has no OUTPUT component, so no node in the scope corresponds to one, and
|
|
70
|
+
* its `outputMode` chooses what happens to a file after the run. {@link
|
|
71
|
+
* defaultRecipeOutputs} is the sane default the wizard starts from.
|
|
72
|
+
*/
|
|
73
|
+
export interface NgisRecipeMeta {
|
|
74
|
+
/** Stable across saves (F14.6). The wizard keeps the previous one. */
|
|
75
|
+
readonly id: string;
|
|
76
|
+
readonly name: string;
|
|
77
|
+
readonly description?: string | null;
|
|
78
|
+
/** Defaults to {@link defaultRecipeOutputs}. Must be non-empty to publish. */
|
|
79
|
+
readonly outputs?: readonly NgisRecipeOutput[];
|
|
80
|
+
/**
|
|
81
|
+
* Node ids whose `toolId` names a **published workflow tool** rather than an
|
|
82
|
+
* analysis tool — F14.6's `kind: "recipe"`, i.e. a nested recipe.
|
|
83
|
+
*
|
|
84
|
+
* **CORRECTION — F14.6's `nodes[].kind` has no channel in the snapshot, and
|
|
85
|
+
* the kickoff's CORRECTION 2 widening does not supply one.**
|
|
86
|
+
* `NgisFlowNodeConfig` carries `toolId` and `toolVersion` and nothing else, so
|
|
87
|
+
* `tool` and `recipe` are indistinguishable from a graph alone: the only thing
|
|
88
|
+
* that separates them is the registry row's `provider`, which lives on
|
|
89
|
+
* `NgisModelSummary` and therefore behind a host read. Emitting the wrong one
|
|
90
|
+
* matters — it decides whether the node carries `modelToolId` or
|
|
91
|
+
* `workflowToolId`, and dispatch is unordered first-match over those very
|
|
92
|
+
* fields (CORRECTION 5). So it is an explicit input here, resolved through the
|
|
93
|
+
* facade by `resolveRecipeNodeKinds` in `recipe-data.ts`, and defaults to
|
|
94
|
+
* **none** — a plain `tool` node — because that is the answer for every
|
|
95
|
+
* non-nested recipe and a wrong `workflowToolId` is the more expensive
|
|
96
|
+
* mistake.
|
|
97
|
+
*/
|
|
98
|
+
readonly nestedNodeIds?: readonly string[];
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* The nodes of a `<Flow>` scope that become graph nodes.
|
|
102
|
+
*
|
|
103
|
+
* **A node runs a tool iff it declares a `task` out port and carries a
|
|
104
|
+
* `config`.** Both halves are needed and neither is a component-identity check —
|
|
105
|
+
* the engine's own rule is that the registry knows nothing about a node beyond
|
|
106
|
+
* its `slot` and its ports, so the discriminator is drawn from F14.5's port
|
|
107
|
+
* table instead of from a slot allowlist:
|
|
108
|
+
*
|
|
109
|
+
* - `<ParamForm>` also carries a `config` (it loads a UI schema, and YD49
|
|
110
|
+
* populates the pair from it), but its out port is kind `record`. It renders a
|
|
111
|
+
* form; it does not run anything, and a recipe with a node per form would
|
|
112
|
+
* publish the same tool twice.
|
|
113
|
+
* - A `<ResourceSelect>` / `<FieldSelect>` / `<ExtentPicker>` carries no config
|
|
114
|
+
* at all.
|
|
115
|
+
*
|
|
116
|
+
* **This is the filter F14.6 needs and does not state, and without it publish
|
|
117
|
+
* fails in two different ways.** `promotableInputs` promotes any unbound
|
|
118
|
+
* `resource`-kind in-port, and two components other than `RunButton` declare
|
|
119
|
+
* one: `FieldSelect`'s `parent` and `ParamForm`'s hidden required inputs. Those
|
|
120
|
+
* would mint `ToolInputSlot`s whose `bindNodeId` names a node the graph does not
|
|
121
|
+
* contain, and `validateSlots` refuses with
|
|
122
|
+
* `"input slot <key> binds to unknown node <id>"`
|
|
123
|
+
* (`WorkflowToolSchemaService.java:187-192`) — for `ParamForm` — while
|
|
124
|
+
* `FieldSelect`'s would publish a slot that silently does nothing.
|
|
125
|
+
*/
|
|
126
|
+
export declare function recipeToolNodes(snapshot: NgisFlowSnapshot): readonly NgisFlowNode[];
|
|
127
|
+
/**
|
|
128
|
+
* Every tool node no other tool node consumes — the terminal producers, which
|
|
129
|
+
* are exactly what `inferDraft` would have called output slots
|
|
130
|
+
* (`WorkflowToolSchemaService.java:60-68`).
|
|
131
|
+
*
|
|
132
|
+
* `ADD_LAYER` for all of them, because it is the only mode with no second
|
|
133
|
+
* required field: `UPDATE_RESOURCE` needs a `targetResourceId` **at definition
|
|
134
|
+
* save** (`WorkflowTypeCheckService.java:181-185`), so defaulting to it would
|
|
135
|
+
* produce a graph that cannot be saved.
|
|
136
|
+
*/
|
|
137
|
+
export declare function defaultRecipeOutputs(snapshot: NgisFlowSnapshot): readonly NgisRecipeOutput[];
|
|
138
|
+
/**
|
|
139
|
+
* `NgisFlowSnapshot` → `NgisRecipe`.
|
|
140
|
+
*
|
|
141
|
+
* Two passes over each tool node, and the split is what keeps F14.4's
|
|
142
|
+
* precedence rule from being implemented twice:
|
|
143
|
+
*
|
|
144
|
+
* 1. **declared in-ports** decide promotion and edges — the only two things a
|
|
145
|
+
* port's *binding* determines rather than its *value*;
|
|
146
|
+
* 2. **`snapshot.resolved`** bakes everything else, spread-contributed sibling
|
|
147
|
+
* keys included. The engine already wrote that map with "later explicit keys
|
|
148
|
+
* win over spread keys" applied (`flow-model.ts`, `V-224`), so reading it is
|
|
149
|
+
* how this serializer avoids a second flattening rule that could disagree
|
|
150
|
+
* with the run path. A spread that resolved and a spread that did not are
|
|
151
|
+
* distinguishable there, which is the whole reason the directive entries
|
|
152
|
+
* exist.
|
|
153
|
+
*
|
|
154
|
+
* **`V-224` is the reason the second pass reads resolutions rather than
|
|
155
|
+
* bindings.** `THRESHOLD` is never a declared port on a `RunButton` — F14.5
|
|
156
|
+
* gives it "one in port per bound tool *input*" and an option is not an input —
|
|
157
|
+
* so a serializer that walked `node.inputs` alone would emit no `params` at all
|
|
158
|
+
* and the published recipe would run on the schema's `default_value`. That is
|
|
159
|
+
* the wrong run, not a type error, and it is exactly what the fixture's
|
|
160
|
+
* `"THRESHOLD": "2.5"` pins.
|
|
161
|
+
*/
|
|
162
|
+
export declare function serializeRecipe(snapshot: NgisFlowSnapshot, meta: NgisRecipeMeta): NgisRecipe;
|
|
163
|
+
/**
|
|
164
|
+
* `NgisRecipe` → the bare `{graph, view}` envelope
|
|
165
|
+
* `POST /api/workflows/definitions` takes as its **body**.
|
|
166
|
+
*
|
|
167
|
+
* `name` and `sceneId` are query parameters, not body fields (F14.6's own
|
|
168
|
+
* CORRECTION), so they are not here.
|
|
169
|
+
*
|
|
170
|
+
* Three properties of the emitted graph that are contract rather than style:
|
|
171
|
+
*
|
|
172
|
+
* 1. **Exactly one discriminator per node.** Dispatch is
|
|
173
|
+
* `executors.stream().filter(supports).findFirst()` with no `@Order`
|
|
174
|
+
* (`WorkflowTaskRunner.java:61-65`) and `checkAmbiguity` guards only the
|
|
175
|
+
* `workflowToolId` combinations, so `modelToolId` **+** `type: "OUTPUT"` is
|
|
176
|
+
* unguarded and would dispatch by classpath-scan order. A TASK node carries
|
|
177
|
+
* `modelToolId` and no `workflowToolId`; a WORKFLOW_TOOL node the reverse; an
|
|
178
|
+
* OUTPUT node neither.
|
|
179
|
+
* 2. **No `fieldMap`, ever** (F14.4). Despite the name it is a flat *string* —
|
|
180
|
+
* a server-side path+pipeline expression over a task's output JSON — and the
|
|
181
|
+
* flow layer has no model of that shape.
|
|
182
|
+
* 3. **The recipe rides in `view`.** See {@link NGIS_RECIPE_VIEW_KEY}.
|
|
183
|
+
*/
|
|
184
|
+
export declare function recipeEnvelope(recipe: NgisRecipe): WorkflowDagConfig;
|
|
185
|
+
/**
|
|
186
|
+
* What `view` held. A reader that does not know the version **refuses** — it
|
|
187
|
+
* never best-efforts, exactly as `ui_schema_version` does not (F14.2, F14.6).
|
|
188
|
+
*/
|
|
189
|
+
export type NgisRecipeRead =
|
|
190
|
+
/** No recipe in this definition — a hand-built or canvas-authored DAG. */
|
|
191
|
+
{
|
|
192
|
+
readonly kind: "absent";
|
|
193
|
+
} | {
|
|
194
|
+
readonly kind: "unsupported-version";
|
|
195
|
+
readonly version: number;
|
|
196
|
+
}
|
|
197
|
+
/** Present but not the frozen shape. Reported, never silently repaired. */
|
|
198
|
+
| {
|
|
199
|
+
readonly kind: "malformed";
|
|
200
|
+
readonly reason: string;
|
|
201
|
+
} | {
|
|
202
|
+
readonly kind: "ready";
|
|
203
|
+
readonly recipe: NgisRecipe;
|
|
204
|
+
};
|
|
205
|
+
/**
|
|
206
|
+
* Read a recipe back out of a definition's `{graph, view}`.
|
|
207
|
+
*
|
|
208
|
+
* The backend stores `view` **verbatim and never reads it**, so this is a pure
|
|
209
|
+
* round-trip of what {@link recipeEnvelope} wrote — which is what makes the
|
|
210
|
+
* envelope leg of the publish chain assertable offline without a database.
|
|
211
|
+
*/
|
|
212
|
+
export declare function readRecipe(config: unknown): NgisRecipeRead;
|
|
213
|
+
/**
|
|
214
|
+
* Per-output publish enrichment.
|
|
215
|
+
*
|
|
216
|
+
* **CORRECTION — the kickoff's CORRECTION 8 cannot be satisfied from the recipe
|
|
217
|
+
* JSON, because F14.6's `outputs[]` has no type field.** The correction is right
|
|
218
|
+
* that an unenriched output slot serves `data_type: "file"` and makes the
|
|
219
|
+
* generated dialog show a file picker where the author declared a raster; but the
|
|
220
|
+
* frozen `NgisRecipeOutput` is `{id, label, from, outputMode, targetResourceId?}`
|
|
221
|
+
* and the seam is read-only, so there is nowhere in a recipe to record the answer.
|
|
222
|
+
* It is therefore a **publish-time** input, offered by the wizard, keyed by
|
|
223
|
+
* recipe-output id and defaulting to the `File` wildcard — which is honest
|
|
224
|
+
* (`File` really is what an unenriched slot means) rather than a guess.
|
|
225
|
+
*/
|
|
226
|
+
export interface NgisRecipePublishOptions {
|
|
227
|
+
readonly definitionId: string;
|
|
228
|
+
readonly name: string;
|
|
229
|
+
readonly description?: string | null;
|
|
230
|
+
/** Recipe-output id → canonical data type (F14.1). Absent ⇒ `File`. */
|
|
231
|
+
readonly outputDataTypes?: Readonly<Record<string, NgisDataType>>;
|
|
232
|
+
readonly summary?: string;
|
|
233
|
+
readonly useCases?: readonly string[];
|
|
234
|
+
readonly synonyms?: readonly string[];
|
|
235
|
+
readonly domain?: readonly string[];
|
|
236
|
+
readonly operationType?: readonly string[];
|
|
237
|
+
}
|
|
238
|
+
/**
|
|
239
|
+
* The explicit `inputSlots` / `outputSlots` F14.6 publishes instead of relying on
|
|
240
|
+
* `getDraft`.
|
|
241
|
+
*
|
|
242
|
+
* **Serialized by name, never positionally.** `ToolInputSlot` is
|
|
243
|
+
* `(slotKey, name, description, dataType, bindNodeId, bindInputKey, optional)`
|
|
244
|
+
* and `ToolOutputSlot` is `(slotKey, name, description, bindNodeId, dataType)` —
|
|
245
|
+
* `dataType` and `bindNodeId` are *transposed* between them, and `ToolOutputSlot`
|
|
246
|
+
* keeps a 4-arg secondary constructor so a 4-tuple compiles and yields
|
|
247
|
+
* `dataType: null`.
|
|
248
|
+
*
|
|
249
|
+
* `bindInputKey` is the field F14.6 omits and the one publish actually dies on:
|
|
250
|
+
* the record is `@JsonIgnoreProperties(ignoreUnknown = true)`, so the six-field
|
|
251
|
+
* shape posts with **no error** and fails at
|
|
252
|
+
* `WorkflowToolSchemaService.java:193-196` with `"input slot <key> is missing
|
|
253
|
+
* bindInputKey"` — and at invoke it is the key the caller's file id is injected
|
|
254
|
+
* under (`WorkflowToolService.java:421-423`), so a wrong value would put a real
|
|
255
|
+
* file under the wrong parameter.
|
|
256
|
+
*
|
|
257
|
+
* An output slot's `slotKey` is the **recipe output's id**, not the producing
|
|
258
|
+
* node's id as `inferDraft` mints it. `compileToolSchema` keys the schema's
|
|
259
|
+
* `properties` by `slotKey` and `mapOutputs` keys a nested invocation's result by
|
|
260
|
+
* it too, so two outputs off one producer would collide under `inferDraft`'s
|
|
261
|
+
* convention; `bindNodeId` still names the producer, which is what
|
|
262
|
+
* `validateSlots` and `outputNodeIds` read.
|
|
263
|
+
*/
|
|
264
|
+
export declare function recipeSlots(recipe: NgisRecipe, options?: Pick<NgisRecipePublishOptions, "outputDataTypes">): {
|
|
265
|
+
readonly inputSlots: readonly NgisToolInputSlot[];
|
|
266
|
+
readonly outputSlots: readonly NgisToolOutputSlot[];
|
|
267
|
+
};
|
|
268
|
+
/**
|
|
269
|
+
* Inputs whose declared types were **widened to the `File` wildcard** at the slot
|
|
270
|
+
* boundary.
|
|
271
|
+
*
|
|
272
|
+
* A slot carries one `dataType` and a port may declare several, so
|
|
273
|
+
* `ngisSlotDataType` widens a multi-type or untyped declaration to `File` — the
|
|
274
|
+
* only spelling that is compatible on both sides of
|
|
275
|
+
* `WorkflowTypeCheckService.compatible` and therefore the only one that preserves
|
|
276
|
+
* `types={["table","raster"]}`. The widening is lossy, so the wizard says so
|
|
277
|
+
* rather than applying it silently.
|
|
278
|
+
*/
|
|
279
|
+
export declare function recipeSlotWidenings(recipe: NgisRecipe): readonly {
|
|
280
|
+
readonly inputId: string;
|
|
281
|
+
readonly dataTypes: readonly NgisDataType[];
|
|
282
|
+
}[];
|
|
283
|
+
/** `POST /api/workflows/tools` — `PublishToolRequest`, in full. */
|
|
284
|
+
export declare function recipePublishPayload(recipe: NgisRecipe, options: NgisRecipePublishOptions): CreateWorkflowToolPayload;
|
|
285
|
+
/**
|
|
286
|
+
* `POST /api/workflows/tools/{toolId}/invoke` — the headless run.
|
|
287
|
+
*
|
|
288
|
+
* `inputs` is `slotKey → fileId` and a published workflow tool's whole invocable
|
|
289
|
+
* surface: `compileToolSchema` emits `x-role` of only `"input"` and `"output"`
|
|
290
|
+
* and **never `"option"`**, so there are no knobs to pass. Every option the
|
|
291
|
+
* author chose is already baked into the published snapshot's node `params`.
|
|
292
|
+
*
|
|
293
|
+
* `LIBRARY` is legal here and **illegal at definition save** — the two
|
|
294
|
+
* `outputMode` enums are different sets (CORRECTION 4) — which is why this
|
|
295
|
+
* function's mode is widened beyond `NgisRecipeOutput`'s.
|
|
296
|
+
*/
|
|
297
|
+
export declare function recipeInvokePayload(options: {
|
|
298
|
+
readonly inputs: Readonly<Record<string, string>>;
|
|
299
|
+
readonly sceneId?: string | null;
|
|
300
|
+
readonly outputMode?: "ADD_LAYER" | "UPDATE_RESOURCE" | "LIBRARY";
|
|
301
|
+
readonly targetResourceId?: string | null;
|
|
302
|
+
}): InvokeWorkflowToolPayload;
|
|
303
|
+
/**
|
|
304
|
+
* `POST /api/extensions/{extId}/versions/reference` — the `tool`-kind listing.
|
|
305
|
+
*
|
|
306
|
+
* `provider` is `"workflow"` because a published recipe lands in the shared
|
|
307
|
+
* `ngis_model_tool` id space with `provider = "workflow"` and
|
|
308
|
+
* `modelbox_id = "workflow-tools"`, which is also why `GetToolSchema(toolId)` and
|
|
309
|
+
* YB1's ui-schema endpoint resolve it exactly like a builtin.
|
|
310
|
+
*
|
|
311
|
+
* `toolVersion` is an `Integer` here while `ngis-workflow`'s node pin is a
|
|
312
|
+
* `long`, and this endpoint answers **`200`, not `201`**.
|
|
313
|
+
*/
|
|
314
|
+
export declare function recipeReferenceRequest(options: {
|
|
315
|
+
readonly version: string;
|
|
316
|
+
readonly minNgisVersion: string;
|
|
317
|
+
readonly toolId: string;
|
|
318
|
+
readonly toolVersion: number;
|
|
319
|
+
readonly changelog?: string | null;
|
|
320
|
+
}): CreateReferenceVersionRequest;
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The host reads behind `<ResultActions>` and `<AttributeTable>` (Stage 14 Y4b).
|
|
3
|
+
*
|
|
4
|
+
* Same discipline as Y2's `picker-data.ts`: every function takes the 0.4 facade
|
|
5
|
+
* and returns plain data, so the wave's real exit criterion — "these work
|
|
6
|
+
* **through `createGisPluginHostFactory`**" — is asserted offline. A node test
|
|
7
|
+
* builds the real, scope-enforced facade and calls these, so a scope refusal or
|
|
8
|
+
* a facet stub surfaces here exactly as it would in a browser. A facade
|
|
9
|
+
* assembled anywhere else is an ungated 0.4 surface every unit test calls green.
|
|
10
|
+
*
|
|
11
|
+
* **The scopes each read needs, on record**, because a refusal has to be
|
|
12
|
+
* legible: `tasks.get`/`tasks.outputs`/`tasks.watch` are `tasks:read`,
|
|
13
|
+
* `resources.list` is `resources:read`, `viz.addResultLayer` is `viz:write`, and
|
|
14
|
+
* `viz.openTable` / `viz.chart` are **ungated** (they mutate nothing — F14.3's
|
|
15
|
+
* amendment to F13.5, already on `NGIS_UNGATED_MEMBERS`).
|
|
16
|
+
*/
|
|
17
|
+
import type { NgisTaskState } from "../../sdk/facets/types";
|
|
18
|
+
import type { NgisChartSpec, NgisHostAPI } from "../../sdk/host-api";
|
|
19
|
+
import { joinOutputs, projectResult, type NgisResultOutput, type NgisResultView } from "./result-model";
|
|
20
|
+
/**
|
|
21
|
+
* The scene's `fileId → resourceId` map.
|
|
22
|
+
*
|
|
23
|
+
* The join exists because the two vocabularies really are different: a task
|
|
24
|
+
* output is addressed by **file** id (F14.4, `output-files[].file_id`) while
|
|
25
|
+
* `host.viz.openTable` takes a **scene-resource** id, and `viz.ts` rejects a
|
|
26
|
+
* file id passed in its place rather than guessing. `NgisResourceSummary.fileId`
|
|
27
|
+
* is the only bridge, and it is a `resources:read` call.
|
|
28
|
+
*/
|
|
29
|
+
export declare function loadResourceIdsByFileId(host: NgisHostAPI): Promise<ReadonlyMap<string, string>>;
|
|
30
|
+
/**
|
|
31
|
+
* One coherent read of "where is this run, and what can be done with it".
|
|
32
|
+
*
|
|
33
|
+
* The output fallback is the interesting half. `NgisTaskState.outputs` is
|
|
34
|
+
* populated from the tracked task's `outputFiles`, which the DIRECT runtime
|
|
35
|
+
* fills after the run succeeds — but a component that attached to an
|
|
36
|
+
* already-finished task (or a WORKFLOW run whose instance was polled before its
|
|
37
|
+
* outputs were fetched) can legitimately see `SUCCESS` with `outputs: []`. So a
|
|
38
|
+
* terminal-success state with no outputs asks `host.tasks.outputs` once. It is
|
|
39
|
+
* **not** treated as "this run produced nothing": that conflation is what would
|
|
40
|
+
* make a real result look like an empty one, which is the failure mode F13.5's
|
|
41
|
+
* refusal rule exists to prevent.
|
|
42
|
+
*/
|
|
43
|
+
export declare function readResultView(host: NgisHostAPI, taskId: string | null, state?: NgisTaskState | null): Promise<NgisResultView>;
|
|
44
|
+
/**
|
|
45
|
+
* The post-hoc path (`viz:write`). Registers a scene resource for the output's
|
|
46
|
+
* file id when absent, then adds a layer — which is precisely what the
|
|
47
|
+
* submit-time path would have done, and the reason `ResultActions` only offers
|
|
48
|
+
* this in the `detached` and `integration-failed` phases.
|
|
49
|
+
*/
|
|
50
|
+
export declare function addResultOutputLayer(host: NgisHostAPI, output: NgisResultOutput, name?: string): Promise<{
|
|
51
|
+
resourceId: string;
|
|
52
|
+
layerId: string;
|
|
53
|
+
}>;
|
|
54
|
+
/**
|
|
55
|
+
* Ungated. Rejects with a named message when the resource has no layer in the
|
|
56
|
+
* scene — the attribute panel targets the *selected layer's* dataset, so the
|
|
57
|
+
* resource must be rendered first. Surfaced, never swallowed.
|
|
58
|
+
*/
|
|
59
|
+
export declare function openResultTable(host: NgisHostAPI, output: NgisResultOutput): Promise<void>;
|
|
60
|
+
/** Ungated (F14.3). The host renders the declarative spec; the plugin ships no
|
|
61
|
+
* chart code, which is what keeps this survivable into Stage 15's worker tier. */
|
|
62
|
+
export declare function renderResultChart(host: NgisHostAPI, spec: NgisChartSpec): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* Public default for ResultActions' field chart. The data read stays behind the
|
|
65
|
+
* resource facet, so a plugin gets the same scope enforcement and lab-scene
|
|
66
|
+
* isolation as every other smart component instead of importing an app API.
|
|
67
|
+
*/
|
|
68
|
+
export declare function buildResultFieldChart(host: NgisHostAPI, output: {
|
|
69
|
+
fileId: string;
|
|
70
|
+
name: string | null;
|
|
71
|
+
}, field: string): Promise<NgisChartSpec>;
|
|
72
|
+
/**
|
|
73
|
+
* What `<AttributeTable>` can learn about the file id on its `resource` in-port.
|
|
74
|
+
*
|
|
75
|
+
* Four arms rather than "a name or nothing", for the same reason
|
|
76
|
+
* `NgisFieldLoad` has four: each is a state an author has to be able to tell
|
|
77
|
+
* apart, and collapsing "not in this scene" into "no name" would hide a resource
|
|
78
|
+
* that was removed.
|
|
79
|
+
*/
|
|
80
|
+
export type NgisTableTarget =
|
|
81
|
+
/** The in-port is unsatisfied. */
|
|
82
|
+
{
|
|
83
|
+
readonly kind: "no-resource";
|
|
84
|
+
}
|
|
85
|
+
/** The file id matches no resource in the open scene. */
|
|
86
|
+
| {
|
|
87
|
+
readonly kind: "unresolved";
|
|
88
|
+
readonly fileId: string;
|
|
89
|
+
}
|
|
90
|
+
/** Resolved, but attributes are vector-only. */
|
|
91
|
+
| {
|
|
92
|
+
readonly kind: "not-vector";
|
|
93
|
+
readonly type: string;
|
|
94
|
+
} | {
|
|
95
|
+
readonly kind: "ready";
|
|
96
|
+
readonly fileId: string;
|
|
97
|
+
readonly resourceId: string;
|
|
98
|
+
readonly name: string;
|
|
99
|
+
};
|
|
100
|
+
/**
|
|
101
|
+
* `resources:read`. Resolves the parent exactly the way `FieldSelect` does —
|
|
102
|
+
* through `resources.list()` keyed on `fileId` — because `resources.get` takes a
|
|
103
|
+
* scene-resource id and the port carries a file id (F14.5).
|
|
104
|
+
*
|
|
105
|
+
* The `not-vector` arm matters: `GisAttributeTable` queries
|
|
106
|
+
* `datasets/{fileId}/attributes/*`, which only a vector dataset answers. Handing
|
|
107
|
+
* it a raster would render an error inside the wrapped grid instead of a reason
|
|
108
|
+
* beside the control.
|
|
109
|
+
*/
|
|
110
|
+
export declare function loadTableTarget(host: NgisHostAPI, fileId: string | null): Promise<NgisTableTarget>;
|
|
111
|
+
/** Re-exported so a caller can build a view from outputs it already holds. */
|
|
112
|
+
export { joinOutputs, projectResult };
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `<ResultActions>`'s whole decision, as one pure projection (Stage 14 Y4b,
|
|
3
|
+
* **F14.5** / **F14.10**).
|
|
4
|
+
*
|
|
5
|
+
* ## The distinction this module exists to keep visible: complete ≠ integrated
|
|
6
|
+
*
|
|
7
|
+
* `NgisTaskStatus` is the *run*. `NgisTaskStage` is the *lifecycle including
|
|
8
|
+
* scene integration*. `status: "SUCCESS"` with `stage:
|
|
9
|
+
* "waiting_scene_integration"` is a real and common state, and it is why
|
|
10
|
+
* `analysis-task-runtime.ts` runs an integration poll **alongside** the SSE
|
|
11
|
+
* stream rather than trusting the stream's terminal write. `integration_status`
|
|
12
|
+
* is a separate axis, so a result surface that collapsed the two would offer a
|
|
13
|
+
* post-hoc "add to map" the instant a task went `SUCCESS` — racing the
|
|
14
|
+
* submit-time integration that is already on its way and producing a duplicate
|
|
15
|
+
* layer.
|
|
16
|
+
*
|
|
17
|
+
* That is the whole reason {@link NgisResultPhase} has six terminal-ish arms
|
|
18
|
+
* instead of `succeeded | failed`:
|
|
19
|
+
*
|
|
20
|
+
* | phase | `status` / `stage` | what it means for the actions |
|
|
21
|
+
* |---|---|---|
|
|
22
|
+
* | `no-task` | the `taskId` in-port is unsatisfied | nothing to act on; a reason, not a dead control (F14.10) |
|
|
23
|
+
* | `running` | `submitting` / `QUEUED` / `RUNNING` | the run is still going |
|
|
24
|
+
* | `integrating` | `SUCCESS` + `waiting_output_datasets` \| `waiting_scene_integration` \| `refreshing_scene` | **complete, not integrated.** No post-hoc add — submit-time integration owns this |
|
|
25
|
+
* | `integrated` | `SUCCESS` + `success`, every output resolved to a scene resource | the scene has it; open the table, chart it |
|
|
26
|
+
* | `detached` | `SUCCESS` + `success`, ≥1 output is not a scene resource | this is what `host.viz.addResultLayer` is *for* |
|
|
27
|
+
* | `integration-failed` | `SUCCESS` + `failed` | the computation happened, the lifecycle did not — post-hoc add is the recovery |
|
|
28
|
+
* | `failed` / `cancelled` | `FAILED` / `CANCELLED` | there is no output |
|
|
29
|
+
*
|
|
30
|
+
* **Submit-time integration is the preferred path** and is reached by passing
|
|
31
|
+
* `sceneId`/`outputMode` to `tasks.run` (Y4a's `RunButton`). `addResultLayer` is
|
|
32
|
+
* the post-hoc path, and `detached` / `integration-failed` are the only two
|
|
33
|
+
* phases where offering it is honest.
|
|
34
|
+
*
|
|
35
|
+
* ## No `disabled`, anywhere
|
|
36
|
+
*
|
|
37
|
+
* F14.10: enablement is derived, and a nothing-to-show state renders a *reason*
|
|
38
|
+
* rather than a dead control. So this module returns which actions are
|
|
39
|
+
* *available* plus the phase that explains the rest, and `ResultActions` renders
|
|
40
|
+
* the reason through `PickerField`'s notice slot. Nothing here produces text —
|
|
41
|
+
* the component translates the phase under `GIS.pluginUi.run.result.*`.
|
|
42
|
+
*/
|
|
43
|
+
import type { NgisTaskOutput, NgisTaskState } from "../../sdk/facets/types";
|
|
44
|
+
export type NgisResultPhase = "no-task" | "running" | "integrating" | "integrated" | "detached" | "integration-failed" | "failed" | "cancelled";
|
|
45
|
+
/**
|
|
46
|
+
* One task output, joined to the scene. `resourceId` is the join `host.viz`
|
|
47
|
+
* needs and `NgisTaskOutput` does not carry: outputs are addressed by **file**
|
|
48
|
+
* id (F14.4), while `viz.openTable` takes a **scene-resource** id, and the join
|
|
49
|
+
* is `NgisResourceSummary.fileId`.
|
|
50
|
+
*/
|
|
51
|
+
export interface NgisResultOutput {
|
|
52
|
+
readonly fileId: string;
|
|
53
|
+
/** The declared output parameter's name (DIRECT) or the producing node id
|
|
54
|
+
* (WORKFLOW). `null` when the wire carried none. */
|
|
55
|
+
readonly name: string | null;
|
|
56
|
+
readonly primary: boolean;
|
|
57
|
+
/** `null` when this output is not (yet) a resource in the open scene. */
|
|
58
|
+
readonly resourceId: string | null;
|
|
59
|
+
}
|
|
60
|
+
export interface NgisResultView {
|
|
61
|
+
readonly phase: NgisResultPhase;
|
|
62
|
+
/** File-id-bearing outputs only. An output row with no `file_id` cannot be
|
|
63
|
+
* added, opened or charted, so carrying it would only produce dead controls. */
|
|
64
|
+
readonly outputs: readonly NgisResultOutput[];
|
|
65
|
+
/** Post-hoc `host.viz.addResultLayer` would do something. */
|
|
66
|
+
readonly canAddLayer: boolean;
|
|
67
|
+
/** At least one output is a scene resource, so `host.viz.openTable` resolves. */
|
|
68
|
+
readonly canOpenTable: boolean;
|
|
69
|
+
/** The run produced something, so charting a spec over it is meaningful. */
|
|
70
|
+
readonly canChart: boolean;
|
|
71
|
+
/** The run's or the integration's own message, verbatim. Never invented. */
|
|
72
|
+
readonly error: string | null;
|
|
73
|
+
}
|
|
74
|
+
export declare function joinOutputs(outputs: readonly NgisTaskOutput[], resourceIdByFileId: ReadonlyMap<string, string>): readonly NgisResultOutput[];
|
|
75
|
+
/**
|
|
76
|
+
* The projection. `resourceIdByFileId` is the scene's `fileId → resourceId` map
|
|
77
|
+
* (`host.resources.list()`); an empty map is a scene with no resources, not a
|
|
78
|
+
* missing read, and it correctly yields `detached` for a successful run — which
|
|
79
|
+
* is exactly the state post-hoc add exists for.
|
|
80
|
+
*/
|
|
81
|
+
export declare function projectResult(state: NgisTaskState | null, resourceIdByFileId: ReadonlyMap<string, string>): NgisResultView;
|
|
82
|
+
/**
|
|
83
|
+
* The one output a bare `"@run"` reference resolves to: `primary === true`, else
|
|
84
|
+
* the first (F14.4, and `executors/base.py` guarantees at most one `primary`).
|
|
85
|
+
* `ResultActions` acts on this by default so the common single-output case needs
|
|
86
|
+
* no picking.
|
|
87
|
+
*
|
|
88
|
+
* **Delegates to the canonical rule (`V-127`, YD45)**, generically, because
|
|
89
|
+
* `NgisResultOutput` is assignable to `NgisTaskOutput` and not the reverse.
|
|
90
|
+
* Behaviour is unchanged: every caller reaches this through {@link joinOutputs},
|
|
91
|
+
* which has already dropped the file-id-less rows, so the canonical rule's
|
|
92
|
+
* decision *not* to filter is a no-op on this path.
|
|
93
|
+
*/
|
|
94
|
+
export declare function primaryOutput(outputs: readonly NgisResultOutput[]): NgisResultOutput | null;
|
|
95
|
+
/** A stable, human-ish name for an output row. Never a key — see F13.11. */
|
|
96
|
+
export declare function outputLabel(output: NgisResultOutput): string;
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The host calls behind `RunButton` / `TaskStatus` / `TaskList` (Stage 14 Y4a).
|
|
3
|
+
*
|
|
4
|
+
* Every function takes the 0.4 facade and returns plain data, for the same reason
|
|
5
|
+
* `picker-data.ts` does: the wave's real exit criterion is "these components work
|
|
6
|
+
* **through `createGisPluginHostFactory`**", and that is only assertable offline
|
|
7
|
+
* if the host reads live above the components rather than inside a `useEffect`.
|
|
8
|
+
* A scope refusal (`NgisScopeError`) or a facet stub therefore surfaces here
|
|
9
|
+
* exactly as it would in a browser, and nothing below swallows one.
|
|
10
|
+
*
|
|
11
|
+
* ## The DIRECT/WORKFLOW branch is not here, and must never be
|
|
12
|
+
*
|
|
13
|
+
* F13.2 puts the fork inside `host.tasks` — `run()` branches on the resolved
|
|
14
|
+
* model's `provider` and `watch()` attaches to the store-backed SSE pipeline for
|
|
15
|
+
* DIRECT or starts a poll timer for WORKFLOW. This module calls one API and does
|
|
16
|
+
* not know which branch it got. The one place the difference is *visible* is
|
|
17
|
+
* {@link hasLogStream}, which reads the `kind` the facet already reported rather
|
|
18
|
+
* than re-deciding it.
|
|
19
|
+
*
|
|
20
|
+
* ## The order of operations, which is F14.9 and not a preference
|
|
21
|
+
*
|
|
22
|
+
* `validate` **always runs once before submit**. {@link runSubmission} is the
|
|
23
|
+
* only sanctioned path for that reason: it validates, refuses on a blocking
|
|
24
|
+
* verdict, and submits only afterwards. A caller that has already validated on
|
|
25
|
+
* change still goes through it — a debounced validation can be stale by the time
|
|
26
|
+
* the button is pressed, and the final call is the one that counts.
|
|
27
|
+
*/
|
|
28
|
+
import type { NgisHostAPI } from "../../sdk/host-api";
|
|
29
|
+
import type { NgisModelValidateRequest, NgisTaskHandle, NgisTaskState, NgisTaskWatcher } from "../../sdk/facets/types";
|
|
30
|
+
import type { NgisExecutionValidation } from "../../types/analysis";
|
|
31
|
+
import { type NgisRunGate } from "./run-model";
|
|
32
|
+
import { type NgisRunSubmission } from "./w2-contracts";
|
|
33
|
+
/** Run-shaping options a submission does not carry (they are the caller's, not
|
|
34
|
+
* the generated form's). Mirrors `NgisTaskRunRequest` plus `targetSrid`, which
|
|
35
|
+
* only the validate leg takes. */
|
|
36
|
+
export interface NgisRunOptions {
|
|
37
|
+
sceneId?: string;
|
|
38
|
+
/** Lab-scene optimistic fence. Ordinary scene runs leave this absent. */
|
|
39
|
+
expectedSceneGeneration?: number;
|
|
40
|
+
outputMode?: "ADD_LAYER" | "UPDATE_RESOURCE";
|
|
41
|
+
targetResourceId?: string;
|
|
42
|
+
/** `validate-execution` only — `POST /api/analysis/tasks` has no such field. */
|
|
43
|
+
targetSrid?: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The `host.models.validate` request for one submission.
|
|
47
|
+
*
|
|
48
|
+
* Note what is **absent**: `owner_id`. F14.3 is explicit that it comes from the
|
|
49
|
+
* authenticated caller and is never read from a body, which is why
|
|
50
|
+
* `NgisModelValidateRequest` has no such member to fill in.
|
|
51
|
+
*/
|
|
52
|
+
export declare function validateRequestOf(submission: NgisRunSubmission, options?: NgisRunOptions): NgisModelValidateRequest;
|
|
53
|
+
/** F14.9's server-validation leg. `models:read` — it runs nothing. */
|
|
54
|
+
export declare function validateRun(host: NgisHostAPI, submission: NgisRunSubmission, options?: NgisRunOptions): Promise<NgisExecutionValidation>;
|
|
55
|
+
/**
|
|
56
|
+
* `host.tasks.run`, with the bindings folded into `params`.
|
|
57
|
+
*
|
|
58
|
+
* `models:run` — running a model is the privileged act (F13.5). The handle's
|
|
59
|
+
* `kind` tells the caller which branch the facade took, and that is the only
|
|
60
|
+
* place the fork is observable from out here.
|
|
61
|
+
*/
|
|
62
|
+
export declare function submitRun(host: NgisHostAPI, submission: NgisRunSubmission, options?: NgisRunOptions): Promise<NgisTaskHandle>;
|
|
63
|
+
/** What one press of a run action produced. Exactly one of the three arms. */
|
|
64
|
+
export type NgisRunOutcome =
|
|
65
|
+
/** Validation answered, and it blocks. Nothing was submitted. */
|
|
66
|
+
{
|
|
67
|
+
readonly kind: "blocked";
|
|
68
|
+
readonly validation: NgisExecutionValidation;
|
|
69
|
+
readonly gate: NgisRunGate;
|
|
70
|
+
} | {
|
|
71
|
+
readonly kind: "submitted";
|
|
72
|
+
readonly validation: NgisExecutionValidation;
|
|
73
|
+
readonly gate: NgisRunGate;
|
|
74
|
+
readonly handle: NgisTaskHandle;
|
|
75
|
+
}
|
|
76
|
+
/** The validate or the run call itself rejected — a scope refusal, a transport
|
|
77
|
+
* failure, a facet stub. Surfaced, never folded into `blocked`: "the server
|
|
78
|
+
* says no" and "we could not ask" are different things to tell an author. */
|
|
79
|
+
| {
|
|
80
|
+
readonly kind: "error";
|
|
81
|
+
readonly error: unknown;
|
|
82
|
+
readonly phase: "validate" | "submit";
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* **F14.9's "always once before submit", implemented once.**
|
|
86
|
+
*
|
|
87
|
+
* The whole sequence lives in one function so the guarantee is a property of the
|
|
88
|
+
* code rather than of a component remembering to call two things in order. A
|
|
89
|
+
* `RunButton` that validated in an effect and submitted in a click handler would
|
|
90
|
+
* satisfy the letter of the clause only as long as nobody reordered the handler.
|
|
91
|
+
*/
|
|
92
|
+
export declare function runSubmission(host: NgisHostAPI, submission: NgisRunSubmission, options?: NgisRunOptions): Promise<NgisRunOutcome>;
|
|
93
|
+
/**
|
|
94
|
+
* **F14.10's single sanctioned publication out of a flow scope.**
|
|
95
|
+
*
|
|
96
|
+
* Flow state is component-local; every `host.context.set` notifies the
|
|
97
|
+
* dependency index and re-evaluates every compiled expression whose read-set
|
|
98
|
+
* intersects, so publishing per-port values would put per-keystroke traffic
|
|
99
|
+
* through the global index. Exactly one value leaves: the task id, and only so a
|
|
100
|
+
* plugin can gate a status-bar badge on it.
|
|
101
|
+
*
|
|
102
|
+
* **The key is bare.** `host.context.set` auto-namespaces (F14.11), and passing
|
|
103
|
+
* a prefixed key is rejected rather than re-prefixed — a component that wrote
|
|
104
|
+
* `plugin:<id>:taskId` itself would double-prefix or throw
|
|
105
|
+
* `NgisContextKeyError`, depending on which spelling the store is on. Writing
|
|
106
|
+
* `"taskId"` is correct under both.
|
|
107
|
+
*/
|
|
108
|
+
export declare function publishTaskId(host: NgisHostAPI, taskId: string): Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* `host.tasks.watch`, unwrapped.
|
|
111
|
+
*
|
|
112
|
+
* Thin on purpose — the branch, the equality guard and the "no workflow SSE"
|
|
113
|
+
* decision all live in the facet, and a wrapper that added its own would be a
|
|
114
|
+
* second notion of when a task changed. `tasks:read`.
|
|
115
|
+
*/
|
|
116
|
+
export declare function watchTask(host: NgisHostAPI, taskId: string, listener: (state: NgisTaskState) => void): NgisTaskWatcher;
|
|
117
|
+
/** `tasks:cancel`. Resolves; the state change arrives through the watcher. */
|
|
118
|
+
export declare function cancelTask(host: NgisHostAPI, taskId: string): Promise<void>;
|