@timeax/digital-service-engine 0.0.9 → 0.1.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.
@@ -1316,7 +1316,6 @@ function useLivePolling(params) {
1316
1316
  live,
1317
1317
  workspaceId,
1318
1318
  actor,
1319
- hasAnyData,
1320
1319
  getCurrentBranchId,
1321
1320
  refreshAll,
1322
1321
  refreshBranchContext,
@@ -1423,11 +1422,6 @@ function useLivePolling(params) {
1423
1422
  disconnect2();
1424
1423
  if (live.mode === "off") {
1425
1424
  setStatus({ connected: false });
1426
- if (!hasAnyData) {
1427
- void (async () => {
1428
- await refreshAll({ strict: false });
1429
- })();
1430
- }
1431
1425
  return;
1432
1426
  }
1433
1427
  const adapter = resolveAdapter();
@@ -1463,7 +1457,6 @@ function useLivePolling(params) {
1463
1457
  }, [
1464
1458
  disconnect2,
1465
1459
  live.mode,
1466
- hasAnyData,
1467
1460
  refreshAll,
1468
1461
  resolveAdapter,
1469
1462
  ctx,
@@ -2817,8 +2810,10 @@ import {
2817
2810
  createContext as createContext2,
2818
2811
  useContext as useContext2,
2819
2812
  useEffect as useEffect7,
2813
+ useLayoutEffect,
2820
2814
  useMemo as useMemo13,
2821
- useRef as useRef6
2815
+ useRef as useRef6,
2816
+ useState as useState11
2822
2817
  } from "react";
2823
2818
 
2824
2819
  // src/react/canvas/events.ts
@@ -9867,8 +9862,8 @@ function CanvasProviderOwned({
9867
9862
  canvasOpts,
9868
9863
  builderOpts
9869
9864
  );
9870
- useHydrateEditorSnapshot(api, initialSnapshot);
9871
- return /* @__PURE__ */ jsx2(Ctx.Provider, { value: api, children });
9865
+ const hydrationReady = useHydrateEditorSnapshot(api, initialSnapshot);
9866
+ return /* @__PURE__ */ jsx2(Ctx.Provider, { value: api, children: hydrationReady ? children : null });
9872
9867
  }
9873
9868
  function useCanvasAPI() {
9874
9869
  const api = useContext2(Ctx);
@@ -9896,42 +9891,71 @@ function useCanvasFromBuilder(builder, opts) {
9896
9891
  function useCanvasFromExisting(api) {
9897
9892
  return api;
9898
9893
  }
9894
+ var NO_SNAPSHOT_HYDRATION_KEY = "__no_snapshot__";
9899
9895
  function useHydrateEditorSnapshot(api, snapshot) {
9900
- const hydratedRef = useRef6(null);
9901
- useEffect7(() => {
9902
- if (!(snapshot == null ? void 0 : snapshot.props)) return;
9903
- const hydrationKey = getSnapshotHydrationKey(snapshot);
9904
- if (hydratedRef.current === hydrationKey) return;
9905
- hydratedRef.current = hydrationKey;
9906
- hydrateEditorFromSnapshot(api, snapshot);
9907
- }, [api, snapshot]);
9896
+ const targetHydrationKey = useMemo13(() => {
9897
+ if (!(snapshot == null ? void 0 : snapshot.props)) return NO_SNAPSHOT_HYDRATION_KEY;
9898
+ return getSnapshotHydrationKey(snapshot);
9899
+ }, [snapshot]);
9900
+ const [hydratedKey, setHydratedKey] = useState11(
9901
+ NO_SNAPSHOT_HYDRATION_KEY
9902
+ );
9903
+ useLayoutEffect(() => {
9904
+ if (hydratedKey === targetHydrationKey) return;
9905
+ if (snapshot == null ? void 0 : snapshot.props) {
9906
+ hydrateEditorFromSnapshot(api, snapshot);
9907
+ }
9908
+ setHydratedKey(targetHydrationKey);
9909
+ }, [api, hydratedKey, snapshot, targetHydrationKey]);
9910
+ return hydratedKey === targetHydrationKey;
9908
9911
  }
9909
9912
  function getSnapshotHydrationKey(snapshot) {
9910
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
9913
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
9911
9914
  const meta = snapshot.meta;
9912
- const preferred = (_e = (_d = (_c = (_b = (_a = meta == null ? void 0 : meta.snapshot_id) != null ? _a : meta == null ? void 0 : meta.snapshotId) != null ? _b : meta == null ? void 0 : meta.version_id) != null ? _c : meta == null ? void 0 : meta.versionId) != null ? _d : meta == null ? void 0 : meta.branch_id) != null ? _e : meta == null ? void 0 : meta.branchId;
9913
- if (preferred != null) {
9914
- return String(preferred);
9915
- }
9916
- const layout = (_f = snapshot.layout) == null ? void 0 : _f.canvas;
9915
+ const metaKey = [
9916
+ (_b = (_a = meta == null ? void 0 : meta.snapshot_id) != null ? _a : meta == null ? void 0 : meta.snapshotId) != null ? _b : "",
9917
+ (_d = (_c = meta == null ? void 0 : meta.version_id) != null ? _c : meta == null ? void 0 : meta.versionId) != null ? _d : "",
9918
+ (_f = (_e = meta == null ? void 0 : meta.branch_id) != null ? _e : meta == null ? void 0 : meta.branchId) != null ? _f : ""
9919
+ ].join("|");
9920
+ const layout = (_g = snapshot.layout) == null ? void 0 : _g.canvas;
9917
9921
  const positionKeys = (layout == null ? void 0 : layout.positions) ? Object.keys(layout.positions).sort().join("|") : "";
9918
9922
  const viewport = (layout == null ? void 0 : layout.viewport) ? `${layout.viewport.x}:${layout.viewport.y}:${layout.viewport.zoom}` : "";
9919
9923
  const selection = (layout == null ? void 0 : layout.selection) ? Array.from(layout.selection).sort().join("|") : "";
9920
- const catalogKey = snapshot.catalog ? JSON.stringify({
9921
- opened: (_g = snapshot.catalog.opened) != null ? _g : null,
9922
- mode: (_h = snapshot.catalog.mode) != null ? _h : null,
9923
- tab: (_i = snapshot.catalog.tab) != null ? _i : null,
9924
- query: (_j = snapshot.catalog.query) != null ? _j : null
9925
- }) : "";
9924
+ const catalogKey = serializeForHydration(snapshot.catalog);
9926
9925
  return [
9927
- String(((_l = (_k = snapshot.props) == null ? void 0 : _k.fields) != null ? _l : []).length),
9928
- String(((_n = (_m = snapshot.props) == null ? void 0 : _m.filters) != null ? _n : []).length),
9926
+ metaKey,
9927
+ String(((_i = (_h = snapshot.props) == null ? void 0 : _h.fields) != null ? _i : []).length),
9928
+ String(((_k = (_j = snapshot.props) == null ? void 0 : _j.filters) != null ? _k : []).length),
9929
9929
  positionKeys,
9930
9930
  viewport,
9931
9931
  selection,
9932
9932
  catalogKey
9933
9933
  ].join("::");
9934
9934
  }
9935
+ function serializeForHydration(value) {
9936
+ if (value == null) return "";
9937
+ try {
9938
+ return JSON.stringify(sortForHydration(value));
9939
+ } catch {
9940
+ return "__unserializable__";
9941
+ }
9942
+ }
9943
+ function sortForHydration(value) {
9944
+ if (Array.isArray(value)) {
9945
+ return value.map((entry) => sortForHydration(entry));
9946
+ }
9947
+ if (value && typeof value === "object") {
9948
+ const entries = Object.entries(value).sort(
9949
+ ([a], [b]) => a.localeCompare(b)
9950
+ );
9951
+ const next = {};
9952
+ for (const [key, entry] of entries) {
9953
+ next[key] = sortForHydration(entry);
9954
+ }
9955
+ return next;
9956
+ }
9957
+ return value;
9958
+ }
9935
9959
  function hydrateEditorFromSnapshot(api, snapshot) {
9936
9960
  var _a;
9937
9961
  api.refreshGraph();
@@ -9946,30 +9970,66 @@ function hydrateCatalog(api, snapshot) {
9946
9970
  api.editor.clearCatalog();
9947
9971
  }
9948
9972
  function hydrateCanvasLayout(api, canvas) {
9973
+ var _a;
9949
9974
  if (!canvas) return;
9950
- if (canvas.positions) {
9975
+ const current = api.snapshot();
9976
+ if (canvas.positions && hasPositionDelta(canvas.positions, current.positions)) {
9951
9977
  api.setPositions(canvas.positions);
9952
9978
  }
9953
- if (canvas.viewport) {
9979
+ if (canvas.viewport && !sameViewport(canvas.viewport, current.viewport)) {
9954
9980
  api.setViewport(canvas.viewport);
9955
9981
  }
9982
+ const currentSelection = api.getSelection().map(String);
9956
9983
  if (canvas.selection) {
9957
9984
  const ids = Array.isArray(canvas.selection) ? canvas.selection : Array.from(canvas.selection);
9958
9985
  if (ids.length > 0) {
9959
- api.select(ids);
9960
- } else {
9986
+ if (!sameIdSet(ids.map(String), currentSelection)) {
9987
+ api.select(ids.map(String));
9988
+ }
9989
+ } else if (currentSelection.length > 0) {
9961
9990
  api.clearSelection();
9962
9991
  }
9963
- } else {
9992
+ } else if (currentSelection.length > 0) {
9964
9993
  api.clearSelection();
9965
9994
  }
9966
- if (canvas.highlighted) {
9967
- const ids = Array.isArray(canvas.highlighted) ? canvas.highlighted : Array.from(canvas.highlighted);
9968
- api.setHighlighted(ids);
9995
+ if ("highlighted" in canvas) {
9996
+ const highlighted = canvas.highlighted;
9997
+ const ids = highlighted ? Array.isArray(highlighted) ? highlighted : Array.from(highlighted) : [];
9998
+ const currentIds = Array.from((_a = current.highlighted) != null ? _a : []).map(String);
9999
+ const nextIds = ids.map(String);
10000
+ if (!sameIdSet(nextIds, currentIds)) {
10001
+ api.setHighlighted(nextIds);
10002
+ }
9969
10003
  }
9970
10004
  if ("hoverId" in canvas) {
9971
- api.setHover(canvas.hoverId);
10005
+ const nextHoverId = canvas.hoverId;
10006
+ if (current.hoverId !== nextHoverId) {
10007
+ api.setHover(nextHoverId);
10008
+ }
10009
+ }
10010
+ }
10011
+ function hasPositionDelta(next, current) {
10012
+ for (const id of Object.keys(next)) {
10013
+ const nextPos = next[id];
10014
+ const currentPos = current[id];
10015
+ if (!currentPos || currentPos.x !== nextPos.x || currentPos.y !== nextPos.y) {
10016
+ return true;
10017
+ }
10018
+ }
10019
+ return false;
10020
+ }
10021
+ function sameViewport(a, b) {
10022
+ if (!a && !b) return true;
10023
+ if (!a || !b) return false;
10024
+ return a.x === b.x && a.y === b.y && a.zoom === b.zoom;
10025
+ }
10026
+ function sameIdSet(a, b) {
10027
+ if (a.length !== b.length) return false;
10028
+ const set = new Set(a);
10029
+ for (const id of b) {
10030
+ if (!set.has(id)) return false;
9972
10031
  }
10032
+ return true;
9973
10033
  }
9974
10034
  function WorkspaceBootScreen({
9975
10035
  boot
@@ -11953,12 +12013,12 @@ function Workspace(props) {
11953
12013
  }
11954
12014
 
11955
12015
  // src/react/workspace/components/canvas.tsx
11956
- import { useMemo as useMemo19, useState as useState15 } from "react";
12016
+ import { useMemo as useMemo19, useState as useState16 } from "react";
11957
12017
  import { Background, ConnectionMode, MiniMap, ReactFlow } from "@xyflow/react";
11958
12018
  import "@xyflow/react/dist/style.css";
11959
12019
 
11960
12020
  // src/react/workspace/adapters/reactflow/adapter.ts
11961
- import { useCallback as useCallback16, useEffect as useEffect10, useMemo as useMemo17, useRef as useRef9, useState as useState13 } from "react";
12021
+ import { useCallback as useCallback16, useEffect as useEffect10, useMemo as useMemo17, useRef as useRef9, useState as useState14 } from "react";
11962
12022
  import { applyNodeChanges, applyEdgeChanges } from "@xyflow/react";
11963
12023
  function rafThrottle(fn, minMs = 80) {
11964
12024
  let frame = 0;
@@ -11984,7 +12044,7 @@ function rafThrottle(fn, minMs = 80) {
11984
12044
  });
11985
12045
  }
11986
12046
  var isCommentId = (id) => id.startsWith("c::");
11987
- function sameIdSet(a, b) {
12047
+ function sameIdSet2(a, b) {
11988
12048
  if (a.length !== b.length) return false;
11989
12049
  const s = new Set(a);
11990
12050
  for (const id of b) if (!s.has(id)) return false;
@@ -12062,7 +12122,7 @@ function useReactFlowAdapter(api, options = {}) {
12062
12122
  useEffect10(() => {
12063
12123
  afterConnectRef.current = options.afterConnect;
12064
12124
  }, [options.afterConnect]);
12065
- const [rf, setRF] = useState13(
12125
+ const [rf, setRF] = useState14(
12066
12126
  () => toRF(api.snapshot(), api, { nodeDecorators, edgeDecorators })
12067
12127
  );
12068
12128
  const relRef = useRef9(api.getEdgeRel());
@@ -12173,7 +12233,7 @@ function useReactFlowAdapter(api, options = {}) {
12173
12233
  const next = Array.from(keep);
12174
12234
  const currRaw = api.getSelection();
12175
12235
  const curr = Array.isArray(currRaw) ? currRaw : Array.from(currRaw);
12176
- if (!sameIdSet(next, curr)) {
12236
+ if (!sameIdSet2(next, curr)) {
12177
12237
  api.select(keep);
12178
12238
  }
12179
12239
  }
@@ -12291,7 +12351,7 @@ function useReactFlowAdapter(api, options = {}) {
12291
12351
  const next = nodes.map((n) => n.id);
12292
12352
  const currRaw = api.getSelection();
12293
12353
  const curr = Array.isArray(currRaw) ? currRaw : Array.from(currRaw);
12294
- if (sameIdSet(next, curr)) return;
12354
+ if (sameIdSet2(next, curr)) return;
12295
12355
  api.select(next);
12296
12356
  },
12297
12357
  [api]
@@ -12312,7 +12372,7 @@ function useReactFlowAdapter(api, options = {}) {
12312
12372
  }
12313
12373
 
12314
12374
  // src/react/workspace/adapters/reactflow/toolbar.tsx
12315
- import { useMemo as useMemo18, useState as useState14, useCallback as useCallback17 } from "react";
12375
+ import { useMemo as useMemo18, useState as useState15, useCallback as useCallback17 } from "react";
12316
12376
  import { useReactFlow } from "@xyflow/react";
12317
12377
 
12318
12378
  // src/react/workspace/adapters/reactflow/toolbar/merge.ts
@@ -12417,7 +12477,7 @@ function Toolbar({
12417
12477
  renderButton
12418
12478
  }) {
12419
12479
  const rf = useReactFlow();
12420
- const [openMenuId, setOpenMenuId] = useState14(null);
12480
+ const [openMenuId, setOpenMenuId] = useState15(null);
12421
12481
  const selectionCount = api.getSelection().length;
12422
12482
  const relation = api.getEdgeRel();
12423
12483
  const canUndo = true;
@@ -12948,8 +13008,8 @@ function Canvas({
12948
13008
  toolbarPositionClassName = "left-2 top-2",
12949
13009
  children
12950
13010
  }) {
12951
- const [showGrid, setShowGrid] = useState15(initialShowGrid);
12952
- const [showMiniMap, setShowMiniMap] = useState15(initialShowMiniMap);
13011
+ const [showGrid, setShowGrid] = useState16(initialShowGrid);
13012
+ const [showMiniMap, setShowMiniMap] = useState16(initialShowMiniMap);
12953
13013
  const {
12954
13014
  nodes,
12955
13015
  edges,