@supernova-studio/client 1.0.0-alpha.2 → 1.0.0-alpha.4

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.d.mts CHANGED
@@ -1135,10 +1135,14 @@ type LocalDocsPageGroup = OmitStrict<ElementGroup, "id" | "brandPersistentId" |
1135
1135
  };
1136
1136
  declare class LocalStorage {
1137
1137
  private readonly pages;
1138
+ private readonly deletedPageIds;
1138
1139
  private readonly groups;
1139
- addPage(page: LocalDocsPage): void;
1140
+ setPage(page: LocalDocsPage): void;
1141
+ deletePage(persistentId: string): void;
1142
+ tryGetPage(persistentId: string): LocalDocsPage | undefined;
1140
1143
  getPage(persistentId: string): LocalDocsPage;
1141
1144
  getAllPages(): LocalDocsPage[];
1145
+ getAllDeletedPages(): Set<string>;
1142
1146
  removePage(persistentId: string): void;
1143
1147
  }
1144
1148
 
@@ -1818,6 +1822,7 @@ declare function yjsToItemConfiguration(yDoc: Y.Doc): DTODocumentationPageRoomHe
1818
1822
  type VersionRoomDocsPage = DocumentationPageV2;
1819
1823
  type VersionRoomDocsPageGroup = ElementGroup;
1820
1824
  type VersionRoomBaseYDocState = {
1825
+ isLoaded: boolean;
1821
1826
  pages: VersionRoomDocsPage[];
1822
1827
  pageSnapshots: DocumentationPageSnapshot[];
1823
1828
  pageContentHashes: Record<string, string>;
@@ -92474,21 +92479,40 @@ type DocPageCreate = {
92474
92479
  parentPersistentId: string;
92475
92480
  afterPersistentId?: string;
92476
92481
  };
92482
+ type DocPageUpdate = {
92483
+ persistentId: string;
92484
+ title?: string;
92485
+ configuration?: DTODocumentationItemConfigurationV2;
92486
+ };
92477
92487
  type TransactionExecutor = (trx: DTOElementActionInput) => Promise<void>;
92478
92488
  declare class DocsStructureRepository {
92479
92489
  private readonly localState;
92480
92490
  private readonly yDoc;
92481
92491
  private readonly yObserver;
92482
- private yState;
92492
+ private _yState;
92493
+ private _currentHierarchy;
92483
92494
  private readonly trxQueue;
92484
92495
  private readonly hierarchyObservers;
92496
+ private readonly initCallbacks;
92485
92497
  constructor(yDoc: Y.Doc, transactionExecutor: TransactionExecutor);
92498
+ private get yState();
92499
+ get isInitialized(): boolean;
92500
+ onInitialized(): Promise<void>;
92486
92501
  addHierarchyObserver(observer: HierarchyObserver): void;
92487
92502
  removeHierarchyObserver(observer: HierarchyObserver): void;
92488
92503
  dispose(): void;
92504
+ get currentHierarchy(): DTODocumentationHierarchyV2;
92489
92505
  createPage(input: DocPageCreate): void;
92490
92506
  createPagePromise(input: DocPageCreate): Promise<void>;
92491
- private recalculateHierarchy;
92507
+ updatePage(update: DocPageUpdate): void;
92508
+ updatePagePromise(update: DocPageUpdate): Promise<void>;
92509
+ private updatePageLocally;
92510
+ deletePagePromise(persistentId: string): Promise<void>;
92511
+ deletePage(persistentId: string): void;
92512
+ private createLocalPageUpdate;
92513
+ private lookupPage;
92514
+ private refreshHierarchy;
92515
+ private calculateHierarchy;
92492
92516
  private onYUpdate;
92493
92517
  private calculateSortOrder;
92494
92518
  }
package/dist/index.d.ts CHANGED
@@ -1135,10 +1135,14 @@ type LocalDocsPageGroup = OmitStrict<ElementGroup, "id" | "brandPersistentId" |
1135
1135
  };
1136
1136
  declare class LocalStorage {
1137
1137
  private readonly pages;
1138
+ private readonly deletedPageIds;
1138
1139
  private readonly groups;
1139
- addPage(page: LocalDocsPage): void;
1140
+ setPage(page: LocalDocsPage): void;
1141
+ deletePage(persistentId: string): void;
1142
+ tryGetPage(persistentId: string): LocalDocsPage | undefined;
1140
1143
  getPage(persistentId: string): LocalDocsPage;
1141
1144
  getAllPages(): LocalDocsPage[];
1145
+ getAllDeletedPages(): Set<string>;
1142
1146
  removePage(persistentId: string): void;
1143
1147
  }
1144
1148
 
@@ -1818,6 +1822,7 @@ declare function yjsToItemConfiguration(yDoc: Y.Doc): DTODocumentationPageRoomHe
1818
1822
  type VersionRoomDocsPage = DocumentationPageV2;
1819
1823
  type VersionRoomDocsPageGroup = ElementGroup;
1820
1824
  type VersionRoomBaseYDocState = {
1825
+ isLoaded: boolean;
1821
1826
  pages: VersionRoomDocsPage[];
1822
1827
  pageSnapshots: DocumentationPageSnapshot[];
1823
1828
  pageContentHashes: Record<string, string>;
@@ -92474,21 +92479,40 @@ type DocPageCreate = {
92474
92479
  parentPersistentId: string;
92475
92480
  afterPersistentId?: string;
92476
92481
  };
92482
+ type DocPageUpdate = {
92483
+ persistentId: string;
92484
+ title?: string;
92485
+ configuration?: DTODocumentationItemConfigurationV2;
92486
+ };
92477
92487
  type TransactionExecutor = (trx: DTOElementActionInput) => Promise<void>;
92478
92488
  declare class DocsStructureRepository {
92479
92489
  private readonly localState;
92480
92490
  private readonly yDoc;
92481
92491
  private readonly yObserver;
92482
- private yState;
92492
+ private _yState;
92493
+ private _currentHierarchy;
92483
92494
  private readonly trxQueue;
92484
92495
  private readonly hierarchyObservers;
92496
+ private readonly initCallbacks;
92485
92497
  constructor(yDoc: Y.Doc, transactionExecutor: TransactionExecutor);
92498
+ private get yState();
92499
+ get isInitialized(): boolean;
92500
+ onInitialized(): Promise<void>;
92486
92501
  addHierarchyObserver(observer: HierarchyObserver): void;
92487
92502
  removeHierarchyObserver(observer: HierarchyObserver): void;
92488
92503
  dispose(): void;
92504
+ get currentHierarchy(): DTODocumentationHierarchyV2;
92489
92505
  createPage(input: DocPageCreate): void;
92490
92506
  createPagePromise(input: DocPageCreate): Promise<void>;
92491
- private recalculateHierarchy;
92507
+ updatePage(update: DocPageUpdate): void;
92508
+ updatePagePromise(update: DocPageUpdate): Promise<void>;
92509
+ private updatePageLocally;
92510
+ deletePagePromise(persistentId: string): Promise<void>;
92511
+ deletePage(persistentId: string): void;
92512
+ private createLocalPageUpdate;
92513
+ private lookupPage;
92514
+ private refreshHierarchy;
92515
+ private calculateHierarchy;
92492
92516
  private onYUpdate;
92493
92517
  private calculateSortOrder;
92494
92518
  }
package/dist/index.js CHANGED
@@ -8074,12 +8074,15 @@ var VersionRoomBaseYDoc = class {
8074
8074
  this.yDoc = yDoc;
8075
8075
  }
8076
8076
  getState() {
8077
+ const groups = this.getGroups();
8078
+ const isLoaded = !!groups.length;
8077
8079
  return {
8080
+ isLoaded,
8081
+ groups,
8082
+ pages: this.getPages(),
8078
8083
  approvals: this.getApprovals(),
8079
- groups: this.getGroups(),
8080
8084
  groupSnapshots: this.getGroupSnapshots(),
8081
8085
  pageContentHashes: this.getDocumentationPageContentHashes(),
8082
- pages: this.getPages(),
8083
8086
  pageSnapshots: this.getPageSnapshots(),
8084
8087
  settings: this.getDocumentationInternalSettings()
8085
8088
  };
@@ -12900,24 +12903,34 @@ var BackendVersionRoomYDoc = class {
12900
12903
  var LocalStorage = class {
12901
12904
  constructor() {
12902
12905
  __publicField(this, "pages", /* @__PURE__ */ new Map());
12906
+ __publicField(this, "deletedPageIds", /* @__PURE__ */ new Set());
12903
12907
  __publicField(this, "groups", /* @__PURE__ */ new Map());
12904
12908
  }
12905
- addPage(page) {
12909
+ setPage(page) {
12906
12910
  if (this.pages.has(page.persistentId)) {
12907
12911
  throw new Error(`Page with id ${page.persistentId} already exists`);
12908
12912
  }
12909
12913
  this.pages.set(page.persistentId, page);
12910
12914
  }
12915
+ deletePage(persistentId) {
12916
+ this.pages.delete(persistentId);
12917
+ this.deletedPageIds.add(persistentId);
12918
+ }
12919
+ tryGetPage(persistentId) {
12920
+ return this.pages.get(persistentId);
12921
+ }
12911
12922
  getPage(persistentId) {
12912
- const page = this.pages.get(persistentId);
12913
- if (!page) {
12923
+ const page = this.tryGetPage(persistentId);
12924
+ if (!page)
12914
12925
  throw new Error(`Page with id ${persistentId} doesn't exist`);
12915
- }
12916
12926
  return page;
12917
12927
  }
12918
12928
  getAllPages() {
12919
12929
  return Array.from(this.pages.values());
12920
12930
  }
12931
+ getAllDeletedPages() {
12932
+ return this.deletedPageIds;
12933
+ }
12921
12934
  removePage(persistentId) {
12922
12935
  this.pages.delete(persistentId);
12923
12936
  }
@@ -12931,19 +12944,42 @@ var DocsStructureRepository = class {
12931
12944
  __publicField(this, "localState", new LocalStorage());
12932
12945
  __publicField(this, "yDoc");
12933
12946
  __publicField(this, "yObserver");
12934
- __publicField(this, "yState");
12947
+ __publicField(this, "_yState");
12948
+ __publicField(this, "_currentHierarchy");
12935
12949
  __publicField(this, "trxQueue");
12936
12950
  __publicField(this, "hierarchyObservers", /* @__PURE__ */ new Set());
12951
+ __publicField(this, "initCallbacks", /* @__PURE__ */ new Set());
12937
12952
  this.yDoc = yDoc;
12938
- this.yState = new VersionRoomBaseYDoc(this.yDoc).getState();
12939
12953
  this.yObserver = yDoc.on("update", () => this.onYUpdate());
12954
+ this.onYUpdate();
12940
12955
  this.trxQueue = new TransactionQueue(transactionExecutor);
12941
12956
  }
12942
12957
  //
12958
+ // Convenience
12959
+ //
12960
+ get yState() {
12961
+ const yState = this._yState;
12962
+ if (!yState)
12963
+ throw SupernovaException.shouldNotHappen(`Accessing Y state before it was loaded`);
12964
+ return yState;
12965
+ }
12966
+ //
12943
12967
  // Lifecycle
12944
12968
  //
12969
+ get isInitialized() {
12970
+ return !!this._currentHierarchy;
12971
+ }
12972
+ onInitialized() {
12973
+ if (this.isInitialized)
12974
+ return Promise.resolve();
12975
+ return new Promise((resolve) => {
12976
+ this.initCallbacks.add(resolve);
12977
+ });
12978
+ }
12945
12979
  addHierarchyObserver(observer) {
12946
12980
  this.hierarchyObservers.add(observer);
12981
+ if (this._currentHierarchy)
12982
+ observer(this._currentHierarchy);
12947
12983
  }
12948
12984
  removeHierarchyObserver(observer) {
12949
12985
  this.hierarchyObservers.delete(observer);
@@ -12954,13 +12990,22 @@ var DocsStructureRepository = class {
12954
12990
  this.trxQueue.clear();
12955
12991
  }
12956
12992
  //
12993
+ // Accessors
12994
+ //
12995
+ get currentHierarchy() {
12996
+ const hierarchy = this._currentHierarchy;
12997
+ if (!hierarchy)
12998
+ throw new Error(`Hierarchy cannot be accessed while it's still loading`);
12999
+ return hierarchy;
13000
+ }
13001
+ //
12957
13002
  // Actions
12958
13003
  //
12959
13004
  createPage(input) {
12960
13005
  void this.createPage(input);
12961
13006
  }
12962
13007
  createPagePromise(input) {
12963
- this.localState.addPage({
13008
+ this.localState.setPage({
12964
13009
  createdAt: /* @__PURE__ */ new Date(),
12965
13010
  parentPersistentId: input.parentPersistentId,
12966
13011
  persistentId: input.persistentId,
@@ -12972,7 +13017,8 @@ var DocsStructureRepository = class {
12972
13017
  sortOrder: this.calculateSortOrder(input.parentPersistentId, input.afterPersistentId),
12973
13018
  designSystemVersionId: ""
12974
13019
  });
12975
- const promise = this.trxQueue.enqueue({
13020
+ this.refreshHierarchy();
13021
+ return this.trxQueue.enqueue({
12976
13022
  type: "DocumentationPageCreate",
12977
13023
  input: {
12978
13024
  persistentId: input.persistentId,
@@ -12982,27 +13028,104 @@ var DocsStructureRepository = class {
12982
13028
  configuration: input.configuration
12983
13029
  }
12984
13030
  });
12985
- this.recalculateHierarchy();
12986
- return promise;
13031
+ }
13032
+ updatePage(update) {
13033
+ void this.updatePagePromise(update);
13034
+ }
13035
+ updatePagePromise(update) {
13036
+ this.updatePageLocally(update);
13037
+ this.refreshHierarchy();
13038
+ return this.trxQueue.enqueue({
13039
+ type: "DocumentationPageUpdate",
13040
+ input: {
13041
+ id: update.persistentId,
13042
+ configuration: update.configuration,
13043
+ title: update.title
13044
+ }
13045
+ });
13046
+ }
13047
+ updatePageLocally(update) {
13048
+ const basePage = this.lookupPage(update.persistentId);
13049
+ this.localState.setPage(this.createLocalPageUpdate(basePage, update));
13050
+ }
13051
+ deletePagePromise(persistentId) {
13052
+ this.lookupPage(persistentId);
13053
+ this.localState.deletePage(persistentId);
13054
+ this.refreshHierarchy();
13055
+ return this.trxQueue.enqueue({
13056
+ type: "DocumentationPageDelete",
13057
+ input: {
13058
+ id: persistentId
13059
+ }
13060
+ });
13061
+ }
13062
+ deletePage(persistentId) {
13063
+ void this.deletePagePromise(persistentId);
13064
+ }
13065
+ createLocalPageUpdate(basePage, update) {
13066
+ const { title, configuration } = update;
13067
+ return {
13068
+ createdAt: basePage.createdAt,
13069
+ data: {
13070
+ configuration: _nullishCoalesce(configuration, () => ( basePage.data.configuration))
13071
+ },
13072
+ designSystemVersionId: basePage.designSystemVersionId,
13073
+ meta: { name: _nullishCoalesce(title, () => ( basePage.meta.name)) },
13074
+ parentPersistentId: basePage.parentPersistentId,
13075
+ persistentId: basePage.persistentId,
13076
+ shortPersistentId: basePage.shortPersistentId,
13077
+ sortOrder: basePage.sortOrder,
13078
+ updatedAt: /* @__PURE__ */ new Date(),
13079
+ slug: basePage.slug
13080
+ };
13081
+ }
13082
+ lookupPage(persistentId) {
13083
+ const localPageToUpdate = this.localState.tryGetPage(persistentId);
13084
+ if (localPageToUpdate)
13085
+ return localPageToUpdate;
13086
+ const remotePage = this.yState.pages.find((p) => p.persistentId === persistentId);
13087
+ if (remotePage)
13088
+ return remotePage;
13089
+ throw SupernovaException.notFound(`Page ${persistentId} was not found`);
12987
13090
  }
12988
13091
  //
12989
13092
  // Reactions
12990
13093
  //
12991
- recalculateHierarchy() {
13094
+ refreshHierarchy() {
13095
+ const hierarchy = this.calculateHierarchy();
13096
+ if (!hierarchy)
13097
+ return;
13098
+ this._currentHierarchy = hierarchy;
13099
+ this.initCallbacks.forEach((f) => f());
13100
+ this.initCallbacks.clear();
13101
+ this.hierarchyObservers.forEach((o) => o(hierarchy));
13102
+ }
13103
+ calculateHierarchy() {
13104
+ const yState = this._yState;
13105
+ if (!yState)
13106
+ return;
13107
+ const allPagesById = mapByUnique(yState.pages, (p) => p.persistentId);
13108
+ this.localState.getAllPages().forEach((p) => {
13109
+ allPagesById.set(p.persistentId, p);
13110
+ });
13111
+ this.localState.getAllDeletedPages().forEach((id) => allPagesById.delete(id));
12992
13112
  const hierarchy = computeDocsHierarchy({
12993
- approvals: this.yState.approvals,
12994
- groups: this.yState.groups,
12995
- groupSnapshots: this.yState.groupSnapshots,
12996
- pageContentHashes: this.yState.pageContentHashes,
12997
- pages: [...this.yState.pages, ...this.localState.getAllPages()],
12998
- pageSnapshots: this.yState.pageSnapshots,
12999
- settings: this.yState.settings
13113
+ approvals: yState.approvals,
13114
+ groups: yState.groups,
13115
+ groupSnapshots: yState.groupSnapshots,
13116
+ pageContentHashes: yState.pageContentHashes,
13117
+ pages: Array.from(allPagesById.values()),
13118
+ pageSnapshots: yState.pageSnapshots,
13119
+ settings: yState.settings
13000
13120
  });
13001
- this.hierarchyObservers.forEach((o) => o(hierarchy));
13121
+ return hierarchy;
13002
13122
  }
13003
13123
  onYUpdate() {
13004
- this.yState = new VersionRoomBaseYDoc(this.yDoc).getState();
13005
- this.recalculateHierarchy();
13124
+ const newState = new VersionRoomBaseYDoc(this.yDoc).getState();
13125
+ if (newState.groups.length) {
13126
+ this._yState = newState;
13127
+ this.refreshHierarchy();
13128
+ }
13006
13129
  }
13007
13130
  //
13008
13131
  // Utils