@powerhousedao/connect 6.0.0-dev.88 → 6.0.0-dev.89

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/src/main.js CHANGED
@@ -7982,7 +7982,7 @@ var init_package = __esm(() => {
7982
7982
  package_default = {
7983
7983
  name: "@powerhousedao/connect",
7984
7984
  productName: "Powerhouse-Connect",
7985
- version: "6.0.0-dev.87",
7985
+ version: "6.0.0-dev.88",
7986
7986
  description: "Powerhouse Connect",
7987
7987
  main: "dist/index.html",
7988
7988
  type: "module",
@@ -8121,6 +8121,7 @@ import { isUndoRedo } from "document-model/core";
8121
8121
  import { deriveOperationId as deriveOperationId2 } from "document-model/core";
8122
8122
  import { ConsoleLogger } from "document-model/core";
8123
8123
  import { AbortError } from "document-drive/utils/errors";
8124
+ import { hashDocumentStateForScope } from "document-model/core";
8124
8125
  function createDocumentAction(input) {
8125
8126
  return {
8126
8127
  id: generateId(),
@@ -15415,6 +15416,10 @@ class RingBuffer {
15415
15416
  return this.size;
15416
15417
  }
15417
15418
  }
15419
+ function extractModuleVersion(doc) {
15420
+ const v = doc.state.document.version;
15421
+ return v === 0 ? undefined : v;
15422
+ }
15418
15423
 
15419
15424
  class KyselyWriteCache {
15420
15425
  streams;
@@ -15579,7 +15584,7 @@ class KyselyWriteCache {
15579
15584
  throw new Error(`Failed to rebuild document ${documentId}: CREATE_DOCUMENT action missing model in input`);
15580
15585
  }
15581
15586
  document2 = createDocumentFromAction(documentCreateAction);
15582
- const docModule = this.registry.getModule(documentType);
15587
+ let docModule = this.registry.getModule(documentType, extractModuleVersion(document2));
15583
15588
  const docScopeOps = await this.operationStore.getSince(documentId, "document", branch, 0, undefined, undefined, signal);
15584
15589
  for (const operation of docScopeOps.results) {
15585
15590
  if (operation.index === 0) {
@@ -15588,6 +15593,7 @@ class KyselyWriteCache {
15588
15593
  if (operation.action.type === "UPGRADE_DOCUMENT") {
15589
15594
  const upgradeAction = operation.action;
15590
15595
  document2 = applyUpgradeDocumentAction(document2, upgradeAction);
15596
+ docModule = this.registry.getModule(documentType, extractModuleVersion(document2));
15591
15597
  } else if (operation.action.type === "DELETE_DOCUMENT") {
15592
15598
  applyDeleteDocumentAction(document2, operation.action);
15593
15599
  } else {
@@ -15599,7 +15605,7 @@ class KyselyWriteCache {
15599
15605
  }
15600
15606
  }
15601
15607
  }
15602
- const module = this.registry.getModule(documentType);
15608
+ const module = this.registry.getModule(documentType, extractModuleVersion(document2));
15603
15609
  let cursor = undefined;
15604
15610
  const pageSize = 100;
15605
15611
  let hasMorePages;
@@ -18037,6 +18043,25 @@ class KyselyKeyframeStore {
18037
18043
  document: row.document
18038
18044
  };
18039
18045
  }
18046
+ async listKeyframes(documentId, scope, branch, signal) {
18047
+ if (signal?.aborted) {
18048
+ throw new Error("Operation aborted");
18049
+ }
18050
+ let query = this.queryExecutor.selectFrom("Keyframe").selectAll().where("documentId", "=", documentId).orderBy("revision", "asc");
18051
+ if (scope !== undefined) {
18052
+ query = query.where("scope", "=", scope);
18053
+ }
18054
+ if (branch !== undefined) {
18055
+ query = query.where("branch", "=", branch);
18056
+ }
18057
+ const rows = await query.execute();
18058
+ return rows.map((row) => ({
18059
+ scope: row.scope,
18060
+ branch: row.branch,
18061
+ revision: row.revision,
18062
+ document: row.document
18063
+ }));
18064
+ }
18040
18065
  async deleteKeyframes(documentId, scope, branch, signal) {
18041
18066
  if (signal?.aborted) {
18042
18067
  throw new Error("Operation aborted");
@@ -22300,6 +22325,118 @@ function relationalDbToQueryBuilder(query) {
22300
22325
  withSchema: (schema) => relationalDbToQueryBuilder(query.withSchema(schema))
22301
22326
  };
22302
22327
  }
22328
+
22329
+ class DocumentIntegrityService {
22330
+ keyframeStore;
22331
+ operationStore;
22332
+ writeCache;
22333
+ documentView;
22334
+ documentModelRegistry;
22335
+ constructor(keyframeStore, operationStore, writeCache, documentView, documentModelRegistry) {
22336
+ this.keyframeStore = keyframeStore;
22337
+ this.operationStore = operationStore;
22338
+ this.writeCache = writeCache;
22339
+ this.documentView = documentView;
22340
+ this.documentModelRegistry = documentModelRegistry;
22341
+ }
22342
+ async validateDocument(documentId, branch = "main", signal) {
22343
+ const keyframeIssues = [];
22344
+ const snapshotIssues = [];
22345
+ const replayCache = new KyselyWriteCache(nullKeyframeStore, this.operationStore, this.documentModelRegistry, {
22346
+ maxDocuments: 1,
22347
+ ringBufferSize: 1,
22348
+ keyframeInterval: Number.MAX_SAFE_INTEGER
22349
+ });
22350
+ const keyframes = await this.keyframeStore.listKeyframes(documentId, undefined, branch, signal);
22351
+ for (const keyframe of keyframes) {
22352
+ if (signal?.aborted) {
22353
+ throw new Error("Operation aborted");
22354
+ }
22355
+ replayCache.invalidate(documentId, keyframe.scope, branch);
22356
+ const replayedDoc = await replayCache.getState(documentId, keyframe.scope, branch, keyframe.revision, signal);
22357
+ const kfHash = hashDocumentStateForScope(keyframe.document, keyframe.scope);
22358
+ const replayHash = hashDocumentStateForScope(replayedDoc, keyframe.scope);
22359
+ if (kfHash !== replayHash) {
22360
+ keyframeIssues.push({
22361
+ scope: keyframe.scope,
22362
+ branch,
22363
+ revision: keyframe.revision,
22364
+ keyframeHash: kfHash,
22365
+ replayedHash: replayHash
22366
+ });
22367
+ }
22368
+ }
22369
+ let currentDoc;
22370
+ try {
22371
+ currentDoc = await this.documentView.get(documentId);
22372
+ } catch {
22373
+ return {
22374
+ documentId,
22375
+ isConsistent: keyframeIssues.length === 0,
22376
+ keyframeIssues,
22377
+ snapshotIssues
22378
+ };
22379
+ }
22380
+ const revisions = await this.operationStore.getRevisions(documentId, branch, signal);
22381
+ const allScopes = Object.keys(revisions.revision);
22382
+ for (const scope of allScopes) {
22383
+ if (scope === "document")
22384
+ continue;
22385
+ replayCache.invalidate(documentId, scope, branch);
22386
+ let replayedDoc;
22387
+ try {
22388
+ replayedDoc = await replayCache.getState(documentId, scope, branch, undefined, signal);
22389
+ } catch {
22390
+ if (signal?.aborted) {
22391
+ throw new Error("Operation aborted");
22392
+ }
22393
+ continue;
22394
+ }
22395
+ const snapshotHash = hashDocumentStateForScope(currentDoc, scope);
22396
+ const replayHash = hashDocumentStateForScope(replayedDoc, scope);
22397
+ if (snapshotHash !== replayHash) {
22398
+ snapshotIssues.push({
22399
+ scope,
22400
+ branch,
22401
+ snapshotHash,
22402
+ replayedHash: replayHash
22403
+ });
22404
+ }
22405
+ }
22406
+ return {
22407
+ documentId,
22408
+ isConsistent: keyframeIssues.length === 0 && snapshotIssues.length === 0,
22409
+ keyframeIssues,
22410
+ snapshotIssues
22411
+ };
22412
+ }
22413
+ async rebuildKeyframes(documentId, branch = "main", signal) {
22414
+ const deleted = await this.keyframeStore.deleteKeyframes(documentId, undefined, branch, signal);
22415
+ return {
22416
+ documentId,
22417
+ keyframesDeleted: deleted,
22418
+ scopesInvalidated: 0
22419
+ };
22420
+ }
22421
+ async rebuildSnapshots(documentId, branch = "main", signal) {
22422
+ const scopes = await this.discoverScopes(documentId, branch, signal);
22423
+ for (const scope of scopes) {
22424
+ if (signal?.aborted) {
22425
+ throw new Error("Operation aborted");
22426
+ }
22427
+ this.writeCache.invalidate(documentId, scope, branch);
22428
+ }
22429
+ return {
22430
+ documentId,
22431
+ keyframesDeleted: 0,
22432
+ scopesInvalidated: scopes.length
22433
+ };
22434
+ }
22435
+ async discoverScopes(documentId, branch, signal) {
22436
+ const revisions = await this.operationStore.getRevisions(documentId, branch, signal);
22437
+ return Object.keys(revisions.revision);
22438
+ }
22439
+ }
22303
22440
  var __defProp2, __export2 = (target, all) => {
22304
22441
  for (var name in all)
22305
22442
  __defProp2(target, name, {
@@ -22442,7 +22579,7 @@ var __defProp2, __export2 = (target, all) => {
22442
22579
  }
22443
22580
  }
22444
22581
  return maxOrdinal;
22445
- }, SyncStatus, cachedEncoder, LOG2_26, IS_RELATIONAL_DB_PROCESSOR, RelationalDbProcessor;
22582
+ }, SyncStatus, cachedEncoder, LOG2_26, IS_RELATIONAL_DB_PROCESSOR, RelationalDbProcessor, nullKeyframeStore;
22446
22583
  var init_src = __esm(() => {
22447
22584
  __defProp2 = Object.defineProperty;
22448
22585
  byteToHex = [];
@@ -27702,6 +27839,12 @@ var init_src = __esm(() => {
27702
27839
  return relationalDbToQueryBuilder(this.relationalDb);
27703
27840
  }
27704
27841
  };
27842
+ nullKeyframeStore = {
27843
+ putKeyframe: () => Promise.resolve(),
27844
+ findNearestKeyframe: () => Promise.resolve(undefined),
27845
+ listKeyframes: () => Promise.resolve([]),
27846
+ deleteKeyframes: () => Promise.resolve(0)
27847
+ };
27705
27848
  });
27706
27849
 
27707
27850
  // ../../packages/reactor-browser/dist/src/index.js
@@ -27916,6 +28059,7 @@ __export(exports_src, {
27916
28059
  InMemoryQueue: () => InMemoryQueue,
27917
28060
  ISSUER_TYPE: () => ISSUER_TYPE,
27918
28061
  GqlRequestChannel: () => GqlRequestChannel,
28062
+ DocumentIntegrityService: () => DocumentIntegrityService,
27919
28063
  DocumentChangeType: () => DocumentChangeType,
27920
28064
  DocumentCache: () => DocumentCache,
27921
28065
  DisconnectIcon: () => DisconnectIcon,
@@ -263718,13 +263862,55 @@ var init_useDbExplorer = __esm(() => {
263718
263862
  ];
263719
263863
  });
263720
263864
 
263721
- // src/components/modal/modals/InspectorModal/useProcessorsInspector.ts
263865
+ // src/components/modal/modals/InspectorModal/useIntegrityInspector.ts
263722
263866
  import { useCallback as useCallback38, useMemo as useMemo18 } from "react";
263867
+ function useIntegrityInspector() {
263868
+ const reactorClientModule = useReactorClientModule2();
263869
+ const reactorModule = reactorClientModule?.reactorModule;
263870
+ const service = useMemo18(() => {
263871
+ if (!reactorModule)
263872
+ return;
263873
+ return new DocumentIntegrityService(reactorModule.keyframeStore, reactorModule.operationStore, reactorModule.writeCache, reactorModule.documentView, reactorModule.documentModelRegistry);
263874
+ }, [reactorModule]);
263875
+ const onValidate = useCallback38(async (documentId, branch) => {
263876
+ if (!service) {
263877
+ throw new Error("Reactor module not available");
263878
+ }
263879
+ return service.validateDocument(documentId, branch);
263880
+ }, [service]);
263881
+ const onRebuildKeyframes = useCallback38(async (documentId, branch) => {
263882
+ if (!service) {
263883
+ throw new Error("Reactor module not available");
263884
+ }
263885
+ return service.rebuildKeyframes(documentId, branch);
263886
+ }, [service]);
263887
+ const onRebuildSnapshots = useCallback38(async (documentId, branch) => {
263888
+ if (!service) {
263889
+ throw new Error("Reactor module not available");
263890
+ }
263891
+ return service.rebuildSnapshots(documentId, branch);
263892
+ }, [service]);
263893
+ if (!service) {
263894
+ return;
263895
+ }
263896
+ return {
263897
+ onValidate,
263898
+ onRebuildKeyframes,
263899
+ onRebuildSnapshots
263900
+ };
263901
+ }
263902
+ var init_useIntegrityInspector = __esm(() => {
263903
+ init_src2();
263904
+ init_connect2();
263905
+ });
263906
+
263907
+ // src/components/modal/modals/InspectorModal/useProcessorsInspector.ts
263908
+ import { useCallback as useCallback39, useMemo as useMemo19 } from "react";
263723
263909
  function useProcessorsInspector() {
263724
263910
  const reactorClientModule = useReactorClientModule2();
263725
263911
  const processorManager = reactorClientModule?.reactorModule?.processorManager;
263726
- const hasProcessorManager = useMemo18(() => processorManager != null, [processorManager]);
263727
- const getProcessors = useCallback38(async () => {
263912
+ const hasProcessorManager = useMemo19(() => processorManager != null, [processorManager]);
263913
+ const getProcessors = useCallback39(async () => {
263728
263914
  if (!processorManager) {
263729
263915
  return [];
263730
263916
  }
@@ -263739,7 +263925,7 @@ function useProcessorsInspector() {
263739
263925
  lastErrorTimestamp: tracked.lastErrorTimestamp
263740
263926
  }));
263741
263927
  }, [processorManager]);
263742
- const onRetry = useCallback38(async (processorId) => {
263928
+ const onRetry = useCallback39(async (processorId) => {
263743
263929
  if (!processorManager)
263744
263930
  return;
263745
263931
  const tracked = processorManager.get(processorId);
@@ -263760,17 +263946,17 @@ var init_useProcessorsInspector = __esm(() => {
263760
263946
  });
263761
263947
 
263762
263948
  // src/components/modal/modals/InspectorModal/useQueueInspector.ts
263763
- import { useCallback as useCallback39, useMemo as useMemo19 } from "react";
263949
+ import { useCallback as useCallback40, useMemo as useMemo20 } from "react";
263764
263950
  function useQueueInspector() {
263765
263951
  const reactorClientModule = useReactorClientModule2();
263766
263952
  const queue = reactorClientModule?.reactorModule?.queue;
263767
- const inMemoryQueue = useMemo19(() => {
263953
+ const inMemoryQueue = useMemo20(() => {
263768
263954
  if (queue instanceof InMemoryQueue) {
263769
263955
  return queue;
263770
263956
  }
263771
263957
  return;
263772
263958
  }, [queue]);
263773
- const getQueueState = useCallback39(async () => {
263959
+ const getQueueState = useCallback40(async () => {
263774
263960
  if (!inMemoryQueue) {
263775
263961
  return {
263776
263962
  isPaused: false,
@@ -263799,12 +263985,12 @@ function useQueueInspector() {
263799
263985
  totalExecuting: executingJobs.length
263800
263986
  };
263801
263987
  }, [inMemoryQueue]);
263802
- const onPause = useCallback39(async () => {
263988
+ const onPause = useCallback40(async () => {
263803
263989
  if (inMemoryQueue) {
263804
263990
  inMemoryQueue.pause();
263805
263991
  }
263806
263992
  }, [inMemoryQueue]);
263807
- const onResume = useCallback39(async () => {
263993
+ const onResume = useCallback40(async () => {
263808
263994
  if (inMemoryQueue) {
263809
263995
  await inMemoryQueue.resume();
263810
263996
  }
@@ -263824,17 +264010,17 @@ var init_useQueueInspector = __esm(() => {
263824
264010
  });
263825
264011
 
263826
264012
  // src/components/modal/modals/InspectorModal/useRemotesInspector.ts
263827
- import { useCallback as useCallback40 } from "react";
264013
+ import { useCallback as useCallback41 } from "react";
263828
264014
  function useRemotesInspector() {
263829
264015
  const syncManager = useSync2();
263830
264016
  if (!syncManager) {
263831
264017
  throw new Error("Sync manager not found");
263832
264018
  }
263833
264019
  const connectionStates = useConnectionStates2();
263834
- const getRemotes = useCallback40(() => {
264020
+ const getRemotes = useCallback41(() => {
263835
264021
  return Promise.resolve(syncManager.list());
263836
264022
  }, [syncManager]);
263837
- const removeRemote = useCallback40((name6) => syncManager.remove(name6), [syncManager]);
264023
+ const removeRemote = useCallback41((name6) => syncManager.remove(name6), [syncManager]);
263838
264024
  return {
263839
264025
  getRemotes,
263840
264026
  removeRemote,
@@ -263855,6 +264041,7 @@ var DEFAULT_PAGE_SIZE = 25, InspectorModal = () => {
263855
264041
  const { getRemotes, removeRemote, connectionStates } = useRemotesInspector();
263856
264042
  const queueInspectorProps = useQueueInspector();
263857
264043
  const processorsInspectorProps = useProcessorsInspector();
264044
+ const integrityInspectorProps = useIntegrityInspector();
263858
264045
  return /* @__PURE__ */ jsxDEV27(ConnectInspectorModal, {
263859
264046
  open,
263860
264047
  onOpenChange: (status) => {
@@ -263876,13 +264063,15 @@ var DEFAULT_PAGE_SIZE = 25, InspectorModal = () => {
263876
264063
  connectionStates
263877
264064
  },
263878
264065
  queueInspectorProps,
263879
- processorsInspectorProps
264066
+ processorsInspectorProps,
264067
+ integrityInspectorProps
263880
264068
  }, undefined, false, undefined, this);
263881
264069
  };
263882
264070
  var init_InspectorModal = __esm(() => {
263883
264071
  init_src2();
263884
264072
  init_src2();
263885
264073
  init_useDbExplorer();
264074
+ init_useIntegrityInspector();
263886
264075
  init_useProcessorsInspector();
263887
264076
  init_useQueueInspector();
263888
264077
  init_useRemotesInspector();
@@ -264441,12 +264630,12 @@ var CookieBanner = () => {
264441
264630
  // src/components/document-editor-container.tsx
264442
264631
  init_services();
264443
264632
  init_src2();
264444
- import { useCallback as useCallback41, useMemo as useMemo20 } from "react";
264633
+ import { useCallback as useCallback42, useMemo as useMemo21 } from "react";
264445
264634
  import { jsxDEV as jsxDEV32 } from "react/jsx-dev-runtime";
264446
264635
  function DocumentEditorContainer() {
264447
264636
  const [selectedDocument] = useSelectedDocument();
264448
264637
  const parentFolder = useNodeParentFolderById(selectedDocument.header.id);
264449
- const onExport = useCallback41(() => {
264638
+ const onExport = useCallback42(() => {
264450
264639
  const validationErrors = validateDocument(selectedDocument);
264451
264640
  if (validationErrors.length) {
264452
264641
  showPHModal({
@@ -264461,10 +264650,10 @@ function DocumentEditorContainer() {
264461
264650
  });
264462
264651
  }
264463
264652
  }, [selectedDocument]);
264464
- const onOpenSwitchboardLink = useMemo20(() => {
264653
+ const onOpenSwitchboardLink = useMemo21(() => {
264465
264654
  return async () => {};
264466
264655
  }, []);
264467
- const onClose = useCallback41(() => {
264656
+ const onClose = useCallback42(() => {
264468
264657
  setSelectedNode(parentFolder);
264469
264658
  }, [parentFolder, setSelectedNode]);
264470
264659
  return /* @__PURE__ */ jsxDEV32("div", {
@@ -264555,13 +264744,13 @@ function DriveEditorContainer() {
264555
264744
  init_src2();
264556
264745
  init_connect2();
264557
264746
  import { Icon as Icon3 } from "@powerhousedao/design-system";
264558
- import { useMemo as useMemo21 } from "react";
264747
+ import { useMemo as useMemo23 } from "react";
264559
264748
  import { jsxDEV as jsxDEV36 } from "react/jsx-dev-runtime";
264560
264749
  function DriveIcon({
264561
264750
  drive
264562
264751
  }) {
264563
264752
  const remotes = useSyncList2();
264564
- const isRemoteDrive = useMemo21(() => {
264753
+ const isRemoteDrive = useMemo23(() => {
264565
264754
  if (!drive)
264566
264755
  return false;
264567
264756
  return remotes.some((remote) => remote.collectionId === driveCollectionId("main", drive.header.id));
@@ -264590,12 +264779,12 @@ function DriveIcon({
264590
264779
  init_src2();
264591
264780
  init_toast();
264592
264781
  import { PackageInstallModal } from "@powerhousedao/design-system/connect";
264593
- import { useCallback as useCallback42 } from "react";
264782
+ import { useCallback as useCallback43 } from "react";
264594
264783
  import { jsxDEV as jsxDEV37 } from "react/jsx-dev-runtime";
264595
264784
  var PackageInstallPrompt = () => {
264596
264785
  const packageManager = useVetraPackageManager();
264597
264786
  const pending = usePendingInstallations();
264598
- const handleInstall = useCallback42(async (packageName) => {
264787
+ const handleInstall = useCallback43(async (packageName) => {
264599
264788
  if (!packageManager)
264600
264789
  return;
264601
264790
  try {
@@ -264610,7 +264799,7 @@ var PackageInstallPrompt = () => {
264610
264799
  });
264611
264800
  }
264612
264801
  }, [packageManager]);
264613
- const handleDismiss = useCallback42((packageName) => {
264802
+ const handleDismiss = useCallback43((packageName) => {
264614
264803
  if (!packageManager)
264615
264804
  return;
264616
264805
  packageManager.rejectInstallation(packageName);
@@ -265674,13 +265863,13 @@ var gql = (chunks, ...variables) => {
265674
265863
  };
265675
265864
  // src/pages/demo/atlas-import.tsx
265676
265865
  init_dist4();
265677
- import { useCallback as useCallback43, useEffect as useEffect53, useMemo as useMemo23, useRef as useRef32, useState as useState44 } from "react";
265866
+ import { useCallback as useCallback44, useEffect as useEffect53, useMemo as useMemo25, useRef as useRef32, useState as useState44 } from "react";
265678
265867
  import { jsxDEV as jsxDEV45, Fragment as Fragment9 } from "react/jsx-dev-runtime";
265679
265868
  var REACTOR_URL = "https://apps.powerhouse.io/sky-atlas/staging/switchboard";
265680
265869
  var MIN_LOADING_TIME = 2000;
265681
265870
  function useReactorUrl() {
265682
265871
  const { search } = useLocation();
265683
- return useMemo23(() => {
265872
+ return useMemo25(() => {
265684
265873
  const params = new URLSearchParams(search);
265685
265874
  const url2 = params.get("reactorUrl") ?? REACTOR_URL;
265686
265875
  return url2.endsWith("/") ? url2 : `${url2}/`;
@@ -265716,12 +265905,12 @@ function AtlasImport() {
265716
265905
  status.current = "forked";
265717
265906
  setDriveId(driveId2);
265718
265907
  }
265719
- const redirectToDrive = useCallback43(() => {
265908
+ const redirectToDrive = useCallback44(() => {
265720
265909
  if (driveId && !loading2) {
265721
265910
  navigate(`/d/${driveId}`, { replace: true });
265722
265911
  }
265723
265912
  }, [driveId, navigate, loading2]);
265724
- const addForkDrive = useCallback43(async (driveId2) => {
265913
+ const addForkDrive = useCallback44(async (driveId2) => {
265725
265914
  console.log("Adding remote drive:", driveId2);
265726
265915
  const driveUrl = `${reactorUrl}d/${driveId2}`;
265727
265916
  try {