@thatopen/services 0.0.4 → 0.0.5

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.
Files changed (140) hide show
  1. package/README.md +24 -263
  2. package/dist/cli/commands/swap.d.ts +3 -0
  3. package/dist/cli/lib/beta.d.ts +2 -0
  4. package/dist/cli/lib/config.d.ts +2 -0
  5. package/dist/cli.js +85 -126
  6. package/dist/core/examples/apps.d.ts +1 -0
  7. package/dist/core/examples/components.d.ts +1 -0
  8. package/dist/core/examples/execution.d.ts +1 -0
  9. package/dist/core/examples/file-metadata.d.ts +1 -0
  10. package/dist/core/examples/files.d.ts +1 -0
  11. package/dist/core/examples/folders.d.ts +1 -0
  12. package/dist/core/examples/hidden-files.d.ts +1 -0
  13. package/dist/core/examples/icons.d.ts +1 -0
  14. package/dist/core/examples/permissions.d.ts +1 -0
  15. package/dist/types/items.d.ts +2 -0
  16. package/docs/builtin/paths.json +54 -0
  17. package/docs/cli/create.md +28 -0
  18. package/docs/cli/local-server.md +38 -0
  19. package/docs/cli/login.md +32 -0
  20. package/docs/cli/paths.json +30 -0
  21. package/docs/cli/publish.md +31 -0
  22. package/docs/cli/run.md +26 -0
  23. package/docs/cli/serve.md +43 -0
  24. package/docs/cli/swap.md +30 -0
  25. package/docs/client/paths.json +38 -0
  26. package/package.json +8 -10
  27. package/resources/AGENTS.md +39 -0
  28. package/src/built-in/AppManager/example.ts +86 -0
  29. package/src/built-in/CDEManager/example.ts +214 -0
  30. package/src/built-in/CDEManager/examples/FileEditing/example.ts +226 -0
  31. package/src/built-in/CDEManager/examples/FileMoves/example.ts +186 -0
  32. package/src/built-in/CDEManager/examples/FileOperations/example.ts +295 -0
  33. package/src/built-in/CDEManager/examples/FileTransfers/example.ts +210 -0
  34. package/src/built-in/CDEManager/examples/FolderManagement/example.ts +230 -0
  35. package/src/built-in/CDEManager/examples/MetadataSchema/example.ts +230 -0
  36. package/src/built-in/CDEManager/examples/MetadataViews/example.ts +166 -0
  37. package/src/built-in/CDEManager/examples/ProjectConfig/example.ts +177 -0
  38. package/src/built-in/FileList/example.ts +107 -0
  39. package/src/built-in/TabbedNavigation/example.ts +115 -0
  40. package/src/built-in/ViewportsManager/example.ts +106 -0
  41. package/src/cli/templates/{shared/app → app}/vite.config.js +42 -23
  42. package/src/cli/templates/{shared/cloud → cloud-component}/vite.config.js +46 -27
  43. package/src/cli/templates/shared/AGENTS.md +8 -30
  44. package/src/cli/templates/shared/CLAUDE.md +1 -1
  45. package/AGENTS.md +0 -86
  46. package/CONTEXT.md +0 -258
  47. package/dist/built-in/index.d.ts +0 -723
  48. package/dist/cli/commands/create-tests.d.ts +0 -3
  49. package/dist/cli/commands/serve-tests.d.ts +0 -3
  50. package/docs/access-backend-data.md +0 -19
  51. package/docs/app-architecture.md +0 -94
  52. package/docs/app-layout.md +0 -139
  53. package/docs/app-wiring.md +0 -123
  54. package/docs/bim-components/coding-conventions.md +0 -128
  55. package/docs/bim-components/element-collections.md +0 -69
  56. package/docs/bim-components/expose-events.md +0 -84
  57. package/docs/bim-components/library-examples.md +0 -28
  58. package/docs/bim-components/observable-collections.md +0 -83
  59. package/docs/bim-components/overview.md +0 -160
  60. package/docs/bim-components/per-frame-updates.md +0 -20
  61. package/docs/bim-components/save-and-restore-state.md +0 -21
  62. package/docs/bim-components/setup-and-cleanup.md +0 -64
  63. package/docs/bim-components/type-conventions.md +0 -49
  64. package/docs/bim-components/user-driven-object-creation.md +0 -56
  65. package/docs/cli-setup.md +0 -54
  66. package/docs/cloud-components.md +0 -74
  67. package/docs/connect-logic-to-ui.md +0 -113
  68. package/docs/previewing.md +0 -45
  69. package/docs/publishing.md +0 -35
  70. package/docs/scaffolding.md +0 -71
  71. package/docs/ui-components/async-actions.md +0 -18
  72. package/docs/ui-components/confirmation-dialog.md +0 -39
  73. package/docs/ui-components/data-table.md +0 -185
  74. package/docs/ui-components/display-text.md +0 -39
  75. package/docs/ui-components/inline-form.md +0 -44
  76. package/docs/ui-components/library-examples.md +0 -24
  77. package/docs/ui-components/overview.md +0 -194
  78. package/docs/ui-components/rendering-patterns.md +0 -129
  79. package/docs/ui-components/sections-layout.md +0 -123
  80. package/docs/update-grid-elements.md +0 -46
  81. package/docs/using-colors.md +0 -32
  82. package/docs/using-icons.md +0 -37
  83. package/src/cli/templates/bim/src/bim-components/CloudRunner/src/index.ts +0 -1
  84. package/src/cli/templates/bim/src/bim-components/CloudRunner/src/types.ts +0 -5
  85. package/src/cli/templates/bim/src/bim-components/index.ts +0 -1
  86. package/src/cli/templates/bim/src/globals.ts +0 -1
  87. package/src/cli/templates/bim/src/setups/index.ts +0 -3
  88. package/src/cli/templates/bim/src/ui-components/app-info-section/index.ts +0 -26
  89. package/src/cli/templates/bim/src/ui-components/app-info-section/src/index.ts +0 -1
  90. package/src/cli/templates/bim/src/ui-components/cloud-runner-section/index.ts +0 -37
  91. package/src/cli/templates/bim/src/ui-components/cloud-runner-section/src/index.ts +0 -1
  92. package/src/cli/templates/bim/src/ui-components/index.ts +0 -2
  93. package/src/cli/templates/bim-beta/CONTEXT.md +0 -241
  94. package/src/cli/templates/bim-beta/package.json +0 -25
  95. package/src/cli/templates/bim-beta/src/app.ts +0 -16
  96. package/src/cli/templates/bim-beta/src/bim-components/CloudRunner/index.ts +0 -91
  97. package/src/cli/templates/bim-beta/src/main.ts +0 -93
  98. package/src/cli/templates/bim-beta/src/setups/cloud-runner.ts +0 -13
  99. package/src/cli/templates/bim-beta/src/setups/ui-manager.ts +0 -27
  100. package/src/cli/templates/bim-beta/src/setups/viewports-manager.ts +0 -22
  101. package/src/cli/templates/bim-beta/src/ui-components/app-info-section/src/types.ts +0 -15
  102. package/src/cli/templates/bim-beta/src/ui-components/cloud-runner-section/src/types.ts +0 -14
  103. package/src/cli/templates/cloud/_thatopen +0 -5
  104. package/src/cli/templates/cloud/package.json +0 -22
  105. package/src/cli/templates/cloud-test/CONTEXT.md +0 -56
  106. package/src/cli/templates/cloud-test/src/main.ts +0 -565
  107. package/src/cli/templates/default/CONTEXT.md +0 -92
  108. package/src/cli/templates/default/package.json +0 -18
  109. package/src/cli/templates/default/src/main.ts +0 -62
  110. package/src/cli/templates/test/CONTEXT.md +0 -53
  111. package/src/cli/templates/test/package.json +0 -25
  112. package/src/cli/templates/test/src/main.ts +0 -955
  113. /package/src/cli/templates/{bim/CONTEXT.md → app/README.md} +0 -0
  114. /package/src/cli/templates/{shared/app → app}/index.html +0 -0
  115. /package/src/cli/templates/{bim → app}/package.json +0 -0
  116. /package/src/cli/templates/{bim → app}/src/app.ts +0 -0
  117. /package/src/cli/templates/{bim → app}/src/bim-components/CloudRunner/index.ts +0 -0
  118. /package/src/cli/templates/{bim-beta → app}/src/bim-components/CloudRunner/src/index.ts +0 -0
  119. /package/src/cli/templates/{bim-beta → app}/src/bim-components/CloudRunner/src/types.ts +0 -0
  120. /package/src/cli/templates/{bim-beta → app}/src/bim-components/index.ts +0 -0
  121. /package/src/cli/templates/{bim-beta → app}/src/globals.ts +0 -0
  122. /package/src/cli/templates/{bim → app}/src/main.ts +0 -0
  123. /package/src/cli/templates/{bim → app}/src/setups/cloud-runner.ts +0 -0
  124. /package/src/cli/templates/{bim-beta → app}/src/setups/index.ts +0 -0
  125. /package/src/cli/templates/{bim → app}/src/setups/ui-manager.ts +0 -0
  126. /package/src/cli/templates/{bim → app}/src/setups/viewports-manager.ts +0 -0
  127. /package/src/cli/templates/{bim-beta → app}/src/ui-components/app-info-section/index.ts +0 -0
  128. /package/src/cli/templates/{bim-beta → app}/src/ui-components/app-info-section/src/index.ts +0 -0
  129. /package/src/cli/templates/{bim → app}/src/ui-components/app-info-section/src/types.ts +0 -0
  130. /package/src/cli/templates/{bim-beta → app}/src/ui-components/cloud-runner-section/index.ts +0 -0
  131. /package/src/cli/templates/{bim-beta → app}/src/ui-components/cloud-runner-section/src/index.ts +0 -0
  132. /package/src/cli/templates/{bim → app}/src/ui-components/cloud-runner-section/src/types.ts +0 -0
  133. /package/src/cli/templates/{bim-beta → app}/src/ui-components/index.ts +0 -0
  134. /package/src/cli/templates/{shared/app → app}/tsconfig.json +0 -0
  135. /package/src/cli/templates/{cloud/CONTEXT.md → cloud-component/README.md} +0 -0
  136. /package/src/cli/templates/{cloud-test → cloud-component}/_thatopen +0 -0
  137. /package/src/cli/templates/{cloud → cloud-component}/declarations.json +0 -0
  138. /package/src/cli/templates/{cloud-test → cloud-component}/package.json +0 -0
  139. /package/src/cli/templates/{cloud → cloud-component}/src/main.ts +0 -0
  140. /package/src/cli/templates/{shared/cloud → cloud-component}/tsconfig.json +0 -0
@@ -1,241 +0,0 @@
1
- # ThatOpen BIM App
2
-
3
- This is a BIM (Building Information Modeling) app built for the That Open Platform.
4
- It runs in the browser inside the platform's iframe and has access to a 3D viewer,
5
- UI components, and the platform API.
6
-
7
- ## How this app works
8
-
9
- - **Entry point**: `src/main.ts` — runs as an IIFE when the platform loads the app.
10
- - **Build output**: `dist/bundle.js` — a single IIFE file built by Vite.
11
- - **Platform context**: The platform injects `window.__THATOPEN_CONTEXT__` with:
12
- - `appId` — this app's unique ID
13
- - `projectId` — the project this app belongs to
14
- - `accessToken` — Auth0 JWT for API calls
15
- - `apiUrl` — base URL for the That Open API
16
-
17
- ## Commands
18
-
19
- ```bash
20
- npm run dev # Start dev server (esbuild watch + serve on :4000)
21
- npm run build # Build dist/bundle.js (Vite/Rollup production build)
22
- npm run login # Authenticate with the platform (saves token locally)
23
- npm run publish # Publish to the platform
24
- ```
25
-
26
- ### Local development
27
-
28
- Apps run inside the That Open Platform (platform.thatopen.com) within a project —
29
- not as standalone websites. To develop locally:
30
-
31
- 1. Run `npm run dev` — this watches source files with esbuild and serves the bundle on port 4000.
32
- 2. Open your project on the platform and click the debug button.
33
- 3. Live reload is enabled — save a file to rebuild automatically.
34
-
35
- The dev server (`thatopen serve`) uses esbuild for near-instant incremental rebuilds.
36
- **Important**: Do NOT run `vite`, `vite build --watch`, or `npx vite` directly for development.
37
- Always use `npm run dev` which runs `thatopen serve` under the hood.
38
-
39
- ## Key libraries
40
-
41
- | Package | Import | Purpose |
42
- |---------|--------|---------|
43
- | `@thatopen-platform/components-beta` | `OBC` | BIM engine — components, fragments, worlds |
44
- | `@thatopen-platform/components-front-beta` | `OBF` | Front-end BIM components (Highlighter, measurements, etc.) |
45
- | `@thatopen-platform/fragments-beta` | `FRAGS` | Fragment geometry format |
46
- | `@thatopen/ui` | `BUI` | UI web components (`<bim-panel>`, `<bim-grid>`, etc.) |
47
- | `three` | `THREE` | 3D rendering engine |
48
- | `@thatopen/services` | `EngineServicesClient` | Platform API client + built-in components |
49
-
50
- ## Architecture pattern
51
-
52
- ```
53
- 1. Create EngineServicesClient from platform context
54
- 2. Call client.setup(globals, ...builtIns) — creates OBC.Components,
55
- inits BUI, loads built-in components, calls components.init()
56
- 3. Create viewport(s) and UI elements
57
- 4. Configure AppManager with elements + layouts
58
- 5. Call app.init()
59
- ```
60
-
61
- ## Built-in components
62
-
63
- Built-in components are platform-hosted UI modules loaded at runtime via the API client.
64
- They are fetched, evaluated, and registered with the OBC component system.
65
-
66
- | Component | Purpose |
67
- |-----------|---------|
68
- | **AppManager** | App shell — CSS grid layout system with sidebar for switching layouts |
69
- | **ViewportsManager** | Factory for 3D viewports with pre-configured world (scene, camera, renderer) |
70
- | **LoadModelButton** | Button + dropdown for loading IFC and Fragments files |
71
- | **ViewerToolbar** | Toolbar with Show/Hide/Focus/Isolate actions and color palette |
72
- | **ModelsPanel** | Panel listing loaded models with search bar and load button |
73
- | **ModelsDropdown** | Dropdown selector listing loaded models |
74
- | **ClassificationsList** | Hierarchical table of IFC classification data |
75
- | **ClashesList** | Interactive clash detection results with click-to-highlight |
76
- | **ClippingsList** | Panel listing clipping planes with enable/delete controls |
77
- | **LengthMeasuringsList** | Panel listing length measurements with cumulative total |
78
- | **AreaMeasuringsList** | Panel listing area measurements with area/perimeter totals |
79
- | **ColorsPalette** | Color picker grid with custom input and Highlighter styles |
80
- | **HighlightersList** | Panel listing Highlighter styles with manage/apply actions |
81
- | **QtoComparisonList** | Side-by-side quantity comparison for two selected elements |
82
- | **QueriesHierarchy** | Recursive multi-level query browser for IFC data |
83
- | **CustomViewLegend** | Color legend overlay with colored circles and labels |
84
- | **ScreenshotAnnotator** | Modal for annotating screenshots (arrows, text, freehand) via MarkerJS |
85
-
86
- **Full API reference**: Each component has detailed JSDoc with `@example` blocks in the
87
- `@thatopen/services` package source (`src/built-in/index.ts`). Read that file for config
88
- interfaces, method signatures, and code examples.
89
-
90
- ### Loading pattern
91
-
92
- Use `setup` to create the component system and load built-in components in one call:
93
-
94
- ```ts
95
- import { PlatformClient, AppManager, ViewportsManager } from "@thatopen/services";
96
-
97
- const client = PlatformClient.fromPlatformContext();
98
-
99
- // Creates OBC.Components, inits BUI, loads built-ins, calls components.init()
100
- const { components } = await client.setup(
101
- { OBC, OBF, BUI, THREE, FRAGS },
102
- AppManager, ViewportsManager,
103
- );
104
-
105
- const app = components.get(AppManager);
106
- const viewports = components.get(ViewportsManager);
107
- ```
108
-
109
- You can also load components individually if needed:
110
-
111
- ```ts
112
- // Batch load (parallel)
113
- await client.initBuiltInComponents(components, AppManager, ViewportsManager);
114
-
115
- // Or one at a time
116
- await client.initBuiltInComponent(AppManager, components);
117
- ```
118
-
119
- ### Required globals per component
120
-
121
- | Component | Globals to pass | Extra npm packages needed |
122
- |-----------|----------------|--------------------------|
123
- | AppManager | `{ OBC, BUI }` | — |
124
- | ViewportsManager | `{ OBC, BUI, THREE, FRAGS }` | — |
125
- | LoadModelButton | `{ OBC, BUI }` | — |
126
- | ModelsDropdown | `{ OBC, BUI }` | — |
127
- | ViewerToolbar | `{ OBC, OBF, BUI, THREE }` | `@thatopen-platform/components-front-beta` |
128
- | ColorsPalette | `{ OBC, OBF, BUI }` | `@thatopen-platform/components-front-beta` |
129
- | ClashesList | `{ OBC, OBF, BUI, THREE }` | `@thatopen-platform/components-front-beta` |
130
- | ClassificationsList | `{ OBC, OBF, BUI }` | `@thatopen-platform/components-front-beta` |
131
- | ClippingsList | `{ OBC, BUI }` | — |
132
- | HighlightersList | `{ OBC, OBF, BUI }` | `@thatopen-platform/components-front-beta` |
133
- | LengthMeasuringsList | `{ OBC, OBF, BUI, THREE }` | `@thatopen-platform/components-front-beta` |
134
- | AreaMeasuringsList | `{ OBC, OBF, BUI, THREE }` | `@thatopen-platform/components-front-beta` |
135
- | QtoComparisonList | `{ OBC, OBF, BUI }` | `@thatopen-platform/components-front-beta` |
136
- | QueriesHierarchy | `{ OBC, OBF, BUI }` | `@thatopen-platform/components-front-beta` |
137
- | CustomViewLegend | `{ OBC, BUI }` | — |
138
- | ScreenshotAnnotator | `{ OBC, BUI, MARKERJS }` | `@markerjs/markerjs3` |
139
-
140
- ### Global abbreviations
141
-
142
- ```ts
143
- import * as OBC from "@thatopen-platform/components-beta";
144
- import * as OBF from "@thatopen-platform/components-front-beta"; // needed for Toolbar, Highlighters, Clashes, etc.
145
- import * as BUI from "@thatopen/ui";
146
- import * as THREE from "three";
147
- import * as FRAGS from "@thatopen-platform/fragments-beta";
148
- import * as MARKERJS from "@markerjs/markerjs3"; // needed for ScreenshotAnnotator
149
- ```
150
-
151
- ### AppManager — app shell with CSS grid layouts
152
-
153
- Creates a grid-based layout system. Define named element slots and named layouts.
154
- A sidebar for switching layouts appears automatically when multiple layouts exist.
155
-
156
- ```ts
157
- const Layouts = ["Viewer", "Split"];
158
- const Elements = ["viewer", "panel"];
159
-
160
- await app.init({
161
- client,
162
- icons: undefined, // pass Record<K, string> when using typed App interface with icon keys
163
- grid: (grid: BUI.Grid<Layouts, Elements>) => {
164
- grid.elements = {
165
- viewer: viewportElement,
166
- panel: panelFunction, // Can be HTMLElement, () => BUI.TemplateResult, or { template, initialState }
167
- };
168
- grid.layouts = {
169
- Viewer: { template: `"viewer" 1fr / 1fr` },
170
- Split: {
171
- template: `"panel viewer" 1fr / 20rem 1fr`,
172
- icon: "solar:settings-bold",
173
- },
174
- };
175
- },
176
- });
177
- ```
178
-
179
- The `template` string uses CSS `grid-template` shorthand: `"areas" rows / columns`.
180
-
181
- ### ViewportsManager — 3D viewport factory
182
-
183
- Creates viewports with pre-configured world (scene, camera, renderer) and auto-initialized fragments.
184
-
185
- ```ts
186
- const viewports = components.get(ViewportsManager);
187
- const { element, world } = await viewports.create();
188
- // element is an HTMLElement to place in a layout slot
189
- // world has world.scene, world.camera, world.renderer
190
- ```
191
-
192
- ## Loading a BIM model
193
-
194
- ```ts
195
- const fragments = components.get(OBC.FragmentsManager);
196
-
197
- // From URL
198
- const response = await fetch("https://example.com/model.frag");
199
- const buffer = await response.arrayBuffer();
200
- await fragments.core.load(buffer, { modelId: "my-model" });
201
-
202
- // From platform storage
203
- const fileResponse = await client.downloadFile(fileId);
204
- const fileBuffer = await fileResponse.arrayBuffer();
205
- await fragments.core.load(fileBuffer, { modelId: "my-model" });
206
- ```
207
-
208
- ## EngineServicesClient API (commonly used in apps)
209
-
210
- ```ts
211
- // Recommended: auto-reads window.__THATOPEN_CONTEXT__ and sets useBearer: true
212
- const client = PlatformClient.fromPlatformContext();
213
- console.log(client.context.projectId); // access the platform context
214
-
215
- // Files
216
- const files = await client.listFiles();
217
- const file = await client.getFile(fileId);
218
- const response = await client.downloadFile(fileId);
219
- await client.createFile({ file: blob, name: "model.ifc", versionTag: "v1" });
220
-
221
- // Folders
222
- const folders = await client.listFolders();
223
- await client.createFolder("My Folder");
224
-
225
- // Execute cloud components
226
- const { executionId } = await client.executeComponent(componentId, { param: "value" });
227
- client.onExecutionProgress(executionId, (data) => {
228
- // data.progressUpdate — progress percentage
229
- // data.messageUpdate — status messages
230
- });
231
-
232
- // Test against a local cloud component (requires thatopen local-server running in the component project)
233
- client.localServerUrl = "http://localhost:4001";
234
- const local = await client.executeComponent("any-id", { param: "value" });
235
- client.localServerUrl = null; // reset to use the cloud API
236
- ```
237
-
238
- ## Configuration
239
-
240
- - `.thatopen` — local config (gitignored). Created by `npm run login`. Contains `accessToken`, `apiUrl`, and `appId` after first publish.
241
- - `vite.config.js` — builds to IIFE format as `dist/bundle.js`. All dependencies are bundled.
@@ -1,25 +0,0 @@
1
- {
2
- "name": "{{PROJECT_NAME}}",
3
- "version": "1.0.0",
4
- "private": true,
5
- "scripts": {
6
- "dev": "thatopen serve",
7
- "build": "vite build",
8
- "login": "thatopen login --local",
9
- "publish": "thatopen publish"
10
- },
11
- "dependencies": {
12
- "@markerjs/markerjs3": "^3.9.0",
13
- "@thatopen-platform/components-beta": "latest",
14
- "@thatopen-platform/components-front-beta": "latest",
15
- "@thatopen-platform/fragments-beta": "latest",
16
- "@thatopen/ui": "~3.4.0",
17
- "@thatopen/services": "file:../../../..",
18
- "three": "^0.182.0"
19
- },
20
- "devDependencies": {
21
- "@types/three": "^0.182.0",
22
- "typescript": "^5.2.0",
23
- "vite": "^5.2.0"
24
- }
25
- }
@@ -1,16 +0,0 @@
1
- import * as OBC from "@thatopen-platform/components-beta";
2
- import * as BUI from "@thatopen/ui";
3
- import { AppManager } from "@thatopen/services";
4
- import { icons } from "./globals";
5
- import { AppInfoSectionGridElement, CloudRunnerSectionGridElement } from "./ui-components";
6
-
7
- export type App = {
8
- icons: (keyof typeof icons)[];
9
- grid: BUI.Grid<
10
- ["Viewer", "Split"],
11
- ["viewer", AppInfoSectionGridElement, CloudRunnerSectionGridElement]
12
- >;
13
- };
14
-
15
- export const getAppManager = (components: OBC.Components) =>
16
- components.get(AppManager<App>);
@@ -1,91 +0,0 @@
1
- import * as OBC from "@thatopen-platform/components-beta";
2
- import { AppManager } from "@thatopen/services";
3
- import { CloudRunnerStatus } from "./src";
4
-
5
- export class CloudRunner extends OBC.Component {
6
- static readonly uuid = "7c4e5d3b-2a1f-4e8d-9b6c-0a3f7e2c5d1b" as const;
7
-
8
- enabled = true;
9
-
10
- readonly onExecutionUpdated = new OBC.Event<CloudRunnerStatus>();
11
-
12
- // TODO: Replace with your actual component ID after publishing.
13
- componentId = "your-component-id";
14
- localServerUrl = "http://localhost:4001";
15
-
16
- // Reactive state — read by the UI template on each render.
17
- status = "Idle";
18
- progress = 0;
19
- messages: string[] = [];
20
-
21
- constructor(components: OBC.Components) {
22
- super(components);
23
- components.add(CloudRunner.uuid, this);
24
- }
25
-
26
- async run(useLocal: boolean) {
27
- // Resolve client at call time via AppManager — never store it as a field.
28
- const app = this.components.get(AppManager);
29
- const client = app.client;
30
-
31
- client.localServerUrl = useLocal ? this.localServerUrl : null;
32
-
33
- this.status = useLocal ? "Starting (local)..." : "Starting (deployed)...";
34
- this.progress = 0;
35
- this.messages = [];
36
- this._trigger();
37
-
38
- try {
39
- const { executionId } = await client.executeComponent(this.componentId, {
40
- greeting: "Hello from the BIM app!",
41
- });
42
-
43
- this.status = `Running (${executionId.slice(0, 8)}...)`;
44
- this._trigger();
45
-
46
- // Subscribe to real-time progress updates via WebSocket.
47
- client.onExecutionProgress(executionId, (data) => {
48
- if (data.progressUpdate) {
49
- this.progress = data.progressUpdate.progress;
50
- if (data.progressUpdate.result) {
51
- this.status = `${data.progressUpdate.result}: ${data.progressUpdate.resultMessage ?? "Done"}`;
52
- }
53
- }
54
- if (data.messageUpdate) {
55
- this.messages.push(data.messageUpdate.content);
56
- }
57
- this._trigger();
58
- });
59
-
60
- // Poll once after a short delay to catch fast executions that complete
61
- // before the WebSocket subscription is established.
62
- setTimeout(async () => {
63
- try {
64
- const exec = await client.getExecution(executionId);
65
- if (exec.result) {
66
- this.progress = exec.progress;
67
- this.status = `${exec.result}: ${exec.resultMessage ?? "Done"}`;
68
- this._trigger();
69
- }
70
- } catch {
71
- /* WebSocket handles it */
72
- }
73
- }, 2000);
74
- } catch (err) {
75
- this.status = `Error: ${err}`;
76
- this._trigger();
77
- } finally {
78
- client.localServerUrl = null;
79
- }
80
- }
81
-
82
- private _trigger() {
83
- this.onExecutionUpdated.trigger({
84
- status: this.status,
85
- progress: this.progress,
86
- messages: [...this.messages],
87
- });
88
- }
89
- }
90
-
91
- export * from "./src";
@@ -1,93 +0,0 @@
1
- import * as THREE from "three";
2
- import * as OBC from "@thatopen-platform/components-beta";
3
- import * as OBF from "@thatopen-platform/components-front-beta";
4
- import * as FRAGS from "@thatopen-platform/fragments-beta";
5
- // Inlines the fragments worker so it runs inside the platform's sandboxed iframe
6
- // (IIFE bundle: no import.meta, no cross-origin fetch). Opt-in — only apps that
7
- // import this pay the worker's size.
8
- import "@thatopen-platform/fragments-beta/inline";
9
- import * as BUI from "@thatopen/ui";
10
- import * as MARKERJS from "@markerjs/markerjs3"
11
- import {
12
- PlatformClient,
13
- AppManager,
14
- ViewportsManager,
15
- UIManager,
16
- } from "@thatopen/services";
17
-
18
- import { getAppManager } from "./app";
19
- import { uiManager, cloudRunner, viewportsManager, getUIManager } from "./setups";
20
-
21
- // Wrap in async function since IIFE format does not support top-level await.
22
- async function main() {
23
- // ─── Platform Client ──────────────────────────────────────────
24
- // Reads auth context from window.__THATOPEN_CONTEXT__ (injected by the
25
- // platform) and creates a client with Bearer auth.
26
- const client = PlatformClient.fromPlatformContext();
27
-
28
- // ─── Built-in Components ──────────────────────────────────────
29
- // First argument: library globals used by the engine.
30
- // Subsequent arguments: platform built-in components to initialise.
31
- const { components } = await client.setup<OBC.Components>(
32
- { OBC, OBF, BUI, THREE, FRAGS, MARKERJS },
33
- { uuid: ViewportsManager.uuid },
34
- { uuid: AppManager.uuid },
35
- { uuid: UIManager.uuid },
36
- );
37
-
38
- // ─── Viewport ─────────────────────────────────────────────────
39
- // Must run before app.init() so the element is ready for the grid.
40
- const viewerElement = await viewportsManager(components);
41
-
42
- // ─── App Init ─────────────────────────────────────────────────
43
- const app = getAppManager(components);
44
-
45
- await app.init({
46
- client,
47
- icons: [],
48
- componentSetups: {
49
- // core: runs in parallel before the grid mounts.
50
- core: [uiManager, cloudRunner],
51
- },
52
- grid: (grid) => {
53
- const uis = getUIManager(components);
54
-
55
- grid.elements = {
56
- viewer: viewerElement,
57
- appInfoSection: {
58
- template: uis.custom.get("appInfoSection").template,
59
- initialState: { components },
60
- label: "App Info",
61
- icon: "solar:info-circle-bold",
62
- },
63
- cloudRunnerSection: {
64
- template: uis.custom.get("cloudRunnerSection").template,
65
- initialState: { components },
66
- label: "Cloud Component",
67
- icon: "solar:code-bold",
68
- },
69
- };
70
-
71
- grid.layouts = {
72
- Viewer: {
73
- template: `"viewer" 1fr / 1fr`,
74
- },
75
- Split: {
76
- template: `
77
- "tabs:left(appInfoSection, cloudRunnerSection) viewer" 1fr
78
- / 24rem 1fr
79
- `,
80
- icon: "solar:info-circle-bold",
81
- },
82
- };
83
-
84
- grid.areaGroups = {
85
- left: { switchersFull: true },
86
- };
87
-
88
- grid.layout = "Split";
89
- },
90
- });
91
- }
92
-
93
- main().catch(console.error);
@@ -1,13 +0,0 @@
1
- import * as OBC from "@thatopen-platform/components-beta";
2
- import { CloudRunner } from "../bim-components";
3
- import { getUIManager } from "./ui-manager";
4
-
5
- export const cloudRunner = (components: OBC.Components) => {
6
- const runner = components.get(CloudRunner);
7
- const uis = getUIManager(components);
8
-
9
- // Re-render all appInfoSection instances whenever execution state changes.
10
- runner.onExecutionUpdated.add(() => {
11
- uis.custom.get("cloudRunnerSection").updateInstances();
12
- });
13
- };
@@ -1,27 +0,0 @@
1
- import * as OBC from "@thatopen-platform/components-beta";
2
- import * as BUI from "@thatopen/ui";
3
- import { UIManager } from "@thatopen/services";
4
- import {
5
- appInfoSectionTemplate,
6
- AppInfoSectionState,
7
- cloudRunnerSectionTemplate,
8
- CloudRunnerSectionState,
9
- } from "../ui-components";
10
-
11
- export type CustomUIs = {
12
- appInfoSection: { type: BUI.PanelSection; state: AppInfoSectionState };
13
- cloudRunnerSection: { type: BUI.PanelSection; state: CloudRunnerSectionState };
14
- };
15
-
16
- export const getUIManager = (components: OBC.Components) =>
17
- components.get(UIManager<CustomUIs>);
18
-
19
- export const uiManager = (components: OBC.Components) => {
20
- const uis = getUIManager(components);
21
- uis.registerTemplate("appInfoSection", {
22
- template: appInfoSectionTemplate,
23
- });
24
- uis.registerTemplate("cloudRunnerSection", {
25
- template: cloudRunnerSectionTemplate,
26
- });
27
- };
@@ -1,22 +0,0 @@
1
- import * as OBC from "@thatopen-platform/components-beta";
2
- import { ViewportsManager } from "@thatopen/services";
3
-
4
- export const viewportsManager = async (components: OBC.Components) => {
5
- const viewports = components.get(ViewportsManager);
6
- const { element, world } = await viewports.create();
7
-
8
- // Load a sample model. Replace with client.downloadFile(fileId) to load
9
- // a model from the platform:
10
- // const response = await client.downloadFile(fileId);
11
- // const buffer = await response.arrayBuffer();
12
- const fragments = components.get(OBC.FragmentsManager);
13
- const file = await fetch(
14
- "https://thatopen.github.io/engine_components/resources/frags/school_arq.frag",
15
- );
16
- const buffer = await file.arrayBuffer();
17
- await fragments.core.load(buffer, { modelId: "school_arq" });
18
- await world.camera.controls.setLookAt(68, 23, -8.5, 21.5, -5.5, 23);
19
- await fragments.core.update(true);
20
-
21
- return element;
22
- };
@@ -1,15 +0,0 @@
1
- import * as BUI from "@thatopen/ui";
2
- import * as OBC from "@thatopen-platform/components-beta";
3
-
4
- export interface AppInfoSectionState {
5
- components: OBC.Components;
6
- }
7
-
8
- export type AppInfoSectionComponent =
9
- BUI.StatefullComponent<AppInfoSectionState>;
10
-
11
- // Used in App type (app.ts) to type this element slot in the grid.
12
- export type AppInfoSectionGridElement = {
13
- name: "appInfoSection";
14
- state: AppInfoSectionState;
15
- };
@@ -1,14 +0,0 @@
1
- import * as OBC from "@thatopen-platform/components-beta";
2
- import * as BUI from "@thatopen/ui";
3
-
4
- export interface CloudRunnerSectionState {
5
- components: OBC.Components;
6
- }
7
-
8
- export type CloudRunnerSectionComponent =
9
- BUI.StatefullComponent<CloudRunnerSectionState>;
10
-
11
- export type CloudRunnerSectionGridElement = {
12
- name: "cloudRunnerSection";
13
- state: CloudRunnerSectionState;
14
- };
@@ -1,5 +0,0 @@
1
- {
2
- "accessToken": "",
3
- "apiUrl": "",
4
- "itemType": "COMPONENT"
5
- }
@@ -1,22 +0,0 @@
1
- {
2
- "name": "{{PROJECT_NAME}}",
3
- "version": "1.0.0",
4
- "private": true,
5
- "scripts": {
6
- "build": "vite build",
7
- "run": "thatopen run",
8
- "local-server": "thatopen local-server",
9
- "login": "thatopen login --local",
10
- "publish": "thatopen publish"
11
- },
12
- "dependencies": {
13
- "@thatopen/components": "~3.4.0",
14
- "@thatopen/services": "^{{VERSION}}",
15
- "three": "^0.182.0"
16
- },
17
- "devDependencies": {
18
- "@types/three": "^0.182.0",
19
- "typescript": "^5.2.0",
20
- "vite": "^5.2.0"
21
- }
22
- }
@@ -1,56 +0,0 @@
1
- # ThatOpen Platform API Test Suite (Cloud Component)
2
-
3
- This is a cloud component that exercises every EngineServicesClient endpoint from a
4
- server-side context. It verifies that the platform API and runtime globals work correctly.
5
-
6
- ## How this component works
7
-
8
- - **Entry point**: `src/main.ts` — exports `async function main()`.
9
- - **Build output**: `dist/bundle.js` — an IIFE built by Vite with platform deps externalized.
10
- - **Execution**: The platform (or `thatopen run` locally) calls `main()`.
11
-
12
- ## What it tests
13
-
14
- | Group | Endpoints tested |
15
- |-------|-----------------|
16
- | **Runtime Globals** | thatOpenServices, executionParams, executionReporter, OBC, THREE, fs |
17
- | **Folders** | createFolder, getFolder, listFolders, updateFolder, archiveFolder, recoverFolder, downloadFolder |
18
- | **Files** | createFile, getFile, listFiles, downloadFile, getFileVersionMetadata, updateFileVersionMetadata, deleteFileVersionMetadata, updateFile, archiveFile, recoverFile |
19
- | **Hidden Files** | createHiddenFile, getHiddenFile, getHiddenFilesByParent, downloadHiddenFile, deleteHiddenFile, deleteHiddenFilesByParent |
20
- | **Icons** | uploadItemIcon, getItemIcon, removeItemIcon |
21
- | **General Items** | updateItem, createVersion |
22
- | **Components** | createComponent, getComponent, listComponents, updateComponent, downloadComponent, downloadComponentBundle, archiveComponent, recoverComponent |
23
- | **Apps** | createApp, listApps, downloadApp, downloadAppBundle, archiveApp |
24
- | **Execution** | executeComponent, getExecution, listExecutions, onExecutionProgress, abortExecution |
25
- | **Built-in** | getBuiltInComponent |
26
-
27
- ## Running locally
28
-
29
- ```bash
30
- npm run run # Build and run once
31
- npm run local-server # Start local execution server
32
- ```
33
-
34
- ## Running on the platform
35
-
36
- ```bash
37
- npm run login # Authenticate
38
- npm run publish # Publish to the platform
39
- ```
40
-
41
- Then execute via the platform UI or from another app:
42
- ```ts
43
- const { executionId } = await client.executeComponent(componentId, {});
44
- client.onExecutionProgress(executionId, (data) => { ... });
45
- ```
46
-
47
- ## Output
48
-
49
- - **Progress**: Reported via `executionReporter` after each test group
50
- - **Messages**: Each group logs individual test results (pass/fail/skip)
51
- - **Return**: `{ type: "SUCCESS", message }` if all pass, `{ type: "WARNING", message }` if any fail
52
-
53
- ## Cleanup
54
-
55
- All test resources (folders, files, components, apps, hidden files) are archived after tests.
56
- The execution tests use the test component created in the Components test group.