@thatopen/services 0.3.3 → 0.3.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.
@@ -1,7 +1,7 @@
1
- # That Open Platform — AI Quick Start (zero to a running app)
1
+ # That Open Platform — AI Quick Start (zero to a running app or cloud component)
2
2
 
3
- You are an AI assistant. A user pointed you at this URL so you can scaffold and run a
4
- **BIM app** on the [That Open Platform](https://platform.thatopen.com) from scratch, using
3
+ You are an AI assistant. A user pointed you at this URL so you can scaffold and run something
4
+ on the [That Open Platform](https://platform.thatopen.com) from scratch, using
5
5
  `@thatopen/services` (the `thatopen` CLI + client library). Follow the steps below in order.
6
6
 
7
7
  > The only secret you need is a **platform API token** — **not** an npm token. The CLI
@@ -9,6 +9,22 @@ You are an AI assistant. A user pointed you at this URL so you can scaffold and
9
9
 
10
10
  ---
11
11
 
12
+ ## First — what are you building? (ask if the user hasn't said)
13
+
14
+ There are two kinds of project. **If the user hasn't told you which they want, ASK them
15
+ before scaffolding** — explain it in plain terms and let them pick:
16
+
17
+ - **App** — something people *open and click around in*, running in the platform's browser
18
+ UI: a 3D BIM viewer, a dashboard, a form, a custom tool. Choose this when the goal is a
19
+ visual interface. Template: `app`.
20
+ - **Cloud component** — *server-side logic* with no UI of its own, running in the platform's
21
+ cloud and triggered by an app or an automation to do work on the project's data — e.g.
22
+ convert a file (IFC→fragments, point cloud→tiles), generate a report, run a calculation.
23
+ Choose this when the goal is processing/automation, not a screen. Template: `cloud-component`.
24
+
25
+ Steps 0–2 are identical for both; they diverge only at `create` (step 3) and how you run them
26
+ (step 4). This guide marks **[app]** / **[component]** where they differ.
27
+
12
28
  ## 0. Prerequisites (check, don't assume)
13
29
 
14
30
  - **Node.js ≥ 18** and **npm** — verify with `node -v`.
@@ -36,39 +52,57 @@ first: the next step's install pulls the private `@thatopen-platform/*-beta` pac
36
52
  `create` uses your logged-in token to write an authenticated `.npmrc` so that install can
37
53
  resolve them. No npm account or manual npm token is involved.
38
54
 
39
- ## 3. Scaffold a beta app
55
+ ## 3. Scaffold a beta project
40
56
 
57
+ **[app]**
41
58
  ```bash
42
59
  thatopen create my-app --beta
43
60
  cd my-app
44
61
  ```
45
62
 
46
- `--beta` is required for now: the bundled viewer uses engine APIs that currently live only
47
- in the beta libraries (public engine support lands with the October release). `create`
48
- configures private beta access from your platform token and runs `npm install` for you.
63
+ **[component]**
64
+ ```bash
65
+ thatopen create my-component -t cloud-component --beta
66
+ cd my-component
67
+ ```
68
+
69
+ `--beta` is required for now (the templates use engine APIs that currently live only in the
70
+ beta libraries; public support lands with the October release). `create` configures private
71
+ beta access from your platform token and runs `npm install` for you. The **app** scaffold is
72
+ a complete working viewer; the **cloud-component** scaffold is a `main()` entry point plus a
73
+ `declarations.json` (the parameters the component accepts) — read its `README.md`, which
74
+ explains the exactly-four globals the cloud engine injects (do NOT import them) and how to
75
+ read/write the project's data.
49
76
 
50
77
  ## 4. Run it
51
78
 
79
+ **[app]**
52
80
  ```bash
53
81
  npm run dev
54
82
  ```
83
+ Serves the app and opens it inside the platform. **You now have a complete, working viewer** —
84
+ model loading, spatial tree, properties, measurement, sectioning, and more.
55
85
 
56
- This serves the app and opens it inside the platform. **You now have a complete, working
57
- viewer** — model loading, spatial tree, properties, measurement, sectioning, and more.
86
+ **[component]**
87
+ ```bash
88
+ npm run run # executes the component locally against the platform (no browser)
89
+ ```
90
+ Runs `main()` in a local emulation of the cloud engine so you can iterate before publishing.
58
91
 
59
92
  ## 5. Then build — read the in-project agent guide
60
93
 
61
- The scaffold is a real app, not a blank page. **Before changing anything**, open and follow:
94
+ The scaffold is real, working code — a complete viewer **[app]** or a runnable `main()`
95
+ **[component]** — not a blank page. **Before changing anything**, open and follow:
62
96
 
63
97
  ```
64
98
  node_modules/@thatopen/services/resources/AGENTS.md
65
99
  ```
66
100
 
67
- (The scaffolded project's own `AGENTS.md` points here too.) It is the canonical guide: it
68
- indexes every platform built-in, the client API, the CLI, and the engine / UI example sets.
69
- Load those indexes before writing code. **All UI must be built with Lit + `@thatopen/ui`
70
- (`BUI`)** — consult the design system before writing any UI. Run the app first, then extend
71
- it; don't rebuild a viewer from scratch.
101
+ (The scaffolded project's own `AGENTS.md` points here too.) It is the canonical guide for
102
+ **both** project types: it indexes every platform built-in, the client API, the CLI, and the
103
+ engine / UI example sets. Load those indexes before writing code. For an **app**, **all UI
104
+ must be built with Lit + `@thatopen/ui` (`BUI`)** — consult the design system first. Run the
105
+ scaffold first, then extend it; don't rebuild from scratch.
72
106
 
73
107
  ## 6. Publish (when ready)
74
108
 
@@ -76,7 +110,9 @@ it; don't rebuild a viewer from scratch.
76
110
  npm run publish
77
111
  ```
78
112
 
79
- Builds the app, zips it (`dist/bundle.zip`), and uploads a new version to the platform.
113
+ Builds, zips (`dist/bundle.zip`), and uploads a new version to the platform — for an **app**
114
+ or a **component** (a component also ships its `declarations.json`). Re-run it any time to
115
+ push a new version.
80
116
 
81
117
  ---
82
118
 
package/package.json CHANGED
@@ -15,7 +15,7 @@
15
15
  "access": "public"
16
16
  },
17
17
  "private": false,
18
- "version": "0.3.3",
18
+ "version": "0.3.4",
19
19
  "main": "dist/index.cjs.js",
20
20
  "module": "dist/index.es.js",
21
21
  "types": "dist/index.d.ts",
@@ -45,6 +45,14 @@ async function main() {
45
45
  // visibility/inspect toolbar (see below), so the platform default would just
46
46
  // duplicate it.
47
47
  const viewerEl = document.createElement("top-viewer");
48
+ // Frame the viewport to match the side panels (BUI bim-panel host = 1px border
49
+ // + 0.75rem radius). top-viewer's host is already overflow:hidden, so the
50
+ // radius clips the canvas corners; border-box keeps the 1px inside the grid
51
+ // area. Done here (not in top-viewer) so the CDE's top-file-viewer, which draws
52
+ // its own frame, never double-borders.
53
+ viewerEl.style.border = "1px solid var(--bim-ui_bg-contrast-20)";
54
+ viewerEl.style.borderRadius = "0.75rem";
55
+ viewerEl.style.boxSizing = "border-box";
48
56
 
49
57
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
58
  const app = document.createElement("top-app") as any;
@@ -169,8 +177,8 @@ async function main() {
169
177
  // Navigation gizmo is now baked into <top-viewer> (setupViewerTools), so the
170
178
  // app no longer mounts it. (Cascade: the rest of the overlay tools follow.)
171
179
 
172
- // Auto-load one model (top-viewer's world wires fragments→scene itself).
173
- void autoLoadFirstModel(components, client);
180
+ // No auto-load: the viewer opens empty. Users add models from the Assets
181
+ // (files) panel — top-models-list loads the .frag they pick into the world.
174
182
  }
175
183
 
176
184
  /** Resolves with the first world once it exists (top-viewer creates it async). */
@@ -188,36 +196,4 @@ function firstWorld(worlds: any): Promise<any> {
188
196
  });
189
197
  }
190
198
 
191
-
192
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
193
- async function autoLoadFirstModel(components: OBC.Components, client: any) {
194
- const fragments = components.get(OBC.FragmentsManager);
195
- const projectId: string | undefined = client?.context?.projectId;
196
- if (!projectId) {
197
- console.warn("[a2] no projectId — skipping auto-load");
198
- return;
199
- }
200
- try {
201
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
202
- const items = (await client.listFiles({ projectId })) as any[];
203
- const frags = items.filter((it) =>
204
- (it.name ?? "").toLowerCase().endsWith(".frag"),
205
- );
206
- const frag =
207
- frags.find((it) => (it.name ?? "").toLowerCase().includes("bloxhub")) ??
208
- frags[0];
209
- if (!frag) {
210
- console.warn("[a2] no .frag in project to auto-load");
211
- return;
212
- }
213
- const resp = await client.downloadFile(String(frag._id));
214
- const buffer = await resp.arrayBuffer();
215
- await fragments.core.load(buffer, { modelId: String(frag._id) });
216
- await fragments.core.update(true);
217
- console.log("[a2] auto-loaded model:", frag.name);
218
- } catch (error) {
219
- console.warn("[a2] auto-load failed", error);
220
- }
221
- }
222
-
223
199
  main().catch(console.error);