@thatopen/services 0.4.0 → 0.6.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.
@@ -0,0 +1,70 @@
1
+ /* MD
2
+ ## git-history-panel
3
+ ---
4
+ `top-git-history` is a GitKraken-style commit timeline for the **revit-flow**
5
+ feature. It lists the commits pushed by the Revit add-in (newest first) and,
6
+ when you click a commit, drives the shared 3D viewer to color that commit's
7
+ changed elements — created green, modified blue, deleted red — on the loaded
8
+ baseline model.
9
+
10
+ All viewer mutation lives in the headless `GitHistoryManager`; the panel is
11
+ intent-only. Mounting it is a single line of markup once `UIManager` and
12
+ `GitHistoryManager` are in the setup call.
13
+ */
14
+
15
+ import { html } from "lit";
16
+ import * as THREE from "three";
17
+ import * as OBC from "@thatopen/components";
18
+ import * as OBF from "@thatopen/components-front";
19
+ import * as FRAGS from "@thatopen/fragments";
20
+ import * as BUI from "@thatopen/ui";
21
+ import { PlatformClient, UIManager, GitHistoryManager } from "@thatopen/services";
22
+ import type { App } from "../app/index";
23
+
24
+
25
+ const client = PlatformClient.fromPlatformContext();
26
+
27
+ const { components } = (await client.setup(
28
+ { OBC, OBF, BUI, THREE, FRAGS },
29
+ { uuid: UIManager.uuid },
30
+ { uuid: GitHistoryManager.uuid },
31
+ )) as { components: OBC.Components };
32
+
33
+ components.get(UIManager).init();
34
+
35
+ // The panel self-wires init(client) on connect, but calling it here keeps the
36
+ // timeline populated before the panel mounts.
37
+ await components.get(GitHistoryManager).init(client);
38
+
39
+ const app = document.createElement("top-app") as unknown as App;
40
+
41
+ app.setup = (waitUntil) => {
42
+ waitUntil(
43
+ (async () => {
44
+ const fragments = components.get(OBC.FragmentsManager);
45
+ const workerUrl = await FRAGS.FragmentsModels.getWorker();
46
+ fragments.init(await FRAGS.toClassicWorker(workerUrl), { classicWorker: true });
47
+ })(),
48
+ "Fragments Core",
49
+ );
50
+ return { components, client };
51
+ };
52
+
53
+ app.elements = {
54
+ viewer: () => html`<top-viewer><top-viewer-tools></top-viewer-tools></top-viewer>`,
55
+ history: () => html`<top-git-history></top-git-history>`,
56
+ };
57
+
58
+ app.layouts = {
59
+ main: {
60
+ label: "Main",
61
+ icon: "solar:branching-paths-up-bold",
62
+ template: `"viewer history" 1fr / 1fr 24rem`,
63
+ },
64
+ };
65
+
66
+ app.layout = "main";
67
+
68
+ const container = document.getElementById("that-open-app") ?? document.body;
69
+ container.appendChild(app);
70
+ document.body.style.margin = "0";
@@ -949,6 +949,191 @@ export type FileList = InstanceType<typeof _FileList>;
949
949
  */
950
950
  export const FileList = { uuid: 'b0b5e2a2-0b3a-4a6b-8b1c-0b1c4a6b8b1c' } as typeof _FileList & { uuid: 'b0b5e2a2-0b3a-4a6b-8b1c-0b1c4a6b8b1c' };
951
951
 
952
+ /** One element mutation inside a revit-flow commit. */
953
+ export interface RevitFlowChange {
954
+ /** create → element added, update → geometry/data changed, delete → removed. */
955
+ type: "create" | "update" | "delete" | string;
956
+ /** Revit UniqueId (GUID). Resolves to a fragments localId via getLocalIdsByGuids. */
957
+ uniqueId: string;
958
+ }
959
+ /** Per-commit change tallies, mirrored from the add-in's `counts` block. */
960
+ export interface RevitFlowCounts {
961
+ added: number;
962
+ modified: number;
963
+ removed: number;
964
+ }
965
+ /**
966
+ * A revit-flow commit — one push of changes from the Revit add-in. `id` is a
967
+ * monotonic integer; `parent` points at the previous commit (null for the
968
+ * root). The commit whose scan was full (earliest with a .frag) carries the
969
+ * WHOLE model in `revitflow_frag_<id>.frag`; later frags are incremental.
970
+ */
971
+ export interface RevitFlowCommit {
972
+ id: number;
973
+ parent: number | null;
974
+ author: string;
975
+ source: string;
976
+ timestamp: string;
977
+ changes: RevitFlowChange[];
978
+ counts: RevitFlowCounts;
979
+ }
980
+ /** Shape of `revitflow_history.json`. */
981
+ export interface RevitFlowHistory {
982
+ model: string;
983
+ commits: RevitFlowCommit[];
984
+ }
985
+ /** Dominant change type of a commit, used to color its timeline node. */
986
+ export type DominantChange = "create" | "update" | "delete";
987
+
988
+ /** Dominant change type of a commit: delete → create → update. */
989
+ export declare function dominantChange(commit: RevitFlowCommit): DominantChange;
990
+ /**
991
+ * GitHistoryManager — headless engine for the revit-flow git-history built-in.
992
+ *
993
+ * Owns ALL viewer mutation: it fetches the commit history + fragment artifacts
994
+ * from project storage, loads the baseline (full-model) .frag into the shared
995
+ * viewer, and colors a commit's changed elements (create → green, update →
996
+ * blue, delete → red) via named Highlighter styles. The Lit panel
997
+ * (`top-git-history`) is intent-only: it calls these methods and subscribes to
998
+ * the events below, and never touches the Highlighter / FragmentsManager
999
+ * directly.
1000
+ *
1001
+ * Data model (per model, in `bimterop/revit-<docId>/`):
1002
+ * - revitflow_history.json — { model, commits: [{ id, parent, author,
1003
+ * source, timestamp, changes:[{type,uniqueId}], counts }] }
1004
+ * - revitflow_frag_<N>.frag — fragments file for commit N. The earliest
1005
+ * commit with a frag is the FULL model (baseline); later frags are
1006
+ * incremental (only that commit's created+modified geometry).
1007
+ */
1008
+ declare class _GitHistoryManager extends OBC.Component {
1009
+ static readonly uuid: "3f9c1a7e-6b2d-4e18-9a5c-7d0e2f4b6c81";
1010
+ enabled: boolean;
1011
+ readonly onCommitsChanged: OBC.Event<RevitFlowCommit[]>;
1012
+ readonly onCommitChanged: OBC.Event<number | null>;
1013
+ readonly onLoadingChanged: OBC.Event<boolean>;
1014
+ readonly onError: OBC.Event<string>;
1015
+ world?: OBC.World;
1016
+ /** When true, showCommit() ghosts (dims) every non-changed element. */
1017
+ isolateChanges: boolean;
1018
+ /** Green — created elements. */
1019
+ readonly STYLE_CREATED = "#22c55e";
1020
+ /** Blue — modified elements. */
1021
+ readonly STYLE_MODIFIED = "#3b82f6";
1022
+ /** Red — deleted elements. */
1023
+ readonly STYLE_DELETED = "#ef4444";
1024
+ private _client?;
1025
+ private _projectId?;
1026
+ private _docFolderId?;
1027
+ private _modelName;
1028
+ private _commits;
1029
+ private _currentCommitId;
1030
+ /** filename(lowercase) → fileId, for the doc folder's current listing. */
1031
+ private _fileIndex;
1032
+ /** modelIds (== frag fileIds) already loaded into the viewer. */
1033
+ private _loadedFrags;
1034
+ /** Ghosted localIds per modelId, so isolate can be cleared/re-applied. */
1035
+ private _ghosted;
1036
+ private _baselineCommitId?;
1037
+ private _stylesRegistered;
1038
+ private _loading;
1039
+ constructor(components: OBC.Components);
1040
+ get ready(): boolean;
1041
+ get loading(): boolean;
1042
+ get commits(): RevitFlowCommit[];
1043
+ get currentCommitId(): number | null;
1044
+ get modelName(): string;
1045
+ get baselineCommitId(): number | undefined;
1046
+ /** True if commit `id` has a fragments file available in storage. */
1047
+ hasFrag(commitId: number): boolean;
1048
+ /**
1049
+ * Wire the platform client and load the commit history. Resolves the
1050
+ * viewer world in the background (it may not exist until <top-viewer>
1051
+ * mounts). Consumer panels call this once on connect.
1052
+ */
1053
+ init(client: PlatformClient): Promise<void>;
1054
+ /**
1055
+ * (Re)fetch `revitflow_history.json` from the project's
1056
+ * `bimterop/revit-*` folder and publish the commit list. Also indexes the
1057
+ * folder's files so frag lookups are a local map hit.
1058
+ */
1059
+ loadHistory(): Promise<void>;
1060
+ /**
1061
+ * Show commit `commitId`: ensure the baseline (full-model) .frag is loaded,
1062
+ * load the commit's own incremental frag (so created elements are present),
1063
+ * then color its changed elements. Deleted elements that no longer exist in
1064
+ * any loaded model are skipped. Fires onCommitChanged.
1065
+ */
1066
+ showCommit(commitId: number): Promise<void>;
1067
+ /** Remove all revit-flow coloring + ghosting and reset the selection. */
1068
+ clear(): Promise<void>;
1069
+ /** Toggle isolate mode; re-applies to the current commit if one is shown. */
1070
+ setIsolateChanges(on: boolean): Promise<void>;
1071
+ private _colorStyle;
1072
+ private _registerStyles;
1073
+ private _clearHighlights;
1074
+ /**
1075
+ * Resolve each change bucket's GUIDs to localIds across every loaded model
1076
+ * and paint them with the matching named style.
1077
+ */
1078
+ private _colorCommit;
1079
+ /** GUIDs → { modelId: Set<localId> } across the given models. */
1080
+ private _buildMap;
1081
+ private _mergeMaps;
1082
+ private _ghostAllExcept;
1083
+ private _clearGhost;
1084
+ private _ensureBaselineLoaded;
1085
+ /** Load commit `commitId`'s .frag into the viewer under modelId == fileId. */
1086
+ private _ensureFragLoaded;
1087
+ /**
1088
+ * Resolve (and cache) the `bimterop/revit-*` doc subfolder id. Filters the
1089
+ * project-wide folder list locally by parentId + name prefix, mirroring the
1090
+ * SnapshotList prototype (the server-side parentFolderId filter is
1091
+ * unreliable). Returns null if the project hasn't been pushed to yet.
1092
+ */
1093
+ private _resolveDocFolderId;
1094
+ private _setLoading;
1095
+ private _firstWorld;
1096
+ }
1097
+
1098
+ /**
1099
+ * GitHistoryManager — headless engine for the revit-flow git-history built-in.
1100
+ *
1101
+ * Owns ALL viewer mutation: it fetches the commit history + fragment artifacts
1102
+ * from project storage, loads the baseline (full-model) .frag into the shared
1103
+ * viewer, and colors a commit's changed elements (create → green, update →
1104
+ * blue, delete → red) via named Highlighter styles. The Lit panel
1105
+ * (`top-git-history`) is intent-only: it calls these methods and subscribes to
1106
+ * the events below, and never touches the Highlighter / FragmentsManager
1107
+ * directly.
1108
+ *
1109
+ * Data model (per model, in `bimterop/revit-<docId>/`):
1110
+ * - revitflow_history.json — { model, commits: [{ id, parent, author,
1111
+ * source, timestamp, changes:[{type,uniqueId}], counts }] }
1112
+ * - revitflow_frag_<N>.frag — fragments file for commit N. The earliest
1113
+ * commit with a frag is the FULL model (baseline); later frags are
1114
+ * incremental (only that commit's created+modified geometry).
1115
+ */
1116
+ export type GitHistoryManager = InstanceType<typeof _GitHistoryManager>;
1117
+ /**
1118
+ * GitHistoryManager — headless engine for the revit-flow git-history built-in.
1119
+ *
1120
+ * Owns ALL viewer mutation: it fetches the commit history + fragment artifacts
1121
+ * from project storage, loads the baseline (full-model) .frag into the shared
1122
+ * viewer, and colors a commit's changed elements (create → green, update →
1123
+ * blue, delete → red) via named Highlighter styles. The Lit panel
1124
+ * (`top-git-history`) is intent-only: it calls these methods and subscribes to
1125
+ * the events below, and never touches the Highlighter / FragmentsManager
1126
+ * directly.
1127
+ *
1128
+ * Data model (per model, in `bimterop/revit-<docId>/`):
1129
+ * - revitflow_history.json — { model, commits: [{ id, parent, author,
1130
+ * source, timestamp, changes:[{type,uniqueId}], counts }] }
1131
+ * - revitflow_frag_<N>.frag — fragments file for commit N. The earliest
1132
+ * commit with a frag is the FULL model (baseline); later frags are
1133
+ * incremental (only that commit's created+modified geometry).
1134
+ */
1135
+ export const GitHistoryManager = { uuid: '3f9c1a7e-6b2d-4e18-9a5c-7d0e2f4b6c81' } as typeof _GitHistoryManager & { uuid: '3f9c1a7e-6b2d-4e18-9a5c-7d0e2f4b6c81' };
1136
+
952
1137
  /**
953
1138
  * A simple test component to validate the built-in component pipeline.
954
1139
  * Replace this with real components once the infrastructure is verified.