@thatopen/services 0.0.2 → 0.0.4
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/AGENTS.md +86 -76
- package/dist/cli.js +10 -1
- package/docs/access-backend-data.md +19 -19
- package/docs/app-architecture.md +94 -94
- package/docs/app-layout.md +139 -139
- package/docs/app-wiring.md +123 -123
- package/docs/bim-components/coding-conventions.md +128 -128
- package/docs/bim-components/element-collections.md +69 -69
- package/docs/bim-components/expose-events.md +84 -84
- package/docs/bim-components/library-examples.md +28 -28
- package/docs/bim-components/observable-collections.md +83 -83
- package/docs/bim-components/overview.md +160 -160
- package/docs/bim-components/per-frame-updates.md +20 -20
- package/docs/bim-components/save-and-restore-state.md +21 -21
- package/docs/bim-components/setup-and-cleanup.md +64 -64
- package/docs/bim-components/type-conventions.md +49 -49
- package/docs/bim-components/user-driven-object-creation.md +56 -56
- package/docs/cli-setup.md +54 -54
- package/docs/cloud-components.md +74 -74
- package/docs/connect-logic-to-ui.md +113 -113
- package/docs/previewing.md +45 -45
- package/docs/publishing.md +35 -35
- package/docs/scaffolding.md +71 -54
- package/docs/ui-components/async-actions.md +18 -18
- package/docs/ui-components/confirmation-dialog.md +39 -39
- package/docs/ui-components/data-table.md +185 -185
- package/docs/ui-components/display-text.md +39 -39
- package/docs/ui-components/inline-form.md +44 -44
- package/docs/ui-components/library-examples.md +24 -24
- package/docs/ui-components/overview.md +194 -194
- package/docs/ui-components/rendering-patterns.md +129 -129
- package/docs/ui-components/sections-layout.md +123 -123
- package/docs/update-grid-elements.md +46 -46
- package/docs/using-colors.md +32 -32
- package/docs/using-icons.md +37 -37
- package/package.json +2 -2
- package/src/cli/templates/bim/CONTEXT.md +1 -4
- package/src/cli/templates/bim/package.json +0 -1
- package/src/cli/templates/bim/src/main.ts +1 -2
- package/src/cli/templates/bim-beta/CONTEXT.md +241 -0
- package/src/cli/templates/bim-beta/package.json +25 -0
- package/src/cli/templates/bim-beta/src/app.ts +16 -0
- package/src/cli/templates/bim-beta/src/bim-components/CloudRunner/index.ts +91 -0
- package/src/cli/templates/bim-beta/src/bim-components/CloudRunner/src/index.ts +1 -0
- package/src/cli/templates/bim-beta/src/bim-components/CloudRunner/src/types.ts +5 -0
- package/src/cli/templates/bim-beta/src/bim-components/index.ts +1 -0
- package/src/cli/templates/bim-beta/src/globals.ts +1 -0
- package/src/cli/templates/bim-beta/src/main.ts +93 -0
- package/src/cli/templates/bim-beta/src/setups/cloud-runner.ts +13 -0
- package/src/cli/templates/bim-beta/src/setups/index.ts +3 -0
- package/src/cli/templates/bim-beta/src/setups/ui-manager.ts +27 -0
- package/src/cli/templates/bim-beta/src/setups/viewports-manager.ts +22 -0
- package/src/cli/templates/bim-beta/src/ui-components/app-info-section/index.ts +26 -0
- package/src/cli/templates/bim-beta/src/ui-components/app-info-section/src/index.ts +1 -0
- package/src/cli/templates/bim-beta/src/ui-components/app-info-section/src/types.ts +15 -0
- package/src/cli/templates/bim-beta/src/ui-components/cloud-runner-section/index.ts +37 -0
- package/src/cli/templates/bim-beta/src/ui-components/cloud-runner-section/src/index.ts +1 -0
- package/src/cli/templates/bim-beta/src/ui-components/cloud-runner-section/src/types.ts +14 -0
- package/src/cli/templates/bim-beta/src/ui-components/index.ts +2 -0
- package/src/cli/templates/cloud/CONTEXT.md +205 -205
- package/src/cli/templates/cloud/src/main.ts +70 -70
- package/src/cli/templates/shared/AGENTS.md +30 -23
- package/src/cli/templates/shared/CLAUDE.md +1 -1
package/AGENTS.md
CHANGED
|
@@ -1,76 +1,86 @@
|
|
|
1
|
-
# Building on the That Open Platform — Agent Guide
|
|
2
|
-
|
|
3
|
-
You are an AI assistant helping a user build a **BIM app** or **cloud component** on the
|
|
4
|
-
That Open Platform using **`@thatopen/services`** (the `thatopen` CLI + client library).
|
|
5
|
-
|
|
6
|
-
**Read this file first.** It states the rules you must follow, then routes you to the one
|
|
7
|
-
detailed doc for whatever you're doing. Open only the doc you need — don't load everything.
|
|
8
|
-
|
|
9
|
-
> This guide is tool-agnostic: it works with any AI (Claude, Codex, your own). All docs it
|
|
10
|
-
> references ship inside the `@thatopen/services` package under `docs/`.
|
|
11
|
-
|
|
12
|
-
---
|
|
13
|
-
|
|
14
|
-
## How to work
|
|
15
|
-
|
|
16
|
-
- **
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
- **
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
|
48
|
-
|
|
49
|
-
|
|
|
50
|
-
|
|
|
51
|
-
|
|
|
52
|
-
|
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
1
|
+
# Building on the That Open Platform — Agent Guide
|
|
2
|
+
|
|
3
|
+
You are an AI assistant helping a user build a **BIM app** or **cloud component** on the
|
|
4
|
+
That Open Platform using **`@thatopen/services`** (the `thatopen` CLI + client library).
|
|
5
|
+
|
|
6
|
+
**Read this file first.** It states the rules you must follow, then routes you to the one
|
|
7
|
+
detailed doc for whatever you're doing. Open only the doc you need — don't load everything.
|
|
8
|
+
|
|
9
|
+
> This guide is tool-agnostic: it works with any AI (Claude, Codex, your own). All docs it
|
|
10
|
+
> references ship inside the `@thatopen/services` package under `docs/`.
|
|
11
|
+
|
|
12
|
+
---
|
|
13
|
+
|
|
14
|
+
## How to work
|
|
15
|
+
|
|
16
|
+
- 🚩 **BEFORE creating anything, ask the user about beta access — this is important.** Ask:
|
|
17
|
+
*"Do you have That Open beta access? It gives you the latest libraries, features and progress —
|
|
18
|
+
and it's what the platform currently runs. Do you want to use it?"* **If yes, scaffold with the
|
|
19
|
+
`bim-beta` template** (`thatopen create <name> -t bim-beta`). Founding members have **permanent** beta
|
|
20
|
+
access, so for them the answer is almost always yes. Using the matching library line avoids
|
|
21
|
+
runtime errors against the platform. (Beta packages are private — the user needs their beta
|
|
22
|
+
access token configured in npm, or `npm install` will fail.) See
|
|
23
|
+
[docs/scaffolding.md](./docs/scaffolding.md).
|
|
24
|
+
- **New app or component?** The **first step is always the CLI** (`thatopen create`) — never
|
|
25
|
+
hand-write the scaffold. See [docs/cli-setup.md](./docs/cli-setup.md) then
|
|
26
|
+
[docs/scaffolding.md](./docs/scaffolding.md).
|
|
27
|
+
- **The scaffold is already a complete, working viewer** (model loading, spatial tree, properties).
|
|
28
|
+
**Run it first** (`npm run dev`) to see it work, *then* extend it — don't rebuild a viewer from scratch.
|
|
29
|
+
- **Propose a short plan and get the user's OK** before changing files. If scope is unclear, ask.
|
|
30
|
+
- Prefer existing engine functionality over custom code (see rule 2).
|
|
31
|
+
|
|
32
|
+
## Hard rules (always apply)
|
|
33
|
+
|
|
34
|
+
1. **All business logic lives in a BIM component** (`src/bim-components/`).
|
|
35
|
+
`setups/` only wire; `ui-components/` only render; `main.ts` only boots. Logic that doesn't
|
|
36
|
+
fit an existing component → create a new one. Never put logic in a setup, template, or `main.ts`.
|
|
37
|
+
2. **Check engine components first** — `@thatopen/components` (`OBC`) and
|
|
38
|
+
`@thatopen/components-front` (`OBF`) — before building anything custom.
|
|
39
|
+
3. **Platform built-ins** (`AppManager`, `ViewportsManager`, `UIManager`, …) come from
|
|
40
|
+
`@thatopen/services` and are available after `client.setup()`. Don't reinvent them.
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
## What are you doing? → open the right doc
|
|
45
|
+
|
|
46
|
+
### Set up & ship
|
|
47
|
+
| Goal | Doc |
|
|
48
|
+
|---|---|
|
|
49
|
+
| Install the CLI + authenticate | [docs/cli-setup.md](./docs/cli-setup.md) |
|
|
50
|
+
| Scaffold a new app / component | [docs/scaffolding.md](./docs/scaffolding.md) |
|
|
51
|
+
| Preview the app inside the platform | [docs/previewing.md](./docs/previewing.md) |
|
|
52
|
+
| Publish an app or component | [docs/publishing.md](./docs/publishing.md) |
|
|
53
|
+
|
|
54
|
+
### Structure & wire an app
|
|
55
|
+
| Goal | Doc |
|
|
56
|
+
|---|---|
|
|
57
|
+
| Project structure, architecture rules, component tiers | [docs/app-architecture.md](./docs/app-architecture.md) |
|
|
58
|
+
| Boot / `app.ts` / `main.ts` / `client.setup()` | [docs/app-wiring.md](./docs/app-wiring.md) |
|
|
59
|
+
| Configure layout, add/reorganize grid sections | [docs/app-layout.md](./docs/app-layout.md) |
|
|
60
|
+
| Connect component logic to the UI | [docs/connect-logic-to-ui.md](./docs/connect-logic-to-ui.md) |
|
|
61
|
+
| Update a grid element's state at runtime | [docs/update-grid-elements.md](./docs/update-grid-elements.md) |
|
|
62
|
+
| Access the backend client / project data | [docs/access-backend-data.md](./docs/access-backend-data.md) |
|
|
63
|
+
| Register and use icons | [docs/using-icons.md](./docs/using-icons.md) |
|
|
64
|
+
| Declare and use colors | [docs/using-colors.md](./docs/using-colors.md) |
|
|
65
|
+
|
|
66
|
+
### Build a custom BIM component
|
|
67
|
+
Start at [docs/bim-components/overview.md](./docs/bim-components/overview.md) — conventions,
|
|
68
|
+
lifecycle (setup/cleanup), exposing events, observable/element collections, per-frame updates,
|
|
69
|
+
saving/restoring state, user-driven object creation.
|
|
70
|
+
|
|
71
|
+
### Build a UI component
|
|
72
|
+
Start at [docs/ui-components/overview.md](./docs/ui-components/overview.md) — rendering patterns,
|
|
73
|
+
section layout, data tables, inline forms, confirmation dialogs, display text, async actions.
|
|
74
|
+
|
|
75
|
+
### Cloud components & automations
|
|
76
|
+
[docs/cloud-components.md](./docs/cloud-components.md) — build / run locally / publish a cloud
|
|
77
|
+
component, the execution globals, and event-triggered automations.
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## Reference (also shipped in this package)
|
|
82
|
+
|
|
83
|
+
- **Library API** — `PlatformClient` vs `EngineServicesClient`, the permissions contract, and the
|
|
84
|
+
full method surface → [CONTEXT.md](./CONTEXT.md)
|
|
85
|
+
- **Built-in components API** — config interfaces, method signatures, `@example` blocks →
|
|
86
|
+
`src/built-in/index.ts` (in the installed package, `node_modules/@thatopen/services/`)
|
package/dist/cli.js
CHANGED
|
@@ -7980,7 +7980,7 @@ const loginCommand = new Command2("login").description("Authenticate with the Th
|
|
|
7980
7980
|
);
|
|
7981
7981
|
}
|
|
7982
7982
|
});
|
|
7983
|
-
const TEMPLATES = ["default", "bim", "cloud", "test", "cloud-test"];
|
|
7983
|
+
const TEMPLATES = ["default", "bim", "bim-beta", "cloud", "test", "cloud-test"];
|
|
7984
7984
|
const libVersion = (() => {
|
|
7985
7985
|
try {
|
|
7986
7986
|
const pkg2 = JSON.parse(require$$3.readFileSync(require$$2.join(__dirname, "..", "package.json"), "utf-8"));
|
|
@@ -8028,12 +8028,21 @@ const createCommand = new Command2("create").argument("<project-name>", 'Name of
|
|
|
8028
8028
|
const pkgPath = require$$2.join(targetDir, "package.json");
|
|
8029
8029
|
const pkg2 = require$$3.readFileSync(pkgPath, "utf-8").replace(/\{\{PROJECT_NAME\}\}/g, packageName).replace(/\{\{VERSION\}\}/g, libVersion).replace(/"@thatopen\/services": "file:[^"]*"/, `"@thatopen/services": "^${libVersion}"`);
|
|
8030
8030
|
require$$3.writeFileSync(pkgPath, pkg2);
|
|
8031
|
+
const isBeta = template === "bim-beta";
|
|
8032
|
+
if (isBeta) {
|
|
8033
|
+
console.log("");
|
|
8034
|
+
console.log("This template uses the private BETA engine libraries (@thatopen-platform/*-beta).");
|
|
8035
|
+
console.log("If install fails with a 401/403, configure your beta access token in npm first.");
|
|
8036
|
+
}
|
|
8031
8037
|
console.log("");
|
|
8032
8038
|
console.log("Installing dependencies...");
|
|
8033
8039
|
try {
|
|
8034
8040
|
require$$1.execSync("npm install", { cwd: targetDir, stdio: "inherit" });
|
|
8035
8041
|
} catch {
|
|
8036
8042
|
console.error("Failed to install dependencies. Run `npm install` manually.");
|
|
8043
|
+
if (isBeta) {
|
|
8044
|
+
console.error("Beta packages are private — if this is an auth error, your beta token may not be configured.");
|
|
8045
|
+
}
|
|
8037
8046
|
}
|
|
8038
8047
|
console.log("");
|
|
8039
8048
|
console.log(useCurrentDir ? " Project ready!" : ` Created ./${projectName}`);
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
# Access Backend Data
|
|
2
|
-
|
|
3
|
-
## Accessing backend data via `AppManager`
|
|
4
|
-
|
|
5
|
-
After `init()`, `AppManager` exposes:
|
|
6
|
-
|
|
7
|
-
- **`app.client`** — `EngineServicesClient`: backend client for API calls
|
|
8
|
-
- **`app.projectData`** — `ProjectData`: current user info, role, project metadata
|
|
9
|
-
|
|
10
|
-
Both are resolved before any setup runs. Always access them through `getAppManager(components)`:
|
|
11
|
-
|
|
12
|
-
```ts
|
|
13
|
-
const app = getAppManager(components)
|
|
14
|
-
if (app.projectData.currentUser?.role.name === "Project Admin") {
|
|
15
|
-
// render admin-only controls
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
const files = await app.client.getProjectFiles(app.projectData.id)
|
|
19
|
-
```
|
|
1
|
+
# Access Backend Data
|
|
2
|
+
|
|
3
|
+
## Accessing backend data via `AppManager`
|
|
4
|
+
|
|
5
|
+
After `init()`, `AppManager` exposes:
|
|
6
|
+
|
|
7
|
+
- **`app.client`** — `EngineServicesClient`: backend client for API calls
|
|
8
|
+
- **`app.projectData`** — `ProjectData`: current user info, role, project metadata
|
|
9
|
+
|
|
10
|
+
Both are resolved before any setup runs. Always access them through `getAppManager(components)`:
|
|
11
|
+
|
|
12
|
+
```ts
|
|
13
|
+
const app = getAppManager(components)
|
|
14
|
+
if (app.projectData.currentUser?.role.name === "Project Admin") {
|
|
15
|
+
// render admin-only controls
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const files = await app.client.getProjectFiles(app.projectData.id)
|
|
19
|
+
```
|
package/docs/app-architecture.md
CHANGED
|
@@ -1,94 +1,94 @@
|
|
|
1
|
-
# App Architecture and Composition
|
|
2
|
-
|
|
3
|
-
## Architecture rule: logic lives only in BIM components
|
|
4
|
-
|
|
5
|
-
**All business logic in a platform app must live inside a BIM component** (`src/bim-components/`). This is not a convention — it is the architectural constraint of the platform.
|
|
6
|
-
|
|
7
|
-
| Layer | What belongs here | What does NOT belong here |
|
|
8
|
-
|---|---|---|
|
|
9
|
-
| `bim-components/` | State, events, async operations, data access, coordination logic | — |
|
|
10
|
-
| `setups/` | Event subscriptions, calling component methods, UI sync | Business logic, data processing, state |
|
|
11
|
-
| `ui-components/` | Rendering, layout, reading component state | Logic, API calls, mutations |
|
|
12
|
-
| `main.ts` | Boot sequence only | Any logic whatsoever |
|
|
13
|
-
|
|
14
|
-
If logic doesn't fit inside an existing BIM component, the answer is always to create a new one or extend an existing one — never to write it in a setup file, a template, or `main.ts`.
|
|
15
|
-
|
|
16
|
-
```ts
|
|
17
|
-
// ✗ Forbidden — logic in a setup file
|
|
18
|
-
export const mySetup = (components: OBC.Components) => {
|
|
19
|
-
const fragments = components.get(OBC.FragmentsManager)
|
|
20
|
-
fragments.list.onItemSet.add(async (model) => {
|
|
21
|
-
const data = await fetchSomething(model.uuid) // ← logic here is wrong
|
|
22
|
-
processData(data)
|
|
23
|
-
})
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
// ✓ Correct — setup only wires; logic lives in the component
|
|
27
|
-
export const mySetup = (components: OBC.Components) => {
|
|
28
|
-
const uis = getUIManager(components)
|
|
29
|
-
const manager = components.get(MyManager)
|
|
30
|
-
manager.onDataReady.add(() => uis.custom.get("myPanel").updateInstances())
|
|
31
|
-
}
|
|
32
|
-
```
|
|
33
|
-
|
|
34
|
-
---
|
|
35
|
-
|
|
36
|
-
## Component tiers in a platform app
|
|
37
|
-
|
|
38
|
-
Every platform app works with three tiers of components, all accessible via `components.get()`:
|
|
39
|
-
|
|
40
|
-
- **Engine components** — public, from `@thatopen/components` (OBC) and `@thatopen/components-front` (OBF). Always check these first before building custom logic.
|
|
41
|
-
- **Platform built-in components** — private components from `@thatopen/services` (e.g. `AppManager`, `UIManager`, `ViewportsManager`). Available after `client.setup()`, already wired up.
|
|
42
|
-
- **Custom components** — see the BIM-component and UI-component guides in `docs/`. Live in `src/bim-components/`, self-register in their constructor via `components.add()`.
|
|
43
|
-
|
|
44
|
-
---
|
|
45
|
-
|
|
46
|
-
## Project Structure
|
|
47
|
-
|
|
48
|
-
Every app has this shape under `src/`. To configure the app layout or add and reorganize sections in the grid, see [./app-layout.md](./app-layout.md).
|
|
49
|
-
|
|
50
|
-
```
|
|
51
|
-
src/
|
|
52
|
-
├── bim-components/ → custom OBC domain components
|
|
53
|
-
├── ui-components/ → BUI templates, barrel only
|
|
54
|
-
├── setups/ → initialization and wiring
|
|
55
|
-
├── app.ts → typed app identity
|
|
56
|
-
├── globals.ts → global constants (icons, tooltips, colors, etc.)
|
|
57
|
-
└── main.ts → entry point
|
|
58
|
-
```
|
|
59
|
-
|
|
60
|
-
### `bim-components/`
|
|
61
|
-
|
|
62
|
-
Each custom OBC component lives in its own folder, built following the BIM-component guide in `docs/` (see [./bim-components/overview.md](./bim-components/overview.md)). The `index.ts` barrel re-exports every component class, its types, and its static `uuid` — this is the single import point for all custom domain logic throughout the app.
|
|
63
|
-
|
|
64
|
-
### `ui-components/`
|
|
65
|
-
|
|
66
|
-
Templates created following the UI-component guide in `docs/` (see [./ui-components/overview.md](./ui-components/overview.md)) are re-exported from the barrel. The `index.ts` is a **pure barrel** — only re-exports, nothing else. Registration of templates in the UIManager happens in `setups/ui-manager.ts`.
|
|
67
|
-
|
|
68
|
-
### `setups/`
|
|
69
|
-
|
|
70
|
-
One file per component being initialized. `ui-manager.ts` is always present as fixed boilerplate; all other files are custom wiring. See [./connect-logic-to-ui.md](./connect-logic-to-ui.md) for the full implementation reference. To update the state of a grid element at runtime from a setup or event handler, see [./update-grid-elements.md](./update-grid-elements.md).
|
|
71
|
-
|
|
72
|
-
### `app.ts` and `main.ts`
|
|
73
|
-
|
|
74
|
-
`app.ts` defines the app's typed shape and the `getAppManager` accessor. `main.ts` boots the platform — no business logic belongs here. See [./app-wiring.md](./app-wiring.md) for structure, `client.setup()`, and `componentSetups`. To access the backend client or project data (`app.client`, `app.projectData`), see [./access-backend-data.md](./access-backend-data.md).
|
|
75
|
-
|
|
76
|
-
### `globals.ts`
|
|
77
|
-
|
|
78
|
-
Contains the icon registry, color registry, and any other global constants. All icons must be declared here and accessed through `AppManager`. Colors are declared here and imported directly where needed. See [./using-icons.md](./using-icons.md) and [./using-colors.md](./using-colors.md) for details.
|
|
79
|
-
|
|
80
|
-
---
|
|
81
|
-
|
|
82
|
-
## See also
|
|
83
|
-
|
|
84
|
-
- [Connect logic to the UI](./connect-logic-to-ui.md) — register templates, sync views, etc.
|
|
85
|
-
- [Configure the app layout](./app-layout.md) — add or reorganize sections in the grid.
|
|
86
|
-
- [App wiring](./app-wiring.md) — boot the app, configure `app.ts`, `main.ts`, `client.setup()`, `componentSetups`.
|
|
87
|
-
- [Access backend data](./access-backend-data.md) — the backend client and project data (`app.client`, `app.projectData`).
|
|
88
|
-
- [Using icons](./using-icons.md) — register or use icons in the app.
|
|
89
|
-
- [Using colors](./using-colors.md) — declare or use global colors (highlighter, palette, etc.).
|
|
90
|
-
- [Update grid elements](./update-grid-elements.md) — update the state of a grid element at runtime.
|
|
91
|
-
- [Scaffolding a new app](./scaffolding.md) — scaffold a new app from scratch using the CLI.
|
|
92
|
-
- [Publishing an app](./publishing.md) — publish an app to the platform (login + publish).
|
|
93
|
-
- [CLI setup](./cli-setup.md) — install the CLI and authenticate with a platform token.
|
|
94
|
-
- [Previewing apps](./previewing.md) — preview the app during development inside the platform.
|
|
1
|
+
# App Architecture and Composition
|
|
2
|
+
|
|
3
|
+
## Architecture rule: logic lives only in BIM components
|
|
4
|
+
|
|
5
|
+
**All business logic in a platform app must live inside a BIM component** (`src/bim-components/`). This is not a convention — it is the architectural constraint of the platform.
|
|
6
|
+
|
|
7
|
+
| Layer | What belongs here | What does NOT belong here |
|
|
8
|
+
|---|---|---|
|
|
9
|
+
| `bim-components/` | State, events, async operations, data access, coordination logic | — |
|
|
10
|
+
| `setups/` | Event subscriptions, calling component methods, UI sync | Business logic, data processing, state |
|
|
11
|
+
| `ui-components/` | Rendering, layout, reading component state | Logic, API calls, mutations |
|
|
12
|
+
| `main.ts` | Boot sequence only | Any logic whatsoever |
|
|
13
|
+
|
|
14
|
+
If logic doesn't fit inside an existing BIM component, the answer is always to create a new one or extend an existing one — never to write it in a setup file, a template, or `main.ts`.
|
|
15
|
+
|
|
16
|
+
```ts
|
|
17
|
+
// ✗ Forbidden — logic in a setup file
|
|
18
|
+
export const mySetup = (components: OBC.Components) => {
|
|
19
|
+
const fragments = components.get(OBC.FragmentsManager)
|
|
20
|
+
fragments.list.onItemSet.add(async (model) => {
|
|
21
|
+
const data = await fetchSomething(model.uuid) // ← logic here is wrong
|
|
22
|
+
processData(data)
|
|
23
|
+
})
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
// ✓ Correct — setup only wires; logic lives in the component
|
|
27
|
+
export const mySetup = (components: OBC.Components) => {
|
|
28
|
+
const uis = getUIManager(components)
|
|
29
|
+
const manager = components.get(MyManager)
|
|
30
|
+
manager.onDataReady.add(() => uis.custom.get("myPanel").updateInstances())
|
|
31
|
+
}
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Component tiers in a platform app
|
|
37
|
+
|
|
38
|
+
Every platform app works with three tiers of components, all accessible via `components.get()`:
|
|
39
|
+
|
|
40
|
+
- **Engine components** — public, from `@thatopen/components` (OBC) and `@thatopen/components-front` (OBF). Always check these first before building custom logic.
|
|
41
|
+
- **Platform built-in components** — private components from `@thatopen/services` (e.g. `AppManager`, `UIManager`, `ViewportsManager`). Available after `client.setup()`, already wired up.
|
|
42
|
+
- **Custom components** — see the BIM-component and UI-component guides in `docs/`. Live in `src/bim-components/`, self-register in their constructor via `components.add()`.
|
|
43
|
+
|
|
44
|
+
---
|
|
45
|
+
|
|
46
|
+
## Project Structure
|
|
47
|
+
|
|
48
|
+
Every app has this shape under `src/`. To configure the app layout or add and reorganize sections in the grid, see [./app-layout.md](./app-layout.md).
|
|
49
|
+
|
|
50
|
+
```
|
|
51
|
+
src/
|
|
52
|
+
├── bim-components/ → custom OBC domain components
|
|
53
|
+
├── ui-components/ → BUI templates, barrel only
|
|
54
|
+
├── setups/ → initialization and wiring
|
|
55
|
+
├── app.ts → typed app identity
|
|
56
|
+
├── globals.ts → global constants (icons, tooltips, colors, etc.)
|
|
57
|
+
└── main.ts → entry point
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### `bim-components/`
|
|
61
|
+
|
|
62
|
+
Each custom OBC component lives in its own folder, built following the BIM-component guide in `docs/` (see [./bim-components/overview.md](./bim-components/overview.md)). The `index.ts` barrel re-exports every component class, its types, and its static `uuid` — this is the single import point for all custom domain logic throughout the app.
|
|
63
|
+
|
|
64
|
+
### `ui-components/`
|
|
65
|
+
|
|
66
|
+
Templates created following the UI-component guide in `docs/` (see [./ui-components/overview.md](./ui-components/overview.md)) are re-exported from the barrel. The `index.ts` is a **pure barrel** — only re-exports, nothing else. Registration of templates in the UIManager happens in `setups/ui-manager.ts`.
|
|
67
|
+
|
|
68
|
+
### `setups/`
|
|
69
|
+
|
|
70
|
+
One file per component being initialized. `ui-manager.ts` is always present as fixed boilerplate; all other files are custom wiring. See [./connect-logic-to-ui.md](./connect-logic-to-ui.md) for the full implementation reference. To update the state of a grid element at runtime from a setup or event handler, see [./update-grid-elements.md](./update-grid-elements.md).
|
|
71
|
+
|
|
72
|
+
### `app.ts` and `main.ts`
|
|
73
|
+
|
|
74
|
+
`app.ts` defines the app's typed shape and the `getAppManager` accessor. `main.ts` boots the platform — no business logic belongs here. See [./app-wiring.md](./app-wiring.md) for structure, `client.setup()`, and `componentSetups`. To access the backend client or project data (`app.client`, `app.projectData`), see [./access-backend-data.md](./access-backend-data.md).
|
|
75
|
+
|
|
76
|
+
### `globals.ts`
|
|
77
|
+
|
|
78
|
+
Contains the icon registry, color registry, and any other global constants. All icons must be declared here and accessed through `AppManager`. Colors are declared here and imported directly where needed. See [./using-icons.md](./using-icons.md) and [./using-colors.md](./using-colors.md) for details.
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## See also
|
|
83
|
+
|
|
84
|
+
- [Connect logic to the UI](./connect-logic-to-ui.md) — register templates, sync views, etc.
|
|
85
|
+
- [Configure the app layout](./app-layout.md) — add or reorganize sections in the grid.
|
|
86
|
+
- [App wiring](./app-wiring.md) — boot the app, configure `app.ts`, `main.ts`, `client.setup()`, `componentSetups`.
|
|
87
|
+
- [Access backend data](./access-backend-data.md) — the backend client and project data (`app.client`, `app.projectData`).
|
|
88
|
+
- [Using icons](./using-icons.md) — register or use icons in the app.
|
|
89
|
+
- [Using colors](./using-colors.md) — declare or use global colors (highlighter, palette, etc.).
|
|
90
|
+
- [Update grid elements](./update-grid-elements.md) — update the state of a grid element at runtime.
|
|
91
|
+
- [Scaffolding a new app](./scaffolding.md) — scaffold a new app from scratch using the CLI.
|
|
92
|
+
- [Publishing an app](./publishing.md) — publish an app to the platform (login + publish).
|
|
93
|
+
- [CLI setup](./cli-setup.md) — install the CLI and authenticate with a platform token.
|
|
94
|
+
- [Previewing apps](./previewing.md) — preview the app during development inside the platform.
|