Skip to content

Commit 8e42e13

Browse files
agviegasclaude
andcommitted
feat(core): OperationBuilder in the SDK, on optional peers
Antonio: the suggestion builder is platform business and belongs in the services API, not in the fragments toolkit. Same class the apps carried as a stopgap copy: geometry-less .frag, envelope revitflow/op@2, laid out exactly as the C# reader expects, bytes ready for suggest({ payload }). flatbuffers and @thatopen/fragments become OPTIONAL peers, dynamically imported only when build() runs and kept external in the bundle, so nothing changes for apps that never author operations. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
1 parent efdccec commit 8e42e13

6 files changed

Lines changed: 463 additions & 0 deletions

File tree

‎.changeset/operation-builder.md‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@thatopen/services': minor
3+
---
4+
5+
`OperationBuilder` joins the SDK: authors an interoperability operation — geometry-less .frag, envelope `revitflow/op@2`, laid out exactly as the C# reader expects — from plain `add`/`set`/`remove` calls, returning the deflated bytes for `suggest({ payload })` or a recipe's result. Attributes are written untranslated, in the target application's own terms and units. Its two dependencies, `flatbuffers` and `@thatopen/fragments`, are OPTIONAL peers resolved only when `build()` runs, so apps that never author operations install and pay nothing new.

‎docs/ai-quickstart.md‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -415,6 +415,14 @@ await client.recipes.run('my-recipe', { // only QUEUES a suggestion:
415415
`docs()` also answers `folderId` — the id the CDE knows that document by, the
416416
bridge between this section and 5c.
417417

418+
To AUTHOR a suggestion's payload, `OperationBuilder` (same import) writes the
419+
operation .frag: `new OperationBuilder(target).add(attrs, placement)` /
420+
`.set(id, attrs)` / `.remove(id)`, then `await builder.build(opId)` gives the
421+
bytes for `suggest({ payload })`. Attributes go in the TARGET app's own terms
422+
and units, untranslated. It needs the optional peers `flatbuffers` and
423+
`@thatopen/fragments` installed (loaded only when `build()` runs — nothing
424+
else in the package needs them).
425+
418426
This surface is the only supported way in: the storage underneath is private
419427
and will move. Never list or write the `bimterop` files directly. The full
420428
walkthrough (manifest fields, StaleHistoryError on concurrent syncs, payloads)

‎package.json‎

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,16 +82,24 @@
8282
},
8383
"peerDependencies": {
8484
"@thatopen/components": "~3.4.0",
85+
"@thatopen/fragments": "~3.4.0",
8586
"@thatopen/ui": "~3.4.0",
87+
"flatbuffers": ">=23.0.0",
8688
"three": ">=0.182.0"
8789
},
8890
"peerDependenciesMeta": {
8991
"@thatopen/components": {
9092
"optional": true
9193
},
94+
"@thatopen/fragments": {
95+
"optional": true
96+
},
9297
"@thatopen/ui": {
9398
"optional": true
9499
},
100+
"flatbuffers": {
101+
"optional": true
102+
},
95103
"three": {
96104
"optional": true
97105
}

0 commit comments

Comments
 (0)