@powerhousedao/reactor-browser 6.2.0-dev.1 → 6.2.0-dev.11

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.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { C as queueOperations, S as queueActions, _ as getAnalyticsStore, a as setDocumentCache, b as setGlobal, c as useDocumentSafe, d as useGetDocumentAsync, f as useGetDocuments, g as createAnalyticsStore, h as readPromiseState, i as addDocumentCacheEventHandler, l as useDocuments, m as addPromiseState, n as useDocumentsByIds, o as useDocument, p as DocumentCache, r as useDispatch, s as useDocumentCache, t as useDocumentById, u as useGetDocument, v as clearGlobal, w as uploadOperations, x as dispatchActions, y as getGlobal } from "./document-by-id-BrIy0iHX.js";
2
- import { n as GetDocumentWithOperationsDocument, r as PropagationMode, t as createClient } from "./client-D7hUM13i.js";
2
+ import { n as GetDocumentWithOperationsDocument, r as PropagationMode, t as createClient } from "./client-CvgFU1Dv.js";
3
3
  import { t as makePHEventFunctions } from "./make-ph-event-functions-DwiD1zH9.js";
4
4
  import { A as useLoginStatus, C as RENOWN_CHAIN_ID, D as addRenownEventHandler, E as VERIFIABLE_CREDENTIAL_EIP712_TYPE, F as setLoading, I as useLoading, M as useUser, N as addLoadingEventHandler, O as setRenown, P as loading, S as ISSUER_TYPE, T as RENOWN_URL, _ as openRenown, a as RenownAuthButton, b as CREDENTIAL_TYPES, c as ChevronDownIcon, d as RenownLogo, f as SpinnerIcon, g as logout, h as login, i as initRenownCrypto, j as useRenown, k as useDid, l as CopyIcon, m as useRenownAuth, n as useRenownInit, o as RenownUserButton, p as UserIcon, r as initConnectCrypto, s as RenownLoginButton, t as Renown, u as DisconnectIcon, v as CREDENTIAL_SCHEMA_EIP712_TYPE, w as RENOWN_NETWORK_ID, x as DOMAIN_TYPE, y as CREDENTIAL_SUBJECT_TYPE } from "./renown-Dzmo1gJD.js";
5
5
  import { n as useRelationalQuery, r as useRelationalDb, t as createProcessorQuery } from "./relational-4_LVwp8p.js";
6
6
  import { documentModelDocumentModelModule, logger } from "document-model";
7
- import { baseLoadFromInput, baseSaveToFileHandle, createPresignedHeader, createZip, documentModelDocumentType, generateId, replayDocument, setName, validateInitialState, validateModules, validateStateSchemaName } from "@powerhousedao/shared/document-model";
7
+ import { baseLoadFromInput, baseLoadFromInputVersioned, baseSaveToFileHandle, createPresignedHeader, createZip, documentModelDocumentType, generateId, replayDocumentVersioned, setName, validateInitialState, validateModules, validateStateSchemaName } from "@powerhousedao/shared/document-model";
8
8
  import { DriveDocumentSchema, addFolder as addFolder$1, copyNode, driveCreateDocument, driveDocumentModelModule, generateNodesCopy, handleTargetNameCollisions, isFileNode, isFolderNode, moveNode, setAvailableOffline, setDriveIcon, setDriveName, setSharingType, updateNode } from "@powerhousedao/shared/document-drive";
9
9
  import { allPass, conditional, constant, filter, find, forEach, forEachObj, funnel, hasAtLeast, isArray, isDefined, isIncludedIn, isNot, isStrictEqual, isString, isTruthy, last, map, mapToObj, once, pipe, prop, split, unique } from "remeda";
10
10
  import { ChannelScheme, DocumentChangeType, DocumentChangeType as DocumentChangeType$1, DocumentIntegrityService, DuplicateManifestError, DuplicateModuleError, GqlRequestChannel, InMemoryQueue, IntervalPollTimer, ModuleNotFoundError, PollBehavior, PropagationMode as PropagationMode$1, REACTOR_SCHEMA, REACTOR_SCHEMA as REACTOR_SCHEMA$1, ReactorBuilder, ReactorClientBuilder, RelationalDbProcessor, SyncOperationStatus, SyncStatus, driveCollectionId, driveCollectionId as driveCollectionId$1, driveIdFromUrl, parseDriveUrl } from "@powerhousedao/reactor";
@@ -204,14 +204,30 @@ async function exportFile(document, suggestedName) {
204
204
  if (!(e instanceof DOMException && e.name === "AbortError")) throw e;
205
205
  }
206
206
  }
207
+ /**
208
+ * Loads a document file and replays it with version-aware reducers from the registry.
209
+ * Falls back to single-version legacy replay when no upgrade manifest is registered for
210
+ * the document type.
211
+ */
207
212
  async function loadFile(path) {
208
213
  const baseDocument = await baseLoadFromInput(path, (state) => state, { checkHashes: true });
209
214
  const reactorClient = window.ph?.reactorClient;
210
215
  if (!reactorClient) throw new Error("ReactorClient not initialized");
216
+ const documentType = baseDocument.header.documentType;
211
217
  const { results: documentModelModules } = await reactorClient.getDocumentModelModules();
212
- const documentModelModule = documentModelModules.find((module) => module.documentModel.global.id === baseDocument.header.documentType);
213
- if (!documentModelModule) throw new DocumentModelNotFoundError(baseDocument.header.documentType);
214
- return documentModelModule.utils.loadFromInput(path);
218
+ const modulesForType = documentModelModules.filter((module) => module.documentModel.global.id === documentType);
219
+ if (modulesForType.length === 0) throw new DocumentModelNotFoundError(documentType);
220
+ const reducers = {};
221
+ for (const module of modulesForType) reducers[module.version ?? 1] = module.reducer;
222
+ const registry = window.ph?.reactorClientModule?.reactorModule?.documentModelRegistry;
223
+ let upgradeManifest;
224
+ if (registry) try {
225
+ upgradeManifest = registry.getUpgradeManifest(documentType);
226
+ } catch {}
227
+ return baseLoadFromInputVersioned(path, {
228
+ reducers,
229
+ upgradeManifest
230
+ });
215
231
  }
216
232
  async function addDocument(driveId, name, documentType, parentFolder, document, id, preferredEditor) {
217
233
  const { isAllowedToCreateDocuments } = getUserPermissions();
@@ -465,9 +481,28 @@ async function moveNode$1(driveId, src, target) {
465
481
  targetParentFolder: target?.id
466
482
  })]);
467
483
  }
484
+ /**
485
+ * Duplicates a document under a new id using version-aware replay.
486
+ * Falls back gracefully when no upgrade manifest is registered for the document type.
487
+ */
468
488
  async function _duplicateDocument(reactor, document, newId = generateId()) {
469
- const documentModule = await reactor.getDocumentModelModule(document.header.documentType);
470
- return replayDocument(document.initialState, document.operations, documentModule.reducer, createPresignedHeader(newId, document.header.documentType));
489
+ const documentType = document.header.documentType;
490
+ const { results: allModules } = await reactor.getDocumentModelModules();
491
+ const modulesForType = allModules.filter((m) => m.documentModel.global.id === documentType);
492
+ const reducers = {};
493
+ for (const m of modulesForType) reducers[m.version ?? 1] = m.reducer;
494
+ if (Object.keys(reducers).length === 0) throw new Error(`Document model module not found for type: ${documentType}`);
495
+ const registry = window.ph?.reactorClientModule?.reactorModule?.documentModelRegistry;
496
+ let upgradeManifest;
497
+ if (registry) try {
498
+ upgradeManifest = registry.getUpgradeManifest(documentType);
499
+ } catch {}
500
+ const config = {
501
+ reducers,
502
+ upgradeManifest
503
+ };
504
+ const header = createPresignedHeader(newId, documentType);
505
+ return replayDocumentVersioned(document.initialState, document.operations, config, header);
471
506
  }
472
507
  async function copyNode$1(driveId, src, target) {
473
508
  const reactor = window.ph?.reactorClient;
@@ -510,6 +545,7 @@ async function copyNode$1(driveId, src, target) {
510
545
  //#endregion
511
546
  //#region src/actions/drive.ts
512
547
  const DEFAULT_INITIAL_SYNC_TIMEOUT_MS = 3e4;
548
+ const inFlightRemoteRegistrations = /* @__PURE__ */ new Map();
513
549
  /**
514
550
  * Resolves once a document with the given id is queryable through the
515
551
  * reactor client. Subscribes to Created events filtered by id and
@@ -575,12 +611,16 @@ async function addRemoteDrive(url, driveId, options) {
575
611
  const driveInfo = await response.json();
576
612
  const resolvedDriveId = driveId ?? driveInfo.id;
577
613
  const collectionId = driveCollectionId$1("main", resolvedDriveId);
578
- if (!sync.list().find((remote) => remote.collectionId === collectionId)) {
614
+ const inFlight = inFlightRemoteRegistrations.get(collectionId);
615
+ if (inFlight) await inFlight;
616
+ else if (!sync.list().find((remote) => remote.collectionId === collectionId)) {
579
617
  const remoteName = crypto.randomUUID();
580
- await sync.add(remoteName, collectionId, {
618
+ const registration = sync.add(remoteName, collectionId, {
581
619
  type: "gql",
582
620
  parameters: { url: driveInfo.graphqlEndpoint }
583
- }, void 0, options?.pollBehavior ? { pollBehavior: options.pollBehavior } : void 0);
621
+ }, void 0, options?.pollBehavior ? { pollBehavior: options.pollBehavior } : void 0).finally(() => inFlightRemoteRegistrations.delete(collectionId));
622
+ inFlightRemoteRegistrations.set(collectionId, registration);
623
+ await registration;
584
624
  }
585
625
  if (options?.awaitInitialSync) await waitForDocumentReady(reactorClient, resolvedDriveId, {
586
626
  timeoutMs: options.initialSyncTimeoutMs,
@@ -3327,13 +3367,6 @@ function remoteOperationToLocal(remote) {
3327
3367
  timestampUtcMs: remote.action.timestampUtcMs,
3328
3368
  input: remote.action.input,
3329
3369
  scope: remote.action.scope,
3330
- attachments: remote.action.attachments?.map((a) => ({
3331
- data: a.data,
3332
- mimeType: a.mimeType,
3333
- hash: a.hash,
3334
- extension: a.extension ?? void 0,
3335
- fileName: a.fileName ?? void 0
3336
- })),
3337
3370
  context: remote.action.context?.signer ? { signer: {
3338
3371
  user: remote.action.context.signer.user ?? {
3339
3372
  address: "",