@thatopen/services 0.19.0 → 0.20.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/dist/built-in/index.d.ts +59 -1
- package/dist/cli.js +1382 -904
- package/dist/cli.js.map +1 -1
- package/dist/core/client.d.ts +14 -0
- package/dist/core/examples/history.d.ts +4 -0
- package/dist/core/history.d.ts +204 -0
- package/dist/core/recipes.d.ts +98 -0
- package/dist/index.cjs.js +2 -2
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.es.js +1635 -1205
- package/dist/index.es.js.map +1 -1
- package/docs/ai-quickstart.md +5 -2
- package/docs/client/paths.json +4 -0
- package/package.json +1 -1
- package/src/built-in/GISManager/example.ts +29 -0
- package/src/built-in/UIManager/src/settings-panel/example.ts +4 -1
- package/src/built-in/index.ts +59 -3
- package/src/core/examples/history.ts +103 -0
package/dist/core/client.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { ProjectHistory } from './history';
|
|
2
|
+
import { Recipes } from './recipes';
|
|
1
3
|
import { ExecutionEntity, ExecutionSuscriptionReturnType } from '../types/execution';
|
|
2
4
|
import { AppVersionProps, ComponentVersionProps, ComponentItem, AppItem, Item, ItemFolder, ItemVersion, ItemWithVersions } from '../types/items';
|
|
3
5
|
import { CreateItemResponse, UpdateItemResponse } from '../types/response';
|
|
@@ -629,6 +631,18 @@ export declare class EngineServicesClient {
|
|
|
629
631
|
* @param onUpdateCallback - Callback invoked on each progress/result event.
|
|
630
632
|
*/
|
|
631
633
|
onExecutionProgress(executionId: string, onUpdateCallback: (data: ExecutionSuscriptionReturnType) => void): Promise<void>;
|
|
634
|
+
/**
|
|
635
|
+
* A project's history of connected documents (Revit models, AutoCAD
|
|
636
|
+
* drawings…): their version timelines and their change requests. See
|
|
637
|
+
* `src/core/history.ts` — this surface is the only supported way to read
|
|
638
|
+
* or write it; the storage underneath is private and will move.
|
|
639
|
+
*/
|
|
640
|
+
history(projectId: string): ProjectHistory;
|
|
641
|
+
/**
|
|
642
|
+
* The recipe registry and runner: scripts that write change requests in a
|
|
643
|
+
* native application's language. See `src/core/recipes.ts`.
|
|
644
|
+
*/
|
|
645
|
+
get recipes(): Recipes;
|
|
632
646
|
/**
|
|
633
647
|
* Creates a hidden file attached to a parent item (e.g., dependencies, assets).
|
|
634
648
|
* @param file - The file to upload.
|
|
@@ -0,0 +1,204 @@
|
|
|
1
|
+
import { EngineServicesClient } from './client';
|
|
2
|
+
|
|
3
|
+
/** One element mutation inside a version. Wire-compatible with the plugins. */
|
|
4
|
+
export interface FlowChange {
|
|
5
|
+
/** create | update | delete. */
|
|
6
|
+
type: 'create' | 'update' | 'delete' | string;
|
|
7
|
+
/** The native application's own id for the element (Revit UniqueId, AutoCAD handle). */
|
|
8
|
+
uniqueId: string;
|
|
9
|
+
}
|
|
10
|
+
/** Per-version change tallies. */
|
|
11
|
+
export interface FlowCounts {
|
|
12
|
+
added: number;
|
|
13
|
+
modified: number;
|
|
14
|
+
removed: number;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* One sync of a document. Field names are the wire format the plugins write
|
|
18
|
+
* (`revitflow_history.json`); do not rename them.
|
|
19
|
+
*/
|
|
20
|
+
export interface FlowVersion {
|
|
21
|
+
/** Identity, minted by the writer. */
|
|
22
|
+
guid: string;
|
|
23
|
+
/** The versions this one was built on; absent on a root. First entry is the continued line. */
|
|
24
|
+
parents?: string[] | null;
|
|
25
|
+
/** The CDE's storage version number, when there is one. Data, never identity. */
|
|
26
|
+
version?: number;
|
|
27
|
+
/** What the author said it was for, when they said anything. */
|
|
28
|
+
message?: string;
|
|
29
|
+
author: string;
|
|
30
|
+
/** Which application wrote it: 'revit', 'autocad', 'rhino'… */
|
|
31
|
+
source: string;
|
|
32
|
+
/** ISO UTC. */
|
|
33
|
+
timestamp: string;
|
|
34
|
+
changes: FlowChange[];
|
|
35
|
+
counts: FlowCounts;
|
|
36
|
+
/** Hidden-file id of the delta .frag; absent on the baseline and geometry-less versions. */
|
|
37
|
+
deltaId?: string;
|
|
38
|
+
/** Hidden-file id of the per-element geometry fingerprints, when the writer keeps them. */
|
|
39
|
+
geomId?: string;
|
|
40
|
+
/** Platform user id of the committer, when the writer knew it. */
|
|
41
|
+
userId?: string;
|
|
42
|
+
/** This version re-exported the whole model (the visible .frag shows it as of here). */
|
|
43
|
+
full?: boolean;
|
|
44
|
+
compact?: boolean;
|
|
45
|
+
/** Suggestions this version applied (their opIds). */
|
|
46
|
+
appliedOps?: string[];
|
|
47
|
+
/** Position in the timeline, derived from the parent graph when read. Never stored. */
|
|
48
|
+
ordinal?: number;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* A change request queued for a document. Wire-compatible with
|
|
52
|
+
* `revitflow_ops.json` (schema `revitflow/ops@1`).
|
|
53
|
+
*/
|
|
54
|
+
export interface FlowSuggestion {
|
|
55
|
+
opId: string;
|
|
56
|
+
/** Groups the suggestions one authored action produced across several docs. */
|
|
57
|
+
batchId?: string;
|
|
58
|
+
/** Hidden-file id of the payload .frag (envelope `revitflow/op@2`). */
|
|
59
|
+
fragId?: string;
|
|
60
|
+
title?: string;
|
|
61
|
+
/** add | set | remove | mixed. */
|
|
62
|
+
verb?: string;
|
|
63
|
+
author?: string;
|
|
64
|
+
userId?: string;
|
|
65
|
+
createdAt?: string;
|
|
66
|
+
/** The version this was authored against, by guid. */
|
|
67
|
+
baseCommitGuid?: string;
|
|
68
|
+
/** The storage version that version landed in, when known. Data only. */
|
|
69
|
+
baseCommit?: number;
|
|
70
|
+
/** How many elements it targets. */
|
|
71
|
+
targets?: number;
|
|
72
|
+
state?: 'pending' | 'applied' | 'discarded' | string;
|
|
73
|
+
/** The native version that materialised it, once applied (storage version number). */
|
|
74
|
+
appliedInCommit?: number | null;
|
|
75
|
+
/** Native ids it touched or created, written by the plugin when it applied. */
|
|
76
|
+
affectedIds?: string[];
|
|
77
|
+
}
|
|
78
|
+
/** A connected document, as listed from the project. */
|
|
79
|
+
export interface FlowDocInfo {
|
|
80
|
+
/** The native application that owns it: 'revit', 'autocad'… */
|
|
81
|
+
source: string;
|
|
82
|
+
/** The document's own id within that application. */
|
|
83
|
+
docId: string;
|
|
84
|
+
/** The visible model file's name, when one exists yet. */
|
|
85
|
+
modelName?: string;
|
|
86
|
+
}
|
|
87
|
+
/** What `sync` needs: the change list plus whatever the writer knows. */
|
|
88
|
+
export interface SyncInput {
|
|
89
|
+
author: string;
|
|
90
|
+
/** Which application/tool is writing: 'revit', 'rhino', 'recipe'… */
|
|
91
|
+
source: string;
|
|
92
|
+
changes: FlowChange[];
|
|
93
|
+
message?: string;
|
|
94
|
+
/** Delta geometry for this version, uploaded as a hidden file. */
|
|
95
|
+
delta?: Blob;
|
|
96
|
+
/** Re-upload of the whole model; marks the version `full`. */
|
|
97
|
+
model?: Blob;
|
|
98
|
+
/** Platform user id, when known. */
|
|
99
|
+
userId?: string;
|
|
100
|
+
/** Suggestions this version applied. */
|
|
101
|
+
appliedOps?: string[];
|
|
102
|
+
/**
|
|
103
|
+
* The head you built on. When given and the stored head differs, `sync`
|
|
104
|
+
* refuses with {@link StaleHistoryError} instead of forking silently.
|
|
105
|
+
*/
|
|
106
|
+
expectedLatestGuid?: string;
|
|
107
|
+
}
|
|
108
|
+
/** What `suggest` needs. */
|
|
109
|
+
export interface SuggestInput {
|
|
110
|
+
title: string;
|
|
111
|
+
/** add | set | remove | mixed. */
|
|
112
|
+
verb: string;
|
|
113
|
+
author: string;
|
|
114
|
+
/** The suggestion's .frag payload (envelope `revitflow/op@2`), when it has one. */
|
|
115
|
+
payload?: Blob;
|
|
116
|
+
targets?: number;
|
|
117
|
+
batchId?: string;
|
|
118
|
+
userId?: string;
|
|
119
|
+
/** The version it was authored against. */
|
|
120
|
+
baseCommitGuid?: string;
|
|
121
|
+
}
|
|
122
|
+
/** The head moved while a writer prepared its version. Re-read and retry. */
|
|
123
|
+
export declare class StaleHistoryError extends Error {
|
|
124
|
+
readonly expectedGuid: string;
|
|
125
|
+
readonly actualGuid: string | undefined;
|
|
126
|
+
constructor(expectedGuid: string, actualGuid: string | undefined);
|
|
127
|
+
}
|
|
128
|
+
/**
|
|
129
|
+
* The history of one project. Get it from {@link EngineServicesClient.history}.
|
|
130
|
+
*/
|
|
131
|
+
export declare class ProjectHistory {
|
|
132
|
+
#private;
|
|
133
|
+
private readonly client;
|
|
134
|
+
readonly projectId: string;
|
|
135
|
+
constructor(client: EngineServicesClient, projectId: string);
|
|
136
|
+
/** The project's connected documents. */
|
|
137
|
+
docs(): Promise<FlowDocInfo[]>;
|
|
138
|
+
/** One document's history. `source` and `docId` as {@link docs} lists them. */
|
|
139
|
+
doc(source: string, docId: string): FlowDoc;
|
|
140
|
+
/** @internal The `bimterop` folder id, resolved once. */
|
|
141
|
+
rootFolderId(create?: boolean): Promise<string | undefined>;
|
|
142
|
+
}
|
|
143
|
+
/**
|
|
144
|
+
* One connected document: its timeline, its model, and its suggestions.
|
|
145
|
+
*/
|
|
146
|
+
export declare class FlowDoc {
|
|
147
|
+
#private;
|
|
148
|
+
private readonly client;
|
|
149
|
+
private readonly project;
|
|
150
|
+
readonly source: string;
|
|
151
|
+
readonly docId: string;
|
|
152
|
+
constructor(client: EngineServicesClient, project: ProjectHistory, source: string, docId: string);
|
|
153
|
+
/**
|
|
154
|
+
* The document's versions, oldest first, ordered by the parent graph (not
|
|
155
|
+
* by array position, which concurrent writers do not keep meaningful).
|
|
156
|
+
* Each version gets its `ordinal` filled in.
|
|
157
|
+
*/
|
|
158
|
+
timeline(): Promise<FlowVersion[]>;
|
|
159
|
+
/** The head of the timeline, or null before the first sync. */
|
|
160
|
+
latest(): Promise<FlowVersion | null>;
|
|
161
|
+
/**
|
|
162
|
+
* A version's delta geometry as a .frag. The baseline (`full`) versions have
|
|
163
|
+
* no delta: their geometry IS the model file — use {@link model}.
|
|
164
|
+
*/
|
|
165
|
+
delta(version: FlowVersion): Promise<Blob>;
|
|
166
|
+
/** The visible model .frag as last fully exported. */
|
|
167
|
+
model(): Promise<Blob>;
|
|
168
|
+
/**
|
|
169
|
+
* Appends one version: uploads the geometry it carries, then the updated
|
|
170
|
+
* history. Give `expectedLatestGuid` whenever you built on a head you read,
|
|
171
|
+
* so a concurrent writer surfaces as {@link StaleHistoryError} instead of a
|
|
172
|
+
* silent fork.
|
|
173
|
+
*/
|
|
174
|
+
sync(input: SyncInput): Promise<FlowVersion>;
|
|
175
|
+
/** Every suggestion in the document's queue, pending or resolved. */
|
|
176
|
+
suggestions(): Promise<FlowSuggestion[]>;
|
|
177
|
+
/** The suggestions still waiting for the owner, oldest first. */
|
|
178
|
+
pendingSuggestions(): Promise<FlowSuggestion[]>;
|
|
179
|
+
/**
|
|
180
|
+
* Queues a change request for this document. The payload, when given, is
|
|
181
|
+
* uploaded as a hidden file under the suggestions index.
|
|
182
|
+
*/
|
|
183
|
+
suggest(input: SuggestInput): Promise<FlowSuggestion>;
|
|
184
|
+
/** A suggestion's .frag payload. */
|
|
185
|
+
suggestionPayload(suggestion: FlowSuggestion): Promise<Blob>;
|
|
186
|
+
/**
|
|
187
|
+
* Marks a suggestion applied (naming the version that materialised it) or
|
|
188
|
+
* discarded. The native plugins do this themselves when they apply; apps
|
|
189
|
+
* use it for `discarded`.
|
|
190
|
+
*/
|
|
191
|
+
resolveSuggestion(opId: string, outcome: {
|
|
192
|
+
state: 'applied';
|
|
193
|
+
appliedInCommit?: number;
|
|
194
|
+
affectedIds?: string[];
|
|
195
|
+
} | {
|
|
196
|
+
state: 'discarded';
|
|
197
|
+
}): Promise<FlowSuggestion>;
|
|
198
|
+
}
|
|
199
|
+
/**
|
|
200
|
+
* Orders versions by walking the parent graph from the root along first
|
|
201
|
+
* parents, breaking forks by timestamp — array position is not meaningful
|
|
202
|
+
* once more than one application writes. Fills `ordinal`.
|
|
203
|
+
*/
|
|
204
|
+
export declare function orderByGraph(versions: FlowVersion[]): FlowVersion[];
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { EngineServicesClient } from './client';
|
|
2
|
+
import { FlowDoc, FlowSuggestion } from './history';
|
|
3
|
+
|
|
4
|
+
/** What a recipe declares about itself. Shown in catalogs, checked by apps. */
|
|
5
|
+
export interface RecipeManifest {
|
|
6
|
+
/** Machine name, unique in a catalog: 'rhino-points-to-revit-columns'. */
|
|
7
|
+
name: string;
|
|
8
|
+
/** The one sentence a non-programmer reads: what it converts into what. */
|
|
9
|
+
description: string;
|
|
10
|
+
/** The native application whose language it writes: 'revit', 'autocad'… */
|
|
11
|
+
to: string;
|
|
12
|
+
/** The input kinds it understands: 'rhino-model', 'platform-elements', 'points', 'csv'… */
|
|
13
|
+
inputs: string[];
|
|
14
|
+
/** Where it runs by default. Browser unless it must run unattended. */
|
|
15
|
+
runtime?: 'browser' | 'cloud';
|
|
16
|
+
/**
|
|
17
|
+
* JSON Schema for `settings`. Apps generate the settings form from it, so
|
|
18
|
+
* anything that names an EXISTING thing (a target document, a family, a
|
|
19
|
+
* level) must be an enum the app can fill — people pick, they never type
|
|
20
|
+
* names of things that exist.
|
|
21
|
+
*/
|
|
22
|
+
settingsSchema?: Record<string, unknown>;
|
|
23
|
+
/**
|
|
24
|
+
* The self-documentation an app renders: a "reads → proposes" table whose
|
|
25
|
+
* rows are RULES (not objects), so a dry run can fill it with real tallies.
|
|
26
|
+
*/
|
|
27
|
+
rules?: {
|
|
28
|
+
reads: string;
|
|
29
|
+
proposes: string;
|
|
30
|
+
}[];
|
|
31
|
+
}
|
|
32
|
+
/** Everything a recipe's `run` gets to work with. */
|
|
33
|
+
export interface RecipeContext<Settings = Record<string, unknown>> {
|
|
34
|
+
client: EngineServicesClient;
|
|
35
|
+
projectId: string;
|
|
36
|
+
/** The document the suggestion is for. Read its timeline/model if needed. */
|
|
37
|
+
targetDoc: FlowDoc;
|
|
38
|
+
/** The declared input, already fetched by the caller (bytes, ids, rows…). */
|
|
39
|
+
input: unknown;
|
|
40
|
+
settings: Settings;
|
|
41
|
+
}
|
|
42
|
+
/** What a recipe's `run` returns: the suggestion, ready to queue. */
|
|
43
|
+
export interface RecipeResult {
|
|
44
|
+
title: string;
|
|
45
|
+
/** add | set | remove | mixed. */
|
|
46
|
+
verb: string;
|
|
47
|
+
/** The .frag payload (envelope `revitflow/op@2`), when the recipe builds one. */
|
|
48
|
+
payload?: Blob;
|
|
49
|
+
targets?: number;
|
|
50
|
+
/** Per-rule tallies matching `manifest.rules`, filled by the run. */
|
|
51
|
+
ruleTallies?: {
|
|
52
|
+
read: number;
|
|
53
|
+
proposed: number;
|
|
54
|
+
}[];
|
|
55
|
+
}
|
|
56
|
+
/** A recipe: its manifest plus the function that writes the suggestion. */
|
|
57
|
+
export interface Recipe<Settings = Record<string, unknown>> extends RecipeManifest {
|
|
58
|
+
run(context: RecipeContext<Settings>): Promise<RecipeResult>;
|
|
59
|
+
}
|
|
60
|
+
/** What {@link Recipes.run} returns: the queued suggestion plus the tallies. */
|
|
61
|
+
export interface RecipeRunOutcome {
|
|
62
|
+
suggestion: FlowSuggestion;
|
|
63
|
+
result: RecipeResult;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* The local recipe registry and runner. Reach it as `client.recipes`.
|
|
67
|
+
*/
|
|
68
|
+
export declare class Recipes {
|
|
69
|
+
#private;
|
|
70
|
+
private readonly client;
|
|
71
|
+
constructor(client: EngineServicesClient);
|
|
72
|
+
/** Registers a recipe. One per name; a second with the same name throws. */
|
|
73
|
+
register<S>(recipe: Recipe<S>): void;
|
|
74
|
+
/** The registered recipes, optionally filtered by target application. */
|
|
75
|
+
list(filter?: {
|
|
76
|
+
to?: string;
|
|
77
|
+
input?: string;
|
|
78
|
+
}): RecipeManifest[];
|
|
79
|
+
/** A registered recipe by name, or undefined. */
|
|
80
|
+
get(name: string): RecipeManifest | undefined;
|
|
81
|
+
/**
|
|
82
|
+
* Runs a recipe and queues its suggestion on the target document. Safe to
|
|
83
|
+
* call freely: nothing touches the native application until its owner
|
|
84
|
+
* accepts the suggestion there.
|
|
85
|
+
*/
|
|
86
|
+
run<S>(name: string, options: {
|
|
87
|
+
projectId: string;
|
|
88
|
+
/** The target document, as `client.history(projectId).docs()` lists it. */
|
|
89
|
+
target: {
|
|
90
|
+
source: string;
|
|
91
|
+
docId: string;
|
|
92
|
+
};
|
|
93
|
+
input?: unknown;
|
|
94
|
+
settings?: S;
|
|
95
|
+
author: string;
|
|
96
|
+
userId?: string;
|
|
97
|
+
}): Promise<RecipeRunOutcome>;
|
|
98
|
+
}
|