@powerhousedao/connect 1.0.8 → 1.0.9-dev.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.
Files changed (29) hide show
  1. package/dist/.env +0 -5
  2. package/dist/assets/{app-D3TxLTK-.css → app-D9QJBr8i.css} +19 -1
  3. package/dist/assets/{app-Bw1Ba-jV.js → app-Uu65do7x.js} +342 -384
  4. package/dist/assets/{app-loader-CjrEwupY.css → app-loader-Bnp0H-wa.css} +16 -0
  5. package/dist/assets/{app-loader-KTD3Q6e9.js → app-loader-BnxLpX27.js} +445 -320
  6. package/dist/assets/{ccip-D3HujWHr.js → ccip-CpD5P3bc.js} +3 -3
  7. package/dist/assets/{content-D3TuBhK9.js → content-DV_bRXbH.js} +3 -3
  8. package/dist/assets/{index-DpasqVlD.js → index-B4m3ucR9.js} +3 -3
  9. package/dist/assets/{index-DsNVpRhT.js → index-Ch_NXi_f.js} +3 -3
  10. package/dist/assets/{index-yFk8X8m1.js → index-yrCJMRn6.js} +4 -4
  11. package/dist/assets/{main.CzEw2R-H.js → main.CpORyZoE.js} +1 -1
  12. package/dist/external-packages.js +5 -0
  13. package/dist/hmr.js +4 -1
  14. package/dist/index.html +1 -4
  15. package/dist/modules/@powerhousedao/reactor-browser/{chunk-POMUCSTC.js → chunk-6MBHOHAA.js} +74 -20
  16. package/dist/modules/@powerhousedao/reactor-browser/{chunk-4LZZ55AN.js → chunk-IC6B3767.js} +1 -1
  17. package/dist/modules/@powerhousedao/reactor-browser/{chunk-YOX3ZAET.js → chunk-N5UNGAA6.js} +256 -183
  18. package/dist/modules/@powerhousedao/reactor-browser/{chunk-P46ZMPJ3.js → chunk-OYYVE7RP.js} +1 -1
  19. package/dist/modules/@powerhousedao/reactor-browser/{chunk-6AXML2S3.js → chunk-UDKYG6I4.js} +1 -1
  20. package/dist/modules/@powerhousedao/reactor-browser/context/index.js +2 -2
  21. package/dist/modules/@powerhousedao/reactor-browser/context/read-mode.js +2 -2
  22. package/dist/modules/@powerhousedao/reactor-browser/hooks/index.js +3 -3
  23. package/dist/modules/@powerhousedao/reactor-browser/hooks/useDriveActions.js +2 -2
  24. package/dist/modules/@powerhousedao/reactor-browser/hooks/useDriveActionsWithUiNodes.js +3 -3
  25. package/dist/modules/@powerhousedao/reactor-browser/index.js +5 -5
  26. package/dist/modules/@powerhousedao/reactor-browser/reactor.js +2 -2
  27. package/dist/swEnv.js +0 -3
  28. package/dist/vite-envs.sh +1 -28
  29. package/package.json +9 -9
@@ -1,4 +1,4 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/app-Bw1Ba-jV.js","assets/main.CzEw2R-H.js","assets/app-D3TxLTK-.css"])))=>i.map(i=>d[i]);
1
+ const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/app-Uu65do7x.js","assets/main.CpORyZoE.js","assets/app-D9QJBr8i.css"])))=>i.map(i=>d[i]);
2
2
  var __defProp = Object.defineProperty;
3
3
  var __typeError = (msg) => {
4
4
  throw TypeError(msg);
@@ -11,7 +11,7 @@ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot
11
11
  var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
12
12
  var __privateMethod = (obj, member, method) => (__accessCheck(obj, member, "access private method"), method);
13
13
  var _tags, _levelString, _errorHandler, _ConsoleLogger_instances, levelValue_get, _getDocumentModelModule, _drives, _ReadModeService_instances, parseGraphQLErrors_fn, fetchDrive_fn, _a, _ServiceWorkerManager_instances, handleServiceWorkerMessage_fn, handleServiceWorker_fn;
14
- import { _ as __vitePreload } from "./main.CzEw2R-H.js";
14
+ import { _ as __vitePreload } from "./main.CpORyZoE.js";
15
15
  import { jsx, jsxs } from "react/jsx-runtime";
16
16
  import { useState, useEffect, Suspense, lazy } from "react";
17
17
  function _mergeNamespaces(n, m) {
@@ -86,34 +86,78 @@ class DocumentEditorDebugTools {
86
86
  this.document = void 0;
87
87
  }
88
88
  }
89
+ const trimResultingState = (document) => {
90
+ const global2 = document.operations.global.map((e) => {
91
+ delete e.resultingState;
92
+ return e;
93
+ });
94
+ const local = document.operations.local.map((e) => {
95
+ delete e.resultingState;
96
+ return e;
97
+ });
98
+ return { ...document, operations: { global: global2, local } };
99
+ };
89
100
  class InMemoryCache {
90
101
  constructor() {
91
- __publicField(this, "cache", /* @__PURE__ */ new Map());
102
+ __publicField(this, "idTodocument", /* @__PURE__ */ new Map());
103
+ __publicField(this, "idToDrive", /* @__PURE__ */ new Map());
104
+ __publicField(this, "slugToDriveId", /* @__PURE__ */ new Map());
92
105
  }
93
- async setDocument(drive, id, document) {
94
- var _a2;
95
- const global2 = document.operations.global.map((e) => {
96
- delete e.resultingState;
97
- return e;
98
- });
99
- const local = document.operations.local.map((e) => {
100
- delete e.resultingState;
101
- return e;
102
- });
103
- const doc = { ...document, operations: { global: global2, local } };
104
- if (!this.cache.has(drive)) {
105
- this.cache.set(drive, /* @__PURE__ */ new Map());
106
+ clear() {
107
+ this.idTodocument.clear();
108
+ this.idToDrive.clear();
109
+ this.slugToDriveId.clear();
110
+ }
111
+ /////////////////////////////////////////////////////////////////////////////
112
+ // ICache
113
+ /////////////////////////////////////////////////////////////////////////////
114
+ async setDocument(documentId, document) {
115
+ const doc = trimResultingState(document);
116
+ this.idTodocument.set(documentId, doc);
117
+ }
118
+ async getDocument(documentId) {
119
+ return this.idTodocument.get(documentId);
120
+ }
121
+ async deleteDocument(documentId) {
122
+ return this.idTodocument.delete(documentId);
123
+ }
124
+ async setDrive(driveId, drive) {
125
+ const doc = trimResultingState(drive);
126
+ this.idToDrive.set(driveId, doc);
127
+ }
128
+ async getDrive(driveId) {
129
+ return this.idToDrive.get(driveId);
130
+ }
131
+ async deleteDrive(driveId) {
132
+ const drive = this.idToDrive.get(driveId);
133
+ if (!drive) {
134
+ return false;
106
135
  }
107
- (_a2 = this.cache.get(drive)) == null ? void 0 : _a2.set(id, doc);
108
- return true;
136
+ const slug = drive.state.global.slug;
137
+ if (slug) {
138
+ this.slugToDriveId.delete(slug);
139
+ }
140
+ return this.idToDrive.delete(driveId);
109
141
  }
110
- async deleteDocument(drive, id) {
111
- var _a2;
112
- return ((_a2 = this.cache.get(drive)) == null ? void 0 : _a2.delete(id)) ?? false;
142
+ async setDriveBySlug(slug, drive) {
143
+ const driveId = drive.state.global.id;
144
+ this.slugToDriveId.set(slug, driveId);
145
+ this.setDrive(driveId, drive);
113
146
  }
114
- async getDocument(drive, id) {
115
- var _a2;
116
- return (_a2 = this.cache.get(drive)) == null ? void 0 : _a2.get(id);
147
+ async getDriveBySlug(slug) {
148
+ const driveId = this.slugToDriveId.get(slug);
149
+ if (!driveId) {
150
+ return void 0;
151
+ }
152
+ return this.getDrive(driveId);
153
+ }
154
+ async deleteDriveBySlug(slug) {
155
+ const driveId = this.slugToDriveId.get(slug);
156
+ if (!driveId) {
157
+ return false;
158
+ }
159
+ this.slugToDriveId.delete(slug);
160
+ return this.deleteDrive(driveId);
117
161
  }
118
162
  }
119
163
  const K = [
@@ -22497,7 +22541,7 @@ const _PullResponderTransmitter = class _PullResponderTransmitter {
22497
22541
  const syncUnits = await this.manager.getListenerSyncUnitIds(driveId, listenerId);
22498
22542
  let success = true;
22499
22543
  for (const revision of revisions) {
22500
- const syncUnit = syncUnits.find((s) => s.scope === revision.scope && s.branch === revision.branch && s.driveId === revision.driveId && s.documentId == revision.documentId);
22544
+ const syncUnit = syncUnits.find((s) => s.scope === revision.scope && s.branch === revision.branch && s.documentId == revision.documentId);
22501
22545
  if (!syncUnit) {
22502
22546
  this.logger.warn("Unknown sync unit was acknowledged", revision);
22503
22547
  success = false;
@@ -22742,6 +22786,187 @@ __publicField(_PullResponderTransmitter, "staticLogger", childLogger([
22742
22786
  "static"
22743
22787
  ]));
22744
22788
  let PullResponderTransmitter = _PullResponderTransmitter;
22789
+ var defaults;
22790
+ var hasRequiredDefaults;
22791
+ function requireDefaults() {
22792
+ if (hasRequiredDefaults) return defaults;
22793
+ hasRequiredDefaults = 1;
22794
+ defaults = {
22795
+ space: "",
22796
+ cycles: false,
22797
+ replacer: (k, v) => v,
22798
+ stringify: JSON.stringify
22799
+ };
22800
+ return defaults;
22801
+ }
22802
+ var util;
22803
+ var hasRequiredUtil;
22804
+ function requireUtil() {
22805
+ if (hasRequiredUtil) return util;
22806
+ hasRequiredUtil = 1;
22807
+ util = {
22808
+ isArray: Array.isArray,
22809
+ assign: Object.assign,
22810
+ isObject: (v) => typeof v === "object",
22811
+ isFunction: (v) => typeof v === "function",
22812
+ isBoolean: (v) => typeof v === "boolean",
22813
+ isRegex: (v) => v instanceof RegExp,
22814
+ keys: Object.keys
22815
+ };
22816
+ return util;
22817
+ }
22818
+ var lib;
22819
+ var hasRequiredLib;
22820
+ function requireLib() {
22821
+ if (hasRequiredLib) return lib;
22822
+ hasRequiredLib = 1;
22823
+ const DEFAULTS = requireDefaults();
22824
+ const isFunction = requireUtil().isFunction;
22825
+ const isBoolean = requireUtil().isBoolean;
22826
+ const isObject = requireUtil().isObject;
22827
+ const isArray = requireUtil().isArray;
22828
+ const isRegex = requireUtil().isRegex;
22829
+ const assign = requireUtil().assign;
22830
+ const keys = requireUtil().keys;
22831
+ function serialize(obj) {
22832
+ if (obj === null || obj === void 0) return obj;
22833
+ if (isRegex(obj)) return obj.toString();
22834
+ return obj.toJSON ? obj.toJSON() : obj;
22835
+ }
22836
+ function stringifyDeterministic(obj, opts) {
22837
+ opts = opts || assign({}, DEFAULTS);
22838
+ if (isFunction(opts)) opts = { compare: opts };
22839
+ const space = opts.space || DEFAULTS.space;
22840
+ const cycles = isBoolean(opts.cycles) ? opts.cycles : DEFAULTS.cycles;
22841
+ const replacer = opts.replacer || DEFAULTS.replacer;
22842
+ const stringify2 = opts.stringify || DEFAULTS.stringify;
22843
+ const compare = opts.compare && /* @__PURE__ */ function(f) {
22844
+ return function(node) {
22845
+ return function(a, b) {
22846
+ const aobj = { key: a, value: node[a] };
22847
+ const bobj = { key: b, value: node[b] };
22848
+ return f(aobj, bobj);
22849
+ };
22850
+ };
22851
+ }(opts.compare);
22852
+ if (!cycles) stringify2(obj);
22853
+ const seen = [];
22854
+ return function _deterministic(parent, key, node, level) {
22855
+ const indent2 = space ? "\n" + new Array(level + 1).join(space) : "";
22856
+ const colonSeparator = space ? ": " : ":";
22857
+ node = serialize(node);
22858
+ node = replacer.call(parent, key, node);
22859
+ if (node === void 0) return;
22860
+ if (!isObject(node) || node === null) return stringify2(node);
22861
+ if (isArray(node)) {
22862
+ const out = [];
22863
+ for (let i = 0; i < node.length; i++) {
22864
+ const item = _deterministic(node, i, node[i], level + 1) || stringify2(null);
22865
+ out.push(indent2 + space + item);
22866
+ }
22867
+ return "[" + out.join(",") + indent2 + "]";
22868
+ } else {
22869
+ if (cycles) {
22870
+ if (seen.indexOf(node) !== -1) {
22871
+ return stringify2("[Circular]");
22872
+ } else {
22873
+ seen.push(node);
22874
+ }
22875
+ }
22876
+ const nodeKeys = keys(node).sort(compare && compare(node));
22877
+ const out = [];
22878
+ for (let i = 0; i < nodeKeys.length; i++) {
22879
+ const key2 = nodeKeys[i];
22880
+ const value = _deterministic(node, key2, node[key2], level + 1);
22881
+ if (!value) continue;
22882
+ const keyValue = stringify2(key2) + colonSeparator + value;
22883
+ out.push(indent2 + space + keyValue);
22884
+ }
22885
+ seen.splice(seen.indexOf(node), 1);
22886
+ return "{" + out.join(",") + indent2 + "}";
22887
+ }
22888
+ }({ "": obj }, "", obj, 0);
22889
+ }
22890
+ lib = stringifyDeterministic;
22891
+ return lib;
22892
+ }
22893
+ var libExports = requireLib();
22894
+ const stringify = /* @__PURE__ */ getDefaultExportFromCjs(libExports);
22895
+ const SYNC_OPS_BATCH_LIMIT = 10;
22896
+ class SwitchboardPushTransmitter {
22897
+ constructor(targetURL) {
22898
+ __publicField(this, "targetURL");
22899
+ __publicField(this, "logger", childLogger([
22900
+ "SwitchboardPushTransmitter",
22901
+ Math.floor(Math.random() * 999).toString()
22902
+ ]));
22903
+ this.targetURL = targetURL;
22904
+ }
22905
+ async transmit(strands, source) {
22906
+ var _a2;
22907
+ if (source.type === "trigger" && ((_a2 = source.trigger.data) == null ? void 0 : _a2.url) === this.targetURL) {
22908
+ this.logger.verbose(`Cutting trigger loop from ${this.targetURL}.`);
22909
+ return strands.map((strand) => {
22910
+ var _a3;
22911
+ return {
22912
+ driveId: strand.driveId,
22913
+ documentId: strand.documentId,
22914
+ scope: strand.scope,
22915
+ branch: strand.branch,
22916
+ status: "SUCCESS",
22917
+ revision: ((_a3 = strand.operations.at(-1)) == null ? void 0 : _a3.index) ?? -1
22918
+ };
22919
+ });
22920
+ }
22921
+ const culledStrands = [];
22922
+ let opsCounter = 0;
22923
+ for (let s = 0; opsCounter <= SYNC_OPS_BATCH_LIMIT && s < strands.length; s++) {
22924
+ const currentStrand = strands.at(s);
22925
+ if (!currentStrand) {
22926
+ break;
22927
+ }
22928
+ const newOps = Math.min(SYNC_OPS_BATCH_LIMIT - opsCounter, currentStrand.operations.length);
22929
+ culledStrands.push({
22930
+ ...currentStrand,
22931
+ operations: currentStrand.operations.slice(0, newOps)
22932
+ });
22933
+ opsCounter += newOps;
22934
+ }
22935
+ this.logger.verbose(` Total update: [${strands.map((s) => s.operations.length).join(", ")}] operations`);
22936
+ this.logger.verbose(`Culled update: [${culledStrands.map((s) => s.operations.length).join(", ")}] operations`);
22937
+ try {
22938
+ const { pushUpdates } = await requestGraphql(this.targetURL, gql`
22939
+ mutation pushUpdates($strands: [InputStrandUpdate!]) {
22940
+ pushUpdates(strands: $strands) {
22941
+ driveId
22942
+ documentId
22943
+ scope
22944
+ branch
22945
+ status
22946
+ revision
22947
+ error
22948
+ }
22949
+ }
22950
+ `, {
22951
+ strands: culledStrands.map((strand) => ({
22952
+ ...strand,
22953
+ operations: strand.operations.map((op) => ({
22954
+ ...op,
22955
+ input: stringify(op.input)
22956
+ }))
22957
+ }))
22958
+ });
22959
+ if (!pushUpdates) {
22960
+ throw new Error("Couldn't update listener revision");
22961
+ }
22962
+ return pushUpdates;
22963
+ } catch (e) {
22964
+ this.logger.error(e);
22965
+ throw e;
22966
+ }
22967
+ return [];
22968
+ }
22969
+ }
22745
22970
  var TransmitterType;
22746
22971
  (function(TransmitterType2) {
22747
22972
  TransmitterType2[TransmitterType2["Internal"] = 0] = "Internal";
@@ -22814,7 +23039,6 @@ class BaseDocumentDriveServer {
22814
23039
  // internal state
22815
23040
  __publicField(this, "triggerMap", /* @__PURE__ */ new Map());
22816
23041
  __publicField(this, "initializePromise");
22817
- var _a2, _b;
22818
23042
  this.documentModelModules = documentModelModules;
22819
23043
  this.storage = storage;
22820
23044
  this.documentStorage = documentStorage;
@@ -22835,17 +23059,6 @@ class BaseDocumentDriveServer {
22835
23059
  taskQueueMethod: (options == null ? void 0 : options.taskQueueMethod) === void 0 ? RunAsap.runAsap : options.taskQueueMethod
22836
23060
  };
22837
23061
  this.defaultDrivesManager = new DefaultDrivesManager(this, this.defaultDrivesManagerDelegate, options);
22838
- (_b = (_a2 = this.storage).setStorageDelegate) == null ? void 0 : _b.call(_a2, {
22839
- getCachedOperations: async (drive, id) => {
22840
- try {
22841
- const document = await this.cache.getDocument(drive, id);
22842
- return document == null ? void 0 : document.operations;
22843
- } catch (error) {
22844
- logger$1.error(error);
22845
- return void 0;
22846
- }
22847
- }
22848
- });
22849
23062
  this.initializePromise = this._initialize();
22850
23063
  }
22851
23064
  // workaround for testing the ephemeral listeners -- we don't have DI in place yet
@@ -22987,11 +23200,32 @@ class BaseDocumentDriveServer {
22987
23200
  return this.triggerMap.delete(driveId);
22988
23201
  }
22989
23202
  async _initializeDrive(driveId) {
23203
+ var _a2, _b, _c, _d, _e, _f;
22990
23204
  const drive = await this.getDrive(driveId);
22991
23205
  await this.synchronizationManager.initializeDriveSyncStatus(driveId, drive);
22992
23206
  if (this.shouldSyncRemoteDrive(drive)) {
22993
23207
  await this.startSyncRemoteDrive(driveId);
22994
23208
  }
23209
+ for (const zodListener of drive.state.local.listeners) {
23210
+ if (((_a2 = zodListener.callInfo) == null ? void 0 : _a2.transmitterType) === "SwitchboardPush") {
23211
+ const transmitter = new SwitchboardPushTransmitter(((_b = zodListener.callInfo) == null ? void 0 : _b.data) ?? "");
23212
+ this.listenerManager.setListener(driveId, {
23213
+ block: zodListener.block,
23214
+ driveId: drive.state.global.id,
23215
+ filter: {
23216
+ branch: ((_c = zodListener.filter) == null ? void 0 : _c.branch) ?? [],
23217
+ documentId: ((_d = zodListener.filter) == null ? void 0 : _d.documentId) ?? [],
23218
+ documentType: ((_e = zodListener.filter) == null ? void 0 : _e.documentType) ?? [],
23219
+ scope: ((_f = zodListener.filter) == null ? void 0 : _f.scope) ?? []
23220
+ },
23221
+ listenerId: zodListener.listenerId,
23222
+ callInfo: zodListener.callInfo,
23223
+ system: zodListener.system,
23224
+ label: zodListener.label ?? "",
23225
+ transmitter
23226
+ });
23227
+ }
23228
+ }
22995
23229
  }
22996
23230
  // Delegate synchronization methods to synchronizationManager
22997
23231
  getSynchronizationUnits(driveId, documentId, scope, branch, documentType2) {
@@ -23033,7 +23267,7 @@ class BaseDocumentDriveServer {
23033
23267
  };
23034
23268
  await this.storage.createDrive(id, document);
23035
23269
  if (input.global.slug) {
23036
- await this.cache.deleteDocument("drives-slug", input.global.slug);
23270
+ await this.cache.deleteDriveBySlug(input.global.slug);
23037
23271
  }
23038
23272
  await this._initializeDrive(id);
23039
23273
  this.eventEmitter.emit("driveAdded", document);
@@ -23065,7 +23299,7 @@ class BaseDocumentDriveServer {
23065
23299
  const result = await Promise.allSettled([
23066
23300
  this.stopSyncRemoteDrive(driveId),
23067
23301
  this.listenerManager.removeDrive(driveId),
23068
- this.cache.deleteDocument("drives", driveId),
23302
+ this.cache.deleteDrive(driveId),
23069
23303
  this.storage.deleteDrive(driveId)
23070
23304
  ]);
23071
23305
  result.forEach((r) => {
@@ -23080,7 +23314,7 @@ class BaseDocumentDriveServer {
23080
23314
  async getDrive(driveId, options) {
23081
23315
  let document;
23082
23316
  try {
23083
- const cachedDocument = await this.cache.getDocument("drives", driveId);
23317
+ const cachedDocument = await this.cache.getDrive(driveId);
23084
23318
  if (cachedDocument && isDocumentDrive(cachedDocument)) {
23085
23319
  document = cachedDocument;
23086
23320
  if (isAtRevision(document, options == null ? void 0 : options.revisions)) {
@@ -23096,16 +23330,16 @@ class BaseDocumentDriveServer {
23096
23330
  throw new Error(`Document with id ${driveId} is not a Document Drive`);
23097
23331
  } else {
23098
23332
  if (!(options == null ? void 0 : options.revisions)) {
23099
- this.cache.setDocument("drives", driveId, result).catch(logger$1.error);
23333
+ this.cache.setDrive(driveId, result).catch(logger$1.error);
23100
23334
  }
23101
23335
  return result;
23102
23336
  }
23103
23337
  }
23104
23338
  async getDriveBySlug(slug, options) {
23105
23339
  try {
23106
- const document2 = await this.cache.getDocument("drives-slug", slug);
23107
- if (document2 && isDocumentDrive(document2)) {
23108
- return document2;
23340
+ const drive = await this.cache.getDriveBySlug(slug);
23341
+ if (drive) {
23342
+ return drive;
23109
23343
  }
23110
23344
  } catch (e) {
23111
23345
  logger$1.error("Error getting drive from cache", e);
@@ -23115,14 +23349,14 @@ class BaseDocumentDriveServer {
23115
23349
  if (!isDocumentDrive(document)) {
23116
23350
  throw new Error(`Document with slug ${slug} is not a Document Drive`);
23117
23351
  } else {
23118
- this.cache.setDocument("drives-slug", slug, document).catch(logger$1.error);
23352
+ this.cache.setDriveBySlug(slug, document).catch(logger$1.error);
23119
23353
  return document;
23120
23354
  }
23121
23355
  }
23122
23356
  async getDocument(driveId, documentId, options) {
23123
23357
  let cachedDocument;
23124
23358
  try {
23125
- cachedDocument = await this.cache.getDocument(driveId, documentId);
23359
+ cachedDocument = await this.cache.getDocument(documentId);
23126
23360
  if (cachedDocument && isAtRevision(cachedDocument, options == null ? void 0 : options.revisions)) {
23127
23361
  return cachedDocument;
23128
23362
  }
@@ -23132,7 +23366,7 @@ class BaseDocumentDriveServer {
23132
23366
  const documentStorage = cachedDocument ?? await this.storage.getDocument(driveId, documentId);
23133
23367
  const document = this._buildDocument(documentStorage, options);
23134
23368
  if (!(options == null ? void 0 : options.revisions)) {
23135
- this.cache.setDocument(driveId, documentId, document).catch(logger$1.error);
23369
+ this.cache.setDocument(documentId, document).catch(logger$1.error);
23136
23370
  }
23137
23371
  return document;
23138
23372
  }
@@ -23189,7 +23423,7 @@ class BaseDocumentDriveServer {
23189
23423
  } catch (error) {
23190
23424
  logger$1.warn("Error deleting document", error);
23191
23425
  }
23192
- await this.cache.deleteDocument(driveId, documentId);
23426
+ await this.cache.deleteDocument(documentId);
23193
23427
  return this.storage.deleteDocument(driveId, documentId);
23194
23428
  }
23195
23429
  async _processOperations(driveId, documentId, documentStorage, operations) {
@@ -23479,7 +23713,7 @@ class BaseDocumentDriveServer {
23479
23713
  };
23480
23714
  });
23481
23715
  if (document) {
23482
- this.cache.setDocument(driveId, documentId, document).catch(logger$1.error);
23716
+ this.cache.setDocument(documentId, document).catch(logger$1.error);
23483
23717
  }
23484
23718
  const { scopes, branches } = operationsApplied.reduce((acc, operation) => {
23485
23719
  if (!acc.scopes.includes(operation.scope)) {
@@ -23642,7 +23876,7 @@ class BaseDocumentDriveServer {
23642
23876
  if (!document || !isDocumentDrive(document)) {
23643
23877
  throw error ?? new Error("Invalid Document Drive document");
23644
23878
  }
23645
- this.cache.setDocument("drives", driveId, document).catch(logger$1.error);
23879
+ this.cache.setDrive(driveId, document).catch(logger$1.error);
23646
23880
  const lastOperation = operationsApplied.filter((op) => op.scope === "global").slice().pop();
23647
23881
  if (lastOperation) {
23648
23882
  const newOp = operationsApplied.find((appliedOp) => !operations.find((o) => o.id === appliedOp.id && o.index === appliedOp.index && o.skip === appliedOp.skip && o.hash === appliedOp.hash));
@@ -23651,7 +23885,6 @@ class BaseDocumentDriveServer {
23651
23885
  this.listenerManager.updateSynchronizationRevisions(driveId, [
23652
23886
  {
23653
23887
  syncId: "0",
23654
- driveId,
23655
23888
  documentId: "",
23656
23889
  scope: "global",
23657
23890
  branch: "main",
@@ -23790,18 +24023,15 @@ const DocumentDriveServer = ReadModeServer(BaseDocumentDriveServer);
23790
24023
  class MemoryStorage {
23791
24024
  constructor() {
23792
24025
  __publicField(this, "documents");
23793
- __publicField(this, "drives");
23794
24026
  __publicField(this, "driveManifests");
23795
- __publicField(this, "slugToDriveId", {});
23796
24027
  this.documents = {};
23797
- this.drives = {};
23798
24028
  this.driveManifests = {};
23799
24029
  }
23800
24030
  ////////////////////////////////
23801
24031
  // IDocumentStorage
23802
24032
  ////////////////////////////////
23803
24033
  exists(documentId) {
23804
- return Promise.resolve(!!this.documents[documentId]);
24034
+ return Promise.resolve(!!this.documents[documentId] || !!this.documents[`drive/${documentId}`]);
23805
24035
  }
23806
24036
  create(documentId, document) {
23807
24037
  this.documents[documentId] = document;
@@ -23810,10 +24040,52 @@ class MemoryStorage {
23810
24040
  get(documentId) {
23811
24041
  const document = this.documents[documentId];
23812
24042
  if (!document) {
24043
+ const drive = this.documents[`drive/${documentId}`];
24044
+ if (drive) {
24045
+ return Promise.resolve(drive);
24046
+ }
23813
24047
  throw new Error(`Document with id ${documentId} not found`);
23814
24048
  }
23815
24049
  return Promise.resolve(document);
23816
24050
  }
24051
+ async delete(documentId) {
24052
+ const drives = await this.getDrives();
24053
+ for (const driveId of drives) {
24054
+ if (driveId === documentId)
24055
+ continue;
24056
+ await this.removeChild(driveId, documentId);
24057
+ }
24058
+ delete this.driveManifests[documentId];
24059
+ if (this.documents[documentId]) {
24060
+ delete this.documents[documentId];
24061
+ return Promise.resolve(true);
24062
+ }
24063
+ return Promise.resolve(false);
24064
+ }
24065
+ async addChild(parentId, childId) {
24066
+ if (parentId === childId) {
24067
+ throw new Error("Cannot associate a document with itself");
24068
+ }
24069
+ const children = await this.getChildren(childId);
24070
+ if (children.includes(parentId)) {
24071
+ throw new Error("Cannot associate a document with its child");
24072
+ }
24073
+ const manifest = this.getManifest(parentId);
24074
+ manifest.documentIds.add(childId);
24075
+ this.updateDriveManifest(parentId, manifest);
24076
+ }
24077
+ async removeChild(parentId, childId) {
24078
+ const manifest = this.getManifest(parentId);
24079
+ if (manifest.documentIds.delete(childId)) {
24080
+ this.updateDriveManifest(parentId, manifest);
24081
+ return true;
24082
+ }
24083
+ return false;
24084
+ }
24085
+ async getChildren(parentId) {
24086
+ const manifest = this.getManifest(parentId);
24087
+ return [...manifest.documentIds];
24088
+ }
23817
24089
  ////////////////////////////////
23818
24090
  // IDriveStorage
23819
24091
  ////////////////////////////////
@@ -23821,27 +24093,19 @@ class MemoryStorage {
23821
24093
  return this.exists(id);
23822
24094
  }
23823
24095
  getDocuments(drive) {
23824
- const manifest = this.getDriveManifest(drive);
24096
+ const manifest = this.getManifest(drive);
23825
24097
  return Promise.resolve([...manifest.documentIds]);
23826
24098
  }
23827
24099
  getDocument(driveId, id) {
23828
24100
  return this.get(id);
23829
24101
  }
23830
- async saveDocument(drive, id, document) {
23831
- this.documents[id] = document;
23832
- const manifest = this.getDriveManifest(drive);
23833
- manifest.documentIds.add(id);
23834
- this.updateDriveManifest(drive, manifest);
23835
- }
23836
24102
  async clearStorage() {
23837
24103
  this.documents = {};
23838
- this.drives = {};
23839
24104
  this.driveManifests = {};
23840
- this.slugToDriveId = {};
23841
24105
  }
23842
24106
  async createDocument(drive, id, document) {
23843
24107
  await this.create(id, document);
23844
- const manifest = this.getDriveManifest(drive);
24108
+ const manifest = this.getManifest(drive);
23845
24109
  manifest.documentIds.add(id);
23846
24110
  this.updateDriveManifest(drive, manifest);
23847
24111
  }
@@ -23858,59 +24122,60 @@ class MemoryStorage {
23858
24122
  };
23859
24123
  }
23860
24124
  async deleteDocument(drive, id) {
23861
- const drives = await this.getDrives();
23862
- for (const driveId of drives) {
23863
- const manifest = this.getDriveManifest(driveId);
23864
- if (manifest.documentIds.has(id)) {
23865
- manifest.documentIds.delete(id);
23866
- this.updateDriveManifest(driveId, manifest);
23867
- }
23868
- }
23869
- delete this.documents[id];
24125
+ this.delete(id);
23870
24126
  }
23871
24127
  async getDrives() {
23872
- return Object.keys(this.drives);
24128
+ return Object.keys(this.driveManifests);
23873
24129
  }
23874
24130
  async getDrive(id) {
23875
- const drive = this.drives[id];
24131
+ const drive = this.documents[`drive/${id}`];
23876
24132
  if (!drive) {
23877
24133
  throw new DriveNotFoundError(id);
23878
24134
  }
23879
24135
  return drive;
23880
24136
  }
23881
24137
  async getDriveBySlug(slug) {
23882
- const driveId = this.slugToDriveId[slug];
23883
- if (!driveId) {
23884
- throw new Error(`Drive with slug ${slug} not found`);
24138
+ for (const driveId of Object.keys(this.driveManifests)) {
24139
+ const drive = this.documents[`drive/${driveId}`];
24140
+ if (drive.initialState.state.global.slug === slug) {
24141
+ return drive;
24142
+ }
23885
24143
  }
23886
- return this.getDrive(driveId);
24144
+ throw new Error(`Drive with slug ${slug} not found`);
23887
24145
  }
23888
24146
  async createDrive(id, drive) {
23889
- this.drives[id] = drive;
23890
- this.updateDriveManifest(id, { documentIds: /* @__PURE__ */ new Set() });
23891
- const { slug } = drive.initialState.state.global;
24147
+ const slug = drive.initialState.state.global.slug;
23892
24148
  if (slug) {
23893
- this.slugToDriveId[slug] = id;
24149
+ let existingDrive;
24150
+ try {
24151
+ existingDrive = await this.getDriveBySlug(slug);
24152
+ } catch {
24153
+ }
24154
+ if (existingDrive) {
24155
+ throw new Error(`Drive with slug ${slug} already exists`);
24156
+ }
23894
24157
  }
24158
+ await this.create(`drive/${id}`, drive);
24159
+ this.updateDriveManifest(id, { documentIds: /* @__PURE__ */ new Set() });
23895
24160
  }
23896
24161
  async addDriveOperations(id, operations, header) {
23897
24162
  const drive = await this.getDrive(id);
23898
24163
  const mergedOperations = mergeOperations(drive.operations, operations);
23899
- this.drives[id] = {
24164
+ this.documents[`drive/${id}`] = {
23900
24165
  ...drive,
23901
24166
  ...header,
23902
24167
  operations: mergedOperations
23903
24168
  };
23904
24169
  }
23905
24170
  async deleteDrive(id) {
23906
- const manifest = this.getDriveManifest(id);
24171
+ const manifest = this.getManifest(id);
23907
24172
  const drives = await this.getDrives();
23908
24173
  await Promise.all([...manifest.documentIds].map((docId) => {
23909
24174
  for (const driveId of drives) {
23910
24175
  if (driveId === id) {
23911
24176
  continue;
23912
24177
  }
23913
- const manifest2 = this.getDriveManifest(driveId);
24178
+ const manifest2 = this.getManifest(driveId);
23914
24179
  if (manifest2.documentIds.has(docId)) {
23915
24180
  return;
23916
24181
  }
@@ -23918,24 +24183,18 @@ class MemoryStorage {
23918
24183
  delete this.documents[docId];
23919
24184
  }));
23920
24185
  delete this.driveManifests[id];
23921
- delete this.drives[id];
23922
- for (const [slug, driveId] of Object.entries(this.slugToDriveId)) {
23923
- if (driveId === id) {
23924
- delete this.slugToDriveId[slug];
23925
- }
23926
- }
24186
+ delete this.documents[id];
23927
24187
  }
23928
24188
  async getSynchronizationUnitsRevision(units) {
23929
24189
  const results = await Promise.allSettled(units.map(async (unit) => {
23930
24190
  try {
23931
- const document = await (unit.documentId ? this.getDocument(unit.driveId, unit.documentId) : this.getDrive(unit.driveId));
24191
+ const document = await this.get(unit.documentId);
23932
24192
  if (!document) {
23933
24193
  return void 0;
23934
24194
  }
23935
24195
  const operation = document.operations[unit.scope].at(-1);
23936
24196
  if (operation) {
23937
24197
  return {
23938
- driveId: unit.driveId,
23939
24198
  documentId: unit.documentId,
23940
24199
  scope: unit.scope,
23941
24200
  branch: unit.branch,
@@ -23957,7 +24216,7 @@ class MemoryStorage {
23957
24216
  ////////////////////////////////
23958
24217
  // Private
23959
24218
  ////////////////////////////////
23960
- getDriveManifest(driveId) {
24219
+ getManifest(driveId) {
23961
24220
  if (!this.driveManifests[driveId]) {
23962
24221
  this.driveManifests[driveId] = { documentIds: /* @__PURE__ */ new Set() };
23963
24222
  }
@@ -24138,7 +24397,7 @@ const _ListenerManager = class _ListenerManager {
24138
24397
  this.logger.verbose(`Abandoning push for sync unit ${syncUnit.syncId}: already up-to-date (${unitState.listenerRev} >= ${syncUnit.revision})`);
24139
24398
  return;
24140
24399
  } else {
24141
- this.logger.verbose(`Listener out-of-date for sync unit (${syncUnit.driveId}, ${syncUnit.scope}, ${syncUnit.documentId}): ${unitState == null ? void 0 : unitState.listenerRev} < ${syncUnit.revision}`);
24400
+ this.logger.verbose(`Listener out-of-date for sync unit (${syncUnit.scope}, ${syncUnit.documentId}): ${unitState == null ? void 0 : unitState.listenerRev} < ${syncUnit.revision}`);
24142
24401
  }
24143
24402
  const opData = [];
24144
24403
  try {
@@ -24296,11 +24555,11 @@ const _ListenerManager = class _ListenerManager {
24296
24555
  if (entry && entry.listenerRev >= syncUnit.revision) {
24297
24556
  return;
24298
24557
  }
24299
- const { documentId, driveId: driveId2, scope, branch } = syncUnit;
24558
+ const { documentId, scope, branch } = syncUnit;
24300
24559
  try {
24301
24560
  const operations = await this.syncManager.getOperationData(
24302
24561
  // DEAL WITH INVALID SYNC ID ERROR
24303
- driveId2,
24562
+ driveId,
24304
24563
  syncUnit.syncId,
24305
24564
  {
24306
24565
  since: options == null ? void 0 : options.since,
@@ -24313,7 +24572,7 @@ const _ListenerManager = class _ListenerManager {
24313
24572
  }
24314
24573
  operationsCount += operations.length;
24315
24574
  strands.push({
24316
- driveId: driveId2,
24575
+ driveId,
24317
24576
  documentId,
24318
24577
  scope,
24319
24578
  branch,
@@ -24356,187 +24615,6 @@ const _ListenerManager = class _ListenerManager {
24356
24615
  };
24357
24616
  __publicField(_ListenerManager, "LISTENER_UPDATE_DELAY", 250);
24358
24617
  let ListenerManager = _ListenerManager;
24359
- var defaults;
24360
- var hasRequiredDefaults;
24361
- function requireDefaults() {
24362
- if (hasRequiredDefaults) return defaults;
24363
- hasRequiredDefaults = 1;
24364
- defaults = {
24365
- space: "",
24366
- cycles: false,
24367
- replacer: (k, v) => v,
24368
- stringify: JSON.stringify
24369
- };
24370
- return defaults;
24371
- }
24372
- var util;
24373
- var hasRequiredUtil;
24374
- function requireUtil() {
24375
- if (hasRequiredUtil) return util;
24376
- hasRequiredUtil = 1;
24377
- util = {
24378
- isArray: Array.isArray,
24379
- assign: Object.assign,
24380
- isObject: (v) => typeof v === "object",
24381
- isFunction: (v) => typeof v === "function",
24382
- isBoolean: (v) => typeof v === "boolean",
24383
- isRegex: (v) => v instanceof RegExp,
24384
- keys: Object.keys
24385
- };
24386
- return util;
24387
- }
24388
- var lib;
24389
- var hasRequiredLib;
24390
- function requireLib() {
24391
- if (hasRequiredLib) return lib;
24392
- hasRequiredLib = 1;
24393
- const DEFAULTS = requireDefaults();
24394
- const isFunction = requireUtil().isFunction;
24395
- const isBoolean = requireUtil().isBoolean;
24396
- const isObject = requireUtil().isObject;
24397
- const isArray = requireUtil().isArray;
24398
- const isRegex = requireUtil().isRegex;
24399
- const assign = requireUtil().assign;
24400
- const keys = requireUtil().keys;
24401
- function serialize(obj) {
24402
- if (obj === null || obj === void 0) return obj;
24403
- if (isRegex(obj)) return obj.toString();
24404
- return obj.toJSON ? obj.toJSON() : obj;
24405
- }
24406
- function stringifyDeterministic(obj, opts) {
24407
- opts = opts || assign({}, DEFAULTS);
24408
- if (isFunction(opts)) opts = { compare: opts };
24409
- const space = opts.space || DEFAULTS.space;
24410
- const cycles = isBoolean(opts.cycles) ? opts.cycles : DEFAULTS.cycles;
24411
- const replacer = opts.replacer || DEFAULTS.replacer;
24412
- const stringify2 = opts.stringify || DEFAULTS.stringify;
24413
- const compare = opts.compare && /* @__PURE__ */ function(f) {
24414
- return function(node) {
24415
- return function(a, b) {
24416
- const aobj = { key: a, value: node[a] };
24417
- const bobj = { key: b, value: node[b] };
24418
- return f(aobj, bobj);
24419
- };
24420
- };
24421
- }(opts.compare);
24422
- if (!cycles) stringify2(obj);
24423
- const seen = [];
24424
- return function _deterministic(parent, key, node, level) {
24425
- const indent2 = space ? "\n" + new Array(level + 1).join(space) : "";
24426
- const colonSeparator = space ? ": " : ":";
24427
- node = serialize(node);
24428
- node = replacer.call(parent, key, node);
24429
- if (node === void 0) return;
24430
- if (!isObject(node) || node === null) return stringify2(node);
24431
- if (isArray(node)) {
24432
- const out = [];
24433
- for (let i = 0; i < node.length; i++) {
24434
- const item = _deterministic(node, i, node[i], level + 1) || stringify2(null);
24435
- out.push(indent2 + space + item);
24436
- }
24437
- return "[" + out.join(",") + indent2 + "]";
24438
- } else {
24439
- if (cycles) {
24440
- if (seen.indexOf(node) !== -1) {
24441
- return stringify2("[Circular]");
24442
- } else {
24443
- seen.push(node);
24444
- }
24445
- }
24446
- const nodeKeys = keys(node).sort(compare && compare(node));
24447
- const out = [];
24448
- for (let i = 0; i < nodeKeys.length; i++) {
24449
- const key2 = nodeKeys[i];
24450
- const value = _deterministic(node, key2, node[key2], level + 1);
24451
- if (!value) continue;
24452
- const keyValue = stringify2(key2) + colonSeparator + value;
24453
- out.push(indent2 + space + keyValue);
24454
- }
24455
- seen.splice(seen.indexOf(node), 1);
24456
- return "{" + out.join(",") + indent2 + "}";
24457
- }
24458
- }({ "": obj }, "", obj, 0);
24459
- }
24460
- lib = stringifyDeterministic;
24461
- return lib;
24462
- }
24463
- var libExports = requireLib();
24464
- const stringify = /* @__PURE__ */ getDefaultExportFromCjs(libExports);
24465
- const SYNC_OPS_BATCH_LIMIT = 10;
24466
- class SwitchboardPushTransmitter {
24467
- constructor(targetURL) {
24468
- __publicField(this, "targetURL");
24469
- __publicField(this, "logger", childLogger([
24470
- "SwitchboardPushTransmitter",
24471
- Math.floor(Math.random() * 999).toString()
24472
- ]));
24473
- this.targetURL = targetURL;
24474
- }
24475
- async transmit(strands, source) {
24476
- var _a2;
24477
- if (source.type === "trigger" && ((_a2 = source.trigger.data) == null ? void 0 : _a2.url) === this.targetURL) {
24478
- this.logger.verbose(`Cutting trigger loop from ${this.targetURL}.`);
24479
- return strands.map((strand) => {
24480
- var _a3;
24481
- return {
24482
- driveId: strand.driveId,
24483
- documentId: strand.documentId,
24484
- scope: strand.scope,
24485
- branch: strand.branch,
24486
- status: "SUCCESS",
24487
- revision: ((_a3 = strand.operations.at(-1)) == null ? void 0 : _a3.index) ?? -1
24488
- };
24489
- });
24490
- }
24491
- const culledStrands = [];
24492
- let opsCounter = 0;
24493
- for (let s = 0; opsCounter <= SYNC_OPS_BATCH_LIMIT && s < strands.length; s++) {
24494
- const currentStrand = strands.at(s);
24495
- if (!currentStrand) {
24496
- break;
24497
- }
24498
- const newOps = Math.min(SYNC_OPS_BATCH_LIMIT - opsCounter, currentStrand.operations.length);
24499
- culledStrands.push({
24500
- ...currentStrand,
24501
- operations: currentStrand.operations.slice(0, newOps)
24502
- });
24503
- opsCounter += newOps;
24504
- }
24505
- this.logger.verbose(` Total update: [${strands.map((s) => s.operations.length).join(", ")}] operations`);
24506
- this.logger.verbose(`Culled update: [${culledStrands.map((s) => s.operations.length).join(", ")}] operations`);
24507
- try {
24508
- const { pushUpdates } = await requestGraphql(this.targetURL, gql`
24509
- mutation pushUpdates($strands: [InputStrandUpdate!]) {
24510
- pushUpdates(strands: $strands) {
24511
- driveId
24512
- documentId
24513
- scope
24514
- branch
24515
- status
24516
- revision
24517
- error
24518
- }
24519
- }
24520
- `, {
24521
- strands: culledStrands.map((strand) => ({
24522
- ...strand,
24523
- operations: strand.operations.map((op) => ({
24524
- ...op,
24525
- input: stringify(op.input)
24526
- }))
24527
- }))
24528
- });
24529
- if (!pushUpdates) {
24530
- throw new Error("Couldn't update listener revision");
24531
- }
24532
- return pushUpdates;
24533
- } catch (e) {
24534
- this.logger.error(e);
24535
- throw e;
24536
- }
24537
- return [];
24538
- }
24539
- }
24540
24618
  class TransmitterFactory {
24541
24619
  constructor(listenerManager) {
24542
24620
  __publicField(this, "listenerManager");
@@ -24580,26 +24658,21 @@ class SynchronizationManager {
24580
24658
  async getSynchronizationUnitsRevision(driveId, syncUnitsQuery) {
24581
24659
  const drive = await this.getDrive(driveId);
24582
24660
  const revisions = await this.storage.getSynchronizationUnitsRevision(syncUnitsQuery);
24583
- const synchronizationUnits = syncUnitsQuery.map((s) => ({
24584
- ...s,
24585
- lastUpdated: drive.created,
24586
- revision: -1
24587
- }));
24588
- for (const revision of revisions) {
24589
- const syncUnit = synchronizationUnits.find((s) => revision.driveId === s.driveId && revision.documentId === s.documentId && revision.scope === s.scope && revision.branch === s.branch);
24590
- if (syncUnit) {
24591
- syncUnit.revision = revision.revision;
24592
- syncUnit.lastUpdated = revision.lastUpdated;
24593
- }
24594
- }
24595
- return synchronizationUnits;
24661
+ return syncUnitsQuery.map((s) => {
24662
+ var _a2;
24663
+ return {
24664
+ ...s,
24665
+ lastUpdated: drive.created,
24666
+ revision: ((_a2 = revisions.find((r) => r.documentId === s.documentId && r.scope === s.scope && r.branch === s.branch)) == null ? void 0 : _a2.revision) ?? -1
24667
+ };
24668
+ });
24596
24669
  }
24597
24670
  async getSynchronizationUnitsIds(driveId, documentId, scope, branch, documentType2) {
24598
24671
  const drive = await this.getDrive(driveId);
24599
24672
  const nodes = drive.state.global.nodes.filter((node) => isFileNode(node) && (!(documentId == null ? void 0 : documentId.length) || documentId.includes(node.id) || documentId.includes("*")) && (!(documentType2 == null ? void 0 : documentType2.length) || documentType2.includes(node.documentType) || documentType2.includes("*")));
24600
24673
  if ((!documentId || documentId.includes("*") || documentId.includes("")) && (!(documentType2 == null ? void 0 : documentType2.length) || documentType2.includes("powerhouse/document-drive") || documentType2.includes("*"))) {
24601
24674
  nodes.unshift({
24602
- id: "",
24675
+ id: drive.state.global.id,
24603
24676
  documentType: "powerhouse/document-drive",
24604
24677
  synchronizationUnits: [
24605
24678
  {
@@ -24641,7 +24714,6 @@ class SynchronizationManager {
24641
24714
  syncId,
24642
24715
  scope: syncUnit.scope,
24643
24716
  branch: syncUnit.branch,
24644
- driveId,
24645
24717
  documentId: node.id,
24646
24718
  documentType: node.documentType
24647
24719
  };
@@ -24659,7 +24731,6 @@ class SynchronizationManager {
24659
24731
  syncId,
24660
24732
  scope,
24661
24733
  branch,
24662
- driveId,
24663
24734
  documentId,
24664
24735
  documentType: documentType2,
24665
24736
  lastUpdated: lastOperation.timestamp ?? document.lastModified,
@@ -24688,7 +24759,7 @@ class SynchronizationManager {
24688
24759
  }
24689
24760
  async getDrive(driveId) {
24690
24761
  try {
24691
- const cachedDocument = await this.cache.getDocument("drives", driveId);
24762
+ const cachedDocument = await this.cache.getDrive(driveId);
24692
24763
  if (cachedDocument && isDocumentDrive(cachedDocument)) {
24693
24764
  return cachedDocument;
24694
24765
  }
@@ -24704,7 +24775,7 @@ class SynchronizationManager {
24704
24775
  }
24705
24776
  async getDocument(driveId, documentId) {
24706
24777
  try {
24707
- const cachedDocument = await this.cache.getDocument(driveId, documentId);
24778
+ const cachedDocument = await this.cache.getDocument(documentId);
24708
24779
  if (cachedDocument) {
24709
24780
  return cachedDocument;
24710
24781
  }
@@ -25545,7 +25616,7 @@ const nodeOptionsMap = {
25545
25616
  };
25546
25617
  const name = "@powerhousedao/connect";
25547
25618
  const productName = "Powerhouse-Connect";
25548
- const version$1 = "1.0.8";
25619
+ const version$1 = "1.0.9-dev.0";
25549
25620
  const description = "Powerhouse Connect";
25550
25621
  const main = "./dist/index.html";
25551
25622
  const type = "module";
@@ -28338,6 +28409,10 @@ const _BrowserStorage = class _BrowserStorage {
28338
28409
  name: namespace ? `${namespace}:${_BrowserStorage.DBName}` : _BrowserStorage.DBName
28339
28410
  }));
28340
28411
  }
28412
+ async clear() {
28413
+ const db = await this.db;
28414
+ await db.clear();
28415
+ }
28341
28416
  ////////////////////////////////
28342
28417
  // IDocumentStorage
28343
28418
  ////////////////////////////////
@@ -28358,13 +28433,57 @@ const _BrowserStorage = class _BrowserStorage {
28358
28433
  }
28359
28434
  return document;
28360
28435
  }
28436
+ async delete(documentId) {
28437
+ const db = await this.db;
28438
+ const document = await db.getItem(this.buildDocumentKey(documentId));
28439
+ if (!document) {
28440
+ return false;
28441
+ }
28442
+ const drives = await this.getDrives();
28443
+ for (const driveId of drives) {
28444
+ if (driveId === documentId)
28445
+ continue;
28446
+ await this.removeChild(driveId, documentId);
28447
+ }
28448
+ await db.removeItem(this.buildManifestKey(documentId));
28449
+ await db.removeItem(this.buildDocumentKey(documentId));
28450
+ return true;
28451
+ }
28452
+ async removeChild(parentId, childId) {
28453
+ const manifest = await this.getManifest(parentId);
28454
+ const docIndex = manifest.documentIds.indexOf(childId);
28455
+ if (docIndex !== -1) {
28456
+ manifest.documentIds.splice(docIndex, 1);
28457
+ await this.updateDriveManifest(parentId, manifest);
28458
+ return true;
28459
+ }
28460
+ return false;
28461
+ }
28462
+ async addChild(parentId, childId) {
28463
+ if (parentId === childId) {
28464
+ throw new Error("Cannot associate a document with itself");
28465
+ }
28466
+ const children = await this.getChildren(childId);
28467
+ if (children.includes(parentId)) {
28468
+ throw new Error("Cannot associate a document with its child");
28469
+ }
28470
+ const manifest = await this.getManifest(parentId);
28471
+ if (!manifest.documentIds.includes(childId)) {
28472
+ manifest.documentIds.push(childId);
28473
+ await this.updateDriveManifest(parentId, manifest);
28474
+ }
28475
+ }
28476
+ async getChildren(parentId) {
28477
+ const manifest = await this.getManifest(parentId);
28478
+ return manifest.documentIds;
28479
+ }
28361
28480
  ////////////////////////////////
28362
28481
  // IDriveStorage
28363
28482
  ////////////////////////////////
28364
28483
  checkDocumentExists(drive, documentId) {
28365
28484
  return this.exists(documentId);
28366
28485
  }
28367
- async getDriveManifest(driveId) {
28486
+ async getManifest(driveId) {
28368
28487
  const db = await this.db;
28369
28488
  const manifest = await db.getItem(this.buildManifestKey(driveId));
28370
28489
  return manifest || { documentIds: [] };
@@ -28374,7 +28493,7 @@ const _BrowserStorage = class _BrowserStorage {
28374
28493
  await db.setItem(this.buildManifestKey(driveId), manifest);
28375
28494
  }
28376
28495
  async getDocuments(drive) {
28377
- const manifest = await this.getDriveManifest(drive);
28496
+ const manifest = await this.getManifest(drive);
28378
28497
  return manifest.documentIds;
28379
28498
  }
28380
28499
  async getDocument(driveId, id) {
@@ -28382,7 +28501,7 @@ const _BrowserStorage = class _BrowserStorage {
28382
28501
  }
28383
28502
  async createDocument(drive, id, document) {
28384
28503
  await this.create(id, document);
28385
- const manifest = await this.getDriveManifest(drive);
28504
+ const manifest = await this.getManifest(drive);
28386
28505
  if (!manifest.documentIds.includes(id)) {
28387
28506
  manifest.documentIds.push(id);
28388
28507
  await this.updateDriveManifest(drive, manifest);
@@ -28390,7 +28509,7 @@ const _BrowserStorage = class _BrowserStorage {
28390
28509
  }
28391
28510
  async deleteDocument(drive, id) {
28392
28511
  await (await this.db).removeItem(this.buildDocumentKey(id));
28393
- const manifest = await this.getDriveManifest(drive);
28512
+ const manifest = await this.getManifest(drive);
28394
28513
  const docIndex = manifest.documentIds.indexOf(id);
28395
28514
  if (docIndex !== -1) {
28396
28515
  manifest.documentIds.splice(docIndex, 1);
@@ -28416,12 +28535,13 @@ const _BrowserStorage = class _BrowserStorage {
28416
28535
  async getDrives() {
28417
28536
  const db = await this.db;
28418
28537
  const keys = await db.keys();
28419
- return keys.filter((key) => key.startsWith(_BrowserStorage.DRIVES_KEY)).map((key) => key.slice(_BrowserStorage.DRIVES_KEY.length + _BrowserStorage.SEP.length));
28538
+ return keys.filter((key) => key.startsWith(_BrowserStorage.MANIFEST_KEY)).map((key) => key.slice(_BrowserStorage.MANIFEST_KEY.length + _BrowserStorage.SEP.length));
28420
28539
  }
28421
28540
  async getDrive(id) {
28422
- const db = await this.db;
28423
- const drive = await db.getItem(this.buildDriveKey(id));
28424
- if (!drive) {
28541
+ let drive;
28542
+ try {
28543
+ drive = await this.get(id);
28544
+ } catch {
28425
28545
  throw new DriveNotFoundError(id);
28426
28546
  }
28427
28547
  return drive;
@@ -28437,8 +28557,18 @@ const _BrowserStorage = class _BrowserStorage {
28437
28557
  throw new Error(`Drive with slug ${slug} not found`);
28438
28558
  }
28439
28559
  async createDrive(id, drive) {
28440
- const db = await this.db;
28441
- await db.setItem(this.buildDriveKey(id), drive);
28560
+ const slug = drive.initialState.state.global.slug;
28561
+ if (slug) {
28562
+ let existingDrive;
28563
+ try {
28564
+ existingDrive = await this.getDriveBySlug(slug);
28565
+ } catch {
28566
+ }
28567
+ if (existingDrive) {
28568
+ throw new Error(`Drive with slug ${slug} already exists`);
28569
+ }
28570
+ }
28571
+ await this.create(id, drive);
28442
28572
  await this.updateDriveManifest(id, { documentIds: [] });
28443
28573
  }
28444
28574
  async deleteDrive(id) {
@@ -28446,13 +28576,13 @@ const _BrowserStorage = class _BrowserStorage {
28446
28576
  await Promise.all(documents.map((doc) => this.deleteDocument(id, doc)));
28447
28577
  const db = await this.db;
28448
28578
  await db.removeItem(this.buildManifestKey(id));
28449
- return db.removeItem(this.buildDriveKey(id));
28579
+ return db.removeItem(this.buildDocumentKey(id));
28450
28580
  }
28451
28581
  async addDriveOperations(id, operations, header) {
28452
28582
  const drive = await this.getDrive(id);
28453
28583
  const mergedOperations = mergeOperations(drive.operations, operations);
28454
28584
  const db = await this.db;
28455
- await db.setItem(this.buildDriveKey(id), {
28585
+ await db.setItem(this.buildDocumentKey(id), {
28456
28586
  ...drive,
28457
28587
  ...header,
28458
28588
  operations: mergedOperations
@@ -28461,14 +28591,13 @@ const _BrowserStorage = class _BrowserStorage {
28461
28591
  async getSynchronizationUnitsRevision(units) {
28462
28592
  const results = await Promise.allSettled(units.map(async (unit) => {
28463
28593
  try {
28464
- const document = await (unit.documentId ? this.getDocument(unit.driveId, unit.documentId) : this.getDrive(unit.driveId));
28594
+ const document = await this.get(unit.documentId);
28465
28595
  if (!document) {
28466
28596
  return void 0;
28467
28597
  }
28468
28598
  const operation = document.operations[unit.scope].at(-1);
28469
28599
  if (operation) {
28470
28600
  return {
28471
- driveId: unit.driveId,
28472
28601
  documentId: unit.documentId,
28473
28602
  scope: unit.scope,
28474
28603
  branch: unit.branch,
@@ -28500,7 +28629,7 @@ const _BrowserStorage = class _BrowserStorage {
28500
28629
  const drive = await this.getDrive(driveId);
28501
28630
  const migratedDrive = migrateDocumentOperationSignatures(drive);
28502
28631
  if (migratedDrive !== drive) {
28503
- return (await this.db).setItem(this.buildDriveKey(driveId), migratedDrive);
28632
+ return (await this.db).setItem(this.buildDocumentKey(driveId), migratedDrive);
28504
28633
  }
28505
28634
  }
28506
28635
  async migrateDocument(drive, id) {
@@ -28513,9 +28642,6 @@ const _BrowserStorage = class _BrowserStorage {
28513
28642
  ////////////////////////////////
28514
28643
  // Private methods
28515
28644
  ////////////////////////////////
28516
- buildDriveKey(driveId) {
28517
- return `${_BrowserStorage.DRIVES_KEY}${_BrowserStorage.SEP}${driveId}`;
28518
- }
28519
28645
  buildDocumentKey(documentId) {
28520
28646
  return `${_BrowserStorage.DOCUMENT_KEY}${_BrowserStorage.SEP}${documentId}`;
28521
28647
  }
@@ -28525,7 +28651,6 @@ const _BrowserStorage = class _BrowserStorage {
28525
28651
  };
28526
28652
  __publicField(_BrowserStorage, "DBName", "DOCUMENT_DRIVES");
28527
28653
  __publicField(_BrowserStorage, "SEP", ":");
28528
- __publicField(_BrowserStorage, "DRIVES_KEY", "DRIVES");
28529
28654
  __publicField(_BrowserStorage, "DOCUMENT_KEY", "DOCUMENT");
28530
28655
  __publicField(_BrowserStorage, "MANIFEST_KEY", "MANIFEST");
28531
28656
  let BrowserStorage = _BrowserStorage;
@@ -31131,7 +31256,7 @@ if (window.__VITE_ENVS.MODE === "development") {
31131
31256
  } else {
31132
31257
  serviceWorkerManager.registerServiceWorker(false);
31133
31258
  }
31134
- const App = lazy(() => __vitePreload(() => import("./app-Bw1Ba-jV.js").then((n) => n.aN), true ? __vite__mapDeps([0,1,2]) : void 0));
31259
+ const App = lazy(() => __vitePreload(() => import("./app-Uu65do7x.js").then((n) => n.aN), true ? __vite__mapDeps([0,1,2]) : void 0));
31135
31260
  const AppLoader = /* @__PURE__ */ jsx(Suspense, { children: /* @__PURE__ */ jsx(App, {}) });
31136
31261
  const appLoader = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
31137
31262
  __proto__: null,