@thatopen/services 0.5.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.
- package/dist/built-in/index.d.ts +184 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.es.js +5 -4
- package/docs/ai-quickstart.md +22 -0
- package/docs/builtin/paths.json +4 -0
- package/docs/flow-architecture.md +389 -0
- package/docs/flow-plugin-guide.md +337 -0
- package/docs/revit-collab-quickstart.md +294 -175
- package/package.json +1 -1
- package/src/built-in/UIManager/src/git-history-panel/example.ts +70 -0
- package/src/built-in/index.ts +185 -0
|
@@ -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";
|
package/src/built-in/index.ts
CHANGED
|
@@ -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.
|