@fortemi/graph 2026.7.4 → 2026.7.7

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/index.js CHANGED
@@ -1,5 +1,3 @@
1
- import { GraphRepository, CommunitiesRepository } from '@fortemi/core';
2
-
3
1
  // src/degree.ts
4
2
  function computeDegrees(graph) {
5
3
  const degree = /* @__PURE__ */ new Map();
@@ -898,187 +896,10 @@ function getComputedPosition(elm) {
898
896
  if (view?.getComputedStyle) return view.getComputedStyle(elm).position || "static";
899
897
  return "static";
900
898
  }
901
- var DEFAULT_LAYOUT = {
902
- algorithm: "force",
903
- preserveViewport: true,
904
- communitySpacing: 1
905
- };
906
- var GraphController = class _GraphController {
907
- graphRepo;
908
- communityRepo;
909
- listeners = /* @__PURE__ */ new Set();
910
- communitySourceId;
911
- state;
912
- /** Build a controller from a database handle (production path). */
913
- static fromDb(db, options = {}) {
914
- return new _GraphController(new GraphRepository(db), new CommunitiesRepository(db), options);
915
- }
916
- constructor(graphRepo, communityRepo, options = {}) {
917
- this.graphRepo = graphRepo;
918
- this.communityRepo = communityRepo;
919
- this.communitySourceId = options.initialCommunitySourceId ?? null;
920
- this.state = {
921
- mode: options.initialMode ?? "citations",
922
- graph: null,
923
- graphSource: void 0,
924
- communitySource: void 0,
925
- embeddingSetSelector: options.initialEmbeddingSetSelector,
926
- filters: options.initialFilters,
927
- layout: { ...DEFAULT_LAYOUT, ...options.layout },
928
- status: { loading: false, error: null, freshness: null, cache: null },
929
- transition: void 0
930
- };
931
- }
932
- getState() {
933
- return this.state;
934
- }
935
- subscribe(listener) {
936
- this.listeners.add(listener);
937
- return () => {
938
- this.listeners.delete(listener);
939
- };
940
- }
941
- /** Run the initial load. Call once after construction (the hook calls this on mount). */
942
- async start() {
943
- await this.refresh();
944
- }
945
- setState(patch) {
946
- this.state = { ...this.state, ...patch };
947
- for (const listener of this.listeners) listener(this.state);
948
- }
949
- beginTransition(toMode, reason, fromMode = this.state.mode) {
950
- this.setState({ transition: { fromMode, toMode, reason, startedAt: (/* @__PURE__ */ new Date()).toISOString() } });
951
- }
952
- async refresh() {
953
- try {
954
- this.setState({ status: { ...this.state.status, loading: true, error: null } });
955
- const sources = await this.communityRepo.listCommunitySources();
956
- const activeCommunity = this.communitySourceId ? sources.find((source) => source.id === this.communitySourceId) : void 0;
957
- this.setState({ communitySource: activeCommunity });
958
- const mode = this.state.mode;
959
- if (mode === "citations") {
960
- const nextGraph = await this.graphRepo.buildLinkGraph();
961
- this.setState({
962
- graph: nextGraph,
963
- graphSource: { id: "citations", name: "Citation graph" },
964
- status: { loading: false, error: null, freshness: "fresh", cache: null }
965
- });
966
- return;
967
- }
968
- if (mode === "topics") {
969
- const selector = this.state.embeddingSetSelector;
970
- if (!selector) throw new Error("topics mode requires an embedding-set selector");
971
- const result = await this.graphRepo.buildOrLoadSimilarityGraph({ selector });
972
- this.setState({
973
- graph: result.graph,
974
- graphSource: result.graphSource,
975
- status: { loading: false, error: null, freshness: result.freshness, cache: result.cache }
976
- });
977
- return;
978
- }
979
- if (mode === "precomputed") {
980
- if (!activeCommunity?.graphSourceId) {
981
- throw new Error("precomputed mode requires a community source with graphSourceId");
982
- }
983
- const assignments = await this.communityRepo.getCommunityAssignments(activeCommunity.id);
984
- const nextGraph = await this.graphRepo.loadGraphArtifact(
985
- activeCommunity.graphSourceId,
986
- assignments.map((assignment) => assignment.noteId)
987
- );
988
- this.setState({
989
- graph: nextGraph,
990
- graphSource: { id: activeCommunity.graphSourceId, name: activeCommunity.name },
991
- status: { loading: false, error: null, freshness: activeCommunity.freshness ?? "unknown", cache: null }
992
- });
993
- return;
994
- }
995
- if (mode === "dynamic-search") {
996
- const assignments = await this.communityRepo.previewDynamicCommunity(this.state.filters ?? {});
997
- this.setState({
998
- graph: {
999
- nodes: assignments.map((assignment) => ({ id: assignment.noteId })),
1000
- edges: [],
1001
- communities: [{ id: "dynamic-preview", nodes: assignments.map((assignment) => assignment.noteId) }]
1002
- },
1003
- graphSource: { id: "dynamic-preview", name: "Dynamic preview" },
1004
- status: { loading: false, error: null, freshness: "unknown", cache: null }
1005
- });
1006
- return;
1007
- }
1008
- if (mode === "user-authored") {
1009
- if (!activeCommunity) throw new Error("user-authored mode requires an active community source");
1010
- const assignments = await this.communityRepo.getCommunityAssignments(activeCommunity.id);
1011
- this.setState({
1012
- graph: {
1013
- nodes: assignments.map((assignment) => ({ id: assignment.noteId })),
1014
- edges: [],
1015
- communities: [{ id: activeCommunity.id, nodes: assignments.map((assignment) => assignment.noteId) }]
1016
- },
1017
- graphSource: { id: activeCommunity.graphSourceId ?? activeCommunity.id, name: activeCommunity.name },
1018
- status: { loading: false, error: null, freshness: activeCommunity.freshness ?? "unknown", cache: null }
1019
- });
1020
- }
1021
- } catch (err) {
1022
- const e = err instanceof Error ? err : new Error(String(err));
1023
- this.setState({ status: { ...this.state.status, loading: false, error: e } });
1024
- throw e;
1025
- }
1026
- }
1027
- setMode(nextMode) {
1028
- this.beginTransition(nextMode, "mode-change");
1029
- this.setState({ mode: nextMode });
1030
- void this.refresh();
1031
- }
1032
- setEmbeddingSetSelector(selector) {
1033
- this.beginTransition("topics", "embedding-set-change");
1034
- this.setState({ embeddingSetSelector: selector, mode: "topics" });
1035
- void this.refresh();
1036
- }
1037
- setCommunitySource(sourceId) {
1038
- this.communitySourceId = sourceId;
1039
- this.beginTransition(this.state.mode, "community-source-change");
1040
- void this.refresh();
1041
- }
1042
- /** Apply dynamic-search filters and switch into that mode (state only). */
1043
- applyFilters(nextFilters) {
1044
- this.beginTransition("dynamic-search", "filter-change");
1045
- this.setState({ filters: nextFilters, mode: "dynamic-search" });
1046
- }
1047
- setFilters(nextFilters) {
1048
- this.applyFilters(nextFilters);
1049
- void this.refresh();
1050
- }
1051
- async recompute() {
1052
- this.beginTransition(this.state.mode, "recompute");
1053
- if (this.state.mode === "topics" && this.state.embeddingSetSelector) {
1054
- const result = await this.graphRepo.buildOrLoadSimilarityGraph({
1055
- selector: this.state.embeddingSetSelector,
1056
- source: "live-only"
1057
- });
1058
- this.setState({
1059
- graph: result.graph,
1060
- graphSource: result.graphSource,
1061
- status: { loading: false, error: null, freshness: result.freshness, cache: result.cache }
1062
- });
1063
- return;
1064
- }
1065
- await this.refresh();
1066
- }
1067
- async previewDynamicCommunity(nextFilters) {
1068
- this.applyFilters(nextFilters);
1069
- await this.refresh();
1070
- }
1071
- async saveCurrentCommunity(input) {
1072
- const source = await this.communityRepo.saveCommunity(input);
1073
- this.communitySourceId = source.id;
1074
- this.setState({ communitySource: source });
1075
- return source;
1076
- }
1077
- };
1078
899
 
1079
900
  // src/index.ts
1080
- var VERSION = "2026.7.4";
901
+ var VERSION = "2026.7.7";
1081
902
 
1082
- export { COMMUNITY_COLORS, GRAPH_SNAPSHOT_VERSION, GREYSCALE_COMMUNITY_RAMP, GraphController, UNASSIGNED_COMMUNITY_COLOR, VERSION, applyControlFilters, bakeRenderGraph, buildAdjacency, colorForCommunity, communityLegend, communityRanks, computeDegrees, computeGraphBounds, deserializeGraphSnapshot, expandNeighborhood, filterCommunityGraph, fitGraphToViewport, hasBakedPositions, isRenderGraph, layoutCommunityGraph, loadRenderSnapshot, mapCommunityGraph, neighborhoodSubgraph, neighborsOf, nodeRadius, renderCommunityGraph, serializeGraphSnapshot, stringifyGraphSnapshot, stringifyRenderGraph, subgraphForNodes };
903
+ export { COMMUNITY_COLORS, GRAPH_SNAPSHOT_VERSION, GREYSCALE_COMMUNITY_RAMP, UNASSIGNED_COMMUNITY_COLOR, VERSION, applyControlFilters, bakeRenderGraph, buildAdjacency, colorForCommunity, communityLegend, communityRanks, computeDegrees, computeGraphBounds, deserializeGraphSnapshot, expandNeighborhood, filterCommunityGraph, fitGraphToViewport, hasBakedPositions, isRenderGraph, layoutCommunityGraph, loadRenderSnapshot, mapCommunityGraph, neighborhoodSubgraph, neighborsOf, nodeRadius, renderCommunityGraph, serializeGraphSnapshot, stringifyGraphSnapshot, stringifyRenderGraph, subgraphForNodes };
1083
904
  //# sourceMappingURL=index.js.map
1084
905
  //# sourceMappingURL=index.js.map