@powerhousedao/reactor-browser 6.2.2-dev.30 → 6.2.2-dev.32

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.
@@ -2,7 +2,7 @@ import { a as PHGlobal$1, b as IPackagesListener, ct as PromiseWithState, d as U
2
2
  import { t as PGlite } from "./pglite-CntadC_p-BtEalg1H.js";
3
3
  import { D as Scalars, E as PropagationMode$1, O as SdkFunctionWrapper, S as GetDocumentQuery, T as PhDocumentFieldsFragment, c as ReactorGraphQLClient, k as ViewFilterInput, x as GetDocumentOperationsQuery, y as DocumentChangesSubscription } from "./types-jEQ5crx9.js";
4
4
  import { Action, DocumentModelLib, DocumentModelModule, Operation, PHDocument } from "document-model";
5
- import { Action as Action$1, DocumentOperations, ISigner, PHBaseState, PHDocument as PHDocument$1, PHDocumentHeader } from "@powerhousedao/shared/document-model";
5
+ import { Action as Action$1, DocumentOperations, ISigner, Operation as Operation$1, PHBaseState, PHDocument as PHDocument$1, PHDocumentHeader } from "@powerhousedao/shared/document-model";
6
6
  import * as _powerhousedao_reactor0 from "@powerhousedao/reactor";
7
7
  import { Database, DocumentChangeEvent, DocumentModelSource, IDocumentModelRegistry, ISyncManager, OperationFilter, PagedResults, PagingOptions, PropagationMode, SearchFilter, ViewFilter } from "@powerhousedao/reactor";
8
8
  import { ReactNode } from "react";
@@ -938,6 +938,26 @@ declare function useDocumentModelModules(): DocumentModelModule[] | undefined;
938
938
  */
939
939
  declare function useDocumentModelModuleById(id: string | null | undefined, version?: number): DocumentModelModule | undefined;
940
940
  //#endregion
941
+ //#region src/hooks/document-operations.d.ts
942
+ type InternalState = {
943
+ globalOperations: Operation$1[];
944
+ localOperations: Operation$1[];
945
+ isLoading: boolean;
946
+ error: Error | undefined;
947
+ };
948
+ /** What `useDocumentOperations` returns; exported so consumers can name it. */
949
+ type DocumentOperationsState = InternalState & {
950
+ refetch: () => void;
951
+ };
952
+ /**
953
+ * Hook to fetch document operations via the reactor client.
954
+ * Operations are no longer auto-populated on documents and must be fetched explicitly.
955
+ *
956
+ * @param documentId - The document ID to fetch operations for
957
+ * @returns Object containing globalOperations, localOperations, isLoading, and error
958
+ */
959
+ declare function useDocumentOperations(documentId: string | null | undefined): DocumentOperationsState;
960
+ //#endregion
941
961
  //#region src/hooks/attachment-service.d.ts
942
962
  /** Returns the attachment service from window.ph */
943
963
  declare const useAttachmentService: UsePHGlobalValue<IAttachmentService>;
@@ -946,5 +966,5 @@ declare const setAttachmentService: SetPHGlobalValue<IAttachmentService>;
946
966
  /** Registers the attachmentService window event handler */
947
967
  declare const addAttachmentServiceEventHandler: AddPHGlobalEventHandler;
948
968
  //#endregion
949
- export { SubgraphSdkRegistry as $, DocumentChangesEventPayload as A, DocumentCache as At, MutateDocumentWithOperationsResult as B, useDocumentCache as C, RemoteControllerOptions as Ct, useGetDocumentAsync as D, RemoteOperationResultPage as Dt, useGetDocument as E, RemoteOperation as Et, StaticPackageManager as F, ensurePHEventHandlers as G, ReactorOperationFieldsFragmentDoc as H, packageFromDocumentModels as I, GraphQLReactorClientOptions as J, useSwitchboardClient as K, signStampedAction as L, makeAuthConnectionParams as M, readPromiseState as Mt, startDocumentChangesSubscription as N, useGetDocuments as O, SyncStatus$1 as Ot, subscriptionsUrlFromGraphqlUrl as P, SubgraphSdkFactory as Q, stampAction as R, useDocument as S, RemoteControllerGraphQLClient as St, useDocuments as T, RemoteDocumentData as Tt, GraphQLReactorProvider as U, MutateDocumentWithOperationsVariables as V, GraphQLReactorProviderProps as W, viewFilterInputFromViewFilter as X, isGraphQLReactorClient as Y, GraphQLRequestOptions as Z, useReactorClientModule as _, GetOperationsResult as _t, useDocumentModelModules as a, makeAuthMiddleware as at, addDocumentCacheEventHandler as b, MergeHandler as bt, useDispatch as c, RevisionsListSelection as ct, setReactorClient as d, revisionMapFromRevisionsList as dt, TypedGraphQLDocument as et, setReactorClientModule as f, ConflictInfo as ft, useReactorClient as g, GetDocumentWithOperationsResult as gt, usePGlite as h, GetDocumentResult as ht, useDocumentModelModuleById as i, ambientRenownTokenProvider as it, DocumentChangesSubscriptionOptions as j, addPromiseState as jt, ConnectionParams as k, TrackedAction as kt, addReactorClientEventHandler as l, phDocumentFromGetDocument as lt, useModelRegistry as m, DocumentChangeListener as mt, setAttachmentService as n, subgraphUrlFromGraphqlUrl as nt, DispatchFn as o, GetDocumentQueryFields as ot, useDatabase as p, ConflictStrategy as pt, GraphQLReactorClient as q, useAttachmentService as r, BearerTokenProvider as rt, UseDispatchResult as s, GetDocumentQueryResult as st, addAttachmentServiceEventHandler as t, describeGraphQLDocument as tt, addReactorClientModuleEventHandler as u, phDocumentFromMutation as ut, useSync as v, IRemoteClient as vt, useDocumentSafe as w, RemoteDocumentChangeEvent as wt, setDocumentCache as x, PushResult as xt, useSyncList as y, IRemoteController as yt, MutateDocumentWithOperationsDocument as z };
950
- //# sourceMappingURL=attachment-service-tOWCj9om.d.ts.map
969
+ export { GraphQLRequestOptions as $, useGetDocuments as A, SyncStatus$1 as At, stampAction as B, setDocumentCache as C, PushResult as Ct, useDocuments as D, RemoteDocumentData as Dt, useDocumentSafe as E, RemoteDocumentChangeEvent as Et, startDocumentChangesSubscription as F, GraphQLReactorProvider as G, MutateDocumentWithOperationsResult as H, subscriptionsUrlFromGraphqlUrl as I, useSwitchboardClient as J, GraphQLReactorProviderProps as K, StaticPackageManager as L, DocumentChangesEventPayload as M, DocumentCache as Mt, DocumentChangesSubscriptionOptions as N, addPromiseState as Nt, useGetDocument as O, RemoteOperation as Ot, makeAuthConnectionParams as P, readPromiseState as Pt, viewFilterInputFromViewFilter as Q, packageFromDocumentModels as R, addDocumentCacheEventHandler as S, MergeHandler as St, useDocumentCache as T, RemoteControllerOptions as Tt, MutateDocumentWithOperationsVariables as U, MutateDocumentWithOperationsDocument as V, ReactorOperationFieldsFragmentDoc as W, GraphQLReactorClientOptions as X, GraphQLReactorClient as Y, isGraphQLReactorClient as Z, usePGlite as _, GetDocumentResult as _t, useDocumentOperations as a, BearerTokenProvider as at, useSync as b, IRemoteClient as bt, DispatchFn as c, GetDocumentQueryFields as ct, addReactorClientEventHandler as d, phDocumentFromGetDocument as dt, SubgraphSdkFactory as et, addReactorClientModuleEventHandler as f, phDocumentFromMutation as ft, useModelRegistry as g, DocumentChangeListener as gt, useDatabase as h, ConflictStrategy as ht, DocumentOperationsState as i, subgraphUrlFromGraphqlUrl as it, ConnectionParams as j, TrackedAction as jt, useGetDocumentAsync as k, RemoteOperationResultPage as kt, UseDispatchResult as l, GetDocumentQueryResult as lt, setReactorClientModule as m, ConflictInfo as mt, setAttachmentService as n, TypedGraphQLDocument as nt, useDocumentModelModuleById as o, ambientRenownTokenProvider as ot, setReactorClient as p, revisionMapFromRevisionsList as pt, ensurePHEventHandlers as q, useAttachmentService as r, describeGraphQLDocument as rt, useDocumentModelModules as s, makeAuthMiddleware as st, addAttachmentServiceEventHandler as t, SubgraphSdkRegistry as tt, useDispatch as u, RevisionsListSelection as ut, useReactorClient as v, GetDocumentWithOperationsResult as vt, useDocument as w, RemoteControllerGraphQLClient as wt, useSyncList as x, IRemoteController as xt, useReactorClientModule as y, GetOperationsResult as yt, signStampedAction as z };
970
+ //# sourceMappingURL=attachment-service-C-NtTPYO.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachment-service-C-NtTPYO.d.ts","names":[],"sources":["../src/document-cache.ts","../src/remote-controller/types.ts","../src/graphql-client/adapter.ts","../src/graphql-client/auth.ts","../src/graphql-client/subgraph.ts","../src/graphql-client/graphql-reactor-client.ts","../src/graphql-client/graphql-reactor-provider.tsx","../src/graphql-client/operations.ts","../src/graphql-client/signing.ts","../src/graphql-client/static-package-manager.ts","../src/graphql-client/subscriptions.ts","../src/hooks/document-cache.ts","../src/hooks/reactor.ts","../src/hooks/dispatch.ts","../src/hooks/document-model-modules.ts","../src/hooks/document-operations.ts","../src/hooks/attachment-service.ts"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { t as makePHEventFunctions } from "./make-ph-event-functions-DBq3iWYn.js";
2
2
  import { logger } from "document-model";
3
3
  import { buildSignedAction } from "@powerhousedao/shared/document-model";
4
- import { use, useCallback, useSyncExternalStore } from "react";
4
+ import { use, useCallback, useEffect, useReducer, useSyncExternalStore } from "react";
5
5
  //#region src/actions/queue.ts
6
6
  async function queueActions(document, actionOrActions) {
7
7
  if (!document) throw new Error("No document provided");
@@ -372,6 +372,19 @@ function useDocument(id) {
372
372
  function useDocumentSafe(id) {
373
373
  const documentCache = useDocumentCache();
374
374
  const promise = useSyncExternalStore((cb) => id && documentCache ? documentCache.subscribe(id, cb) : () => {}, () => id ? documentCache?.get(id) : void 0);
375
+ const [, bumpOnSettle] = useReducer((count) => count + 1, 0);
376
+ const pendingPromise = promise && readPromiseState(promise).status === "pending" ? promise : null;
377
+ useEffect(() => {
378
+ if (!pendingPromise) return;
379
+ let active = true;
380
+ const settled = () => {
381
+ if (active) bumpOnSettle();
382
+ };
383
+ pendingPromise.then(settled, settled);
384
+ return () => {
385
+ active = false;
386
+ };
387
+ }, [pendingPromise]);
375
388
  if (!promise || !documentCache || !id) return {
376
389
  status: "initial",
377
390
  isPending: false,
@@ -476,4 +489,4 @@ function useDocumentsByIds(ids) {
476
489
  //#endregion
477
490
  export { uploadOperations as S, isDuplicateManifestError as _, setDocumentCache as a, queueActions as b, useDocumentSafe as c, useGetDocumentAsync as d, useGetDocuments as f, DOCUMENT_CHANGE_TYPE as g, readPromiseState as h, addDocumentCacheEventHandler as i, useDocuments as l, addPromiseState as m, useDocumentsByIds as n, useDocument as o, DocumentCache as p, useDispatch as r, useDocumentCache as s, useDocumentById as t, useGetDocument as u, isDuplicateModuleError as v, queueOperations as x, dispatchActions as y };
478
491
 
479
- //# sourceMappingURL=document-by-id-RNQCGkYh.js.map
492
+ //# sourceMappingURL=document-by-id-BPj6Gd7n.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"document-by-id-RNQCGkYh.js","names":[],"sources":["../src/actions/queue.ts","../src/actions/sign.ts","../src/actions/dispatch.ts","../src/reactor-interop.ts","../src/document-cache.ts","../src/hooks/document-cache.ts","../src/hooks/dispatch.ts","../src/hooks/document-by-id.ts"],"sourcesContent":["import type { FileUploadProgressCallback } from \"@powerhousedao/reactor-browser\";\nimport type {\n Action,\n DocumentOperations,\n Operation,\n PHDocument,\n} from \"@powerhousedao/shared/document-model\";\nimport { logger } from \"document-model\";\n\nexport async function queueActions(\n document: PHDocument | undefined,\n actionOrActions: Action[] | Action | undefined,\n) {\n if (!document) {\n throw new Error(\"No document provided\");\n }\n if (!actionOrActions) {\n throw new Error(\"No actions provided\");\n }\n const actions = Array.isArray(actionOrActions)\n ? actionOrActions\n : [actionOrActions];\n\n if (actions.length === 0) {\n throw new Error(\"No actions provided\");\n }\n\n const reactorClient = window.ph?.reactorClient;\n if (!reactorClient) {\n throw new Error(\"ReactorClient not initialized\");\n }\n\n return await reactorClient.execute(document.header.id, \"main\", actions);\n}\n\nexport async function queueOperations(\n documentId: string,\n operationOrOperations: Operation[] | Operation | undefined,\n) {\n if (!documentId) {\n throw new Error(\"No documentId provided\");\n }\n if (!operationOrOperations) {\n throw new Error(\"No operations provided\");\n }\n const operations = Array.isArray(operationOrOperations)\n ? operationOrOperations\n : [operationOrOperations];\n\n if (operations.length === 0) {\n throw new Error(\"No operations provided\");\n }\n\n const reactorClient = window.ph?.reactorClient;\n if (!reactorClient) {\n throw new Error(\"ReactorClient not initialized\");\n }\n\n const actions = operations.map((op) => op.action);\n return await reactorClient.execute(documentId, \"main\", actions);\n}\n\nexport function deduplicateOperations(\n existingOperations: Record<string, Operation[]>,\n operationsToDeduplicate: Operation[],\n) {\n // make a set of all the operation indices for each scope to avoid duplicates\n const operationIndicesByScope = {} as Record<string, Set<number>>;\n for (const scope of Object.keys(existingOperations)) {\n operationIndicesByScope[scope] = new Set(\n existingOperations[scope].map((op) => op.index),\n );\n }\n\n const newOperations: Operation[] = [];\n\n for (const operation of operationsToDeduplicate) {\n const scope = operation.action.scope;\n const index = operation.index;\n if (operationIndicesByScope[scope].has(index)) {\n const duplicatedExistingOperation = existingOperations[scope].find(\n (op) => op.index === index,\n );\n const duplicatedNewOperation = newOperations.find(\n (op) => op.index === index,\n );\n console.warn(\"skipping duplicate operation\");\n if (duplicatedExistingOperation) {\n console.warn(\n \"duplicate existing operation\",\n duplicatedExistingOperation,\n );\n }\n if (duplicatedNewOperation) {\n console.warn(\"duplicate new operation\", duplicatedNewOperation);\n }\n continue;\n }\n newOperations.push(operation);\n operationIndicesByScope[scope].add(index);\n }\n\n const uniqueOperationIds = new Set<string>();\n const operationsDedupedById: Operation[] = [];\n\n for (const [scope, operations] of Object.entries(existingOperations)) {\n for (const operation of operations) {\n const id = operation.id;\n if (!id) {\n console.warn(\"skipping operation with no id\", operation);\n continue;\n }\n if (uniqueOperationIds.has(id)) {\n console.warn(\n \"skipping existing operation with duplicate id in scope\",\n scope,\n operation,\n );\n continue;\n }\n uniqueOperationIds.add(id);\n }\n }\n\n for (const operation of newOperations) {\n const id = operation.id;\n if (!id) {\n console.warn(\"skipping operation with no id\", operation);\n continue;\n }\n if (uniqueOperationIds.has(id)) {\n console.warn(\n \"skipping new operation with duplicate id in scope\",\n operation.action.scope,\n operation,\n );\n continue;\n }\n uniqueOperationIds.add(id);\n operationsDedupedById.push(operation);\n }\n return operationsDedupedById;\n}\n\nexport async function uploadOperations(\n documentId: string,\n allOperations: DocumentOperations,\n pushOperations: (\n documentId: string,\n operations: Operation[],\n ) => Promise<PHDocument | undefined>,\n options?: {\n operationsLimit?: number;\n onProgress?: FileUploadProgressCallback;\n },\n) {\n const operationsLimit = options?.operationsLimit || 50;\n const onProgress = options?.onProgress;\n\n logger.verbose(\n `uploadDocumentOperations(documentId:${documentId}, ops: ${Object.keys(allOperations).join(\",\")}, limit:${operationsLimit})`,\n );\n\n // Calculate total operations for progress tracking\n const allOperationsArray = Object.values(allOperations).filter(\n (ops): ops is Operation[] => ops !== undefined,\n );\n const totalOperations = allOperationsArray.reduce(\n (total, operations) => total + operations.length,\n 0,\n );\n let uploadedOperations = 0;\n\n for (const operations of allOperationsArray) {\n for (let i = 0; i < operations.length; i += operationsLimit) {\n logger.verbose(\n `uploadDocumentOperations:for(i:${i}, ops:${operations.length}, limit:${operationsLimit}): START`,\n );\n const chunk = operations.slice(i, i + operationsLimit);\n const operation = chunk.at(-1);\n if (!operation) {\n break;\n }\n const scope = operation.action.scope;\n\n await pushOperations(documentId, chunk);\n\n uploadedOperations += chunk.length;\n\n // Report progress\n if (onProgress) {\n const progress = Math.round(\n (uploadedOperations / totalOperations) * 100,\n );\n onProgress({\n stage: \"uploading\",\n progress,\n totalOperations,\n uploadedOperations,\n });\n }\n\n logger.verbose(\n `uploadDocumentOperations:for:waitForUpdate(${documentId}:${scope} rev ${operation.index}): NEXT`,\n );\n }\n }\n\n logger.verbose(\n `uploadDocumentOperations:for:waitForUpdate(${documentId}): END`,\n );\n}\n","import type { Action, PHDocument } from \"@powerhousedao/shared/document-model\";\nimport {\n buildSignedAction,\n type ActionSigner,\n} from \"@powerhousedao/shared/document-model\";\nimport { logger } from \"document-model\";\n\nexport async function signAction(action: Action, document: PHDocument) {\n const renown = window.ph?.renown;\n if (!renown?.user) return action;\n if (!action.context?.signer) return action;\n\n // The document model module only exists on the full in-process reactor client;\n // without it there is no reducer to build a signed action with.\n const reactorClient = window.ph?.reactorClientModule?.client;\n if (!reactorClient) return action;\n\n const documentModelModule = await reactorClient.getDocumentModelModule(\n document.header.documentType,\n );\n const reducer = documentModelModule.reducer;\n\n const actionSigner = action.context.signer;\n const unsafeSignedAction = await buildSignedAction(\n action,\n reducer,\n document,\n actionSigner,\n renown.crypto.sign,\n );\n\n // TODO: this is super dangerous and is caused by the `buildSignedAction` function returning an `Operation` instead of an `Action`\n return unsafeSignedAction as unknown as Action;\n}\n\nexport function addActionContext(action: Action) {\n const renown = window.ph?.renown;\n if (!renown?.user) return action;\n\n const signer: ActionSigner = {\n app: {\n name: \"Connect\",\n key: renown.did,\n },\n user: {\n address: renown.user.address,\n networkId: renown.user.networkId,\n chainId: renown.user.chainId,\n },\n signatures: [],\n };\n\n return {\n context: { signer },\n ...action,\n };\n}\n\nasync function makeSignedActionWithContext(\n action: Action | undefined,\n document: PHDocument | undefined,\n) {\n if (!action) {\n logger.error(\"No action found\");\n return;\n }\n if (!document) {\n logger.error(\"No document found\");\n return;\n }\n const signedAction = await signAction(action, document);\n const signedActionWithContext = addActionContext(signedAction);\n return signedActionWithContext;\n}\n\nexport async function makeSignedActionsWithContext(\n actionOrActions: Action[] | Action | undefined,\n document: PHDocument | undefined,\n) {\n if (!actionOrActions) {\n logger.error(\"No actions found\");\n return;\n }\n const actions = Array.isArray(actionOrActions)\n ? actionOrActions\n : [actionOrActions];\n\n const signedActionsWithContext = await Promise.all(\n actions.map((action) => makeSignedActionWithContext(action, document)),\n );\n return signedActionsWithContext.filter((a) => a !== undefined);\n}\n","import type { Action, PHDocument } from \"@powerhousedao/shared/document-model\";\nimport { logger } from \"document-model\";\nimport { queueActions } from \"./queue.js\";\nimport { makeSignedActionsWithContext } from \"./sign.js\";\n\nasync function getDocument(\n documentId: string,\n): Promise<PHDocument | undefined> {\n try {\n return await window.ph?.reactorClient?.get(documentId);\n } catch (error) {\n logger.debug(`Failed to get document with id ${documentId}:`, error);\n return undefined;\n }\n}\n\nfunction getActionErrors(result: PHDocument, actions: Action[]) {\n return actions.reduce((errors, a) => {\n const scopeOperations = result.operations[a.scope];\n if (!scopeOperations) {\n return errors;\n }\n const op = scopeOperations.findLast((op) => op.action.id === a.id);\n\n if (op?.error) {\n errors.push(new Error(op.error));\n }\n return errors;\n }, new Array<Error>());\n}\n\n/**\n * Dispatches actions to a document.\n * @param actionOrActions - The action or actions to dispatch.\n * @param document - The document to dispatch actions to.\n * @param onErrors - Callback invoked with any errors that occurred during action execution.\n * @returns The updated document, or undefined if the dispatch failed.\n */\nexport async function dispatchActions<TDocument = PHDocument, TAction = Action>(\n actionOrActions: TAction[] | TAction | undefined,\n document: TDocument | undefined,\n onErrors?: (errors: Error[]) => void,\n onSuccess?: (result: PHDocument) => void,\n): Promise<PHDocument | undefined>;\n/**\n * Dispatches actions to a document.\n * @param actionOrActions - The action or actions to dispatch.\n * @param documentId - The ID of the document to dispatch actions to.\n * @param onErrors - Callback invoked with any errors that occurred during action execution.\n * @returns The updated document, or undefined if the dispatch failed.\n */\nexport async function dispatchActions(\n actionOrActions: Action[] | Action | undefined,\n documentId: string,\n onErrors?: (errors: Error[]) => void,\n onSuccess?: (result: PHDocument) => void,\n): Promise<PHDocument | undefined>;\nexport async function dispatchActions(\n actionOrActions: Action[] | Action | undefined,\n documentOrDocumentId: PHDocument | string | undefined,\n onErrors?: (errors: Error[]) => void,\n onSuccess?: (result: PHDocument) => void,\n): Promise<PHDocument | undefined> {\n const document =\n typeof documentOrDocumentId === \"string\"\n ? await getDocument(documentOrDocumentId)\n : documentOrDocumentId;\n\n if (!document) {\n logger.error(\n `Document with id ${JSON.stringify(documentOrDocumentId)} not found`,\n );\n return;\n }\n\n const signedActionsWithContext = await makeSignedActionsWithContext(\n actionOrActions,\n document,\n );\n if (!signedActionsWithContext) {\n logger.error(\"No signed actions with context found\");\n return;\n }\n const result = await queueActions(document, signedActionsWithContext);\n\n if (onErrors && result) {\n const errors = getActionErrors(result, signedActionsWithContext);\n if (errors.length) {\n onErrors(errors);\n }\n }\n\n if (onSuccess && result) {\n onSuccess(result);\n }\n\n return result;\n}\n","import type {\n DocumentChangeType,\n DuplicateManifestError,\n DuplicateModuleError,\n} from \"@powerhousedao/reactor\";\n\n/**\n * The handful of runtime values the browser-safe surface needs from\n * `@powerhousedao/reactor`, mirrored so that nothing on that surface has to\n * import the package as a value.\n *\n * `@powerhousedao/reactor` has a single entry point, and it reaches `pg`\n * (`dns`/`fs`/`net`/`tls`), `@electric-sql/pglite` and `node:worker_threads`. A\n * browser bundler must resolve all of those the moment any module imports a\n * VALUE from the package, which is what previously forced every consuming app\n * to alias the reactor away in its own build config. Type imports are erased\n * before the bundler ever sees them, so types keep coming from the reactor and\n * only these values are mirrored.\n *\n * Drift is a compile error rather than a runtime surprise - see the assertions\n * below.\n */\n\nconst DOCUMENT_CHANGE_TYPE_VALUES = {\n Created: \"created\",\n Deleted: \"deleted\",\n Updated: \"updated\",\n ParentAdded: \"parent_added\",\n ParentRemoved: \"parent_removed\",\n ChildAdded: \"child_added\",\n ChildRemoved: \"child_removed\",\n} as const satisfies Record<string, `${DocumentChangeType}`>;\n\n/**\n * `satisfies` above rejects a mirrored value the enum does not declare. This\n * rejects the other direction: a member the reactor added and this mirror does\n * not cover.\n */\ntype MissingDocumentChangeTypeMembers = Exclude<\n `${DocumentChangeType}`,\n (typeof DOCUMENT_CHANGE_TYPE_VALUES)[keyof typeof DOCUMENT_CHANGE_TYPE_VALUES]\n>;\ntype AssertNoMissingDocumentChangeTypeMembers = [\n MissingDocumentChangeTypeMembers,\n] extends [never]\n ? true\n : [\n \"DOCUMENT_CHANGE_TYPE is missing DocumentChangeType members\",\n MissingDocumentChangeTypeMembers,\n ];\nconst documentChangeTypeMirrorIsComplete: AssertNoMissingDocumentChangeTypeMembers = true;\nvoid documentChangeTypeMirrorIsComplete;\n\n/**\n * The reactor's `DocumentChangeType` members, typed as the enum so they can be\n * assigned to `DocumentChangeEvent.type`. The assertion is unavoidable - a\n * TypeScript string enum is nominal, so no string literal is assignable to it\n * without one - and the two checks above are what make it safe.\n */\nexport const DOCUMENT_CHANGE_TYPE = DOCUMENT_CHANGE_TYPE_VALUES as unknown as {\n readonly [K in keyof typeof DOCUMENT_CHANGE_TYPE_VALUES]: DocumentChangeType;\n};\n\n/**\n * Structural equivalents of the reactor error classes' own static `isError`\n * guards. Those guards match on `error.name` rather than the prototype chain\n * (`packages/reactor/src/registry/errors.ts`), so re-implementing them here is\n * behaviour-preserving and does not need the class at runtime.\n */\nexport function isDuplicateModuleError(\n error: unknown,\n): error is DuplicateModuleError {\n return Error.isError(error) && error.name === \"DuplicateModuleError\";\n}\n\nexport function isDuplicateManifestError(\n error: unknown,\n): error is DuplicateManifestError {\n return Error.isError(error) && error.name === \"DuplicateManifestError\";\n}\n","import type { DocumentChangeEvent } from \"@powerhousedao/reactor\";\nimport { DOCUMENT_CHANGE_TYPE } from \"./reactor-interop.js\";\nimport type { PHDocument } from \"@powerhousedao/shared/document-model\";\nimport type {\n FulfilledPromise,\n IDocumentCache,\n PromiseState,\n PromiseWithState,\n RejectedPromise,\n} from \"./types/documents.js\";\nimport type { IReactorBrowserClient } from \"./types/reactor-browser-client.js\";\n\nexport function addPromiseState<T>(promise: Promise<T>): PromiseWithState<T> {\n if (\"status\" in promise) {\n return promise as PromiseWithState<T>;\n }\n\n const promiseWithState = promise as PromiseWithState<T>;\n promiseWithState.status = \"pending\";\n promiseWithState.then(\n (value) => {\n promiseWithState.status = \"fulfilled\";\n (promiseWithState as FulfilledPromise<T>).value = value;\n },\n (reason) => {\n promiseWithState.status = \"rejected\";\n (promiseWithState as RejectedPromise<T>).reason = reason;\n // Re-throw to preserve unhandled rejection behavior\n // This allows React's error boundaries to catch the error\n throw reason;\n },\n );\n\n return promiseWithState;\n}\n\nexport function readPromiseState<T>(\n promise: Promise<T> | PromiseWithState<T>,\n): PromiseState<T> {\n return \"status\" in promise ? promise : { status: \"pending\" };\n}\n\n/**\n * Resolves an array of document promises using `Promise.allSettled`,\n * returning only the fulfilled values. A single missing/rejected\n * document does not poison the whole batch. Rejected entries are\n * logged at warn level so developers can see dangling references.\n */\nfunction fulfilledOnly(promises: Promise<PHDocument>[]): Promise<PHDocument[]> {\n return Promise.allSettled(promises).then((results) => {\n const documents: PHDocument[] = [];\n for (const result of results) {\n if (result.status === \"fulfilled\") {\n documents.push(result.value);\n } else {\n console.warn(\n \"[DocumentCache] Skipped unavailable document:\",\n result.reason,\n );\n }\n }\n return documents;\n });\n}\n\n/**\n * Document cache implementation that uses the new ReactorClient API.\n *\n * This cache subscribes to document change events via IReactorBrowserClient.subscribe()\n * and automatically updates the cache when documents are created, updated, or deleted.\n */\nexport class DocumentCache implements IDocumentCache {\n private documents = new Map<string, PromiseWithState<PHDocument>>();\n private batchPromises = new Map<\n string,\n { promises: Promise<PHDocument>[]; promise: Promise<PHDocument[]> }\n >();\n private listeners = new Map<string, (() => void)[]>();\n private unsubscribe: (() => void) | null = null;\n\n constructor(private client: IReactorBrowserClient) {\n this.unsubscribe = client.subscribe({}, (event: DocumentChangeEvent) => {\n this.handleDocumentChange(event);\n });\n }\n\n private handleDocumentChange(event: DocumentChangeEvent): void {\n if (event.type === DOCUMENT_CHANGE_TYPE.Deleted) {\n const documentId = event.context?.childId;\n if (documentId) {\n this.handleDocumentDeleted(documentId);\n }\n } else if (event.type === DOCUMENT_CHANGE_TYPE.Updated) {\n for (const doc of event.documents) {\n this.handleDocumentUpdated(doc.header.id).catch(console.warn);\n }\n }\n }\n\n private handleDocumentDeleted(documentId: string): void {\n const listeners = this.listeners.get(documentId);\n this.documents.delete(documentId);\n this.invalidateBatchesContaining(documentId);\n if (listeners) {\n listeners.forEach((listener) => listener());\n }\n this.listeners.delete(documentId);\n }\n\n private async handleDocumentUpdated(documentId: string): Promise<void> {\n if (this.documents.has(documentId)) {\n await this.get(documentId, true);\n const listeners = this.listeners.get(documentId);\n if (listeners) {\n listeners.forEach((listener) => listener());\n }\n }\n }\n\n private invalidateBatchesContaining(documentId: string): void {\n for (const key of this.batchPromises.keys()) {\n if (key.split(\",\").includes(documentId)) {\n this.batchPromises.delete(key);\n }\n }\n }\n\n get(id: string, refetch?: boolean): Promise<PHDocument> {\n const currentData = this.documents.get(id);\n if (currentData) {\n if (currentData.status === \"pending\") {\n return currentData;\n }\n if (!refetch) {\n return currentData;\n }\n }\n\n const documentPromise = this.client.get(id);\n this.documents.set(id, addPromiseState(documentPromise));\n return documentPromise;\n }\n\n getBatch(ids: string[]): Promise<PHDocument[]> {\n const key = ids.join(\",\");\n const cached = this.batchPromises.get(key);\n\n const hasDeletedDocuments = ids.some((id) => !this.documents.has(id));\n const currentPromises = ids.map((id) => this.get(id));\n\n if (hasDeletedDocuments) {\n const batchPromise = fulfilledOnly(currentPromises);\n this.batchPromises.set(key, {\n promises: currentPromises,\n promise: batchPromise,\n });\n return batchPromise;\n }\n\n if (cached) {\n const samePromises = currentPromises.every(\n (p, i) => p === cached.promises[i],\n );\n if (samePromises) {\n return cached.promise;\n }\n }\n\n const states = currentPromises.map((p) =>\n readPromiseState(p as PromiseWithState<PHDocument>),\n );\n const allSettled = states.every((s) => s.status !== \"pending\");\n\n if (allSettled) {\n const values = states\n .filter(\n (s): s is { status: \"fulfilled\"; value: PHDocument } =>\n s.status === \"fulfilled\",\n )\n .map((s) => s.value);\n const batchPromise = Promise.resolve(values) as PromiseWithState<\n PHDocument[]\n >;\n batchPromise.status = \"fulfilled\";\n (batchPromise as FulfilledPromise<PHDocument[]>).value = values;\n\n this.batchPromises.set(key, {\n promises: currentPromises,\n promise: batchPromise,\n });\n return batchPromise;\n }\n\n if (cached) {\n return cached.promise;\n }\n\n const batchPromise = fulfilledOnly(currentPromises);\n this.batchPromises.set(key, {\n promises: currentPromises,\n promise: batchPromise,\n });\n return batchPromise;\n }\n\n subscribe(id: string | string[], callback: () => void): () => void {\n const ids = Array.isArray(id) ? id : [id];\n for (const docId of ids) {\n const listeners = this.listeners.get(docId) ?? [];\n this.listeners.set(docId, [...listeners, callback]);\n }\n return () => {\n for (const docId of ids) {\n const listeners = this.listeners.get(docId) ?? [];\n this.listeners.set(\n docId,\n listeners.filter((listener) => listener !== callback),\n );\n }\n };\n }\n\n /**\n * Disposes of the cache and unsubscribes from document change events.\n */\n dispose(): void {\n if (this.unsubscribe) {\n this.unsubscribe();\n this.unsubscribe = null;\n }\n }\n}\n","import type { PHDocument } from \"@powerhousedao/shared/document-model\";\nimport { use, useCallback, useSyncExternalStore } from \"react\";\nimport { readPromiseState } from \"../document-cache.js\";\nimport type { IDocumentCache } from \"../types/documents.js\";\nimport type { SetPHGlobalValue, UsePHGlobalValue } from \"../types/global.js\";\nimport { makePHEventFunctions } from \"./make-ph-event-functions.js\";\n\nconst documentEventFunctions = makePHEventFunctions(\"documentCache\");\n\n/** Returns all documents in the reactor. */\nexport const useDocumentCache: UsePHGlobalValue<IDocumentCache> =\n documentEventFunctions.useValue;\n\n/** Sets all of the documents in the reactor. */\nexport const setDocumentCache: SetPHGlobalValue<IDocumentCache> =\n documentEventFunctions.setValue;\n\n/** Adds an event handler for all of the documents in the reactor. */\nexport const addDocumentCacheEventHandler =\n documentEventFunctions.addEventHandler;\n\n/**\n * Reads the state of a document promise and converts it to a query state object.\n * @param promise - The document promise to read\n * @returns An object containing the status, data, error, and isPending flag\n */\nfunction getDocumentQueryState(promise: Promise<PHDocument>) {\n const state = readPromiseState(promise);\n switch (state.status) {\n case \"pending\":\n return {\n status: \"pending\",\n isPending: true,\n error: undefined,\n data: undefined,\n } as const;\n case \"fulfilled\":\n return {\n status: \"success\",\n isPending: false,\n error: undefined,\n data: state.value,\n } as const;\n case \"rejected\":\n return {\n status: \"error\",\n isPending: false,\n error: state.reason,\n data: undefined,\n } as const;\n }\n}\n\n/**\n * Retrieves a document from the reactor and subscribes to changes using React Suspense.\n * This hook will suspend rendering while the document is loading.\n * @param id - The document ID to retrieve, or null/undefined to skip retrieval\n * @returns The document if found, or undefined if id is null/undefined\n */\nexport function useDocument(id: string | null | undefined) {\n const documentCache = useDocumentCache();\n const document = useSyncExternalStore(\n (cb) => (id && documentCache ? documentCache.subscribe(id, cb) : () => {}),\n () => (id ? documentCache?.get(id) : undefined),\n );\n return document ? use(document) : undefined;\n}\n\n/**\n * Retrieves a document from the reactor and subscribes to changes without\n * suspending or throwing. Use this when the ID might be stale (e.g., a\n * previously selected node that has since been deleted) and the consumer\n * wants to render a placeholder instead of crashing.\n *\n * Unlike {@link useGetDocumentAsync}, this hook subscribes to cache\n * updates, so the returned state stays in sync with reactor changes.\n *\n * @param id - The document ID to retrieve, or null/undefined to skip retrieval\n * @returns An object containing:\n * - status: \"initial\" | \"pending\" | \"success\" | \"error\"\n * - data: The document if successfully loaded\n * - isPending: Whether the document is currently loading\n * - error: Any error that occurred during loading (e.g., document not found)\n * - reload: Function to force a refetch, or undefined when no id is supplied\n */\nexport function useDocumentSafe(id: string | null | undefined) {\n const documentCache = useDocumentCache();\n const promise = useSyncExternalStore(\n (cb) => (id && documentCache ? documentCache.subscribe(id, cb) : () => {}),\n () => (id ? documentCache?.get(id) : undefined),\n );\n\n if (!promise || !documentCache || !id) {\n return {\n status: \"initial\",\n isPending: false,\n error: undefined,\n data: undefined,\n reload: undefined,\n } as const;\n }\n\n const state = getDocumentQueryState(promise);\n return { ...state, reload: () => documentCache.get(id, true) } as const;\n}\n\n/**\n * Retrieves multiple documents from the reactor using React Suspense.\n * This hook will suspend rendering while any of the documents are loading.\n *\n * Uses getBatch from the document cache which handles promise caching internally,\n * ensuring stable references for useSyncExternalStore.\n *\n * @param ids - Array of document IDs to retrieve, or null/undefined to skip retrieval\n * @returns An array of documents if found, or empty array if ids is null/undefined\n */\nexport function useDocuments(ids: string[] | null | undefined) {\n const documentCache = useDocumentCache();\n\n const documents = useSyncExternalStore(\n (cb) =>\n ids?.length && documentCache\n ? documentCache.subscribe(ids, cb)\n : () => {},\n () =>\n ids?.length && documentCache ? documentCache.getBatch(ids) : undefined,\n );\n\n return documents ? use(documents) : [];\n}\n\n/**\n * Returns a function to retrieve a document from the cache.\n * The returned function fetches and returns a document by ID.\n * @returns A function that takes a document ID and returns a Promise of the document\n */\nexport function useGetDocument() {\n const documentCache = useDocumentCache();\n\n return useCallback(\n (id: string) => {\n if (!documentCache) {\n return Promise.reject(new Error(\"Document cache not initialized\"));\n }\n return documentCache.get(id);\n },\n [documentCache],\n );\n}\n\n/**\n * Returns a function to retrieve multiple documents from the cache.\n * The returned function fetches and returns documents by their IDs.\n * @returns A function that takes an array of document IDs and returns a Promise of the documents\n */\nexport function useGetDocuments() {\n const documentCache = useDocumentCache();\n\n return useCallback(\n (ids: string[]) => {\n if (!documentCache) {\n return Promise.reject(new Error(\"Document cache not initialized\"));\n }\n return documentCache.getBatch(ids);\n },\n [documentCache],\n );\n}\n\n/**\n * Retrieves a document from the reactor without suspending rendering.\n * Returns the current state of the document loading operation.\n * @param id - The document ID to retrieve, or null/undefined to skip retrieval\n * @returns An object containing:\n * - status: \"initial\" | \"pending\" | \"success\" | \"error\"\n * - data: The document if successfully loaded\n * - isPending: Boolean indicating if the document is currently loading\n * - error: Any error that occurred during loading\n * - reload: Function to force reload the document from cache\n */\nexport function useGetDocumentAsync(id: string | null | undefined) {\n const documentCache = useDocumentCache();\n if (!id || !documentCache) {\n return {\n status: \"initial\",\n data: undefined,\n isPending: false,\n error: undefined,\n reload: undefined,\n } as const;\n }\n\n const promise = documentCache.get(id);\n const state = getDocumentQueryState(promise);\n\n return { ...state, reload: () => documentCache.get(id, true) } as const;\n}\n","import type { Action, PHDocument } from \"@powerhousedao/shared/document-model\";\nimport { logger } from \"document-model\";\nimport { dispatchActions } from \"../actions/dispatch.js\";\n\n/**\n * Returns a dispatch function for dispatching actions to a document.\n * Used internally by other hooks to provide action dispatching capabilities.\n * @param document - The document to dispatch actions to.\n * @returns A tuple containing the document and a dispatch function.\n */\nexport type DispatchFn<TAction> = (\n actionOrActions: TAction[] | TAction | undefined,\n onErrors?: (errors: Error[]) => void,\n onSuccess?: (result: PHDocument) => void,\n) => void;\n\nexport type UseDispatchResult<TDocument, TAction> = readonly [\n TDocument | undefined,\n DispatchFn<TAction>,\n];\n\nexport function useDispatch<TDocument = PHDocument, TAction = Action>(\n document: TDocument | undefined,\n): UseDispatchResult<TDocument, TAction> {\n /**\n * Dispatches actions to the document.\n * @param actionOrActions - The action or actions to dispatch.\n * @param onErrors - Callback invoked with any errors that occurred during action execution.\n */\n function dispatch(\n actionOrActions: TAction[] | TAction | undefined,\n onErrors?: (errors: Error[]) => void,\n onSuccess?: (result: PHDocument) => void,\n ) {\n dispatchActions(actionOrActions, document, onErrors, onSuccess).catch(\n logger.error,\n );\n }\n return [document, dispatch] as const;\n}\n","import type { Action, PHDocument } from \"@powerhousedao/shared/document-model\";\nimport { useDispatch, type UseDispatchResult } from \"./dispatch.js\";\nimport { useDocument, useDocuments } from \"./document-cache.js\";\n\n/** Returns a document by id. */\nexport function useDocumentById(\n id: string | null | undefined,\n): UseDispatchResult<PHDocument, Action> {\n const document = useDocument(id);\n const [, dispatch] = useDispatch<PHDocument, Action>(document);\n return [document, dispatch] as const;\n}\n\n/** Returns documents by ids. */\nexport function useDocumentsByIds(ids: string[] | null | undefined) {\n return useDocuments(ids);\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"document-by-id-BPj6Gd7n.js","names":[],"sources":["../src/actions/queue.ts","../src/actions/sign.ts","../src/actions/dispatch.ts","../src/reactor-interop.ts","../src/document-cache.ts","../src/hooks/document-cache.ts","../src/hooks/dispatch.ts","../src/hooks/document-by-id.ts"],"sourcesContent":["import type { FileUploadProgressCallback } from \"@powerhousedao/reactor-browser\";\nimport type {\n Action,\n DocumentOperations,\n Operation,\n PHDocument,\n} from \"@powerhousedao/shared/document-model\";\nimport { logger } from \"document-model\";\n\nexport async function queueActions(\n document: PHDocument | undefined,\n actionOrActions: Action[] | Action | undefined,\n) {\n if (!document) {\n throw new Error(\"No document provided\");\n }\n if (!actionOrActions) {\n throw new Error(\"No actions provided\");\n }\n const actions = Array.isArray(actionOrActions)\n ? actionOrActions\n : [actionOrActions];\n\n if (actions.length === 0) {\n throw new Error(\"No actions provided\");\n }\n\n const reactorClient = window.ph?.reactorClient;\n if (!reactorClient) {\n throw new Error(\"ReactorClient not initialized\");\n }\n\n return await reactorClient.execute(document.header.id, \"main\", actions);\n}\n\nexport async function queueOperations(\n documentId: string,\n operationOrOperations: Operation[] | Operation | undefined,\n) {\n if (!documentId) {\n throw new Error(\"No documentId provided\");\n }\n if (!operationOrOperations) {\n throw new Error(\"No operations provided\");\n }\n const operations = Array.isArray(operationOrOperations)\n ? operationOrOperations\n : [operationOrOperations];\n\n if (operations.length === 0) {\n throw new Error(\"No operations provided\");\n }\n\n const reactorClient = window.ph?.reactorClient;\n if (!reactorClient) {\n throw new Error(\"ReactorClient not initialized\");\n }\n\n const actions = operations.map((op) => op.action);\n return await reactorClient.execute(documentId, \"main\", actions);\n}\n\nexport function deduplicateOperations(\n existingOperations: Record<string, Operation[]>,\n operationsToDeduplicate: Operation[],\n) {\n // make a set of all the operation indices for each scope to avoid duplicates\n const operationIndicesByScope = {} as Record<string, Set<number>>;\n for (const scope of Object.keys(existingOperations)) {\n operationIndicesByScope[scope] = new Set(\n existingOperations[scope].map((op) => op.index),\n );\n }\n\n const newOperations: Operation[] = [];\n\n for (const operation of operationsToDeduplicate) {\n const scope = operation.action.scope;\n const index = operation.index;\n if (operationIndicesByScope[scope].has(index)) {\n const duplicatedExistingOperation = existingOperations[scope].find(\n (op) => op.index === index,\n );\n const duplicatedNewOperation = newOperations.find(\n (op) => op.index === index,\n );\n console.warn(\"skipping duplicate operation\");\n if (duplicatedExistingOperation) {\n console.warn(\n \"duplicate existing operation\",\n duplicatedExistingOperation,\n );\n }\n if (duplicatedNewOperation) {\n console.warn(\"duplicate new operation\", duplicatedNewOperation);\n }\n continue;\n }\n newOperations.push(operation);\n operationIndicesByScope[scope].add(index);\n }\n\n const uniqueOperationIds = new Set<string>();\n const operationsDedupedById: Operation[] = [];\n\n for (const [scope, operations] of Object.entries(existingOperations)) {\n for (const operation of operations) {\n const id = operation.id;\n if (!id) {\n console.warn(\"skipping operation with no id\", operation);\n continue;\n }\n if (uniqueOperationIds.has(id)) {\n console.warn(\n \"skipping existing operation with duplicate id in scope\",\n scope,\n operation,\n );\n continue;\n }\n uniqueOperationIds.add(id);\n }\n }\n\n for (const operation of newOperations) {\n const id = operation.id;\n if (!id) {\n console.warn(\"skipping operation with no id\", operation);\n continue;\n }\n if (uniqueOperationIds.has(id)) {\n console.warn(\n \"skipping new operation with duplicate id in scope\",\n operation.action.scope,\n operation,\n );\n continue;\n }\n uniqueOperationIds.add(id);\n operationsDedupedById.push(operation);\n }\n return operationsDedupedById;\n}\n\nexport async function uploadOperations(\n documentId: string,\n allOperations: DocumentOperations,\n pushOperations: (\n documentId: string,\n operations: Operation[],\n ) => Promise<PHDocument | undefined>,\n options?: {\n operationsLimit?: number;\n onProgress?: FileUploadProgressCallback;\n },\n) {\n const operationsLimit = options?.operationsLimit || 50;\n const onProgress = options?.onProgress;\n\n logger.verbose(\n `uploadDocumentOperations(documentId:${documentId}, ops: ${Object.keys(allOperations).join(\",\")}, limit:${operationsLimit})`,\n );\n\n // Calculate total operations for progress tracking\n const allOperationsArray = Object.values(allOperations).filter(\n (ops): ops is Operation[] => ops !== undefined,\n );\n const totalOperations = allOperationsArray.reduce(\n (total, operations) => total + operations.length,\n 0,\n );\n let uploadedOperations = 0;\n\n for (const operations of allOperationsArray) {\n for (let i = 0; i < operations.length; i += operationsLimit) {\n logger.verbose(\n `uploadDocumentOperations:for(i:${i}, ops:${operations.length}, limit:${operationsLimit}): START`,\n );\n const chunk = operations.slice(i, i + operationsLimit);\n const operation = chunk.at(-1);\n if (!operation) {\n break;\n }\n const scope = operation.action.scope;\n\n await pushOperations(documentId, chunk);\n\n uploadedOperations += chunk.length;\n\n // Report progress\n if (onProgress) {\n const progress = Math.round(\n (uploadedOperations / totalOperations) * 100,\n );\n onProgress({\n stage: \"uploading\",\n progress,\n totalOperations,\n uploadedOperations,\n });\n }\n\n logger.verbose(\n `uploadDocumentOperations:for:waitForUpdate(${documentId}:${scope} rev ${operation.index}): NEXT`,\n );\n }\n }\n\n logger.verbose(\n `uploadDocumentOperations:for:waitForUpdate(${documentId}): END`,\n );\n}\n","import type { Action, PHDocument } from \"@powerhousedao/shared/document-model\";\nimport {\n buildSignedAction,\n type ActionSigner,\n} from \"@powerhousedao/shared/document-model\";\nimport { logger } from \"document-model\";\n\nexport async function signAction(action: Action, document: PHDocument) {\n const renown = window.ph?.renown;\n if (!renown?.user) return action;\n if (!action.context?.signer) return action;\n\n // The document model module only exists on the full in-process reactor client;\n // without it there is no reducer to build a signed action with.\n const reactorClient = window.ph?.reactorClientModule?.client;\n if (!reactorClient) return action;\n\n const documentModelModule = await reactorClient.getDocumentModelModule(\n document.header.documentType,\n );\n const reducer = documentModelModule.reducer;\n\n const actionSigner = action.context.signer;\n const unsafeSignedAction = await buildSignedAction(\n action,\n reducer,\n document,\n actionSigner,\n renown.crypto.sign,\n );\n\n // TODO: this is super dangerous and is caused by the `buildSignedAction` function returning an `Operation` instead of an `Action`\n return unsafeSignedAction as unknown as Action;\n}\n\nexport function addActionContext(action: Action) {\n const renown = window.ph?.renown;\n if (!renown?.user) return action;\n\n const signer: ActionSigner = {\n app: {\n name: \"Connect\",\n key: renown.did,\n },\n user: {\n address: renown.user.address,\n networkId: renown.user.networkId,\n chainId: renown.user.chainId,\n },\n signatures: [],\n };\n\n return {\n context: { signer },\n ...action,\n };\n}\n\nasync function makeSignedActionWithContext(\n action: Action | undefined,\n document: PHDocument | undefined,\n) {\n if (!action) {\n logger.error(\"No action found\");\n return;\n }\n if (!document) {\n logger.error(\"No document found\");\n return;\n }\n const signedAction = await signAction(action, document);\n const signedActionWithContext = addActionContext(signedAction);\n return signedActionWithContext;\n}\n\nexport async function makeSignedActionsWithContext(\n actionOrActions: Action[] | Action | undefined,\n document: PHDocument | undefined,\n) {\n if (!actionOrActions) {\n logger.error(\"No actions found\");\n return;\n }\n const actions = Array.isArray(actionOrActions)\n ? actionOrActions\n : [actionOrActions];\n\n const signedActionsWithContext = await Promise.all(\n actions.map((action) => makeSignedActionWithContext(action, document)),\n );\n return signedActionsWithContext.filter((a) => a !== undefined);\n}\n","import type { Action, PHDocument } from \"@powerhousedao/shared/document-model\";\nimport { logger } from \"document-model\";\nimport { queueActions } from \"./queue.js\";\nimport { makeSignedActionsWithContext } from \"./sign.js\";\n\nasync function getDocument(\n documentId: string,\n): Promise<PHDocument | undefined> {\n try {\n return await window.ph?.reactorClient?.get(documentId);\n } catch (error) {\n logger.debug(`Failed to get document with id ${documentId}:`, error);\n return undefined;\n }\n}\n\nfunction getActionErrors(result: PHDocument, actions: Action[]) {\n return actions.reduce((errors, a) => {\n const scopeOperations = result.operations[a.scope];\n if (!scopeOperations) {\n return errors;\n }\n const op = scopeOperations.findLast((op) => op.action.id === a.id);\n\n if (op?.error) {\n errors.push(new Error(op.error));\n }\n return errors;\n }, new Array<Error>());\n}\n\n/**\n * Dispatches actions to a document.\n * @param actionOrActions - The action or actions to dispatch.\n * @param document - The document to dispatch actions to.\n * @param onErrors - Callback invoked with any errors that occurred during action execution.\n * @returns The updated document, or undefined if the dispatch failed.\n */\nexport async function dispatchActions<TDocument = PHDocument, TAction = Action>(\n actionOrActions: TAction[] | TAction | undefined,\n document: TDocument | undefined,\n onErrors?: (errors: Error[]) => void,\n onSuccess?: (result: PHDocument) => void,\n): Promise<PHDocument | undefined>;\n/**\n * Dispatches actions to a document.\n * @param actionOrActions - The action or actions to dispatch.\n * @param documentId - The ID of the document to dispatch actions to.\n * @param onErrors - Callback invoked with any errors that occurred during action execution.\n * @returns The updated document, or undefined if the dispatch failed.\n */\nexport async function dispatchActions(\n actionOrActions: Action[] | Action | undefined,\n documentId: string,\n onErrors?: (errors: Error[]) => void,\n onSuccess?: (result: PHDocument) => void,\n): Promise<PHDocument | undefined>;\nexport async function dispatchActions(\n actionOrActions: Action[] | Action | undefined,\n documentOrDocumentId: PHDocument | string | undefined,\n onErrors?: (errors: Error[]) => void,\n onSuccess?: (result: PHDocument) => void,\n): Promise<PHDocument | undefined> {\n const document =\n typeof documentOrDocumentId === \"string\"\n ? await getDocument(documentOrDocumentId)\n : documentOrDocumentId;\n\n if (!document) {\n logger.error(\n `Document with id ${JSON.stringify(documentOrDocumentId)} not found`,\n );\n return;\n }\n\n const signedActionsWithContext = await makeSignedActionsWithContext(\n actionOrActions,\n document,\n );\n if (!signedActionsWithContext) {\n logger.error(\"No signed actions with context found\");\n return;\n }\n const result = await queueActions(document, signedActionsWithContext);\n\n if (onErrors && result) {\n const errors = getActionErrors(result, signedActionsWithContext);\n if (errors.length) {\n onErrors(errors);\n }\n }\n\n if (onSuccess && result) {\n onSuccess(result);\n }\n\n return result;\n}\n","import type {\n DocumentChangeType,\n DuplicateManifestError,\n DuplicateModuleError,\n} from \"@powerhousedao/reactor\";\n\n/**\n * The handful of runtime values the browser-safe surface needs from\n * `@powerhousedao/reactor`, mirrored so that nothing on that surface has to\n * import the package as a value.\n *\n * `@powerhousedao/reactor` has a single entry point, and it reaches `pg`\n * (`dns`/`fs`/`net`/`tls`), `@electric-sql/pglite` and `node:worker_threads`. A\n * browser bundler must resolve all of those the moment any module imports a\n * VALUE from the package, which is what previously forced every consuming app\n * to alias the reactor away in its own build config. Type imports are erased\n * before the bundler ever sees them, so types keep coming from the reactor and\n * only these values are mirrored.\n *\n * Drift is a compile error rather than a runtime surprise - see the assertions\n * below.\n */\n\nconst DOCUMENT_CHANGE_TYPE_VALUES = {\n Created: \"created\",\n Deleted: \"deleted\",\n Updated: \"updated\",\n ParentAdded: \"parent_added\",\n ParentRemoved: \"parent_removed\",\n ChildAdded: \"child_added\",\n ChildRemoved: \"child_removed\",\n} as const satisfies Record<string, `${DocumentChangeType}`>;\n\n/**\n * `satisfies` above rejects a mirrored value the enum does not declare. This\n * rejects the other direction: a member the reactor added and this mirror does\n * not cover.\n */\ntype MissingDocumentChangeTypeMembers = Exclude<\n `${DocumentChangeType}`,\n (typeof DOCUMENT_CHANGE_TYPE_VALUES)[keyof typeof DOCUMENT_CHANGE_TYPE_VALUES]\n>;\ntype AssertNoMissingDocumentChangeTypeMembers = [\n MissingDocumentChangeTypeMembers,\n] extends [never]\n ? true\n : [\n \"DOCUMENT_CHANGE_TYPE is missing DocumentChangeType members\",\n MissingDocumentChangeTypeMembers,\n ];\nconst documentChangeTypeMirrorIsComplete: AssertNoMissingDocumentChangeTypeMembers = true;\nvoid documentChangeTypeMirrorIsComplete;\n\n/**\n * The reactor's `DocumentChangeType` members, typed as the enum so they can be\n * assigned to `DocumentChangeEvent.type`. The assertion is unavoidable - a\n * TypeScript string enum is nominal, so no string literal is assignable to it\n * without one - and the two checks above are what make it safe.\n */\nexport const DOCUMENT_CHANGE_TYPE = DOCUMENT_CHANGE_TYPE_VALUES as unknown as {\n readonly [K in keyof typeof DOCUMENT_CHANGE_TYPE_VALUES]: DocumentChangeType;\n};\n\n/**\n * Structural equivalents of the reactor error classes' own static `isError`\n * guards. Those guards match on `error.name` rather than the prototype chain\n * (`packages/reactor/src/registry/errors.ts`), so re-implementing them here is\n * behaviour-preserving and does not need the class at runtime.\n */\nexport function isDuplicateModuleError(\n error: unknown,\n): error is DuplicateModuleError {\n return Error.isError(error) && error.name === \"DuplicateModuleError\";\n}\n\nexport function isDuplicateManifestError(\n error: unknown,\n): error is DuplicateManifestError {\n return Error.isError(error) && error.name === \"DuplicateManifestError\";\n}\n","import type { DocumentChangeEvent } from \"@powerhousedao/reactor\";\nimport { DOCUMENT_CHANGE_TYPE } from \"./reactor-interop.js\";\nimport type { PHDocument } from \"@powerhousedao/shared/document-model\";\nimport type {\n FulfilledPromise,\n IDocumentCache,\n PromiseState,\n PromiseWithState,\n RejectedPromise,\n} from \"./types/documents.js\";\nimport type { IReactorBrowserClient } from \"./types/reactor-browser-client.js\";\n\nexport function addPromiseState<T>(promise: Promise<T>): PromiseWithState<T> {\n if (\"status\" in promise) {\n return promise as PromiseWithState<T>;\n }\n\n const promiseWithState = promise as PromiseWithState<T>;\n promiseWithState.status = \"pending\";\n promiseWithState.then(\n (value) => {\n promiseWithState.status = \"fulfilled\";\n (promiseWithState as FulfilledPromise<T>).value = value;\n },\n (reason) => {\n promiseWithState.status = \"rejected\";\n (promiseWithState as RejectedPromise<T>).reason = reason;\n // Re-throw to preserve unhandled rejection behavior\n // This allows React's error boundaries to catch the error\n throw reason;\n },\n );\n\n return promiseWithState;\n}\n\nexport function readPromiseState<T>(\n promise: Promise<T> | PromiseWithState<T>,\n): PromiseState<T> {\n return \"status\" in promise ? promise : { status: \"pending\" };\n}\n\n/**\n * Resolves an array of document promises using `Promise.allSettled`,\n * returning only the fulfilled values. A single missing/rejected\n * document does not poison the whole batch. Rejected entries are\n * logged at warn level so developers can see dangling references.\n */\nfunction fulfilledOnly(promises: Promise<PHDocument>[]): Promise<PHDocument[]> {\n return Promise.allSettled(promises).then((results) => {\n const documents: PHDocument[] = [];\n for (const result of results) {\n if (result.status === \"fulfilled\") {\n documents.push(result.value);\n } else {\n console.warn(\n \"[DocumentCache] Skipped unavailable document:\",\n result.reason,\n );\n }\n }\n return documents;\n });\n}\n\n/**\n * Document cache implementation that uses the new ReactorClient API.\n *\n * This cache subscribes to document change events via IReactorBrowserClient.subscribe()\n * and automatically updates the cache when documents are created, updated, or deleted.\n */\nexport class DocumentCache implements IDocumentCache {\n private documents = new Map<string, PromiseWithState<PHDocument>>();\n private batchPromises = new Map<\n string,\n { promises: Promise<PHDocument>[]; promise: Promise<PHDocument[]> }\n >();\n private listeners = new Map<string, (() => void)[]>();\n private unsubscribe: (() => void) | null = null;\n\n constructor(private client: IReactorBrowserClient) {\n this.unsubscribe = client.subscribe({}, (event: DocumentChangeEvent) => {\n this.handleDocumentChange(event);\n });\n }\n\n private handleDocumentChange(event: DocumentChangeEvent): void {\n if (event.type === DOCUMENT_CHANGE_TYPE.Deleted) {\n const documentId = event.context?.childId;\n if (documentId) {\n this.handleDocumentDeleted(documentId);\n }\n } else if (event.type === DOCUMENT_CHANGE_TYPE.Updated) {\n for (const doc of event.documents) {\n this.handleDocumentUpdated(doc.header.id).catch(console.warn);\n }\n }\n }\n\n private handleDocumentDeleted(documentId: string): void {\n const listeners = this.listeners.get(documentId);\n this.documents.delete(documentId);\n this.invalidateBatchesContaining(documentId);\n if (listeners) {\n listeners.forEach((listener) => listener());\n }\n this.listeners.delete(documentId);\n }\n\n private async handleDocumentUpdated(documentId: string): Promise<void> {\n if (this.documents.has(documentId)) {\n await this.get(documentId, true);\n const listeners = this.listeners.get(documentId);\n if (listeners) {\n listeners.forEach((listener) => listener());\n }\n }\n }\n\n private invalidateBatchesContaining(documentId: string): void {\n for (const key of this.batchPromises.keys()) {\n if (key.split(\",\").includes(documentId)) {\n this.batchPromises.delete(key);\n }\n }\n }\n\n get(id: string, refetch?: boolean): Promise<PHDocument> {\n const currentData = this.documents.get(id);\n if (currentData) {\n if (currentData.status === \"pending\") {\n return currentData;\n }\n if (!refetch) {\n return currentData;\n }\n }\n\n const documentPromise = this.client.get(id);\n this.documents.set(id, addPromiseState(documentPromise));\n return documentPromise;\n }\n\n getBatch(ids: string[]): Promise<PHDocument[]> {\n const key = ids.join(\",\");\n const cached = this.batchPromises.get(key);\n\n const hasDeletedDocuments = ids.some((id) => !this.documents.has(id));\n const currentPromises = ids.map((id) => this.get(id));\n\n if (hasDeletedDocuments) {\n const batchPromise = fulfilledOnly(currentPromises);\n this.batchPromises.set(key, {\n promises: currentPromises,\n promise: batchPromise,\n });\n return batchPromise;\n }\n\n if (cached) {\n const samePromises = currentPromises.every(\n (p, i) => p === cached.promises[i],\n );\n if (samePromises) {\n return cached.promise;\n }\n }\n\n const states = currentPromises.map((p) =>\n readPromiseState(p as PromiseWithState<PHDocument>),\n );\n const allSettled = states.every((s) => s.status !== \"pending\");\n\n if (allSettled) {\n const values = states\n .filter(\n (s): s is { status: \"fulfilled\"; value: PHDocument } =>\n s.status === \"fulfilled\",\n )\n .map((s) => s.value);\n const batchPromise = Promise.resolve(values) as PromiseWithState<\n PHDocument[]\n >;\n batchPromise.status = \"fulfilled\";\n (batchPromise as FulfilledPromise<PHDocument[]>).value = values;\n\n this.batchPromises.set(key, {\n promises: currentPromises,\n promise: batchPromise,\n });\n return batchPromise;\n }\n\n if (cached) {\n return cached.promise;\n }\n\n const batchPromise = fulfilledOnly(currentPromises);\n this.batchPromises.set(key, {\n promises: currentPromises,\n promise: batchPromise,\n });\n return batchPromise;\n }\n\n subscribe(id: string | string[], callback: () => void): () => void {\n const ids = Array.isArray(id) ? id : [id];\n for (const docId of ids) {\n const listeners = this.listeners.get(docId) ?? [];\n this.listeners.set(docId, [...listeners, callback]);\n }\n return () => {\n for (const docId of ids) {\n const listeners = this.listeners.get(docId) ?? [];\n this.listeners.set(\n docId,\n listeners.filter((listener) => listener !== callback),\n );\n }\n };\n }\n\n /**\n * Disposes of the cache and unsubscribes from document change events.\n */\n dispose(): void {\n if (this.unsubscribe) {\n this.unsubscribe();\n this.unsubscribe = null;\n }\n }\n}\n","import type { PHDocument } from \"@powerhousedao/shared/document-model\";\nimport {\n use,\n useCallback,\n useEffect,\n useReducer,\n useSyncExternalStore,\n} from \"react\";\nimport { readPromiseState } from \"../document-cache.js\";\nimport type { IDocumentCache } from \"../types/documents.js\";\nimport type { SetPHGlobalValue, UsePHGlobalValue } from \"../types/global.js\";\nimport { makePHEventFunctions } from \"./make-ph-event-functions.js\";\n\nconst documentEventFunctions = makePHEventFunctions(\"documentCache\");\n\n/** Returns all documents in the reactor. */\nexport const useDocumentCache: UsePHGlobalValue<IDocumentCache> =\n documentEventFunctions.useValue;\n\n/** Sets all of the documents in the reactor. */\nexport const setDocumentCache: SetPHGlobalValue<IDocumentCache> =\n documentEventFunctions.setValue;\n\n/** Adds an event handler for all of the documents in the reactor. */\nexport const addDocumentCacheEventHandler =\n documentEventFunctions.addEventHandler;\n\n/**\n * Reads the state of a document promise and converts it to a query state object.\n * @param promise - The document promise to read\n * @returns An object containing the status, data, error, and isPending flag\n */\nfunction getDocumentQueryState(promise: Promise<PHDocument>) {\n const state = readPromiseState(promise);\n switch (state.status) {\n case \"pending\":\n return {\n status: \"pending\",\n isPending: true,\n error: undefined,\n data: undefined,\n } as const;\n case \"fulfilled\":\n return {\n status: \"success\",\n isPending: false,\n error: undefined,\n data: state.value,\n } as const;\n case \"rejected\":\n return {\n status: \"error\",\n isPending: false,\n error: state.reason,\n data: undefined,\n } as const;\n }\n}\n\n/**\n * Retrieves a document from the reactor and subscribes to changes using React Suspense.\n * This hook will suspend rendering while the document is loading.\n * @param id - The document ID to retrieve, or null/undefined to skip retrieval\n * @returns The document if found, or undefined if id is null/undefined\n */\nexport function useDocument(id: string | null | undefined) {\n const documentCache = useDocumentCache();\n const document = useSyncExternalStore(\n (cb) => (id && documentCache ? documentCache.subscribe(id, cb) : () => {}),\n () => (id ? documentCache?.get(id) : undefined),\n );\n return document ? use(document) : undefined;\n}\n\n/**\n * Retrieves a document from the reactor and subscribes to changes without\n * suspending or throwing. Use this when the ID might be stale (e.g., a\n * previously selected node that has since been deleted) and the consumer\n * wants to render a placeholder instead of crashing.\n *\n * Unlike {@link useGetDocumentAsync}, this hook subscribes to cache\n * updates, so the returned state stays in sync with reactor changes.\n *\n * @param id - The document ID to retrieve, or null/undefined to skip retrieval\n * @returns An object containing:\n * - status: \"initial\" | \"pending\" | \"success\" | \"error\"\n * - data: The document if successfully loaded\n * - isPending: Whether the document is currently loading\n * - error: Any error that occurred during loading (e.g., document not found)\n * - reload: Function to force a refetch, or undefined when no id is supplied\n */\nexport function useDocumentSafe(id: string | null | undefined) {\n const documentCache = useDocumentCache();\n const promise = useSyncExternalStore(\n (cb) => (id && documentCache ? documentCache.subscribe(id, cb) : () => {}),\n () => (id ? documentCache?.get(id) : undefined),\n );\n\n // The cache notifies subscribers only when a document CHANGES (its stored\n // promise is replaced); the INITIAL fetch settles without a notification,\n // and since the snapshot above is the promise itself - same identity before\n // and after settling - nothing re-renders this hook past \"pending\" on a\n // page that is otherwise quiet. Watch the pending promise and bump local\n // state when it settles, so the state below is re-read. The promise is\n // captured at render time: if it settles before the effect runs, `.then`\n // still fires the bump on the next microtask, so the race loses nothing.\n // `useDocument` needs none of this - React itself resumes a component\n // suspended on `use(promise)`.\n const [, bumpOnSettle] = useReducer((count: number) => count + 1, 0);\n const pendingPromise =\n promise && readPromiseState(promise).status === \"pending\" ? promise : null;\n useEffect(() => {\n if (!pendingPromise) return;\n let active = true;\n const settled = () => {\n if (active) bumpOnSettle();\n };\n pendingPromise.then(settled, settled);\n return () => {\n active = false;\n };\n }, [pendingPromise]);\n\n if (!promise || !documentCache || !id) {\n return {\n status: \"initial\",\n isPending: false,\n error: undefined,\n data: undefined,\n reload: undefined,\n } as const;\n }\n\n const state = getDocumentQueryState(promise);\n return { ...state, reload: () => documentCache.get(id, true) } as const;\n}\n\n/**\n * Retrieves multiple documents from the reactor using React Suspense.\n * This hook will suspend rendering while any of the documents are loading.\n *\n * Uses getBatch from the document cache which handles promise caching internally,\n * ensuring stable references for useSyncExternalStore.\n *\n * @param ids - Array of document IDs to retrieve, or null/undefined to skip retrieval\n * @returns An array of documents if found, or empty array if ids is null/undefined\n */\nexport function useDocuments(ids: string[] | null | undefined) {\n const documentCache = useDocumentCache();\n\n const documents = useSyncExternalStore(\n (cb) =>\n ids?.length && documentCache\n ? documentCache.subscribe(ids, cb)\n : () => {},\n () =>\n ids?.length && documentCache ? documentCache.getBatch(ids) : undefined,\n );\n\n return documents ? use(documents) : [];\n}\n\n/**\n * Returns a function to retrieve a document from the cache.\n * The returned function fetches and returns a document by ID.\n * @returns A function that takes a document ID and returns a Promise of the document\n */\nexport function useGetDocument() {\n const documentCache = useDocumentCache();\n\n return useCallback(\n (id: string) => {\n if (!documentCache) {\n return Promise.reject(new Error(\"Document cache not initialized\"));\n }\n return documentCache.get(id);\n },\n [documentCache],\n );\n}\n\n/**\n * Returns a function to retrieve multiple documents from the cache.\n * The returned function fetches and returns documents by their IDs.\n * @returns A function that takes an array of document IDs and returns a Promise of the documents\n */\nexport function useGetDocuments() {\n const documentCache = useDocumentCache();\n\n return useCallback(\n (ids: string[]) => {\n if (!documentCache) {\n return Promise.reject(new Error(\"Document cache not initialized\"));\n }\n return documentCache.getBatch(ids);\n },\n [documentCache],\n );\n}\n\n/**\n * Retrieves a document from the reactor without suspending rendering.\n * Returns the current state of the document loading operation.\n * @param id - The document ID to retrieve, or null/undefined to skip retrieval\n * @returns An object containing:\n * - status: \"initial\" | \"pending\" | \"success\" | \"error\"\n * - data: The document if successfully loaded\n * - isPending: Boolean indicating if the document is currently loading\n * - error: Any error that occurred during loading\n * - reload: Function to force reload the document from cache\n */\nexport function useGetDocumentAsync(id: string | null | undefined) {\n const documentCache = useDocumentCache();\n if (!id || !documentCache) {\n return {\n status: \"initial\",\n data: undefined,\n isPending: false,\n error: undefined,\n reload: undefined,\n } as const;\n }\n\n const promise = documentCache.get(id);\n const state = getDocumentQueryState(promise);\n\n return { ...state, reload: () => documentCache.get(id, true) } as const;\n}\n","import type { Action, PHDocument } from \"@powerhousedao/shared/document-model\";\nimport { logger } from \"document-model\";\nimport { dispatchActions } from \"../actions/dispatch.js\";\n\n/**\n * Returns a dispatch function for dispatching actions to a document.\n * Used internally by other hooks to provide action dispatching capabilities.\n * @param document - The document to dispatch actions to.\n * @returns A tuple containing the document and a dispatch function.\n */\nexport type DispatchFn<TAction> = (\n actionOrActions: TAction[] | TAction | undefined,\n onErrors?: (errors: Error[]) => void,\n onSuccess?: (result: PHDocument) => void,\n) => void;\n\nexport type UseDispatchResult<TDocument, TAction> = readonly [\n TDocument | undefined,\n DispatchFn<TAction>,\n];\n\nexport function useDispatch<TDocument = PHDocument, TAction = Action>(\n document: TDocument | undefined,\n): UseDispatchResult<TDocument, TAction> {\n /**\n * Dispatches actions to the document.\n * @param actionOrActions - The action or actions to dispatch.\n * @param onErrors - Callback invoked with any errors that occurred during action execution.\n */\n function dispatch(\n actionOrActions: TAction[] | TAction | undefined,\n onErrors?: (errors: Error[]) => void,\n onSuccess?: (result: PHDocument) => void,\n ) {\n dispatchActions(actionOrActions, document, onErrors, onSuccess).catch(\n logger.error,\n );\n }\n return [document, dispatch] as const;\n}\n","import type { Action, PHDocument } from \"@powerhousedao/shared/document-model\";\nimport { useDispatch, type UseDispatchResult } from \"./dispatch.js\";\nimport { useDocument, useDocuments } from \"./document-cache.js\";\n\n/** Returns a document by id. */\nexport function useDocumentById(\n id: string | null | undefined,\n): UseDispatchResult<PHDocument, Action> {\n const document = useDocument(id);\n const [, dispatch] = useDispatch<PHDocument, Action>(document);\n return [document, dispatch] as const;\n}\n\n/** Returns documents by ids. */\nexport function useDocumentsByIds(ids: string[] | null | undefined) {\n return useDocuments(ids);\n}\n"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- import { S as uploadOperations, _ as isDuplicateManifestError, a as setDocumentCache, b as queueActions, g as DOCUMENT_CHANGE_TYPE, i as addDocumentCacheEventHandler, n as useDocumentsByIds, p as DocumentCache, r as useDispatch, v as isDuplicateModuleError, x as queueOperations } from "./document-by-id-RNQCGkYh.js";
1
+ import { S as uploadOperations, _ as isDuplicateManifestError, a as setDocumentCache, b as queueActions, g as DOCUMENT_CHANGE_TYPE, i as addDocumentCacheEventHandler, n as useDocumentsByIds, p as DocumentCache, r as useDispatch, v as isDuplicateModuleError, x as queueOperations } from "./document-by-id-BPj6Gd7n.js";
2
2
  import { t as makePHEventFunctions } from "./make-ph-event-functions-DBq3iWYn.js";
3
3
  import { a as PhDocumentFieldsFragmentDoc, n as DocumentChangeType, o as PropagationMode, r as DocumentChangesDocument, t as createClient$1 } from "./client-B1Af81HB.js";
4
4
  import { f as addLoadingEventHandler, t as addRenownEventHandler } from "./renown-BZabzj4l.js";
@@ -6,7 +6,7 @@ import { logger } from "document-model";
6
6
  import { assertAuthPreservedOnDuplicate, baseLoadFromInput, baseLoadFromInputVersioned, baseSaveToFileHandle, createPresignedHeader, createZip, documentModelDocumentType, generateId, hashDocumentStateForScope, replayDocumentVersioned, setName } from "@powerhousedao/shared/document-model";
7
7
  import { addFolder, copyNode, generateNodesCopy, handleTargetNameCollisions, isFileNode, isFolderNode, moveNode, updateNode } from "@powerhousedao/shared/document-drive";
8
8
  import { allPass, conditional, constant, forEachObj, funnel, isDefined, isNot, isStrictEqual, isString, isTruthy, once } from "remeda";
9
- import { useEffect, useState, useSyncExternalStore } from "react";
9
+ import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from "react";
10
10
  import { GraphQLClient } from "graphql-request";
11
11
  import { gql } from "graphql-tag";
12
12
  import { Kind, print } from "graphql";
@@ -2587,6 +2587,90 @@ function useDocumentModelModuleById(id, version) {
2587
2587
  return latestModule;
2588
2588
  }
2589
2589
  //#endregion
2590
- export { setGraphQLReactorClient as $, phDocumentFromGetDocument as $i, setIsDeleteLocalDrivesEnabled as $n, useIsEditorDebugModeEnabled as $r, addIsAnalyticsExternalProcessorsEnabledEventHandler as $t, isFileNodeKind as A, DocumentTypeMismatchError as Aa, phDocumentEditorConfigHooks as Ai, addVersionEventHandler as An, useAnalyticsDatabaseName as Ar, resolveUrlPathname as At, setReactorClient as B, viewFilterInputFromViewFilter as Bi, setDrivesPreserveStrategy as Bn, useIsAddDriveEnabled as Br, addCliVersionEventHandler as Bt, useSelectedTimelineItem as C, moveNode$1 as Ca, useWarnOutdatedApp as Ci, addRouterBasenameEventHandler as Cn, setSentryRelease as Cr, extractNodeIdFromPath as Ct, useFileNodesInSelectedDrive as D, isDocumentTypeSupported as Da, isExternalControlsEnabledEventFunctions as Di, addStudioModeEventHandler as Dn, setVersionCheckInterval as Dr, getPathWithoutBase as Dt, useDocumentsInSelectedDrive as E, getUserPermissions as Ea, addIsExternalControlsEnabledEventHandler as Ei, addSentryReleaseEventHandler as En, setVersion as Er, findUuid as Et, setRevisionHistoryVisible as F, useAllowedDocumentTypes as Fi, setAnalyticsDatabaseName as Fn, useDrivesPreserveStrategy as Fr, setAttachmentService as Ft, useReactorClient as G, describeGraphQLDocument as Gi, setIsAddDriveEnabled as Gn, useIsAnalyticsExternalProcessorsEnabled as Gr, addFileUploadOperationsChunkSizeEventHandler as Gt, useDatabase as H, startDocumentChangesSubscription as Hi, setFileUploadOperationsChunkSize as Hn, useIsAddPublicDrivesEnabled as Hr, addDisabledEditorsEventHandler as Ht, showRevisionHistory as I, useIsDragAndDropEnabled as Ii, setBasePath as In, useEnabledEditors as Ir, useAttachmentService as It, useSyncList as J, stampAction as Ji, setIsAnalyticsDatabaseWorkerEnabled as Jn, useIsDeleteLocalDrivesEnabled as Jr, addIsAddDriveEnabledEventHandler as Jt, useReactorClientModule as K, subgraphUrlFromGraphqlUrl as Ki, setIsAddLocalDrivesEnabled as Kn, useIsCloudDrivesEnabled as Kr, addGaTrackingIdEventHandler as Kt, useRevisionHistoryVisible as L, useIsExternalControlsEnabled as Li, setCliVersion as Ln, useFileUploadOperationsChunkSize as Lr, addAllowListEventHandler as Lt, sortNodesByName as M, UnsupportedDocumentTypeError as Ma, setAllowedDocumentTypes as Mi, phGlobalConfigHooks as Mn, useCliVersion as Mr, setFeatures as Mt, addRevisionHistoryVisibleEventHandler as N, setIsDragAndDropEnabled as Ni, phGlobalConfigSetters as Nn, useDefaultDrivesUrl as Nr, useFeatures as Nt, useFolderNodesInSelectedDrive as O, DocumentModelNotFoundError as Oa, phAppConfigHooks as Oi, addSwitchboardUrlEventHandler as On, setWarnOutdatedApp as Or, makeDriveUrlComponent as Ot, hideRevisionHistory as P, setIsExternalControlsEnabled as Pi, setAllowList as Pn, useDisabledEditors as Pr, addAttachmentServiceEventHandler as Pt, addGraphQLReactorClientEventHandler as Q, makeAuthMiddleware as Qi, setIsDeleteCloudDrivesEnabled as Qn, useIsDriveAnalyticsEnabled as Qr, addIsAnalyticsEnabledEventHandler as Qt, addReactorClientEventHandler as R, GraphQLReactorClient as Ri, setDefaultDrivesUrl as Rn, useGaTrackingId as Rr, addAnalyticsDatabaseNameEventHandler as Rt, setSelectedTimelineItem as S, loadFile as Sa, useVersionCheckInterval as Si, addRequiresHardRefreshEventHandler as Sn, setSentryEnv as Sr, extractDriveSlugFromPath as St, useDocumentTypesInSelectedDrive as T, renameNode as Ta, addIsDragAndDropEnabledEventHandler as Ti, addSentryEnvEventHandler as Tn, setSwitchboardUrl as Tr, extractNodeSlugFromPath as Tt, useModelRegistry as U, subscriptionsUrlFromGraphqlUrl as Ui, setGaTrackingId as Un, useIsAnalyticsDatabaseWorkerEnabled as Ur, addDrivesPreserveStrategyEventHandler as Ut, setReactorClientModule as V, makeAuthConnectionParams as Vi, setEnabledEditors as Vn, useIsAddLocalDrivesEnabled as Vr, addDefaultDrivesUrlEventHandler as Vt, usePGlite as W, SubgraphSdkRegistry as Wi, setIsAddCloudDrivesEnabled as Wn, useIsAnalyticsEnabled as Wr, addEnabledEditorsEventHandler as Wt, setPackageDiscoveryService as X, ReactorOperationFieldsFragmentDoc as Xi, setIsAnalyticsExternalProcessorsEnabled as Xn, useIsDiffAnalyticsEnabled as Xr, addIsAddPublicDrivesEnabledEventHandler as Xt, addPackageDiscoveryServiceEventHandler as Y, MutateDocumentWithOperationsDocument as Yi, setIsAnalyticsEnabled as Yn, useIsDeletePublicDrivesEnabled as Yr, addIsAddLocalDrivesEnabledEventHandler as Yt, usePackageDiscoveryService as Z, ambientRenownTokenProvider as Zi, setIsCloudDrivesEnabled as Zn, useIsDocumentModelSelectionSettingsEnabled as Zr, addIsAnalyticsDatabaseWorkerEnabledEventHandler as Zt, usePHToast as _, addFileWithProgress as _a, useSentryEnv as _i, addLogLevelEventHandler as _n, setRenownNetworkId as _r, setDrives as _t, useSwitchboardClient as a, extractRevisionMap as aa, useIsPublicDrivesEnabled as ai, addIsDocumentModelSelectionSettingsEnabledEventHandler as an, setIsEditorReadModeEnabled as ar, addSelectedDriveIdEventHandler as at, useSelectedTimelineRevision as b, deleteNode as ba, useSwitchboardUrl as bi, addRenownNetworkIdEventHandler as bn, setRouterBasename as br, extractDriveIdFromPath as bt, addPHEventHandlers as c, addModalEventHandler as ca, useLocalDrivesEnabled as ci, addIsEditorReadModeEnabledEventHandler as cn, setIsExternalRelationalProcessorsEnabled as cr, setSelectedDriveId as ct, addVetraPackageManagerEventHandler as d, showCreateDocumentModal as da, useRenownChainId as di, addIsExternalRelationalProcessorsEnabledEventHandler as dn, setIsRelationalProcessorsEnabled as dr, useSelectedDriveSafe as dt, phDocumentFromMutation as ea, useIsEditorReadModeEnabled as ei, addIsCloudDrivesEnabledEventHandler as en, setIsDeletePublicDrivesEnabled as er, useGraphQLReactorClient as et, setVetraPackageManager as f, showDeleteNodeModal as fa, useRenownNetworkId as fi, addIsLocalDrivesEnabledEventHandler as fn, setIsSentryTracingEnabled as fr, addResetSelectedNodeEventHandler as ft, setPHToast as g, addFile as ga, useSentryDsn as gi, addLocalDrivesEnabledEventHandler as gn, setRenownChainId as gr, addDrivesEventHandler as gt, addToastEventHandler as h, addDocument as ha, useRouterBasename as hi, addIsSentryTracingEnabledEventHandler as hn, setRenownAdapters as hr, setSelectedNode as ht, ensurePHEventHandlers as i, convertRemoteOperations as ia, useIsLocalDrivesEnabled as ii, addIsDiffAnalyticsEnabledEventHandler as in, setIsEditorDebugModeEnabled as ir, useDropTarget as it, isFolderNodeKind as j, NoSelectedDocumentError as ja, phDocumentEditorConfigSetters as ji, addWarnOutdatedAppEventHandler as jn, useBasePath as jr, addFeaturesEventHandler as jt, useNodesInSelectedDrive as k, DocumentNotFoundError as ka, phAppConfigSetters as ki, addVersionCheckIntervalEventHandler as kn, useAllowList as kr, makeNodeSlug as kt, callEventHandlerRegisterFunctions as l, closePHModal as la, useLogLevel as li, addIsExternalPackagesEnabledEventHandler as ln, setIsLocalDrivesEnabled as lr, useSelectedDrive as lt, useVetraPackages as m, usePHModal as ma, useRequiresHardRefresh as mi, addIsRelationalProcessorsEnabledEventHandler as mn, setLogLevel as mr, addSetSelectedNodeOnPopStateEventHandler as mt, useDocumentModelModules as n, ConflictError as na, useIsExternalProcessorsEnabled as ni, addIsDeleteLocalDrivesEnabledEventHandler as nn, setIsDocumentModelSelectionSettingsEnabled as nr, useDragNode as nt, StaticPackageManager as o, hasRevisionConflict as oa, useIsRelationalProcessorsEnabled as oi, addIsDriveAnalyticsEnabledEventHandler as on, setIsExternalPackagesEnabled as or, addSetSelectedDriveOnPopStateEventHandler as ot, useVetraPackageManager as p, showPHModal as pa, useRenownUrl as pi, addIsPublicDrivesEnabledEventHandler as pn, setLocalDrivesEnabled as pr, addSelectedNodeIdEventHandler as pt, useSync as q, signStampedAction as qi, setIsAddPublicDrivesEnabled as qn, useIsDeleteCloudDrivesEnabled as qr, addIsAddCloudDrivesEnabledEventHandler as qt, GraphQLReactorProvider as r, buildPulledDocument as ra, useIsExternalRelationalProcessorsEnabled as ri, addIsDeletePublicDrivesEnabledEventHandler as rn, setIsDriveAnalyticsEnabled as rr, useDropNode as rt, packageFromDocumentModels as s, screamingSnakeToCamel as sa, useIsSentryTracingEnabled as si, addIsEditorDebugModeEnabledEventHandler as sn, setIsExternalProcessorsEnabled as sr, setSelectedDrive as st, useDocumentModelModuleById as t, revisionMapFromRevisionsList as ta, useIsExternalPackagesEnabled as ti, addIsDeleteCloudDrivesEnabledEventHandler as tn, setIsDiffAnalyticsEnabled as tr, addDraggingNodeEventHandler as tt, commonGlobalEventHandlerFunctions as u, setPHModal as ua, useRenownAdapters as ui, addIsExternalProcessorsEnabledEventHandler as un, setIsPublicDrivesEnabled as ur, useSelectedDriveId as ut, addSelectedTimelineRevisionEventHandler as v, addFolder$1 as va, useSentryRelease as vi, addRenownAdaptersEventHandler as vn, setRenownUrl as vr, useDrives as vt, useSelectedNode as w, renameDriveNode as wa, addAllowedDocumentTypesEventHandler as wi, addSentryDsnEventHandler as wn, setStudioMode as wr, extractNodeIdFromSlug as wt, addSelectedTimelineItemEventHandler as x, exportFile as xa, useVersion as xi, addRenownUrlEventHandler as xn, setSentryDsn as xr, extractDriveIdFromSlug as xt, setSelectedTimelineRevision as y, copyNode$1 as ya, useStudioMode as yi, addRenownChainIdEventHandler as yn, setRequiresHardRefresh as yr, createUrlWithPreservedParams as yt, addReactorClientModuleEventHandler as z, isGraphQLReactorClient as zi, setDisabledEditors as zn, useIsAddCloudDrivesEnabled as zr, addBasePathEventHandler as zt };
2590
+ //#region src/hooks/document-operations.ts
2591
+ /**
2592
+ * Hook to fetch document operations via the reactor client.
2593
+ * Operations are no longer auto-populated on documents and must be fetched explicitly.
2594
+ *
2595
+ * @param documentId - The document ID to fetch operations for
2596
+ * @returns Object containing globalOperations, localOperations, isLoading, and error
2597
+ */
2598
+ function useDocumentOperations(documentId) {
2599
+ const reactorClient = useReactorClient();
2600
+ const hasFetchedRef = useRef(false);
2601
+ const [state, setState] = useState(() => ({
2602
+ globalOperations: [],
2603
+ localOperations: [],
2604
+ isLoading: !!documentId,
2605
+ error: void 0
2606
+ }));
2607
+ const fetchOperations = useCallback(async (retryCount = 0) => {
2608
+ const MAX_RETRIES = 5;
2609
+ const RETRY_DELAY_MS = 500;
2610
+ if (!documentId || !reactorClient) {
2611
+ setState({
2612
+ globalOperations: [],
2613
+ localOperations: [],
2614
+ isLoading: false,
2615
+ error: void 0
2616
+ });
2617
+ return;
2618
+ }
2619
+ setState((prev) => ({
2620
+ ...prev,
2621
+ isLoading: true,
2622
+ error: void 0
2623
+ }));
2624
+ let globalOps = [];
2625
+ let localOps = [];
2626
+ let fetchError;
2627
+ try {
2628
+ globalOps = (await reactorClient.getOperations(documentId, { scopes: ["global"] })).results;
2629
+ } catch (err) {
2630
+ fetchError = err instanceof Error ? err : new Error(String(err));
2631
+ }
2632
+ if (!fetchError) try {
2633
+ localOps = (await reactorClient.getOperations(documentId, { scopes: ["local"] })).results;
2634
+ } catch (err) {
2635
+ fetchError = err instanceof Error ? err : new Error(String(err));
2636
+ }
2637
+ if (!fetchError && globalOps.length === 0 && localOps.length === 0 && retryCount < MAX_RETRIES) {
2638
+ await new Promise((resolve) => setTimeout(resolve, RETRY_DELAY_MS));
2639
+ return fetchOperations(retryCount + 1);
2640
+ }
2641
+ setState({
2642
+ globalOperations: globalOps,
2643
+ localOperations: localOps,
2644
+ isLoading: false,
2645
+ error: fetchError
2646
+ });
2647
+ hasFetchedRef.current = true;
2648
+ }, [documentId, reactorClient]);
2649
+ useEffect(() => {
2650
+ if (documentId && reactorClient) fetchOperations();
2651
+ else if (!documentId) {
2652
+ setState({
2653
+ globalOperations: [],
2654
+ localOperations: [],
2655
+ isLoading: false,
2656
+ error: void 0
2657
+ });
2658
+ hasFetchedRef.current = false;
2659
+ }
2660
+ }, [
2661
+ documentId,
2662
+ reactorClient,
2663
+ fetchOperations
2664
+ ]);
2665
+ const refetch = useCallback(() => {
2666
+ fetchOperations(0);
2667
+ }, [fetchOperations]);
2668
+ return {
2669
+ ...state,
2670
+ refetch
2671
+ };
2672
+ }
2673
+ //#endregion
2674
+ export { addGraphQLReactorClientEventHandler as $, makeAuthMiddleware as $i, setIsDeleteCloudDrivesEnabled as $n, useIsDriveAnalyticsEnabled as $r, addIsAnalyticsEnabledEventHandler as $t, useNodesInSelectedDrive as A, DocumentNotFoundError as Aa, phAppConfigSetters as Ai, addVersionCheckIntervalEventHandler as An, useAllowList as Ar, makeNodeSlug as At, addReactorClientModuleEventHandler as B, isGraphQLReactorClient as Bi, setDisabledEditors as Bn, useIsAddCloudDrivesEnabled as Br, addBasePathEventHandler as Bt, setSelectedTimelineItem as C, loadFile as Ca, useVersionCheckInterval as Ci, addRequiresHardRefreshEventHandler as Cn, setSentryEnv as Cr, extractDriveSlugFromPath as Ct, useDocumentsInSelectedDrive as D, getUserPermissions as Da, addIsExternalControlsEnabledEventHandler as Di, addSentryReleaseEventHandler as Dn, setVersion as Dr, findUuid as Dt, useDocumentTypesInSelectedDrive as E, renameNode as Ea, addIsDragAndDropEnabledEventHandler as Ei, addSentryEnvEventHandler as En, setSwitchboardUrl as Er, extractNodeSlugFromPath as Et, hideRevisionHistory as F, setIsExternalControlsEnabled as Fi, setAllowList as Fn, useDisabledEditors as Fr, addAttachmentServiceEventHandler as Ft, usePGlite as G, SubgraphSdkRegistry as Gi, setIsAddCloudDrivesEnabled as Gn, useIsAnalyticsEnabled as Gr, addEnabledEditorsEventHandler as Gt, setReactorClientModule as H, makeAuthConnectionParams as Hi, setEnabledEditors as Hn, useIsAddLocalDrivesEnabled as Hr, addDefaultDrivesUrlEventHandler as Ht, setRevisionHistoryVisible as I, useAllowedDocumentTypes as Ii, setAnalyticsDatabaseName as In, useDrivesPreserveStrategy as Ir, setAttachmentService as It, useSync as J, signStampedAction as Ji, setIsAddPublicDrivesEnabled as Jn, useIsDeleteCloudDrivesEnabled as Jr, addIsAddCloudDrivesEnabledEventHandler as Jt, useReactorClient as K, describeGraphQLDocument as Ki, setIsAddDriveEnabled as Kn, useIsAnalyticsExternalProcessorsEnabled as Kr, addFileUploadOperationsChunkSizeEventHandler as Kt, showRevisionHistory as L, useIsDragAndDropEnabled as Li, setBasePath as Ln, useEnabledEditors as Lr, useAttachmentService as Lt, isFolderNodeKind as M, NoSelectedDocumentError as Ma, phDocumentEditorConfigSetters as Mi, addWarnOutdatedAppEventHandler as Mn, useBasePath as Mr, addFeaturesEventHandler as Mt, sortNodesByName as N, UnsupportedDocumentTypeError as Na, setAllowedDocumentTypes as Ni, phGlobalConfigHooks as Nn, useCliVersion as Nr, setFeatures as Nt, useFileNodesInSelectedDrive as O, isDocumentTypeSupported as Oa, isExternalControlsEnabledEventFunctions as Oi, addStudioModeEventHandler as On, setVersionCheckInterval as Or, getPathWithoutBase as Ot, addRevisionHistoryVisibleEventHandler as P, setIsDragAndDropEnabled as Pi, phGlobalConfigSetters as Pn, useDefaultDrivesUrl as Pr, useFeatures as Pt, usePackageDiscoveryService as Q, ambientRenownTokenProvider as Qi, setIsCloudDrivesEnabled as Qn, useIsDocumentModelSelectionSettingsEnabled as Qr, addIsAnalyticsDatabaseWorkerEnabledEventHandler as Qt, useRevisionHistoryVisible as R, useIsExternalControlsEnabled as Ri, setCliVersion as Rn, useFileUploadOperationsChunkSize as Rr, addAllowListEventHandler as Rt, addSelectedTimelineItemEventHandler as S, exportFile as Sa, useVersion as Si, addRenownUrlEventHandler as Sn, setSentryDsn as Sr, extractDriveIdFromSlug as St, useSelectedNode as T, renameDriveNode as Ta, addAllowedDocumentTypesEventHandler as Ti, addSentryDsnEventHandler as Tn, setStudioMode as Tr, extractNodeIdFromSlug as Tt, useDatabase as U, startDocumentChangesSubscription as Ui, setFileUploadOperationsChunkSize as Un, useIsAddPublicDrivesEnabled as Ur, addDisabledEditorsEventHandler as Ut, setReactorClient as V, viewFilterInputFromViewFilter as Vi, setDrivesPreserveStrategy as Vn, useIsAddDriveEnabled as Vr, addCliVersionEventHandler as Vt, useModelRegistry as W, subscriptionsUrlFromGraphqlUrl as Wi, setGaTrackingId as Wn, useIsAnalyticsDatabaseWorkerEnabled as Wr, addDrivesPreserveStrategyEventHandler as Wt, addPackageDiscoveryServiceEventHandler as X, MutateDocumentWithOperationsDocument as Xi, setIsAnalyticsEnabled as Xn, useIsDeletePublicDrivesEnabled as Xr, addIsAddLocalDrivesEnabledEventHandler as Xt, useSyncList as Y, stampAction as Yi, setIsAnalyticsDatabaseWorkerEnabled as Yn, useIsDeleteLocalDrivesEnabled as Yr, addIsAddDriveEnabledEventHandler as Yt, setPackageDiscoveryService as Z, ReactorOperationFieldsFragmentDoc as Zi, setIsAnalyticsExternalProcessorsEnabled as Zn, useIsDiffAnalyticsEnabled as Zr, addIsAddPublicDrivesEnabledEventHandler as Zt, setPHToast as _, addFile as _a, useSentryDsn as _i, addLocalDrivesEnabledEventHandler as _n, setRenownChainId as _r, addDrivesEventHandler as _t, ensurePHEventHandlers as a, convertRemoteOperations as aa, useIsLocalDrivesEnabled as ai, addIsDiffAnalyticsEnabledEventHandler as an, setIsEditorDebugModeEnabled as ar, useDropTarget as at, setSelectedTimelineRevision as b, copyNode$1 as ba, useStudioMode as bi, addRenownChainIdEventHandler as bn, setRequiresHardRefresh as br, createUrlWithPreservedParams as bt, packageFromDocumentModels as c, screamingSnakeToCamel as ca, useIsSentryTracingEnabled as ci, addIsEditorDebugModeEnabledEventHandler as cn, setIsExternalProcessorsEnabled as cr, setSelectedDrive as ct, commonGlobalEventHandlerFunctions as d, setPHModal as da, useRenownAdapters as di, addIsExternalProcessorsEnabledEventHandler as dn, setIsPublicDrivesEnabled as dr, useSelectedDriveId as dt, phDocumentFromGetDocument as ea, useIsEditorDebugModeEnabled as ei, addIsAnalyticsExternalProcessorsEnabledEventHandler as en, setIsDeleteLocalDrivesEnabled as er, setGraphQLReactorClient as et, addVetraPackageManagerEventHandler as f, showCreateDocumentModal as fa, useRenownChainId as fi, addIsExternalRelationalProcessorsEnabledEventHandler as fn, setIsRelationalProcessorsEnabled as fr, useSelectedDriveSafe as ft, addToastEventHandler as g, addDocument as ga, useRouterBasename as gi, addIsSentryTracingEnabledEventHandler as gn, setRenownAdapters as gr, setSelectedNode as gt, useVetraPackages as h, usePHModal as ha, useRequiresHardRefresh as hi, addIsRelationalProcessorsEnabledEventHandler as hn, setLogLevel as hr, addSetSelectedNodeOnPopStateEventHandler as ht, GraphQLReactorProvider as i, buildPulledDocument as ia, useIsExternalRelationalProcessorsEnabled as ii, addIsDeletePublicDrivesEnabledEventHandler as in, setIsDriveAnalyticsEnabled as ir, useDropNode as it, isFileNodeKind as j, DocumentTypeMismatchError as ja, phDocumentEditorConfigHooks as ji, addVersionEventHandler as jn, useAnalyticsDatabaseName as jr, resolveUrlPathname as jt, useFolderNodesInSelectedDrive as k, DocumentModelNotFoundError as ka, phAppConfigHooks as ki, addSwitchboardUrlEventHandler as kn, setWarnOutdatedApp as kr, makeDriveUrlComponent as kt, addPHEventHandlers as l, addModalEventHandler as la, useLocalDrivesEnabled as li, addIsEditorReadModeEnabledEventHandler as ln, setIsExternalRelationalProcessorsEnabled as lr, setSelectedDriveId as lt, useVetraPackageManager as m, showPHModal as ma, useRenownUrl as mi, addIsPublicDrivesEnabledEventHandler as mn, setLocalDrivesEnabled as mr, addSelectedNodeIdEventHandler as mt, useDocumentModelModuleById as n, revisionMapFromRevisionsList as na, useIsExternalPackagesEnabled as ni, addIsDeleteCloudDrivesEnabledEventHandler as nn, setIsDiffAnalyticsEnabled as nr, addDraggingNodeEventHandler as nt, useSwitchboardClient as o, extractRevisionMap as oa, useIsPublicDrivesEnabled as oi, addIsDocumentModelSelectionSettingsEnabledEventHandler as on, setIsEditorReadModeEnabled as or, addSelectedDriveIdEventHandler as ot, setVetraPackageManager as p, showDeleteNodeModal as pa, useRenownNetworkId as pi, addIsLocalDrivesEnabledEventHandler as pn, setIsSentryTracingEnabled as pr, addResetSelectedNodeEventHandler as pt, useReactorClientModule as q, subgraphUrlFromGraphqlUrl as qi, setIsAddLocalDrivesEnabled as qn, useIsCloudDrivesEnabled as qr, addGaTrackingIdEventHandler as qt, useDocumentModelModules as r, ConflictError as ra, useIsExternalProcessorsEnabled as ri, addIsDeleteLocalDrivesEnabledEventHandler as rn, setIsDocumentModelSelectionSettingsEnabled as rr, useDragNode as rt, StaticPackageManager as s, hasRevisionConflict as sa, useIsRelationalProcessorsEnabled as si, addIsDriveAnalyticsEnabledEventHandler as sn, setIsExternalPackagesEnabled as sr, addSetSelectedDriveOnPopStateEventHandler as st, useDocumentOperations as t, phDocumentFromMutation as ta, useIsEditorReadModeEnabled as ti, addIsCloudDrivesEnabledEventHandler as tn, setIsDeletePublicDrivesEnabled as tr, useGraphQLReactorClient as tt, callEventHandlerRegisterFunctions as u, closePHModal as ua, useLogLevel as ui, addIsExternalPackagesEnabledEventHandler as un, setIsLocalDrivesEnabled as ur, useSelectedDrive as ut, usePHToast as v, addFileWithProgress as va, useSentryEnv as vi, addLogLevelEventHandler as vn, setRenownNetworkId as vr, setDrives as vt, useSelectedTimelineItem as w, moveNode$1 as wa, useWarnOutdatedApp as wi, addRouterBasenameEventHandler as wn, setSentryRelease as wr, extractNodeIdFromPath as wt, useSelectedTimelineRevision as x, deleteNode as xa, useSwitchboardUrl as xi, addRenownNetworkIdEventHandler as xn, setRouterBasename as xr, extractDriveIdFromPath as xt, addSelectedTimelineRevisionEventHandler as y, addFolder$1 as ya, useSentryRelease as yi, addRenownAdaptersEventHandler as yn, setRenownUrl as yr, useDrives as yt, addReactorClientEventHandler as z, GraphQLReactorClient as zi, setDefaultDrivesUrl as zn, useGaTrackingId as zr, addAnalyticsDatabaseNameEventHandler as zt };
2591
2675
 
2592
- //# sourceMappingURL=document-model-modules-DObmiDli.js.map
2676
+ //# sourceMappingURL=document-operations-CsJ6vcqr.js.map