@powerhousedao/reactor-browser 6.2.3-dev.10 → 6.2.3-dev.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/dist/{attachment-service-BW1v0OAT.d.ts → attachment-service-C14mVTk_.d.ts} +84 -13
  2. package/dist/attachment-service-C14mVTk_.d.ts.map +1 -0
  3. package/dist/{document-by-id-B4FIzG1w.js → document-by-id-iXB59Ge-.js} +208 -4
  4. package/dist/document-by-id-iXB59Ge-.js.map +1 -0
  5. package/dist/{document-model-modules-bTP87nyr.js → document-model-modules-BSwKnUR_.js} +2 -2
  6. package/dist/{document-model-modules-bTP87nyr.js.map → document-model-modules-BSwKnUR_.js.map} +1 -1
  7. package/dist/{document-operations-Cm4EtaZs.js → document-operations-BjZmu1JC.js} +81 -78
  8. package/dist/{document-operations-Cm4EtaZs.js.map → document-operations-BjZmu1JC.js.map} +1 -1
  9. package/dist/{global-CgCouXuH.d.ts → global-D4e836Hk.d.ts} +28 -3
  10. package/dist/global-D4e836Hk.d.ts.map +1 -0
  11. package/dist/{index-CBjFO54H.d.ts → index-BvJaeywJ.d.ts} +2 -2
  12. package/dist/{index-CBjFO54H.d.ts.map → index-BvJaeywJ.d.ts.map} +1 -1
  13. package/dist/index.d.ts +5 -5
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +5 -5
  16. package/dist/index.js.map +1 -1
  17. package/dist/src/ai/index.js +2 -2
  18. package/dist/src/analytics/index.js +1 -1
  19. package/dist/src/graphql-client/entry.d.ts +3 -3
  20. package/dist/src/graphql-client/entry.js +4 -4
  21. package/dist/src/renown/index.d.ts +1 -1
  22. package/dist/src/rpc/index.d.ts +8 -0
  23. package/dist/src/rpc/index.d.ts.map +1 -1
  24. package/dist/src/rpc/index.js +12 -1
  25. package/dist/src/rpc/index.js.map +1 -1
  26. package/dist/{switchboard-CaXQ4-5Q.js → switchboard-Yt6ASJRx.js} +3 -3
  27. package/dist/{switchboard-CaXQ4-5Q.js.map → switchboard-Yt6ASJRx.js.map} +1 -1
  28. package/package.json +9 -9
  29. package/dist/attachment-service-BW1v0OAT.d.ts.map +0 -1
  30. package/dist/document-by-id-B4FIzG1w.js.map +0 -1
  31. package/dist/global-CgCouXuH.d.ts.map +0 -1
@@ -1,4 +1,4 @@
1
- import { a as PHGlobal$1, b as IPackagesListener, ct as PromiseWithState, d as UsePHGlobalValue$1, ot as IDocumentCache, rt as IReactorBrowserClient$1, st as PromiseState, u as SetPHGlobalValue$1, v as IPackageListerUnsubscribe, x as PackageManagerInstallResult, y as IPackageManager } from "./global-CgCouXuH.js";
1
+ import { a as PHGlobal$1, b as IPackagesListener, ct as OperationsCacheEntry, d as UsePHGlobalValue$1, lt as PromiseState, ot as IDocumentCache, rt as IReactorBrowserClient$1, st as IOperationCache, u as SetPHGlobalValue$1, ut as PromiseWithState, v as IPackageListerUnsubscribe, x as PackageManagerInstallResult, y as IPackageManager } from "./global-D4e836Hk.js";
2
2
  import { t as PGlite } from "./pglite-CntadC_p-9NDG14dS.js";
3
3
  import { A as ViewFilterInput, C as GetDocumentQuery, D as PropagationMode$1, E as PhDocumentFieldsFragment, O as Scalars, S as GetDocumentOperationsQuery, b as DocumentChangesSubscription, c as ReactorGraphQLClient, g as ActionInput, k as SdkFunctionWrapper } from "./types-N3Jy6Nry.js";
4
4
  import { Action, DocumentModelLib, DocumentModelModule, Operation, PHDocument } from "document-model";
@@ -18,13 +18,19 @@ import { RegistryPackageSource } from "@powerhousedao/shared";
18
18
  //#region src/document-cache.d.ts
19
19
  declare function addPromiseState<T>(promise: Promise<T>): PromiseWithState<T>;
20
20
  declare function readPromiseState<T>(promise: Promise<T> | PromiseWithState<T>): PromiseState<T>;
21
+ /** The snapshot every uncached document scope reads as. One frozen object, so `useSyncExternalStore` sees a stable value. */
22
+ declare const IDLE_OPERATIONS_ENTRY: OperationsCacheEntry;
23
+ /** Whether a document cache also serves operation history. `GraphQLClientDocumentCache` does not. */
24
+ declare function isOperationCache(cache: unknown): cache is IOperationCache;
21
25
  /**
22
26
  * Document cache implementation that uses the new ReactorClient API.
23
27
  *
24
28
  * This cache subscribes to document change events via IReactorBrowserClient.subscribe()
25
29
  * and automatically updates the cache when documents are created, updated, or deleted.
30
+ * It also holds paginated operation history per document scope (see `IOperationCache`),
31
+ * which is dropped for a document whenever a change event for it arrives.
26
32
  */
27
- declare class DocumentCache implements IDocumentCache {
33
+ declare class DocumentCache implements IDocumentCache, IOperationCache {
28
34
  private client;
29
35
  private documents;
30
36
  private batchPromises;
@@ -37,6 +43,11 @@ declare class DocumentCache implements IDocumentCache {
37
43
  * the same document is cached under.
38
44
  */
39
45
  private aliasKeys;
46
+ /** Operations by document id, then scope. Entries are replaced, never mutated. */
47
+ private operationEntries;
48
+ /** In-flight controllers and the next page's cursor/limit, by document id then scope. */
49
+ private operationRequests;
50
+ private operationListeners;
40
51
  private unsubscribe;
41
52
  constructor(client: IReactorBrowserClient$1);
42
53
  private handleDocumentChange;
@@ -50,6 +61,35 @@ declare class DocumentCache implements IDocumentCache {
50
61
  get(id: string, refetch?: boolean): Promise<PHDocument$1>;
51
62
  getBatch(ids: string[]): Promise<PHDocument$1[]>;
52
63
  subscribe(id: string | string[], callback: () => void): () => void;
64
+ getOperationsState(documentId: string, scope: string): OperationsCacheEntry;
65
+ loadOperations(documentId: string, scope: string, limit: number): void;
66
+ loadMoreOperations(documentId: string, scope: string): void;
67
+ /**
68
+ * Bring a document's cached scopes up to date after it changed, without
69
+ * throwing away what is already loaded.
70
+ *
71
+ * The operation stream is append-only: an update adds operations at higher
72
+ * revisions and never rewrites the ones below, so history already paged in
73
+ * is still correct. Dropping it meant a panel showing a fully loaded
74
+ * document re-walked every page on each edit -- the cost of which grows
75
+ * with the document, exactly where it hurts most. Each scope instead asks
76
+ * only for what comes after the newest revision it holds, using the
77
+ * `sinceRevision` filter, and appends the answer.
78
+ *
79
+ * A scope that has not finished paging is dropped as before: it has no
80
+ * meaningful "newest revision" to resume from, since asking for everything
81
+ * past the newest row it happens to hold would skip the pages between that
82
+ * row and the end of the stream.
83
+ */
84
+ private refreshOperations;
85
+ /** Drops one scope of a document, aborting its request if one is in flight. */
86
+ private invalidateOperationsScope;
87
+ invalidateOperations(documentId: string): void;
88
+ subscribeOperations(documentId: string, callback: () => void): () => void;
89
+ private settleOperationsPage;
90
+ private setOperationsEntry;
91
+ private setOperationsRequest;
92
+ private notifyOperationListeners;
53
93
  /**
54
94
  * Disposes of the cache and unsubscribes from document change events.
55
95
  */
@@ -1067,24 +1107,55 @@ declare function useDocumentModelModules(): DocumentModelModule[] | undefined;
1067
1107
  declare function useDocumentModelModuleById(id: string | null | undefined, version?: number): DocumentModelModule | undefined;
1068
1108
  //#endregion
1069
1109
  //#region src/hooks/document-operations.d.ts
1070
- type InternalState = {
1110
+ type UseDocumentOperationsOptions = {
1111
+ /**
1112
+ * Operations per page. Default 100. Applies to the next first-page load;
1113
+ * changing it while pages are already loaded has no effect until the next
1114
+ * invalidation or `refetch`.
1115
+ */
1116
+ limit?: number; /** Whether to fetch at all. Default true. Pass false until the operations are needed. */
1117
+ enabled?: boolean;
1118
+ };
1119
+ /** What `useDocumentOperations` returns; exported so consumers can name it. */
1120
+ type DocumentOperationsResult = {
1121
+ /** Every operation of the scope loaded so far, oldest first. */operations: readonly Operation$1[]; /** A page is in flight. */
1122
+ isLoading: boolean; /** The last page failed. Operations loaded before it stay available. */
1123
+ error: Error | undefined; /** The last page reported a further page. */
1124
+ hasNextPage: boolean; /** Reported by the GraphQL client only. */
1125
+ totalCount: number | undefined; /** Loads the next page and appends it. No-op while loading or when there is none. */
1126
+ fetchNextPage: () => void; /** Drops the document's cached operations and reloads from the first page. */
1127
+ refetch: () => void;
1128
+ };
1129
+ /**
1130
+ * Legacy result of `useDocumentOperations(documentId)`.
1131
+ * @deprecated Call `useDocumentOperations(documentId, scope, options)` and read `operations`. Removed in the next major.
1132
+ */
1133
+ type DocumentOperationsState = {
1071
1134
  globalOperations: Operation$1[];
1072
1135
  localOperations: Operation$1[];
1073
1136
  isLoading: boolean;
1074
1137
  error: Error | undefined;
1075
- };
1076
- /** What `useDocumentOperations` returns; exported so consumers can name it. */
1077
- type DocumentOperationsState = InternalState & {
1078
1138
  refetch: () => void;
1079
1139
  };
1140
+ /** @deprecated Pass a scope: `useDocumentOperations(documentId, "global")`. The legacy form fetches the whole global and local history eagerly. Removed in the next major. */
1141
+ declare function useDocumentOperations(documentId: string | null | undefined): DocumentOperationsState;
1080
1142
  /**
1081
- * Hook to fetch document operations via the reactor client.
1082
- * Operations are no longer auto-populated on documents and must be fetched explicitly.
1143
+ * Operation history of a document, read from the document cache and kept in
1144
+ * step with it: a change event for the document drops the cached pages and
1145
+ * the hook loads the first page again.
1146
+ *
1147
+ * Pages arrive oldest first. A view that wants the whole history calls
1148
+ * `fetchNextPage` while `hasNextPage` is true.
1083
1149
  *
1084
- * @param documentId - The document ID to fetch operations for
1085
- * @returns Object containing globalOperations, localOperations, isLoading, and error
1150
+ * An empty first page is a final result; there is no retry. When the active
1151
+ * document cache does not serve operations, the result is empty and not
1152
+ * loading.
1153
+ *
1154
+ * @param documentId - The document id, or null/undefined to skip fetching
1155
+ * @param scope - The operation scope, for example "global" or "local"
1156
+ * @param options - Page size and whether fetching is enabled
1086
1157
  */
1087
- declare function useDocumentOperations(documentId: string | null | undefined): DocumentOperationsState;
1158
+ declare function useDocumentOperations(documentId: string | null | undefined, scope: string, options?: UseDocumentOperationsOptions): DocumentOperationsResult;
1088
1159
  //#endregion
1089
1160
  //#region src/hooks/attachment-service.d.ts
1090
1161
  /** Returns the attachment service from window.ph */
@@ -1094,5 +1165,5 @@ declare const setAttachmentService: SetPHGlobalValue<IAttachmentService>;
1094
1165
  /** Registers the attachmentService window event handler */
1095
1166
  declare const addAttachmentServiceEventHandler: AddPHGlobalEventHandler;
1096
1167
  //#endregion
1097
- export { GraphQLReactorClientOptions as $, useGetDocuments as A, RemoteDocumentData as At, resolveDocumentModelModule as B, setDocumentCache as C, IRemoteClient as Ct, useDocuments as D, RemoteControllerGraphQLClient as Dt, useDocumentSafe as E, PushResult as Et, makeAuthConnectionParams as F, DocumentCache as Ft, MutateDocumentWithOperationsResult as G, signStampedAction as H, startDocumentChangesSubscription as I, addPromiseState as It, GraphQLReactorProvider as J, MutateDocumentWithOperationsVariables as K, subscriptionsUrlFromGraphqlUrl as L, readPromiseState as Lt, DocumentChangesEventPayload as M, RemoteOperationResultPage as Mt, DocumentChangesSubscriptionOptions as N, SyncStatus$1 as Nt, useGetDocument as O, RemoteControllerOptions as Ot, isAuthRefusalClose as P, TrackedAction as Pt, GraphQLReactorClient as Q, StaticPackageManager as R, addDocumentCacheEventHandler as S, GetOperationsResult as St, useDocumentCache as T, MergeHandler as Tt, stampAction as U, prepareSignedActions as V, MutateDocumentWithOperationsDocument as W, ensurePHEventHandlers as X, GraphQLReactorProviderProps as Y, useSwitchboardClient as Z, usePGlite as _, ConflictInfo as _t, useDocumentOperations as a, TypedGraphQLDocument as at, useSync as b, GetDocumentResult as bt, DispatchFn as c, BearerTokenProvider as ct, addReactorClientEventHandler as d, GetDocumentQueryFields as dt, isGraphQLReactorClient as et, addReactorClientModuleEventHandler as f, GetDocumentQueryResult as ft, useModelRegistry as g, revisionMapFromRevisionsList as gt, useDatabase as h, phDocumentFromMutation as ht, DocumentOperationsState as i, SubgraphSdkRegistry as it, ConnectionParams as j, RemoteOperation as jt, useGetDocumentAsync as k, RemoteDocumentChangeEvent as kt, UseDispatchResult as l, ambientRenownTokenProvider as lt, setReactorClientModule as m, phDocumentFromGetDocument as mt, setAttachmentService as n, GraphQLRequestOptions as nt, useDocumentModelModuleById as o, describeGraphQLDocument as ot, setReactorClient as p, RevisionsListSelection as pt, ReactorOperationFieldsFragmentDoc as q, useAttachmentService as r, SubgraphSdkFactory as rt, useDocumentModelModules as s, subgraphUrlFromGraphqlUrl as st, addAttachmentServiceEventHandler as t, viewFilterInputFromViewFilter as tt, useDispatch as u, makeAuthMiddleware as ut, useReactorClient as v, ConflictStrategy as vt, useDocument as w, IRemoteController as wt, useSyncList as x, GetDocumentWithOperationsResult as xt, useReactorClientModule as y, DocumentChangeListener as yt, packageFromDocumentModels as z };
1098
- //# sourceMappingURL=attachment-service-BW1v0OAT.d.ts.map
1168
+ export { useSwitchboardClient as $, useGetDocument as A, RemoteControllerOptions as At, StaticPackageManager as B, isOperationCache as Bt, useSyncList as C, GetDocumentWithOperationsResult as Ct, useDocumentCache as D, MergeHandler as Dt, useDocument as E, IRemoteController as Et, DocumentChangesSubscriptionOptions as F, SyncStatus$1 as Ft, stampAction as G, resolveDocumentModelModule as H, isAuthRefusalClose as I, TrackedAction as It, MutateDocumentWithOperationsVariables as J, MutateDocumentWithOperationsDocument as K, makeAuthConnectionParams as L, DocumentCache as Lt, useGetDocuments as M, RemoteDocumentData as Mt, ConnectionParams as N, RemoteOperation as Nt, useDocumentSafe as O, PushResult as Ot, DocumentChangesEventPayload as P, RemoteOperationResultPage as Pt, ensurePHEventHandlers as Q, startDocumentChangesSubscription as R, IDLE_OPERATIONS_ENTRY as Rt, useSync as S, GetDocumentResult as St, setDocumentCache as T, IRemoteClient as Tt, prepareSignedActions as U, packageFromDocumentModels as V, readPromiseState as Vt, signStampedAction as W, GraphQLReactorProvider as X, ReactorOperationFieldsFragmentDoc as Y, GraphQLReactorProviderProps as Z, useDatabase as _, phDocumentFromMutation as _t, DocumentOperationsState as a, SubgraphSdkFactory as at, useReactorClient as b, ConflictStrategy as bt, useDocumentModelModuleById as c, describeGraphQLDocument as ct, UseDispatchResult as d, ambientRenownTokenProvider as dt, GraphQLReactorClient as et, useDispatch as f, makeAuthMiddleware as ft, setReactorClientModule as g, phDocumentFromGetDocument as gt, setReactorClient as h, RevisionsListSelection as ht, DocumentOperationsResult as i, GraphQLRequestOptions as it, useGetDocumentAsync as j, RemoteDocumentChangeEvent as jt, useDocuments as k, RemoteControllerGraphQLClient as kt, useDocumentModelModules as l, subgraphUrlFromGraphqlUrl as lt, addReactorClientModuleEventHandler as m, GetDocumentQueryResult as mt, setAttachmentService as n, isGraphQLReactorClient as nt, UseDocumentOperationsOptions as o, SubgraphSdkRegistry as ot, addReactorClientEventHandler as p, GetDocumentQueryFields as pt, MutateDocumentWithOperationsResult as q, useAttachmentService as r, viewFilterInputFromViewFilter as rt, useDocumentOperations as s, TypedGraphQLDocument as st, addAttachmentServiceEventHandler as t, GraphQLReactorClientOptions as tt, DispatchFn as u, BearerTokenProvider as ut, useModelRegistry as v, revisionMapFromRevisionsList as vt, addDocumentCacheEventHandler as w, GetOperationsResult as wt, useReactorClientModule as x, DocumentChangeListener as xt, usePGlite as y, ConflictInfo as yt, subscriptionsUrlFromGraphqlUrl as z, addPromiseState as zt };
1169
+ //# sourceMappingURL=attachment-service-C14mVTk_.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"attachment-service-C14mVTk_.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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"}
@@ -195,11 +195,42 @@ function fulfilledOnly(promises) {
195
195
  return documents;
196
196
  });
197
197
  }
198
+ /** The snapshot every uncached document scope reads as. One frozen object, so `useSyncExternalStore` sees a stable value. */
199
+ const IDLE_OPERATIONS_ENTRY = Object.freeze({
200
+ status: "idle",
201
+ operations: Object.freeze([]),
202
+ error: void 0,
203
+ hasNextPage: false,
204
+ totalCount: void 0
205
+ });
206
+ /** Whether a document cache also serves operation history. `GraphQLClientDocumentCache` does not. */
207
+ function isOperationCache(cache) {
208
+ if (typeof cache !== "object" || cache === null) return false;
209
+ const candidate = cache;
210
+ return typeof candidate.getOperationsState === "function" && typeof candidate.loadOperations === "function" && typeof candidate.loadMoreOperations === "function" && typeof candidate.invalidateOperations === "function" && typeof candidate.subscribeOperations === "function";
211
+ }
212
+ /**
213
+ * Page size used to refresh a scope whose request record has gone missing.
214
+ * A loaded scope always has one, so this is a floor rather than a default.
215
+ */
216
+ const FALLBACK_REFRESH_LIMIT = 100;
217
+ /**
218
+ * The highest revision among the operations loaded so far, or -1 for none.
219
+ * Pages arrive oldest first, so this is normally the last entry; it is
220
+ * computed rather than assumed because nothing in the cache enforces that.
221
+ */
222
+ function highestOperationIndex(operations) {
223
+ let highest = -1;
224
+ for (const operation of operations) if (operation.index > highest) highest = operation.index;
225
+ return highest;
226
+ }
198
227
  /**
199
228
  * Document cache implementation that uses the new ReactorClient API.
200
229
  *
201
230
  * This cache subscribes to document change events via IReactorBrowserClient.subscribe()
202
231
  * and automatically updates the cache when documents are created, updated, or deleted.
232
+ * It also holds paginated operation history per document scope (see `IOperationCache`),
233
+ * which is dropped for a document whenever a change event for it arrives.
203
234
  */
204
235
  var DocumentCache = class {
205
236
  documents = /* @__PURE__ */ new Map();
@@ -213,6 +244,11 @@ var DocumentCache = class {
213
244
  * the same document is cached under.
214
245
  */
215
246
  aliasKeys = /* @__PURE__ */ new Map();
247
+ /** Operations by document id, then scope. Entries are replaced, never mutated. */
248
+ operationEntries = /* @__PURE__ */ new Map();
249
+ /** In-flight controllers and the next page's cursor/limit, by document id then scope. */
250
+ operationRequests = /* @__PURE__ */ new Map();
251
+ operationListeners = /* @__PURE__ */ new Map();
216
252
  unsubscribe = null;
217
253
  constructor(client) {
218
254
  this.client = client;
@@ -223,8 +259,16 @@ var DocumentCache = class {
223
259
  handleDocumentChange(event) {
224
260
  if (event.type === DOCUMENT_CHANGE_TYPE.Deleted) {
225
261
  const documentId = event.context?.childId;
226
- if (documentId) this.handleDocumentDeleted(documentId);
227
- } else if (event.type === DOCUMENT_CHANGE_TYPE.Updated) for (const doc of event.documents) this.handleDocumentUpdated(doc.header.id).catch(console.warn);
262
+ if (documentId) {
263
+ const keys = this.cacheKeysFor(documentId);
264
+ this.handleDocumentDeleted(documentId);
265
+ for (const key of keys) this.invalidateOperations(key);
266
+ }
267
+ } else if (event.type === DOCUMENT_CHANGE_TYPE.Updated) for (const doc of event.documents) {
268
+ const keys = this.cacheKeysFor(doc.header.id);
269
+ this.handleDocumentUpdated(doc.header.id).catch(console.warn);
270
+ for (const key of keys) this.refreshOperations(key);
271
+ }
228
272
  }
229
273
  handleDocumentDeleted(documentId) {
230
274
  for (const key of this.cacheKeysFor(documentId)) {
@@ -319,6 +363,162 @@ var DocumentCache = class {
319
363
  }
320
364
  };
321
365
  }
366
+ getOperationsState(documentId, scope) {
367
+ return this.operationEntries.get(documentId)?.get(scope) ?? IDLE_OPERATIONS_ENTRY;
368
+ }
369
+ loadOperations(documentId, scope, limit) {
370
+ const current = this.getOperationsState(documentId, scope);
371
+ if (current.status !== "idle") return;
372
+ const controller = new AbortController();
373
+ this.setOperationsRequest(documentId, scope, {
374
+ controller,
375
+ nextCursor: void 0,
376
+ limit
377
+ });
378
+ this.setOperationsEntry(documentId, scope, {
379
+ ...current,
380
+ status: "pending"
381
+ });
382
+ this.settleOperationsPage(documentId, scope, this.client.getOperations(documentId, { scopes: [scope] }, void 0, {
383
+ cursor: "",
384
+ limit
385
+ }, controller.signal), controller, limit);
386
+ }
387
+ loadMoreOperations(documentId, scope) {
388
+ const current = this.getOperationsState(documentId, scope);
389
+ const request = this.operationRequests.get(documentId)?.get(scope);
390
+ if (current.status !== "success" || !current.hasNextPage || !request?.nextCursor) return;
391
+ const controller = new AbortController();
392
+ const { nextCursor, limit } = request;
393
+ this.setOperationsRequest(documentId, scope, {
394
+ controller,
395
+ nextCursor,
396
+ limit
397
+ });
398
+ this.setOperationsEntry(documentId, scope, {
399
+ ...current,
400
+ status: "pending"
401
+ });
402
+ this.settleOperationsPage(documentId, scope, this.client.getOperations(documentId, { scopes: [scope] }, void 0, {
403
+ cursor: nextCursor,
404
+ limit
405
+ }, controller.signal), controller, limit);
406
+ }
407
+ /**
408
+ * Bring a document's cached scopes up to date after it changed, without
409
+ * throwing away what is already loaded.
410
+ *
411
+ * The operation stream is append-only: an update adds operations at higher
412
+ * revisions and never rewrites the ones below, so history already paged in
413
+ * is still correct. Dropping it meant a panel showing a fully loaded
414
+ * document re-walked every page on each edit -- the cost of which grows
415
+ * with the document, exactly where it hurts most. Each scope instead asks
416
+ * only for what comes after the newest revision it holds, using the
417
+ * `sinceRevision` filter, and appends the answer.
418
+ *
419
+ * A scope that has not finished paging is dropped as before: it has no
420
+ * meaningful "newest revision" to resume from, since asking for everything
421
+ * past the newest row it happens to hold would skip the pages between that
422
+ * row and the end of the stream.
423
+ */
424
+ refreshOperations(documentId) {
425
+ const scopes = this.operationEntries.get(documentId);
426
+ if (!scopes) return;
427
+ for (const [scope, entry] of [...scopes.entries()]) {
428
+ if (entry.status !== "success" || entry.hasNextPage) {
429
+ this.invalidateOperationsScope(documentId, scope);
430
+ continue;
431
+ }
432
+ const previous = this.operationRequests.get(documentId)?.get(scope);
433
+ const limit = previous?.limit ?? FALLBACK_REFRESH_LIMIT;
434
+ previous?.controller.abort();
435
+ const controller = new AbortController();
436
+ this.setOperationsRequest(documentId, scope, {
437
+ controller,
438
+ nextCursor: void 0,
439
+ limit
440
+ });
441
+ this.setOperationsEntry(documentId, scope, {
442
+ ...entry,
443
+ status: "pending"
444
+ });
445
+ this.settleOperationsPage(documentId, scope, this.client.getOperations(documentId, { scopes: [scope] }, { sinceRevision: highestOperationIndex(entry.operations) + 1 }, {
446
+ cursor: "",
447
+ limit
448
+ }, controller.signal), controller, limit);
449
+ }
450
+ }
451
+ /** Drops one scope of a document, aborting its request if one is in flight. */
452
+ invalidateOperationsScope(documentId, scope) {
453
+ const requests = this.operationRequests.get(documentId);
454
+ const request = requests?.get(scope);
455
+ if (request && requests) {
456
+ request.controller.abort();
457
+ requests.delete(scope);
458
+ if (requests.size === 0) this.operationRequests.delete(documentId);
459
+ }
460
+ const scopes = this.operationEntries.get(documentId);
461
+ if (scopes?.delete(scope)) {
462
+ if (scopes.size === 0) this.operationEntries.delete(documentId);
463
+ this.notifyOperationListeners(documentId);
464
+ }
465
+ }
466
+ invalidateOperations(documentId) {
467
+ const requests = this.operationRequests.get(documentId);
468
+ if (requests) {
469
+ for (const request of requests.values()) request.controller.abort();
470
+ this.operationRequests.delete(documentId);
471
+ }
472
+ if (this.operationEntries.delete(documentId)) this.notifyOperationListeners(documentId);
473
+ }
474
+ subscribeOperations(documentId, callback) {
475
+ const listeners = this.operationListeners.get(documentId) ?? [];
476
+ this.operationListeners.set(documentId, [...listeners, callback]);
477
+ return () => {
478
+ const current = this.operationListeners.get(documentId) ?? [];
479
+ this.operationListeners.set(documentId, current.filter((listener) => listener !== callback));
480
+ };
481
+ }
482
+ settleOperationsPage(documentId, scope, page, controller, limit) {
483
+ page.then((result) => {
484
+ if (controller.signal.aborted) return;
485
+ const current = this.getOperationsState(documentId, scope);
486
+ this.setOperationsRequest(documentId, scope, {
487
+ controller,
488
+ nextCursor: result.nextCursor,
489
+ limit
490
+ });
491
+ this.setOperationsEntry(documentId, scope, {
492
+ status: "success",
493
+ operations: [...current.operations, ...result.results],
494
+ error: void 0,
495
+ hasNextPage: !!result.nextCursor,
496
+ totalCount: result.totalCount
497
+ });
498
+ }, (reason) => {
499
+ if (controller.signal.aborted) return;
500
+ const current = this.getOperationsState(documentId, scope);
501
+ this.setOperationsEntry(documentId, scope, {
502
+ ...current,
503
+ status: "error",
504
+ error: reason
505
+ });
506
+ });
507
+ }
508
+ setOperationsEntry(documentId, scope, entry) {
509
+ const scopes = this.operationEntries.get(documentId) ?? /* @__PURE__ */ new Map();
510
+ scopes.set(scope, entry);
511
+ this.operationEntries.set(documentId, scopes);
512
+ this.notifyOperationListeners(documentId);
513
+ }
514
+ setOperationsRequest(documentId, scope, request) {
515
+ const scopes = this.operationRequests.get(documentId) ?? /* @__PURE__ */ new Map();
516
+ scopes.set(scope, request);
517
+ this.operationRequests.set(documentId, scopes);
518
+ }
519
+ notifyOperationListeners(documentId) {
520
+ for (const listener of this.operationListeners.get(documentId) ?? []) listener();
521
+ }
322
522
  /**
323
523
  * Disposes of the cache and unsubscribes from document change events.
324
524
  */
@@ -327,6 +527,10 @@ var DocumentCache = class {
327
527
  this.unsubscribe();
328
528
  this.unsubscribe = null;
329
529
  }
530
+ for (const requests of this.operationRequests.values()) for (const request of requests.values()) request.controller.abort();
531
+ this.operationRequests.clear();
532
+ this.operationEntries.clear();
533
+ this.operationListeners.clear();
330
534
  }
331
535
  };
332
536
  //#endregion
@@ -514,6 +718,6 @@ function useDocumentsByIds(ids) {
514
718
  return useDocuments(ids);
515
719
  }
516
720
  //#endregion
517
- 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 };
721
+ export { queueOperations as C, queueActions as S, readPromiseState as _, setDocumentCache as a, isDuplicateModuleError as b, useDocumentSafe as c, useGetDocumentAsync as d, useGetDocuments as f, isOperationCache as g, addPromiseState as h, addDocumentCacheEventHandler as i, useDocuments as l, IDLE_OPERATIONS_ENTRY as m, useDocumentsByIds as n, useDocument as o, DocumentCache as p, useDispatch as r, useDocumentCache as s, useDocumentById as t, useGetDocument as u, DOCUMENT_CHANGE_TYPE as v, uploadOperations as w, dispatchActions as x, isDuplicateManifestError as y };
518
722
 
519
- //# sourceMappingURL=document-by-id-B4FIzG1w.js.map
723
+ //# sourceMappingURL=document-by-id-iXB59Ge-.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"document-by-id-iXB59Ge-.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 // Resolved by the document's stamped version: signing a not-yet-upgraded\n // document with the latest reducer builds an operation replay can't verify.\n const documentModelModule =\n await reactorClient.getDocumentModelModuleForDocument(document);\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, PagedResults } from \"@powerhousedao/reactor\";\nimport { DOCUMENT_CHANGE_TYPE } from \"./reactor-interop.js\";\nimport type {\n Operation,\n PHDocument,\n} from \"@powerhousedao/shared/document-model\";\nimport type {\n FulfilledPromise,\n IDocumentCache,\n IOperationCache,\n OperationsCacheEntry,\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/** The snapshot every uncached document scope reads as. One frozen object, so `useSyncExternalStore` sees a stable value. */\nexport const IDLE_OPERATIONS_ENTRY: OperationsCacheEntry = Object.freeze({\n status: \"idle\",\n operations: Object.freeze([]) as readonly Operation[],\n error: undefined,\n hasNextPage: false,\n totalCount: undefined,\n});\n\n/** Whether a document cache also serves operation history. `GraphQLClientDocumentCache` does not. */\nexport function isOperationCache(cache: unknown): cache is IOperationCache {\n if (typeof cache !== \"object\" || cache === null) return false;\n const candidate = cache as Partial<IOperationCache>;\n return (\n typeof candidate.getOperationsState === \"function\" &&\n typeof candidate.loadOperations === \"function\" &&\n typeof candidate.loadMoreOperations === \"function\" &&\n typeof candidate.invalidateOperations === \"function\" &&\n typeof candidate.subscribeOperations === \"function\"\n );\n}\n\n/**\n * Page size used to refresh a scope whose request record has gone missing.\n * A loaded scope always has one, so this is a floor rather than a default.\n */\nconst FALLBACK_REFRESH_LIMIT = 100;\n\n/**\n * The highest revision among the operations loaded so far, or -1 for none.\n * Pages arrive oldest first, so this is normally the last entry; it is\n * computed rather than assumed because nothing in the cache enforces that.\n */\nfunction highestOperationIndex(operations: readonly Operation[]): number {\n let highest = -1;\n for (const operation of operations) {\n if (operation.index > highest) highest = operation.index;\n }\n return highest;\n}\n\n/** Bookkeeping for one document scope that is not part of its snapshot. */\ntype OperationsRequest = {\n /** Aborts the request in flight, or marks a settled one as superseded. */\n controller: AbortController;\n /** The cursor for the page after the last loaded one; `undefined` when there is none. */\n nextCursor: string | undefined;\n /** The page size the scope was loaded with, reused for every subsequent page. */\n limit: number;\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 * It also holds paginated operation history per document scope (see `IOperationCache`),\n * which is dropped for a document whenever a change event for it arrives.\n */\nexport class DocumentCache implements IDocumentCache, IOperationCache {\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\n /**\n * Cache keys that fetched a document under a name other than its id --\n * slugs, which `client.get` resolves. Change events dispatch by `header.id`,\n * so without this mapping a slug-keyed entry (and its listeners) would never\n * see an update: keyed by the id the events carry, valued by the other keys\n * the same document is cached under.\n */\n private aliasKeys = new Map<string, Set<string>>();\n\n /** Operations by document id, then scope. Entries are replaced, never mutated. */\n private operationEntries = new Map<\n string,\n Map<string, OperationsCacheEntry>\n >();\n /** In-flight controllers and the next page's cursor/limit, by document id then scope. */\n private operationRequests = new Map<string, Map<string, OperationsRequest>>();\n private operationListeners = new Map<string, (() => void)[]>();\n\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 // Read the alias keys before `handleDocumentDeleted` clears them, so a\n // slug-keyed operations entry is invalidated too.\n const keys = this.cacheKeysFor(documentId);\n this.handleDocumentDeleted(documentId);\n for (const key of keys) {\n this.invalidateOperations(key);\n }\n }\n } else if (event.type === DOCUMENT_CHANGE_TYPE.Updated) {\n for (const doc of event.documents) {\n const keys = this.cacheKeysFor(doc.header.id);\n this.handleDocumentUpdated(doc.header.id).catch(console.warn);\n for (const key of keys) {\n this.refreshOperations(key);\n }\n }\n }\n }\n\n private handleDocumentDeleted(documentId: string): void {\n for (const key of this.cacheKeysFor(documentId)) {\n const listeners = this.listeners.get(key);\n this.documents.delete(key);\n this.invalidateBatchesContaining(key);\n if (listeners) {\n listeners.forEach((listener) => listener());\n }\n this.listeners.delete(key);\n }\n this.aliasKeys.delete(documentId);\n }\n\n private async handleDocumentUpdated(documentId: string): Promise<void> {\n for (const key of this.cacheKeysFor(documentId)) {\n if (!this.documents.has(key)) {\n continue;\n }\n await this.get(key, true);\n const listeners = this.listeners.get(key);\n if (listeners) {\n listeners.forEach((listener) => listener());\n }\n }\n }\n\n /** The id an event dispatches by, plus every alias the document is cached under. */\n private cacheKeysFor(documentId: string): string[] {\n return [documentId, ...(this.aliasKeys.get(documentId) ?? [])];\n }\n\n /** Records that `key` cached the document change events know as `header.id`. */\n private recordAlias(documentId: string, key: string): void {\n const keys = this.aliasKeys.get(documentId) ?? new Set<string>();\n keys.add(key);\n this.aliasKeys.set(documentId, keys);\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 documentPromise.then(\n (doc) => {\n if (doc.header.id !== id) {\n this.recordAlias(doc.header.id, id);\n }\n },\n // Rejections are surfaced by the stored promise; this chain only learns aliases.\n () => undefined,\n );\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 getOperationsState(documentId: string, scope: string): OperationsCacheEntry {\n return (\n this.operationEntries.get(documentId)?.get(scope) ?? IDLE_OPERATIONS_ENTRY\n );\n }\n\n loadOperations(documentId: string, scope: string, limit: number): void {\n const current = this.getOperationsState(documentId, scope);\n if (current.status !== \"idle\") {\n return;\n }\n const controller = new AbortController();\n this.setOperationsRequest(documentId, scope, {\n controller,\n nextCursor: undefined,\n limit,\n });\n this.setOperationsEntry(documentId, scope, {\n ...current,\n status: \"pending\",\n });\n this.settleOperationsPage(\n documentId,\n scope,\n this.client.getOperations(\n documentId,\n { scopes: [scope] },\n undefined,\n { cursor: \"\", limit },\n controller.signal,\n ),\n controller,\n limit,\n );\n }\n\n loadMoreOperations(documentId: string, scope: string): void {\n const current = this.getOperationsState(documentId, scope);\n const request = this.operationRequests.get(documentId)?.get(scope);\n if (\n current.status !== \"success\" ||\n !current.hasNextPage ||\n !request?.nextCursor\n ) {\n return;\n }\n // Each page gets its own controller, so invalidation can abort whichever\n // page is currently in flight.\n const controller = new AbortController();\n const { nextCursor, limit } = request;\n this.setOperationsRequest(documentId, scope, {\n controller,\n nextCursor,\n limit,\n });\n this.setOperationsEntry(documentId, scope, {\n ...current,\n status: \"pending\",\n });\n this.settleOperationsPage(\n documentId,\n scope,\n this.client.getOperations(\n documentId,\n { scopes: [scope] },\n undefined,\n { cursor: nextCursor, limit },\n controller.signal,\n ),\n controller,\n limit,\n );\n }\n\n /**\n * Bring a document's cached scopes up to date after it changed, without\n * throwing away what is already loaded.\n *\n * The operation stream is append-only: an update adds operations at higher\n * revisions and never rewrites the ones below, so history already paged in\n * is still correct. Dropping it meant a panel showing a fully loaded\n * document re-walked every page on each edit -- the cost of which grows\n * with the document, exactly where it hurts most. Each scope instead asks\n * only for what comes after the newest revision it holds, using the\n * `sinceRevision` filter, and appends the answer.\n *\n * A scope that has not finished paging is dropped as before: it has no\n * meaningful \"newest revision\" to resume from, since asking for everything\n * past the newest row it happens to hold would skip the pages between that\n * row and the end of the stream.\n */\n private refreshOperations(documentId: string): void {\n const scopes = this.operationEntries.get(documentId);\n if (!scopes) return;\n\n for (const [scope, entry] of [...scopes.entries()]) {\n if (entry.status !== \"success\" || entry.hasNextPage) {\n this.invalidateOperationsScope(documentId, scope);\n continue;\n }\n\n const previous = this.operationRequests.get(documentId)?.get(scope);\n const limit = previous?.limit ?? FALLBACK_REFRESH_LIMIT;\n // Marks the settled page superseded, so a late arrival cannot append\n // on top of the refresh.\n previous?.controller.abort();\n\n const controller = new AbortController();\n this.setOperationsRequest(documentId, scope, {\n controller,\n nextCursor: undefined,\n limit,\n });\n // Pending, but the operations stay in the entry: consumers keep\n // rendering the history they have instead of flashing empty while the\n // tail is fetched.\n this.setOperationsEntry(documentId, scope, {\n ...entry,\n status: \"pending\",\n });\n this.settleOperationsPage(\n documentId,\n scope,\n this.client.getOperations(\n documentId,\n { scopes: [scope] },\n { sinceRevision: highestOperationIndex(entry.operations) + 1 },\n { cursor: \"\", limit },\n controller.signal,\n ),\n controller,\n limit,\n );\n }\n }\n\n /** Drops one scope of a document, aborting its request if one is in flight. */\n private invalidateOperationsScope(documentId: string, scope: string): void {\n const requests = this.operationRequests.get(documentId);\n const request = requests?.get(scope);\n if (request && requests) {\n request.controller.abort();\n requests.delete(scope);\n if (requests.size === 0) {\n this.operationRequests.delete(documentId);\n }\n }\n const scopes = this.operationEntries.get(documentId);\n if (scopes?.delete(scope)) {\n if (scopes.size === 0) {\n this.operationEntries.delete(documentId);\n }\n this.notifyOperationListeners(documentId);\n }\n }\n\n invalidateOperations(documentId: string): void {\n const requests = this.operationRequests.get(documentId);\n if (requests) {\n for (const request of requests.values()) {\n request.controller.abort();\n }\n this.operationRequests.delete(documentId);\n }\n if (this.operationEntries.delete(documentId)) {\n this.notifyOperationListeners(documentId);\n }\n }\n\n subscribeOperations(documentId: string, callback: () => void): () => void {\n const listeners = this.operationListeners.get(documentId) ?? [];\n this.operationListeners.set(documentId, [...listeners, callback]);\n return () => {\n const current = this.operationListeners.get(documentId) ?? [];\n this.operationListeners.set(\n documentId,\n current.filter((listener) => listener !== callback),\n );\n };\n }\n\n private settleOperationsPage(\n documentId: string,\n scope: string,\n page: Promise<PagedResults<Operation>>,\n controller: AbortController,\n limit: number,\n ): void {\n page.then(\n (result) => {\n if (controller.signal.aborted) return;\n const current = this.getOperationsState(documentId, scope);\n this.setOperationsRequest(documentId, scope, {\n controller,\n nextCursor: result.nextCursor,\n limit,\n });\n this.setOperationsEntry(documentId, scope, {\n status: \"success\",\n operations: [...current.operations, ...result.results],\n error: undefined,\n hasNextPage: !!result.nextCursor,\n totalCount: result.totalCount,\n });\n },\n (reason: unknown) => {\n if (controller.signal.aborted) return;\n const current = this.getOperationsState(documentId, scope);\n this.setOperationsEntry(documentId, scope, {\n ...current,\n status: \"error\",\n error: reason,\n });\n },\n );\n }\n\n private setOperationsEntry(\n documentId: string,\n scope: string,\n entry: OperationsCacheEntry,\n ): void {\n const scopes =\n this.operationEntries.get(documentId) ??\n new Map<string, OperationsCacheEntry>();\n scopes.set(scope, entry);\n this.operationEntries.set(documentId, scopes);\n this.notifyOperationListeners(documentId);\n }\n\n private setOperationsRequest(\n documentId: string,\n scope: string,\n request: OperationsRequest,\n ): void {\n const scopes =\n this.operationRequests.get(documentId) ??\n new Map<string, OperationsRequest>();\n scopes.set(scope, request);\n this.operationRequests.set(documentId, scopes);\n }\n\n private notifyOperationListeners(documentId: string): void {\n for (const listener of this.operationListeners.get(documentId) ?? []) {\n listener();\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 for (const requests of this.operationRequests.values()) {\n for (const request of requests.values()) {\n request.controller.abort();\n }\n }\n this.operationRequests.clear();\n this.operationEntries.clear();\n this.operationListeners.clear();\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 (error: unknown) => {\n logger.error(\"Failed to dispatch actions: @error\", error);\n },\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 { _ as isDuplicateManifestError, n as useDocumentsByIds, r as useDispatch, v as isDuplicateModuleError } from "./document-by-id-B4FIzG1w.js";
1
+ import { b as isDuplicateModuleError, n as useDocumentsByIds, r as useDispatch, y as isDuplicateManifestError } from "./document-by-id-iXB59Ge-.js";
2
2
  import { t as makePHEventFunctions } from "./make-ph-event-functions-DBq3iWYn.js";
3
3
  import { useSyncExternalStore } from "react";
4
4
  import slug from "slug";
@@ -416,4 +416,4 @@ function useDocumentModelModuleById(id, version) {
416
416
  //#endregion
417
417
  export { createUrlWithPreservedParams as A, makeNodeSlug as B, addResetSelectedNodeEventHandler as C, addDrivesEventHandler as D, setSelectedNode as E, extractNodeIdFromSlug as F, UnsupportedDocumentTypeError as G, DocumentModelNotFoundError as H, extractNodeSlugFromPath as I, ambientRenownTokenProvider as K, findUuid as L, extractDriveIdFromSlug as M, extractDriveSlugFromPath as N, setDrives as O, extractNodeIdFromPath as P, getPathWithoutBase as R, useSelectedDriveSafe as S, addSetSelectedNodeOnPopStateEventHandler as T, DocumentTypeMismatchError as U, resolveUrlPathname as V, NoSelectedDocumentError as W, addSetSelectedDriveOnPopStateEventHandler as _, useVetraPackageManager as a, useSelectedDrive as b, useDocumentTypesInSelectedDrive as c, useFolderNodesInSelectedDrive as d, useNodesInSelectedDrive as f, addSelectedDriveIdEventHandler as g, sortNodesByName as h, setVetraPackageManager as i, extractDriveIdFromPath as j, useDrives as k, useDocumentsInSelectedDrive as l, isFolderNodeKind as m, useDocumentModelModules as n, useVetraPackages as o, isFileNodeKind as p, makeAuthMiddleware as q, addVetraPackageManagerEventHandler as r, useSelectedNode as s, useDocumentModelModuleById as t, useFileNodesInSelectedDrive as u, setSelectedDrive as v, addSelectedNodeIdEventHandler as w, useSelectedDriveId as x, setSelectedDriveId as y, makeDriveUrlComponent as z };
418
418
 
419
- //# sourceMappingURL=document-model-modules-bTP87nyr.js.map
419
+ //# sourceMappingURL=document-model-modules-BSwKnUR_.js.map