@ankhzet/graph 0.1.0 → 0.3.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ankhzet/graph",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "type": "module",
5
5
  "main": "./src/index.ts",
6
6
  "types": "./src/index.ts",
@@ -8,7 +8,7 @@
8
8
  "package.json",
9
9
  "src/**/*.ts",
10
10
  "src/**/*.tsx",
11
- "build",
11
+ "dist",
12
12
  "*.md"
13
13
  ],
14
14
  "exports": {
@@ -30,10 +30,10 @@
30
30
  "@pixi/events": "^7.4.3",
31
31
  "mobx": "^6.15.4",
32
32
  "mobx-react-lite": "^4.1.1",
33
- "@ankhzet/eventual": "1.1.0",
34
- "@ankhzet/gcl": "1.1.0",
35
- "@ankhzet/utils": "1.17.0",
36
- "@ankhzet/ui": "0.1.0"
33
+ "@ankhzet/eventual": "1.2.0",
34
+ "@ankhzet/ui": "0.2.0",
35
+ "@ankhzet/utils": "1.18.0",
36
+ "@ankhzet/gcl": "1.2.0"
37
37
  },
38
38
  "peerDependencies": {
39
39
  "react": "^19.2.6"
@@ -1,14 +1,14 @@
1
1
  import { useLastCallback } from '@ankhzet/ui';
2
2
  import { type TypeId } from './types';
3
3
  import { type ItemsGroup, NodeGroups } from './graph';
4
- import { CircuitNode } from './CircuitNode';
4
+ import { ManagedGraphNode } from './ManagedGraphNode';
5
5
 
6
- export interface CircuitGroupsProps {
7
- items: CircuitNode[];
6
+ export interface GraphGroupsProps {
7
+ items: ManagedGraphNode[];
8
8
  onSelect: (ids: TypeId[]) => void;
9
9
  }
10
10
 
11
- export const CircuitGroups = ({ onSelect, ...props }: CircuitGroupsProps) => {
11
+ export const GraphGroups = ({ onSelect, ...props }: GraphGroupsProps) => {
12
12
  const handleSelect = useLastCallback((group: ItemsGroup<TypeId>) => onSelect(group.ids));
13
13
 
14
14
  return (
@@ -20,7 +20,7 @@ export const CircuitGroups = ({ onSelect, ...props }: CircuitGroupsProps) => {
20
20
  );
21
21
  };
22
22
 
23
- const resolver = (node: CircuitNode) => {
23
+ const resolver = (node: ManagedGraphNode) => {
24
24
  if (!node.item.isolator) {
25
25
  return;
26
26
  }
package/src/LoadNodes.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import type { TypeId } from './types';
2
2
  import type { NodeConnection, Position, StoreInterface } from './graph';
3
- import { CircuitNode } from './CircuitNode';
3
+ import { ManagedGraphNode } from './ManagedGraphNode';
4
4
 
5
- export type GraphListeners<N extends CircuitNode<any>> = {
5
+ export type GraphListeners<N extends ManagedGraphNode<any>> = {
6
6
  onEdit: (node: N) => void;
7
7
  onConnect: (connection: NodeConnection<TypeId>) => Promise<void>;
8
8
  onMove: (node: N, pos: Position) => Promise<void>;
@@ -12,9 +12,9 @@ export type GraphListeners<N extends CircuitNode<any>> = {
12
12
  onDelete: (node: N) => Promise<void>;
13
13
  };
14
14
 
15
- type SyncConfig<N extends CircuitNode<any>> = { added: N[]; removed: TypeId[] };
15
+ type SyncConfig<N extends ManagedGraphNode<any>> = { added: N[]; removed: TypeId[] };
16
16
 
17
- const connectHandlers = <N extends CircuitNode>(
17
+ const connectHandlers = <N extends ManagedGraphNode>(
18
18
  node: N,
19
19
  { onEdit, onMove, onConnect, onDelete, onAddPort, onDisconnectPort, onDeletePort }: GraphListeners<N>,
20
20
  ) => {
@@ -27,7 +27,7 @@ const connectHandlers = <N extends CircuitNode>(
27
27
  node.onDeletePortAction(({ port }) => onDeletePort(node, port));
28
28
  };
29
29
 
30
- export const syncNodes = <N extends CircuitNode<any>>(
30
+ export const syncNodes = <N extends ManagedGraphNode<any>>(
31
31
  nodes: StoreInterface<N>,
32
32
  handlers: GraphListeners<N> | undefined,
33
33
  { added, removed }: SyncConfig<N>,
@@ -1,7 +1,7 @@
1
1
  import { useLastCallback, handleAsNoop, Styles } from '@ankhzet/ui';
2
2
  import { RefObject, useRef, useMemo, useState, PropsWithChildren, useImperativeHandle } from 'react';
3
- import { CircuitGroups } from './CircuitGroups';
4
- import type { CircuitNode, IItem } from './CircuitNode';
3
+ import { GraphGroups } from './GraphGroups';
4
+ import type { ManagedGraphNode, IItem } from './ManagedGraphNode';
5
5
  import { type GraphHandlers, createGraphHandlers } from './createGraphHandlers';
6
6
  import type { GraphAdapter } from './graph';
7
7
  import { Store, useStore } from './graph';
@@ -15,37 +15,36 @@ import { Coordinates, GRID_SIZE } from './utils';
15
15
 
16
16
  export type { GraphHandlers };
17
17
 
18
- export interface CircuitGraphProps<Circuit extends Identifiable, Item extends IItem, DTO> {
19
- innerRef?: RefObject<{ graph: GraphAdapter<CircuitNode<Item>>; element?: HTMLDivElement }>;
20
- circuit: Circuit;
18
+ export interface IGraph<Item extends IItem> extends Identifiable {
19
+ items: Item[];
20
+ }
21
+
22
+ export interface ManagedGraphProps<Graph extends IGraph<Item>, Item extends IItem, DTO> {
23
+ innerRef?: RefObject<{ graph: GraphAdapter<ManagedGraphNode<Item>>; element?: HTMLDivElement }>;
24
+ graph: Graph;
21
25
  selected?: Item[];
22
26
  className?: string;
23
27
  handlers?: Partial<GraphHandlers<DTO, Item>>;
24
- exportToJson?: (circuit: Circuit) => string;
28
+ onExport?: (graph: Graph) => string;
25
29
  }
26
30
 
27
- export const CircuitGraph = <Circuit extends Identifiable, Item extends IItem, DTO extends GraphDTO>({
31
+ export const ManagedGraph = <Graph extends IGraph<Item>, Item extends IItem, DTO extends GraphDTO>({
28
32
  innerRef,
29
- circuit,
33
+ graph,
30
34
  selected,
31
35
  handlers,
32
36
  children,
33
- exportToJson,
37
+ onExport,
34
38
  ...rest
35
- }: PropsWithChildren<CircuitGraphProps<Circuit, Item, DTO>>) => {
36
- const graphRef = useRef<{ graph: GraphAdapter<CircuitNode<Item>>; element?: HTMLDivElement }>(null);
39
+ }: PropsWithChildren<ManagedGraphProps<Graph, Item, DTO>>) => {
40
+ const graphRef = useRef<{ graph: GraphAdapter<ManagedGraphNode<Item>>; element?: HTMLDivElement }>(null);
37
41
  const coordinator = useMemo(() => new Coordinates(GRID_SIZE), []);
38
- const [nodes, all] = useStore(() => new Store<CircuitNode<Item>>());
39
- const [group, setGroup] = useState<TypeId[] | undefined>();
40
-
41
42
  const menu = useGraphMenu(coordinator, handlers?.onCreate);
43
+ const [nodes, all] = useStore(() => new Store<ManagedGraphNode<Item>>());
44
+ const [group, setGroup] = useState<TypeId[] | undefined>();
42
45
  const { canvas, loader } = createGraphHandlers(coordinator, nodes, handlers);
43
46
 
44
- const handleExport = useLastCallback(async () => {
45
- exportToJson && await navigator.clipboard.writeText(
46
- JSON.stringify(exportToJson(circuit), null, 3)
47
- );
48
- });
47
+ const handleExport = useLastCallback(() => onExport?.(graph));
49
48
 
50
49
  useImperativeHandle(innerRef, () => ({
51
50
  get graph() {
@@ -57,14 +56,14 @@ export const CircuitGraph = <Circuit extends Identifiable, Item extends IItem, D
57
56
  }));
58
57
 
59
58
  const store = useMemo(() => {
60
- const items = new Store<Item>();
59
+ const items = new Store<Item>(graph.items);
61
60
 
62
61
  return {
63
62
  items,
64
63
  get: () => items.all,
65
64
  onChange: (cb: () => void) => items.onChange(cb),
66
65
  };
67
- }, []);
66
+ }, [graph.items]);
68
67
 
69
68
  useNodes({
70
69
  store,
@@ -81,11 +80,11 @@ export const CircuitGraph = <Circuit extends Identifiable, Item extends IItem, D
81
80
  <div style={styles.selector}>
82
81
  {children}
83
82
 
84
- <CircuitGroups items={all} onSelect={setGroup} />
83
+ <GraphGroups items={all} onSelect={setGroup} />
85
84
 
86
85
  <button onClick={() => setGroup(undefined)}>Update</button>
87
86
 
88
- {exportToJson && (
87
+ {onExport && (
89
88
  <button onClick={handleExport}>Export</button>
90
89
  )}
91
90
  </div>
@@ -71,13 +71,13 @@ export enum NodeStatus {
71
71
  Selected = 1 << 4,
72
72
  }
73
73
 
74
- type NodeData<Item> = {
74
+ export type NodeData<Item> = {
75
75
  item: Item;
76
76
  status: NodeStatus;
77
77
  progress: number;
78
78
  };
79
79
 
80
- enum MenuActions {
80
+ export enum MenuActions {
81
81
  EDIT_NODE = 1,
82
82
  ADD_PORT = 2,
83
83
  DISCONNECT_PORT = 3,
@@ -85,7 +85,7 @@ enum MenuActions {
85
85
  DELETE_NODE = 5,
86
86
  }
87
87
 
88
- export class CircuitNode<Item extends IItem = IItem>
88
+ export class ManagedGraphNode<Item extends IItem = IItem>
89
89
  extends GraphNode<TypeId, NodeData<Item>, Container>
90
90
  implements IMenuProvider<MenuAction>
91
91
  {
@@ -1,6 +1,6 @@
1
1
  import type { TypeId } from './types';
2
2
  import type { GraphListeners } from './LoadNodes';
3
- import type { CircuitNode, IItem } from './CircuitNode';
3
+ import type { ManagedGraphNode, IItem } from './ManagedGraphNode';
4
4
  import type { ConnectionPoint, Coordinator, NodeConnection, Position, StoreInterface } from './graph';
5
5
 
6
6
  export interface GraphHandlers<DTO, Item> {
@@ -16,7 +16,7 @@ export interface GraphHandlers<DTO, Item> {
16
16
  onContextMenu?: (item: Item | null, pos: Position) => void | false;
17
17
  }
18
18
 
19
- export const createGraphHandlers = <DTO, Item extends IItem, Node extends CircuitNode<Item>>(
19
+ export const createGraphHandlers = <DTO, Item extends IItem, Node extends ManagedGraphNode<Item>>(
20
20
  coordinator: Coordinator,
21
21
  nodes: StoreInterface<Node>,
22
22
  {
package/src/index.ts CHANGED
@@ -1,3 +1,5 @@
1
+ export * from './types';
1
2
  export * from './graph';
2
- export * from './CircuitGraph';
3
+ export * from './ManagedGraph';
4
+ export * from './ManagedGraphNode';
3
5
  export * from './GraphCanvas';
@@ -2,9 +2,9 @@ import { useRef } from 'react';
2
2
  import { matchId } from '@ankhzet/utils';
3
3
  import { useIsomorphicLayoutEffect } from '@ankhzet/ui';
4
4
 
5
- import type { CircuitNode, IItem } from './CircuitNode';
5
+ import type { ManagedGraphNode, IItem } from './ManagedGraphNode';
6
6
 
7
- export const useNodeSelection = <Item extends IItem>(nodes: CircuitNode<Item>[], selected?: Item[]) => {
7
+ export const useNodeSelection = <Item extends IItem>(nodes: ManagedGraphNode<Item>[], selected?: Item[]) => {
8
8
  const ref = useRef<Item[]>([]);
9
9
 
10
10
  useIsomorphicLayoutEffect(() => {
package/src/useNodes.tsx CHANGED
@@ -4,7 +4,7 @@ import { reaction } from 'mobx';
4
4
  import { useLastCallback, useSyncStore } from '@ankhzet/ui';
5
5
  import type { Coordinator} from './graph';
6
6
  import { isEqualIdentifiables } from './graph';
7
- import { CircuitNode, IItem } from './CircuitNode';
7
+ import { ManagedGraphNode, IItem } from './ManagedGraphNode';
8
8
  import { TypeId } from './types';
9
9
 
10
10
  export const useNodes = <Item extends IItem>({
@@ -16,7 +16,7 @@ export const useNodes = <Item extends IItem>({
16
16
  }: {
17
17
  store: { get: () => Item[]; onChange: (cb: () => void) => () => void };
18
18
  coordinator: Coordinator;
19
- sync: (config: { added: CircuitNode<Item>[]; removed: TypeId[] }) => void;
19
+ sync: (config: { added: ManagedGraphNode<Item>[]; removed: TypeId[] }) => void;
20
20
  toTitle: (item: Item) => string;
21
21
  onUpdate: () => void;
22
22
  }) => {
@@ -45,7 +45,7 @@ export const useNodes = <Item extends IItem>({
45
45
  ref.current = sync;
46
46
 
47
47
  useIsomorphicLayoutEffect(() => {
48
- const factory = (item: Item): CircuitNode<Item> => new CircuitNode<Item>({
48
+ const factory = (item: Item): ManagedGraphNode<Item> => new ManagedGraphNode<Item>({
49
49
  finder,
50
50
  item,
51
51
  coordinator,
@@ -57,7 +57,7 @@ export const useNodes = <Item extends IItem>({
57
57
  (acc: Record<TypeId, boolean>, { id }) => ((acc[id] = true), acc),
58
58
  {}
59
59
  );
60
- const added = items.filter((processor) => !cache[processor.id]).map(factory);
60
+ const added = items.filter((item) => !cache[item.id]).map(factory);
61
61
  const removed = Object.keys(cache).filter((id) => !finder(id));
62
62
 
63
63
  if (added.length || removed.length) {
package/src/utils.ts CHANGED
@@ -1,5 +1,4 @@
1
- // import { ProcessorType } from '@council/model';
2
- import type { CircuitNode } from './CircuitNode';
1
+ import type { ManagedGraphNode } from './ManagedGraphNode';
3
2
  import type { Coordinator, Position } from './graph';
4
3
 
5
4
  export const GRID_SIZE = 16;
@@ -50,9 +49,8 @@ export class Coordinates implements Coordinator {
50
49
  }
51
50
  }
52
51
 
53
- // export const groupResolver = ({ description: { processor } }: CircuitNode) =>
54
- // processor.type === ProcessorType.Call || processor.isolator ? processor.title : null;
52
+ export const groupResolver = ({ description: { item } }: ManagedGraphNode) => item.isolator ? item.title : null;
55
53
 
56
54
  const re = /^signal_?/;
57
55
 
58
- export const isBarrier = ({ description }: CircuitNode<any>) => re.test(description.title);
56
+ export const isBarrier = ({ description }: ManagedGraphNode<any>) => re.test(description.title);