@powerhousedao/connect-core 6.2.3-dev.85 → 6.2.3-dev.87

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.
@@ -1,10 +1,10 @@
1
1
  import "./runtime-config-D3YPhYyj.js";
2
- import { BrowserReactorClientModule, PHStore, SwitchboardBackend, WorkerReactorClientModule } from "@powerhousedao/reactor-browser";
3
- import { PHConnectCollection, PHConnectRemoteBackend, PHConnectRuntimeDefaultDrive, PHReactorClientMode } from "@powerhousedao/shared/clis";
2
+ import { BrowserReactorClientModule, PHStore, SwitchboardBackend, SwitchboardBreaker, WorkerReactorClientModule } from "@powerhousedao/reactor-browser";
3
+ import { PHConnectCollection, PHConnectRemoteBackend, PHConnectRouterSettings, PHConnectRuntimeDefaultDrive, PHReactorClientMode } from "@powerhousedao/shared/clis";
4
4
  import { DocumentDriveDocument } from "@powerhousedao/shared/document-drive";
5
5
  import { DocumentModelModule, ISigner } from "@powerhousedao/shared/document-model";
6
6
  import { DriveCollectionId, IReactorClient, ReactorInfo } from "@powerhousedao/reactor";
7
- import { CollectionRequirementsInput, ReactorReach, RoutableBackendConfig, RouterDiagnostic, RoutingClientOptions, RoutingReactorClient } from "@powerhousedao/reactor-router";
7
+ import { ReactorReach, RoutableBackendConfig, RouterDiagnostic, RoutingClientOptions, RoutingReactorClient } from "@powerhousedao/reactor-router";
8
8
  import { DocumentModelLib } from "document-model";
9
9
  //#endregion
10
10
  //#region src/runtime/runtime-flag.d.ts
@@ -52,6 +52,8 @@ type ReactorClientMode = PHReactorClientMode;
52
52
  declare const REACTOR_CLIENT_QUERY_KEY = "reactorClient";
53
53
  declare const REACTOR_CLIENT_STORAGE_KEY = "ph:reactorClient";
54
54
  declare function resolveReactorClientMode(): ReactorClientMode;
55
+ /** Why this page load can't create a drive where the host says, or undefined when it can. */
56
+ declare function newDrivesBlocked(): Error | undefined;
55
57
  //#endregion
56
58
  //#region src/runtime/drive-placement.d.ts
57
59
  /** The router backend of the reactor in this browser. */
@@ -88,6 +90,9 @@ type PlacementConfig = {
88
90
  collections?: Record<string, PHConnectCollection>;
89
91
  };
90
92
  };
93
+ /** The config's local default drives, placed on this browser so a
94
+ * switchboard `newDrives` doesn't take them. */
95
+ declare function localDrivePlacements(defaultDrives: readonly PHConnectRuntimeDefaultDrive[]): Record<string, string>;
91
96
  declare function keepsLocalCopy(drive: PHConnectRuntimeDefaultDrive): boolean;
92
97
  /** Remote default drives with a backend, then collections. */
93
98
  declare function switchboardDrives(config: PlacementConfig): SwitchboardDrive[];
@@ -127,21 +132,22 @@ declare function removeLocalCopies(sync: SyncRemotes, resolved: readonly {
127
132
  id?: string;
128
133
  }[]): Promise<void>;
129
134
  declare namespace multi_reactor_d_exports {
130
- export { ConnectRoutingClient, LOCAL_BACKEND_NAME, LoadedDocumentModels, LocalReactorModule, MultiReactorParams, PLACE_ON_LOCAL, PLACE_ON_REMOTE, REMOTE_BACKEND_NAME, SwitchboardRemote, buildMultiReactorClient, deriveSwitchboardGraphqlUrl, localFacts, localReach };
135
+ export { ConnectRoutingClient, LOCAL_BACKEND_NAME, LoadedDocumentModels, LocalReactorModule, MultiReactorParams, REMOTE_BACKEND_NAME, SwitchboardRemote, buildMultiReactorClient, deriveSwitchboardGraphqlUrl, localFacts, localReach };
131
136
  }
132
137
  declare const REMOTE_BACKEND_NAME = "switchboard-remote";
133
138
  type LocalReactorModule = BrowserReactorClientModule | WorkerReactorClientModule;
134
- /** Only the tab's reactor is inspectable here, so new collections land on it. */
135
- declare const PLACE_ON_LOCAL: CollectionRequirementsInput;
136
139
  declare function localReach(kind: LocalReactorModule["kind"]): ReactorReach;
137
140
  /** Read at every refresh, never kept: a rebuilt reactor reports its own. */
138
141
  declare function localFacts(module: LocalReactorModule): () => Promise<ReactorInfo>;
139
142
  /** `<origin>[/<prefix>]/d/<slug>` -> `<origin>[/<prefix>]/graphql`. */
140
143
  declare function deriveSwitchboardGraphqlUrl(remoteDriveUrl: string): string | undefined;
141
- /** A switchboard the router reaches, by its router backend name. */
144
+ /** A switchboard the router reaches, by its router backend name, with its connection settings. */
142
145
  type SwitchboardRemote = {
143
146
  name: string;
144
147
  graphqlUrl: string;
148
+ requestTimeoutMs?: number;
149
+ breaker?: SwitchboardBreaker;
150
+ realtime?: boolean;
145
151
  };
146
152
  /** The loaded document models, or a getter that reads the current ones. */
147
153
  type LoadedDocumentModels = readonly DocumentModelModule[] | (() => readonly DocumentModelModule[]);
@@ -154,19 +160,22 @@ type MultiReactorParams = {
154
160
  remoteGraphqlUrl?: string;
155
161
  /** Collection key or drive id -> backend; names no backend here are dropped. */
156
162
  collections?: Readonly<Record<string, string>>;
163
+ /** The remote new drives are created on, with no copy here. Absent: the
164
+ * local reactor, else the only switchboard. */
165
+ newDrives?: string;
166
+ probeTimeoutMs?: number;
167
+ provisionalRouteMs?: number;
157
168
  /** Signs routed writes; unsigned (anonymous) without one. */
158
169
  signer?: ISigner;
159
170
  /** Signing models when the local module exposes no registry; the router asks the local reactor (or, remote-only, the loaded set). */
160
171
  documentModelModules: LoadedDocumentModels;
161
172
  onDiagnostic?: RouterDiagnostic;
162
173
  };
163
- /** Remote-only placement: the Switchboard serves every collection. (It offers
164
- * no inspection surface over GraphQL, so PLACE_ON_LOCAL's `inspectable`
165
- * requirement must NOT apply, or no backend would be eligible.) */
166
- declare const PLACE_ON_REMOTE: CollectionRequirementsInput;
167
174
  /** The router Connect installs, with Connect's handling of credentials and id checks. */
168
175
  declare class ConnectRoutingClient extends RoutingReactorClient {
169
176
  private readonly remotes;
177
+ /** The switchboard new drives are created on; undefined when it is this browser. */
178
+ readonly newDrives: string | undefined;
170
179
  constructor(backends: readonly RoutableBackendConfig[], options: RoutingClientOptions, remotes: readonly SwitchboardBackend[], hasLocal: boolean);
171
180
  /** Renown's sign-in and sign-out call this on whatever client is installed. */
172
181
  notifyCredentialsChanged(): void;
@@ -190,10 +199,9 @@ type AppReactorClientParams = {
190
199
  /** The fallback switchboard when `remoteBackends` is empty. */
191
200
  remoteDriveUrl: string | undefined;
192
201
  /** One per switchboard, by host key; `url` is a drive address on it. */
193
- remoteBackends?: readonly {
194
- name: string;
195
- url: string;
196
- }[];
202
+ remoteBackends?: readonly PHConnectRemoteBackend[];
203
+ /** Where new drives go and the router's timeouts, from the host config. */
204
+ router?: PHConnectRouterSettings;
197
205
  /** Config placements known at build time; later ones go through `setConfiguredPlacement`. */
198
206
  collections?: Readonly<Record<string, string>>;
199
207
  /** Signs routed writes; unsigned (anonymous) without one. */
@@ -257,6 +265,23 @@ declare function refreshAppDrives(client: IReactorClient, local: IReactorClient)
257
265
  */
258
266
  declare function relistAppDrives(): Promise<void>;
259
267
  //#endregion
268
+ //#region src/runtime/new-drive.d.ts
269
+ /** A drive create the switchboard new drives go to did not answer. */
270
+ declare class NewDriveUnansweredError extends Error {
271
+ readonly backend: string;
272
+ readonly name = "NewDriveUnansweredError";
273
+ constructor(backend: string, options?: ErrorOptions);
274
+ }
275
+ /** `auth`: the switchboard refused the caller, so signing in may help. */
276
+ declare class NewDriveRefusedError extends Error {
277
+ readonly backend: string;
278
+ readonly auth: boolean;
279
+ readonly name = "NewDriveRefusedError";
280
+ constructor(backend: string, auth: boolean, reason: string | undefined, options?: ErrorOptions);
281
+ }
282
+ /** A failed drive create, named for the switchboard `client` creates new drives on; else `error` itself. */
283
+ declare function newDriveError(client: unknown, error: unknown): unknown;
284
+ //#endregion
260
285
  //#region src/runtime/drive-placements.d.ts
261
286
  /** A collection by its declared slug among its switchboard's drives, e.g. one served hashed. */
262
287
  declare function findServedDrive(router: Pick<RoutingReactorClient, "backends">, drive: SwitchboardDrive): Promise<{
@@ -360,6 +385,6 @@ type LocalPackageSource = LocalPackage | (() => Promise<LocalPackage>);
360
385
  /** Starts loading the project's package; a loader runs once, here. */
361
386
  declare function loadLocalPackage(source: LocalPackageSource | undefined): DocumentModelLib | Promise<DocumentModelLib> | undefined;
362
387
  //#endregion
363
- export { resolveRuntimeFlag as $, ResolvedSwitchboardDrive as A, REACTOR_CLIENT_QUERY_KEY as B, relistAppDrives as C, LOCAL_BACKEND_NAME as D, LocalReactorModule as E, removeLocalCopies as F, REACTOR_WORKER_STORAGE_KEY as G, ReactorClientMode as H, resolveSwitchboardDrives as I, resolveReactorWorkerEnabled as J, ReactorWorkerFlagInput as K, servedUrl as L, applyPlacementEntries as M, keepsLocalCopy as N, PlacementEntry as O, placementKeys as P, isRuntimeFlagEnabled as Q, servesSlug as R, refreshAppDrives as S, LoadedDocumentModels as T, resolveReactorClientMode as U, REACTOR_CLIENT_STORAGE_KEY as V, REACTOR_WORKER_QUERY_KEY as W, RuntimeFlagInput as X, isMultiReactorEnabled as Y, RuntimeFlagKeys as Z, LocalReactorFactory as _, getConnectPHStore as a, getAppDrives as b, PlacementRouter as c, caughtUp as d, effectiveBackend as f, CreateAppReactorClientOptions as g, AppReactorClientParams as h, loadLocalPackage as i, SwitchboardDrive as j, ResolveSwitchboardDrivesOptions as k, PlacementStore as l, needsCopy as m, LocalPackageSource as n, DrivePlacement as o, findServedDrive as p, isReactorWorkerEnabled as q, ModuleNamespace as r, DrivePlacements as s, LocalPackage as t, PlacementSync as u, ReactorClientPlan as v, selectAppReactorClient as w, planReactorClient as x, createAppReactorClient as y, switchboardDrives as z };
388
+ export { resolveReactorWorkerEnabled as $, LOCAL_BACKEND_NAME as A, resolveSwitchboardDrives as B, getAppDrives as C, selectAppReactorClient as D, relistAppDrives as E, applyPlacementEntries as F, REACTOR_CLIENT_STORAGE_KEY as G, servesSlug as H, keepsLocalCopy as I, resolveReactorClientMode as J, ReactorClientMode as K, localDrivePlacements as L, ResolveSwitchboardDrivesOptions as M, ResolvedSwitchboardDrive as N, LoadedDocumentModels as O, SwitchboardDrive as P, isReactorWorkerEnabled as Q, placementKeys as R, createAppReactorClient as S, refreshAppDrives as T, switchboardDrives as U, servedUrl as V, REACTOR_CLIENT_QUERY_KEY as W, REACTOR_WORKER_STORAGE_KEY as X, REACTOR_WORKER_QUERY_KEY as Y, ReactorWorkerFlagInput as Z, newDriveError as _, getConnectPHStore as a, LocalReactorFactory as b, PlacementRouter as c, caughtUp as d, isMultiReactorEnabled as et, effectiveBackend as f, NewDriveUnansweredError as g, NewDriveRefusedError as h, loadLocalPackage as i, resolveRuntimeFlag as it, PlacementEntry as j, LocalReactorModule as k, PlacementStore as l, needsCopy as m, LocalPackageSource as n, RuntimeFlagKeys as nt, DrivePlacement as o, findServedDrive as p, newDrivesBlocked as q, ModuleNamespace as r, isRuntimeFlagEnabled as rt, DrivePlacements as s, LocalPackage as t, RuntimeFlagInput as tt, PlacementSync as u, AppReactorClientParams as v, planReactorClient as w, ReactorClientPlan as x, CreateAppReactorClientOptions as y, removeLocalCopies as z };
364
389
  export {};
365
- //# sourceMappingURL=index-ZFFeYX4A.d.ts.map
390
+ //# sourceMappingURL=index-BNdsbq2I.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index-BNdsbq2I.d.ts","names":[],"sources":["../src/runtime/runtime-flag.ts","../src/runtime/multi-reactor-flag.ts","../src/runtime/reactor-worker-flag.ts","../src/runtime/reactor-client-mode.ts","../src/runtime/drive-placement.ts","../src/runtime/multi-reactor.ts","../src/runtime/app-reactor-client.ts","../src/runtime/new-drive.ts","../src/runtime/drive-placements.ts","../src/runtime/ph-store.ts","../src/runtime/local-package.ts"],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as resolveRuntimeFlag, A as ResolvedSwitchboardDrive, B as REACTOR_CLIENT_QUERY_KEY, C as relistAppDrives, D as LOCAL_BACKEND_NAME, E as LocalReactorModule, F as removeLocalCopies, G as REACTOR_WORKER_STORAGE_KEY, H as ReactorClientMode, I as resolveSwitchboardDrives, J as resolveReactorWorkerEnabled, K as ReactorWorkerFlagInput, L as servedUrl, M as applyPlacementEntries, N as keepsLocalCopy, O as PlacementEntry, P as placementKeys, Q as isRuntimeFlagEnabled, R as servesSlug, S as refreshAppDrives, T as LoadedDocumentModels, U as resolveReactorClientMode, V as REACTOR_CLIENT_STORAGE_KEY, W as REACTOR_WORKER_QUERY_KEY, X as RuntimeFlagInput, Y as isMultiReactorEnabled, Z as RuntimeFlagKeys, _ as LocalReactorFactory, a as getConnectPHStore, b as getAppDrives, c as PlacementRouter, d as caughtUp, f as effectiveBackend, g as CreateAppReactorClientOptions, h as AppReactorClientParams, i as loadLocalPackage, j as SwitchboardDrive, k as ResolveSwitchboardDrivesOptions, l as PlacementStore, m as needsCopy, n as LocalPackageSource, o as DrivePlacement, p as findServedDrive, q as isReactorWorkerEnabled, r as ModuleNamespace, s as DrivePlacements, t as LocalPackage, u as PlacementSync, v as ReactorClientPlan, w as selectAppReactorClient, x as planReactorClient, y as createAppReactorClient, z as switchboardDrives } from "./index-ZFFeYX4A.js";
1
+ import { $ as resolveReactorWorkerEnabled, A as LOCAL_BACKEND_NAME, B as resolveSwitchboardDrives, C as getAppDrives, D as selectAppReactorClient, E as relistAppDrives, F as applyPlacementEntries, G as REACTOR_CLIENT_STORAGE_KEY, H as servesSlug, I as keepsLocalCopy, J as resolveReactorClientMode, K as ReactorClientMode, L as localDrivePlacements, M as ResolveSwitchboardDrivesOptions, N as ResolvedSwitchboardDrive, O as LoadedDocumentModels, P as SwitchboardDrive, Q as isReactorWorkerEnabled, R as placementKeys, S as createAppReactorClient, T as refreshAppDrives, U as switchboardDrives, V as servedUrl, W as REACTOR_CLIENT_QUERY_KEY, X as REACTOR_WORKER_STORAGE_KEY, Y as REACTOR_WORKER_QUERY_KEY, Z as ReactorWorkerFlagInput, _ as newDriveError, a as getConnectPHStore, b as LocalReactorFactory, c as PlacementRouter, d as caughtUp, et as isMultiReactorEnabled, f as effectiveBackend, g as NewDriveUnansweredError, h as NewDriveRefusedError, i as loadLocalPackage, it as resolveRuntimeFlag, j as PlacementEntry, k as LocalReactorModule, l as PlacementStore, m as needsCopy, n as LocalPackageSource, nt as RuntimeFlagKeys, o as DrivePlacement, p as findServedDrive, q as newDrivesBlocked, r as ModuleNamespace, rt as isRuntimeFlagEnabled, s as DrivePlacements, t as LocalPackage, tt as RuntimeFlagInput, u as PlacementSync, v as AppReactorClientParams, w as planReactorClient, x as ReactorClientPlan, y as CreateAppReactorClientOptions, z as removeLocalCopies } from "./index-BNdsbq2I.js";
2
2
  import { A as useDriveRouteData, B as ConnectConfigHooks, C as holdConnectRoutes, D as DRIVE_ROUTE_ID, E as removeConnectRoutes, F as DriveRouteData, G as ConnectPluginUi, H as ConnectPluginContext, I as DriveRouteParams, J as ConnectModals, K as ConnectRouteUi, L as isDriveNotFound, M as ConnectRouterContext, N as DriveLoaderOptions, O as DriveRouteView, P as DriveNotFoundData, R as loadDrive, S as connectRoutesSettled, T as registerPackageRoutes, U as ConnectPluginDefinition, V as ConnectPlugin, W as ConnectPluginFactory, Y as ModalOutlet, _ as ConnectRoutes, a as bindConnectRouter, b as addConnectRoutes, c as applyConnectPluginUi, d as mergeConnectPluginUi, f as resetConnectPluginUi, g as ConnectRootRoute, h as APP_ROUTE_ID, i as ConnectRouterOptions, j as useDriveRouteIds, k as NODE_ROUTE_ID, l as getConnectPluginUi, m as ConnectRouteRegistration, n as ConnectRouterBundle, o as createConnectRouter, q as CORE_MODAL_VIEWS, r as ConnectRouterFor, s as ConnectPluginUiSet, t as ConnectRouter, u as loadConnectPluginUi, v as HOME_ROUTE_ID, w as registerConnectRoutes, x as connectRoutes, y as PackageRoute, z as loadNode } from "./connect-router-11uRIT3z.js";
3
3
  import { a as DrivePending, i as DocumentViewProps, n as ContentOutlet, o as DriveViewProps, r as DRIVE_PENDING_MS, t as CONTENT_VIEW_ID } from "./route-components-1XyfosoL.js";
4
4
  import { $ as disposeConnectAppRouter, A as stringifyConnectSearch, B as ConnectCoreApp, C as useSidebarMode, D as connectSearchMiddlewares, E as GLOBAL_SEARCH_PARAMS, F as CoreRouteOptions, G as isCoreView, H as CoreNotFound, I as coreRouteOptions, J as markNavigationClick, K as PERF_STORAGE_KEY, L as ModalDialog, M as validateDriveSearch, N as bindConnectScroll, O as definedSearch, P as connectScrollRestoration, Q as ConnectAppRouterOptions, R as ModalFrameProps, S as useNavRoutes, T as FEATURE_FLAG_PARAM_PREFIX, U as coreModals, V as CoreError, W as coreView, X as routerPerfEnabled, Y as markRouterNavigations, Z as createConnectNavigation, _ as ConnectNavItem, a as SETTINGS_ROUTE_ID, b as navRoutes, c as redirectToSettingsTab, d as settingsTabsOf, et as getConnectAppRouter, f as settingsTitle, g as ConnectChrome, h as useSettingsTabs, i as ConnectSettingsTab, j as validateConnectSearch, k as parseConnectSearch, l as setSettingsRoute, m as useForgetSettingsOpenedFrom, n as driveTitle, nt as CreateDocumentTarget, o as SettingsTabEntry, p as showsSettingsTab, q as ROUTER_MEASURES, r as notFoundTitle, rt as useCreateDocumentTarget, s as keepOpenedFrom, t as appTitle, tt as useIsColdStart, u as settingsTabs, v as NavRouteEntry, w as ConnectSearch, x as useConnectChrome, y as SidebarMode, z as useModalFrame } from "./index-Bfl1VYdj.js";
@@ -7,5 +7,5 @@ import { i as primeRuntimeConfig, n as getRuntimeConfig, r as loadRuntimeConfig
7
7
  import { n as useBackendAuthGate, t as BackendAuthGateMode } from "./backend-auth-gate-DiFpY5rt.js";
8
8
  import { n as useIsEmbedded, t as getIsEmbedded } from "./embedded-DT1C47F0.js";
9
9
  import { A as NodeView, C as EditorHostProps, D as DirectoryListing, E as HISTORY_PAGE_SIZE, O as DocumentView, S as EditorHost, T as DocumentHistory, _ as CoreRoot, a as CoreRouteError, b as DriveIndex, c as DeleteItemModal, d as DriveAuthRequiredModal, f as LoginModal, g as CoreLayout, h as CoreHeader, i as CoreSettingsPage, k as DriveLayout, l as DocumentVersionUnsupportedModal, m as NotFoundPage, n as PackagesTab, o as ConfirmDocumentUpgradeModal, p as DriveNotFoundPage, r as AppearanceTab, s as CreateDocumentModal, t as ThemeToggle, u as DownloadDocumentWithErrorsModal, v as BackendAuthGate, w as DocumentJson, x as DocumentEditorProps, y as formatModified } from "./index-Beqvfchq.js";
10
- export { APP_ROUTE_ID, type AppReactorClientParams, AppearanceTab, BackendAuthGate, type BackendAuthGateMode, CONTENT_VIEW_ID, CORE_MODAL_VIEWS, ConfirmDocumentUpgradeModal, type ConnectAppRouterOptions, type ConnectChrome, type ConnectConfigHooks, ConnectCoreApp, type ConnectModals, type ConnectNavItem, type ConnectPlugin, type ConnectPluginContext, type ConnectPluginDefinition, type ConnectPluginFactory, type ConnectPluginUi, type ConnectPluginUiSet, type ConnectRootRoute, type ConnectRouteRegistration, type ConnectRouteUi, type ConnectRouter, type ConnectRouterBundle, type ConnectRouterContext, type ConnectRouterFor, type ConnectRouterOptions, type ConnectRoutes, type ConnectSearch, type ConnectSettingsTab, ContentOutlet, CoreError, CoreHeader, CoreLayout, CoreNotFound, CoreRoot, CoreRouteError, type CoreRouteOptions, CoreSettingsPage, type CreateAppReactorClientOptions, CreateDocumentModal, type CreateDocumentTarget, DRIVE_PENDING_MS, DRIVE_ROUTE_ID, DeleteItemModal, DirectoryListing, type DocumentEditorProps, DocumentHistory, DocumentJson, DocumentVersionUnsupportedModal, DocumentView, type DocumentViewProps, DownloadDocumentWithErrorsModal, DriveAuthRequiredModal, DriveIndex, DriveLayout, type DriveLoaderOptions, type DriveNotFoundData, DriveNotFoundPage, DrivePending, type DrivePlacement, DrivePlacements, type DriveRouteData, type DriveRouteParams, type DriveRouteView, type DriveViewProps, EditorHost, type EditorHostProps, FEATURE_FLAG_PARAM_PREFIX, GLOBAL_SEARCH_PARAMS, HISTORY_PAGE_SIZE, HOME_ROUTE_ID, LOCAL_BACKEND_NAME, type LoadedDocumentModels, type LocalPackage, type LocalPackageSource, type LocalReactorFactory, type LocalReactorModule, LoginModal, ModalDialog, type ModalFrameProps, ModalOutlet, type ModuleNamespace, NODE_ROUTE_ID, type NavRouteEntry, NodeView, NotFoundPage, PERF_STORAGE_KEY, type PackageRoute, PackagesTab, type PlacementEntry, type PlacementRouter, type PlacementStore, type PlacementSync, REACTOR_CLIENT_QUERY_KEY, REACTOR_CLIENT_STORAGE_KEY, REACTOR_WORKER_QUERY_KEY, REACTOR_WORKER_STORAGE_KEY, ROUTER_MEASURES, type ReactorClientMode, type ReactorClientPlan, type ReactorWorkerFlagInput, type ResolveSwitchboardDrivesOptions, type ResolvedSwitchboardDrive, type RuntimeFlagInput, type RuntimeFlagKeys, SETTINGS_ROUTE_ID, type SettingsTabEntry, type SidebarMode, type SwitchboardDrive, ThemeToggle, addConnectRoutes, appTitle, applyComposition, applyConnectPluginUi, applyPlacementEntries, bindConnectRouter, bindConnectScroll, caughtUp, connectRoutes, connectRoutesSettled, connectScrollRestoration, connectSearchMiddlewares, coreModals, coreRouteOptions, coreView, createAppReactorClient, createConnectNavigation, createConnectRouter, definedSearch, disposeConnectAppRouter, driveTitle, effectiveBackend, findServedDrive, formatModified, getActivePluginModules, getAppDrives, getConnectAppRouter, getConnectPHStore, getConnectPluginUi, getIsEmbedded, getRuntimeConfig, holdConnectRoutes, isCoreView, isDriveNotFound, isMultiReactorEnabled, isPluginActive, isReactorWorkerEnabled, isRuntimeFlagEnabled, keepOpenedFrom, keepsLocalCopy, knownPlugins, loadConnectPluginUi, loadDrive, loadLocalPackage, loadNode, loadRuntimeConfig, markNavigationClick, markRouterNavigations, mergeConnectPluginUi, navRoutes, needsCopy, notFoundTitle, parseConnectSearch, placementKeys, planReactorClient, primeRuntimeConfig, redirectToSettingsTab, refreshAppDrives, registerConnectPlugins, registerConnectRoutes, registerPackageRoutes, relistAppDrives, removeConnectRoutes, removeLocalCopies, resetConnectPluginUi, resolveReactorClientMode, resolveReactorWorkerEnabled, resolveRuntimeFlag, resolveSwitchboardDrives, routerPerfEnabled, selectAppReactorClient, servedUrl, servesSlug, setSettingsRoute, settingsTabs, settingsTabsOf, settingsTitle, showsSettingsTab, stringifyConnectSearch, switchboardDrives, useBackendAuthGate, useConnectChrome, useCreateDocumentTarget, useDriveRouteData, useDriveRouteIds, useForgetSettingsOpenedFrom, useIsColdStart, useIsEmbedded, useModalFrame, useNavRoutes, useSettingsTabs, useSidebarMode, validateConnectSearch, validateDriveSearch };
10
+ export { APP_ROUTE_ID, type AppReactorClientParams, AppearanceTab, BackendAuthGate, type BackendAuthGateMode, CONTENT_VIEW_ID, CORE_MODAL_VIEWS, ConfirmDocumentUpgradeModal, type ConnectAppRouterOptions, type ConnectChrome, type ConnectConfigHooks, ConnectCoreApp, type ConnectModals, type ConnectNavItem, type ConnectPlugin, type ConnectPluginContext, type ConnectPluginDefinition, type ConnectPluginFactory, type ConnectPluginUi, type ConnectPluginUiSet, type ConnectRootRoute, type ConnectRouteRegistration, type ConnectRouteUi, type ConnectRouter, type ConnectRouterBundle, type ConnectRouterContext, type ConnectRouterFor, type ConnectRouterOptions, type ConnectRoutes, type ConnectSearch, type ConnectSettingsTab, ContentOutlet, CoreError, CoreHeader, CoreLayout, CoreNotFound, CoreRoot, CoreRouteError, type CoreRouteOptions, CoreSettingsPage, type CreateAppReactorClientOptions, CreateDocumentModal, type CreateDocumentTarget, DRIVE_PENDING_MS, DRIVE_ROUTE_ID, DeleteItemModal, DirectoryListing, type DocumentEditorProps, DocumentHistory, DocumentJson, DocumentVersionUnsupportedModal, DocumentView, type DocumentViewProps, DownloadDocumentWithErrorsModal, DriveAuthRequiredModal, DriveIndex, DriveLayout, type DriveLoaderOptions, type DriveNotFoundData, DriveNotFoundPage, DrivePending, type DrivePlacement, DrivePlacements, type DriveRouteData, type DriveRouteParams, type DriveRouteView, type DriveViewProps, EditorHost, type EditorHostProps, FEATURE_FLAG_PARAM_PREFIX, GLOBAL_SEARCH_PARAMS, HISTORY_PAGE_SIZE, HOME_ROUTE_ID, LOCAL_BACKEND_NAME, type LoadedDocumentModels, type LocalPackage, type LocalPackageSource, type LocalReactorFactory, type LocalReactorModule, LoginModal, ModalDialog, type ModalFrameProps, ModalOutlet, type ModuleNamespace, NODE_ROUTE_ID, type NavRouteEntry, NewDriveRefusedError, NewDriveUnansweredError, NodeView, NotFoundPage, PERF_STORAGE_KEY, type PackageRoute, PackagesTab, type PlacementEntry, type PlacementRouter, type PlacementStore, type PlacementSync, REACTOR_CLIENT_QUERY_KEY, REACTOR_CLIENT_STORAGE_KEY, REACTOR_WORKER_QUERY_KEY, REACTOR_WORKER_STORAGE_KEY, ROUTER_MEASURES, type ReactorClientMode, type ReactorClientPlan, type ReactorWorkerFlagInput, type ResolveSwitchboardDrivesOptions, type ResolvedSwitchboardDrive, type RuntimeFlagInput, type RuntimeFlagKeys, SETTINGS_ROUTE_ID, type SettingsTabEntry, type SidebarMode, type SwitchboardDrive, ThemeToggle, addConnectRoutes, appTitle, applyComposition, applyConnectPluginUi, applyPlacementEntries, bindConnectRouter, bindConnectScroll, caughtUp, connectRoutes, connectRoutesSettled, connectScrollRestoration, connectSearchMiddlewares, coreModals, coreRouteOptions, coreView, createAppReactorClient, createConnectNavigation, createConnectRouter, definedSearch, disposeConnectAppRouter, driveTitle, effectiveBackend, findServedDrive, formatModified, getActivePluginModules, getAppDrives, getConnectAppRouter, getConnectPHStore, getConnectPluginUi, getIsEmbedded, getRuntimeConfig, holdConnectRoutes, isCoreView, isDriveNotFound, isMultiReactorEnabled, isPluginActive, isReactorWorkerEnabled, isRuntimeFlagEnabled, keepOpenedFrom, keepsLocalCopy, knownPlugins, loadConnectPluginUi, loadDrive, loadLocalPackage, loadNode, loadRuntimeConfig, localDrivePlacements, markNavigationClick, markRouterNavigations, mergeConnectPluginUi, navRoutes, needsCopy, newDriveError, newDrivesBlocked, notFoundTitle, parseConnectSearch, placementKeys, planReactorClient, primeRuntimeConfig, redirectToSettingsTab, refreshAppDrives, registerConnectPlugins, registerConnectRoutes, registerPackageRoutes, relistAppDrives, removeConnectRoutes, removeLocalCopies, resetConnectPluginUi, resolveReactorClientMode, resolveReactorWorkerEnabled, resolveRuntimeFlag, resolveSwitchboardDrives, routerPerfEnabled, selectAppReactorClient, servedUrl, servesSlug, setSettingsRoute, settingsTabs, settingsTabsOf, settingsTitle, showsSettingsTab, stringifyConnectSearch, switchboardDrives, useBackendAuthGate, useConnectChrome, useCreateDocumentTarget, useDriveRouteData, useDriveRouteIds, useForgetSettingsOpenedFrom, useIsColdStart, useIsEmbedded, useModalFrame, useNavRoutes, useSettingsTabs, useSidebarMode, validateConnectSearch, validateDriveSearch };
11
11
  export {};
package/dist/index.js CHANGED
@@ -8,6 +8,6 @@ import { getIsEmbedded, useIsEmbedded } from "./embedded.js";
8
8
  import { getRuntimeConfig, loadRuntimeConfig, primeRuntimeConfig } from "./runtime-config.js";
9
9
  import { n as isPluginActive, t as getActivePluginModules } from "./plugins-x1XqLPzp.js";
10
10
  import { n as resolveRuntimeFlag, t as isRuntimeFlagEnabled } from "./runtime-flag-DvxW_SD4.js";
11
- import { A as isMultiReactorEnabled, C as REACTOR_CLIENT_QUERY_KEY, D as REACTOR_WORKER_STORAGE_KEY, E as REACTOR_WORKER_QUERY_KEY, O as isReactorWorkerEnabled, S as selectAppReactorClient, T as resolveReactorClientMode, _ as createAppReactorClient, a as effectiveBackend, b as refreshAppDrives, c as LOCAL_BACKEND_NAME, d as placementKeys, f as removeLocalCopies, g as switchboardDrives, h as servesSlug, i as caughtUp, k as resolveReactorWorkerEnabled, l as applyPlacementEntries, m as servedUrl, n as getConnectPHStore, o as findServedDrive, p as resolveSwitchboardDrives, r as DrivePlacements, s as needsCopy, t as loadLocalPackage, u as keepsLocalCopy, v as getAppDrives, w as REACTOR_CLIENT_STORAGE_KEY, x as relistAppDrives, y as planReactorClient } from "./runtime-LvAkxbdf.js";
11
+ import { A as resolveReactorClientMode, C as planReactorClient, D as REACTOR_CLIENT_QUERY_KEY, E as selectAppReactorClient, F as isMultiReactorEnabled, M as REACTOR_WORKER_STORAGE_KEY, N as isReactorWorkerEnabled, O as REACTOR_CLIENT_STORAGE_KEY, P as resolveReactorWorkerEnabled, S as getAppDrives, T as relistAppDrives, _ as switchboardDrives, a as effectiveBackend, b as newDriveError, c as LOCAL_BACKEND_NAME, d as localDrivePlacements, f as placementKeys, g as servesSlug, h as servedUrl, i as caughtUp, j as REACTOR_WORKER_QUERY_KEY, k as newDrivesBlocked, l as applyPlacementEntries, m as resolveSwitchboardDrives, n as getConnectPHStore, o as findServedDrive, p as removeLocalCopies, r as DrivePlacements, s as needsCopy, t as loadLocalPackage, u as keepsLocalCopy, v as NewDriveRefusedError, w as refreshAppDrives, x as createAppReactorClient, y as NewDriveUnansweredError } from "./runtime-CtZfHUnR.js";
12
12
  import { t as useBackendAuthGate } from "./backend-auth-gate-DNKg_v4Y.js";
13
- export { APP_ROUTE_ID, AppearanceTab, BackendAuthGate, CONTENT_VIEW_ID, CORE_MODAL_VIEWS, ConfirmDocumentUpgradeModal, ConnectCoreApp, ContentOutlet, CoreError, CoreHeader, CoreLayout, CoreNotFound, CoreRoot, CoreRouteError, CoreSettingsPage, CreateDocumentModal, DRIVE_PENDING_MS, DRIVE_ROUTE_ID, DeleteItemModal, DirectoryListing, DocumentHistory, DocumentJson, DocumentVersionUnsupportedModal, DocumentView, DownloadDocumentWithErrorsModal, DriveAuthRequiredModal, DriveIndex, DriveLayout, DriveNotFoundPage, DrivePending, DrivePlacements, EditorHost, FEATURE_FLAG_PARAM_PREFIX, GLOBAL_SEARCH_PARAMS, HISTORY_PAGE_SIZE, HOME_ROUTE_ID, LOCAL_BACKEND_NAME, LoginModal, ModalDialog, ModalOutlet, NODE_ROUTE_ID, NodeView, NotFoundPage, PERF_STORAGE_KEY, PackagesTab, REACTOR_CLIENT_QUERY_KEY, REACTOR_CLIENT_STORAGE_KEY, REACTOR_WORKER_QUERY_KEY, REACTOR_WORKER_STORAGE_KEY, ROUTER_MEASURES, SETTINGS_ROUTE_ID, ThemeToggle, addConnectRoutes, appTitle, applyComposition, applyConnectPluginUi, applyPlacementEntries, bindConnectRouter, bindConnectScroll, caughtUp, connectRoutes, connectRoutesSettled, connectScrollRestoration, connectSearchMiddlewares, coreModals, coreRouteOptions, coreView, createAppReactorClient, createConnectNavigation, createConnectRouter, definedSearch, disposeConnectAppRouter, driveTitle, effectiveBackend, findServedDrive, formatModified, getActivePluginModules, getAppDrives, getConnectAppRouter, getConnectPHStore, getConnectPluginUi, getIsEmbedded, getRuntimeConfig, holdConnectRoutes, isCoreView, isDriveNotFound, isMultiReactorEnabled, isPluginActive, isReactorWorkerEnabled, isRuntimeFlagEnabled, keepOpenedFrom, keepsLocalCopy, knownPlugins, loadConnectPluginUi, loadDrive, loadLocalPackage, loadNode, loadRuntimeConfig, markNavigationClick, markRouterNavigations, mergeConnectPluginUi, navRoutes, needsCopy, notFoundTitle, parseConnectSearch, placementKeys, planReactorClient, primeRuntimeConfig, redirectToSettingsTab, refreshAppDrives, registerConnectPlugins, registerConnectRoutes, registerPackageRoutes, relistAppDrives, removeConnectRoutes, removeLocalCopies, resetConnectPluginUi, resolveReactorClientMode, resolveReactorWorkerEnabled, resolveRuntimeFlag, resolveSwitchboardDrives, routerPerfEnabled, selectAppReactorClient, servedUrl, servesSlug, setSettingsRoute, settingsTabs, settingsTabsOf, settingsTitle, showsSettingsTab, stringifyConnectSearch, switchboardDrives, useBackendAuthGate, useConnectChrome, useCreateDocumentTarget, useDriveRouteData, useDriveRouteIds, useForgetSettingsOpenedFrom, useIsColdStart, useIsEmbedded, useModalFrame, useNavRoutes, useSettingsTabs, useSidebarMode, validateConnectSearch, validateDriveSearch };
13
+ export { APP_ROUTE_ID, AppearanceTab, BackendAuthGate, CONTENT_VIEW_ID, CORE_MODAL_VIEWS, ConfirmDocumentUpgradeModal, ConnectCoreApp, ContentOutlet, CoreError, CoreHeader, CoreLayout, CoreNotFound, CoreRoot, CoreRouteError, CoreSettingsPage, CreateDocumentModal, DRIVE_PENDING_MS, DRIVE_ROUTE_ID, DeleteItemModal, DirectoryListing, DocumentHistory, DocumentJson, DocumentVersionUnsupportedModal, DocumentView, DownloadDocumentWithErrorsModal, DriveAuthRequiredModal, DriveIndex, DriveLayout, DriveNotFoundPage, DrivePending, DrivePlacements, EditorHost, FEATURE_FLAG_PARAM_PREFIX, GLOBAL_SEARCH_PARAMS, HISTORY_PAGE_SIZE, HOME_ROUTE_ID, LOCAL_BACKEND_NAME, LoginModal, ModalDialog, ModalOutlet, NODE_ROUTE_ID, NewDriveRefusedError, NewDriveUnansweredError, NodeView, NotFoundPage, PERF_STORAGE_KEY, PackagesTab, REACTOR_CLIENT_QUERY_KEY, REACTOR_CLIENT_STORAGE_KEY, REACTOR_WORKER_QUERY_KEY, REACTOR_WORKER_STORAGE_KEY, ROUTER_MEASURES, SETTINGS_ROUTE_ID, ThemeToggle, addConnectRoutes, appTitle, applyComposition, applyConnectPluginUi, applyPlacementEntries, bindConnectRouter, bindConnectScroll, caughtUp, connectRoutes, connectRoutesSettled, connectScrollRestoration, connectSearchMiddlewares, coreModals, coreRouteOptions, coreView, createAppReactorClient, createConnectNavigation, createConnectRouter, definedSearch, disposeConnectAppRouter, driveTitle, effectiveBackend, findServedDrive, formatModified, getActivePluginModules, getAppDrives, getConnectAppRouter, getConnectPHStore, getConnectPluginUi, getIsEmbedded, getRuntimeConfig, holdConnectRoutes, isCoreView, isDriveNotFound, isMultiReactorEnabled, isPluginActive, isReactorWorkerEnabled, isRuntimeFlagEnabled, keepOpenedFrom, keepsLocalCopy, knownPlugins, loadConnectPluginUi, loadDrive, loadLocalPackage, loadNode, loadRuntimeConfig, localDrivePlacements, markNavigationClick, markRouterNavigations, mergeConnectPluginUi, navRoutes, needsCopy, newDriveError, newDrivesBlocked, notFoundTitle, parseConnectSearch, placementKeys, planReactorClient, primeRuntimeConfig, redirectToSettingsTab, refreshAppDrives, registerConnectPlugins, registerConnectRoutes, registerPackageRoutes, relistAppDrives, removeConnectRoutes, removeLocalCopies, resetConnectPluginUi, resolveReactorClientMode, resolveReactorWorkerEnabled, resolveRuntimeFlag, resolveSwitchboardDrives, routerPerfEnabled, selectAppReactorClient, servedUrl, servesSlug, setSettingsRoute, settingsTabs, settingsTabsOf, settingsTitle, showsSettingsTab, stringifyConnectSearch, switchboardDrives, useBackendAuthGate, useConnectChrome, useCreateDocumentTarget, useDriveRouteData, useDriveRouteIds, useForgetSettingsOpenedFrom, useIsColdStart, useIsEmbedded, useModalFrame, useNavRoutes, useSettingsTabs, useSidebarMode, validateConnectSearch, validateDriveSearch };
@@ -1,4 +1,4 @@
1
- import { c as LOCAL_BACKEND_NAME } from "./runtime-LvAkxbdf.js";
1
+ import { c as LOCAL_BACKEND_NAME } from "./runtime-CtZfHUnR.js";
2
2
  import { ambientRenownSigner, ambientRenownTokenProvider, createSwitchboardBackend } from "@powerhousedao/reactor-browser";
3
3
  import { logger } from "document-model";
4
4
  import { switchboardOfDrive } from "@powerhousedao/shared/host-tokens";
@@ -6,8 +6,6 @@ import { createReactorInspector } from "@powerhousedao/reactor";
6
6
  import { FanInPartialFailureError, RoutingReactorClient, fromReactorClient } from "@powerhousedao/reactor-router";
7
7
  //#region src/runtime/multi-reactor.ts
8
8
  const REMOTE_BACKEND_NAME = "switchboard-remote";
9
- /** Only the tab's reactor is inspectable here, so new collections land on it. */
10
- const PLACE_ON_LOCAL = Object.freeze({ inspectable: true });
11
9
  function localReach(kind) {
12
10
  return kind === "worker" ? {
13
11
  hosting: "worker",
@@ -30,10 +28,6 @@ function localFacts(module) {
30
28
  function deriveSwitchboardGraphqlUrl(remoteDriveUrl) {
31
29
  return switchboardOfDrive(remoteDriveUrl)?.graphql;
32
30
  }
33
- /** Remote-only placement: the Switchboard serves every collection. (It offers
34
- * no inspection surface over GraphQL, so PLACE_ON_LOCAL's `inspectable`
35
- * requirement must NOT apply, or no backend would be eligible.) */
36
- const PLACE_ON_REMOTE = Object.freeze({});
37
31
  /**
38
32
  * The local answer stands when only the Switchboard could not answer -- but
39
33
  * only when there IS a local backend. Remote-only has nothing to fall back to,
@@ -48,6 +42,8 @@ function localIdCheckAnswer(documentId, error, remoteNames) {
48
42
  /** The router Connect installs, with Connect's handling of credentials and id checks. */
49
43
  var ConnectRoutingClient = class extends RoutingReactorClient {
50
44
  remotes;
45
+ /** The switchboard new drives are created on; undefined when it is this browser. */
46
+ newDrives;
51
47
  constructor(backends, options, remotes, hasLocal) {
52
48
  const remoteNames = new Set(remotes.map((remote) => remote.config.name));
53
49
  super(backends, {
@@ -55,6 +51,8 @@ var ConnectRoutingClient = class extends RoutingReactorClient {
55
51
  answerFailedIdCheck: hasLocal ? (id, error) => localIdCheckAnswer(id, error, remoteNames) : options.answerFailedIdCheck
56
52
  });
57
53
  this.remotes = remotes;
54
+ const home = options.defaultBackend ?? options.primaryBackend;
55
+ this.newDrives = home && remoteNames.has(home) ? home : void 0;
58
56
  }
59
57
  /** Renown's sign-in and sign-out call this on whatever client is installed. */
60
58
  notifyCredentialsChanged() {
@@ -94,13 +92,17 @@ async function buildMultiReactorClient(params) {
94
92
  const loadedModules = typeof loaded === "function" ? loaded : () => loaded;
95
93
  const listed = remotesOf(params);
96
94
  if (listed.length === 0) throw new Error("A routing client needs at least one switchboard");
95
+ if (params.newDrives !== void 0 && !listed.some((remote) => remote.name === params.newDrives)) throw new Error(`New drives go to ${params.newDrives}, but this Connect doesn't link to it (it links to ${listed.map((remote) => remote.name).join(", ")}).`);
97
96
  const remotes = listed.map((remote) => createSwitchboardBackend({
98
97
  name: remote.name,
99
98
  url: remote.graphqlUrl,
100
99
  tokenProvider: ambientRenownTokenProvider,
101
100
  signer: ambientRenownSigner,
102
101
  documentModels: () => registry?.getAllModules() ?? loadedModules(),
103
- inspection: "none"
102
+ inspection: "none",
103
+ requestTimeoutMs: remote.requestTimeoutMs,
104
+ breaker: remote.breaker,
105
+ realtime: remote.realtime
104
106
  }));
105
107
  const remoteBackends = remotes.map((remote) => remote.config);
106
108
  const backends = module ? [{
@@ -112,9 +114,12 @@ async function buildMultiReactorClient(params) {
112
114
  }, ...remoteBackends] : remoteBackends;
113
115
  const names = new Set(backends.map((backend) => backend.name));
114
116
  const collections = Object.fromEntries(Object.entries(params.collections ?? {}).filter(([, backend]) => names.has(backend)));
117
+ const primary = module ? LOCAL_BACKEND_NAME : params.newDrives ?? remoteBackends[0].name;
115
118
  const router = new ConnectRoutingClient(backends, {
116
- primaryBackend: module ? LOCAL_BACKEND_NAME : remoteBackends[0].name,
117
- defaultRequirements: module ? PLACE_ON_LOCAL : PLACE_ON_REMOTE,
119
+ primaryBackend: primary,
120
+ defaultBackend: params.newDrives ?? primary,
121
+ probeTimeoutMs: params.probeTimeoutMs,
122
+ provisionalRouteMs: params.provisionalRouteMs,
118
123
  collections,
119
124
  signer: params.signer,
120
125
  onDiagnostic: params.onDiagnostic,
@@ -124,6 +129,6 @@ async function buildMultiReactorClient(params) {
124
129
  return router;
125
130
  }
126
131
  //#endregion
127
- export { ConnectRoutingClient, LOCAL_BACKEND_NAME, PLACE_ON_LOCAL, PLACE_ON_REMOTE, REMOTE_BACKEND_NAME, buildMultiReactorClient, deriveSwitchboardGraphqlUrl, localFacts, localReach };
132
+ export { ConnectRoutingClient, LOCAL_BACKEND_NAME, REMOTE_BACKEND_NAME, buildMultiReactorClient, deriveSwitchboardGraphqlUrl, localFacts, localReach };
128
133
 
129
- //# sourceMappingURL=multi-reactor-Dvwv69u1.js.map
134
+ //# sourceMappingURL=multi-reactor-91g8OeBB.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multi-reactor-91g8OeBB.js","names":[],"sources":["../src/runtime/multi-reactor.ts"],"sourcesContent":["import {\n createReactorInspector,\n type ReactorInfo,\n} from \"@powerhousedao/reactor\";\nimport {\n ambientRenownSigner,\n ambientRenownTokenProvider,\n createSwitchboardBackend,\n type BrowserReactorClientModule,\n type SwitchboardBackend,\n type SwitchboardBreaker,\n type WorkerReactorClientModule,\n} from \"@powerhousedao/reactor-browser\";\nimport {\n FanInPartialFailureError,\n fromReactorClient,\n RoutingReactorClient,\n type ReactorReach,\n type RoutableBackendConfig,\n type RouterDiagnostic,\n type RoutingClientOptions,\n} from \"@powerhousedao/reactor-router\";\nimport type {\n DocumentModelModule,\n ISigner,\n} from \"@powerhousedao/shared/document-model\";\nimport { switchboardOfDrive } from \"@powerhousedao/shared/host-tokens\";\nimport { logger } from \"document-model\";\nimport { LOCAL_BACKEND_NAME } from \"./drive-placement.js\";\n\nexport { LOCAL_BACKEND_NAME } from \"./drive-placement.js\";\nexport const REMOTE_BACKEND_NAME = \"switchboard-remote\";\n\nexport type LocalReactorModule =\n | BrowserReactorClientModule\n | WorkerReactorClientModule;\n\nexport function localReach(kind: LocalReactorModule[\"kind\"]): ReactorReach {\n return kind === \"worker\"\n ? { hosting: \"worker\", inspection: \"rpc\" }\n : { hosting: \"in-process\", inspection: \"direct\" };\n}\n\n/** Read at every refresh, never kept: a rebuilt reactor reports its own. */\nexport function localFacts(\n module: LocalReactorModule,\n): () => Promise<ReactorInfo> {\n if (module.kind === \"worker\") {\n return () => module.inspector.info();\n }\n return async () => {\n const reactorModule = module.reactorModule;\n if (!reactorModule) {\n throw new Error(\"The in-tab reactor exposes no module to inspect\");\n }\n return createReactorInspector(reactorModule).info();\n };\n}\n\n/** `<origin>[/<prefix>]/d/<slug>` -> `<origin>[/<prefix>]/graphql`. */\nexport function deriveSwitchboardGraphqlUrl(\n remoteDriveUrl: string,\n): string | undefined {\n return switchboardOfDrive(remoteDriveUrl)?.graphql;\n}\n\n/** A switchboard the router reaches, by its router backend name, with its connection settings. */\nexport type SwitchboardRemote = {\n name: string;\n graphqlUrl: string;\n requestTimeoutMs?: number;\n breaker?: SwitchboardBreaker;\n realtime?: boolean;\n};\n\n/** The loaded document models, or a getter that reads the current ones. */\nexport type LoadedDocumentModels =\n | readonly DocumentModelModule[]\n | (() => readonly DocumentModelModule[]);\n\nexport type MultiReactorParams = {\n /** The local module, built and ready. Undefined builds a REMOTE-ONLY router\n * (no local backend → no local reactor, no PGlite): the `remote` client. */\n module: LocalReactorModule | undefined;\n /** One per switchboard; `remoteGraphqlUrl` alone is one named `switchboard-remote`. */\n remotes?: readonly SwitchboardRemote[];\n remoteGraphqlUrl?: string;\n /** Collection key or drive id -> backend; names no backend here are dropped. */\n collections?: Readonly<Record<string, string>>;\n /** The remote new drives are created on, with no copy here. Absent: the\n * local reactor, else the only switchboard. */\n newDrives?: string;\n probeTimeoutMs?: number;\n provisionalRouteMs?: number;\n /** Signs routed writes; unsigned (anonymous) without one. */\n signer?: ISigner;\n /** Signing models when the local module exposes no registry; the router asks the local reactor (or, remote-only, the loaded set). */\n documentModelModules: LoadedDocumentModels;\n onDiagnostic?: RouterDiagnostic;\n};\n\n/**\n * The local answer stands when only the Switchboard could not answer -- but\n * only when there IS a local backend. Remote-only has nothing to fall back to,\n * so its errors surface. Installed as the router's `answerFailedIdCheck`, so\n * the facade and `write.isDocumentIdTaken` both apply it.\n */\nfunction localIdCheckAnswer(\n documentId: string,\n error: unknown,\n remoteNames: ReadonlySet<string>,\n): boolean | undefined {\n if (!failedOnlyOnRemote(error, remoteNames)) {\n return undefined;\n }\n logger.warn(\n \"The Switchboard could not say whether @id is taken; using the local reactor's answer: @error\",\n documentId,\n error,\n );\n return false;\n}\n\n/** The router Connect installs, with Connect's handling of credentials and id checks. */\nexport class ConnectRoutingClient extends RoutingReactorClient {\n private readonly remotes: readonly SwitchboardBackend[];\n /** The switchboard new drives are created on; undefined when it is this browser. */\n readonly newDrives: string | undefined;\n\n constructor(\n backends: readonly RoutableBackendConfig[],\n options: RoutingClientOptions,\n remotes: readonly SwitchboardBackend[],\n hasLocal: boolean,\n ) {\n const remoteNames = new Set(remotes.map((remote) => remote.config.name));\n super(backends, {\n ...options,\n answerFailedIdCheck: hasLocal\n ? (id, error) => localIdCheckAnswer(id, error, remoteNames)\n : options.answerFailedIdCheck,\n });\n this.remotes = remotes;\n const home = options.defaultBackend ?? options.primaryBackend;\n this.newDrives = home && remoteNames.has(home) ? home : undefined;\n }\n\n /** Renown's sign-in and sign-out call this on whatever client is installed. */\n notifyCredentialsChanged(): void {\n for (const remote of this.remotes) remote.notifyCredentialsChanged();\n }\n}\n\nfunction failedOnlyOnRemote(\n error: unknown,\n remoteNames: ReadonlySet<string>,\n): boolean {\n return (\n error instanceof FanInPartialFailureError &&\n error.failures.every((failure) => remoteNames.has(failure.backend))\n );\n}\n\n/** The remotes to build, one per switchboard: the first link to a base wins. */\nfunction remotesOf(params: MultiReactorParams): SwitchboardRemote[] {\n const listed: readonly SwitchboardRemote[] = params.remotes?.length\n ? params.remotes\n : params.remoteGraphqlUrl\n ? [{ name: REMOTE_BACKEND_NAME, graphqlUrl: params.remoteGraphqlUrl }]\n : [];\n const seen = new Set<string>();\n return listed.filter((remote) => {\n if (seen.has(remote.graphqlUrl)) {\n logger.warn(\n \"@name opens the same switchboard as an earlier backend; skipping it\",\n remote.name,\n );\n return false;\n }\n seen.add(remote.graphqlUrl);\n return true;\n });\n}\n\n/**\n * Build the Connect routing client. With a local `module` it is the router\n * over the tab's reactor (primary) and the Switchboard; WITHOUT one it is the\n * `remote` client — a remote-only router whose single backend is the\n * Switchboard, so no local reactor (and no PGlite) is built. Either way the\n * result is a full IReactorClient the app graph consumes unchanged.\n */\nexport async function buildMultiReactorClient(\n params: MultiReactorParams,\n): Promise<ConnectRoutingClient> {\n const module = params.module;\n const registry = module?.reactorModule?.documentModelRegistry;\n const loaded = params.documentModelModules;\n const loadedModules = typeof loaded === \"function\" ? loaded : () => loaded;\n const listed = remotesOf(params);\n if (listed.length === 0) {\n throw new Error(\"A routing client needs at least one switchboard\");\n }\n if (\n params.newDrives !== undefined &&\n !listed.some((remote) => remote.name === params.newDrives)\n ) {\n throw new Error(\n `New drives go to ${params.newDrives}, but this Connect doesn't link to it (it links to ${listed.map((remote) => remote.name).join(\", \")}).`,\n );\n }\n // The logged-in Renown user's token and signer, read per request as before.\n const remotes = listed.map((remote) =>\n createSwitchboardBackend({\n name: remote.name,\n url: remote.graphqlUrl,\n tokenProvider: ambientRenownTokenProvider,\n signer: ambientRenownSigner,\n documentModels: () => registry?.getAllModules() ?? loadedModules(),\n inspection: \"none\",\n requestTimeoutMs: remote.requestTimeoutMs,\n breaker: remote.breaker,\n realtime: remote.realtime,\n }),\n );\n const remoteBackends = remotes.map((remote) => remote.config);\n const backends: RoutableBackendConfig[] = module\n ? [\n {\n name: LOCAL_BACKEND_NAME,\n backend: fromReactorClient(module.client),\n facts: localFacts(module),\n reach: localReach(module.kind),\n refusesMisroutes: false,\n },\n ...remoteBackends,\n ]\n : remoteBackends;\n const names = new Set(backends.map((backend) => backend.name));\n const collections = Object.fromEntries(\n Object.entries(params.collections ?? {}).filter(([, backend]) =>\n names.has(backend),\n ),\n );\n // The local reactor answers the registry and create defaults; remote-only,\n // the switchboard new drives go to does.\n const primary = module\n ? LOCAL_BACKEND_NAME\n : (params.newDrives ?? remoteBackends[0].name);\n const router = new ConnectRoutingClient(\n backends,\n {\n primaryBackend: primary,\n defaultBackend: params.newDrives ?? primary,\n probeTimeoutMs: params.probeTimeoutMs,\n provisionalRouteMs: params.provisionalRouteMs,\n collections,\n signer: params.signer,\n onDiagnostic: params.onDiagnostic,\n // The Switchboard serves no models over GraphQL; remote-only uses the loaded set.\n documentModelModules: module ? undefined : loadedModules,\n },\n remotes,\n Boolean(module),\n );\n await router.refreshFacts();\n return router;\n}\n"],"mappings":"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"}
@@ -4,7 +4,7 @@ import { n as setDriveRelister } from "./backend-auth-gate-DNKg_v4Y.js";
4
4
  import { bindPHStoreToWindow, createPHStore, getActivePHStore, getDrives, getFullReactorClient, getPHStore, recordBackendAuthError, setBackendAuth, setDrives, setFullReactorClient } from "@powerhousedao/reactor-browser";
5
5
  import { logger } from "document-model";
6
6
  import { switchboardOfDrive } from "@powerhousedao/shared/host-tokens";
7
- import { DriveCollectionId } from "@powerhousedao/reactor";
7
+ import { DriveCollectionId, isDriveAuthError } from "@powerhousedao/reactor";
8
8
  import { driveDocumentType } from "@powerhousedao/shared/document-drive";
9
9
  //#region src/runtime/multi-reactor-flag.ts
10
10
  function isMultiReactorEnabled() {
@@ -35,7 +35,11 @@ const MODES = /* @__PURE__ */ new Set([
35
35
  const REACTOR_CLIENT_QUERY_KEY = "reactorClient";
36
36
  const REACTOR_CLIENT_STORAGE_KEY = "ph:reactorClient";
37
37
  const asMode = (value) => value && MODES.has(value) ? value : void 0;
38
- function fromTab() {
38
+ const LOCAL_ONLY = /* @__PURE__ */ new Set(["in-process", "worker"]);
39
+ /** Set while this page load keeps its reactor to itself against the host's `newDrives`. */
40
+ let blockedNewDrives;
41
+ /** While new drives go to a switchboard, a local-only override applies only from the URL, never from storage. */
42
+ function fromTab(newDrives) {
39
43
  if (typeof window === "undefined") return void 0;
40
44
  let query;
41
45
  try {
@@ -43,29 +47,42 @@ function fromTab() {
43
47
  } catch {
44
48
  return;
45
49
  }
50
+ const localOnly = (mode) => newDrives !== void 0 && mode !== void 0 && LOCAL_ONLY.has(mode);
46
51
  try {
47
52
  if (query) {
48
- window.localStorage.setItem(REACTOR_CLIENT_STORAGE_KEY, query);
53
+ if (localOnly(query)) window.localStorage.removeItem(REACTOR_CLIENT_STORAGE_KEY);
54
+ else window.localStorage.setItem(REACTOR_CLIENT_STORAGE_KEY, query);
49
55
  return query;
50
56
  }
51
- return asMode(window.localStorage.getItem(REACTOR_CLIENT_STORAGE_KEY));
57
+ const stored = asMode(window.localStorage.getItem(REACTOR_CLIENT_STORAGE_KEY));
58
+ if (!localOnly(stored)) return stored;
59
+ window.localStorage.removeItem(REACTOR_CLIENT_STORAGE_KEY);
60
+ logger.warn("Ignoring the stored ?reactorClient=@mode: new drives go to @switchboard", stored, newDrives);
61
+ return;
52
62
  } catch {
53
63
  return query;
54
64
  }
55
65
  }
56
66
  function resolveReactorClientMode() {
57
- const override = fromTab();
67
+ const instance = getRuntimeConfig().connect.instance;
68
+ const newDrives = instance?.router?.newDrives;
69
+ const override = fromTab(newDrives);
70
+ blockedNewDrives = override && newDrives !== void 0 && LOCAL_ONLY.has(override) ? /* @__PURE__ */ new Error(`New drives go to ${newDrives}, but this browser is set to keep its reactor to itself (?reactorClient=${override}).`) : void 0;
58
71
  if (override) return override;
59
- const configured = getRuntimeConfig().connect.instance?.reactorClient;
72
+ const configured = instance?.reactorClient;
60
73
  if (configured && MODES.has(configured)) return configured;
61
74
  if (isMultiReactorEnabled()) return "router";
62
75
  if (isReactorWorkerEnabled()) return "worker";
63
76
  return "in-process";
64
77
  }
78
+ /** Why this page load can't create a drive where the host says, or undefined when it can. */
79
+ function newDrivesBlocked() {
80
+ return blockedNewDrives;
81
+ }
65
82
  //#endregion
66
83
  //#region src/runtime/app-reactor-client.ts
67
84
  const REMOTE_BACKEND_NAME = "switchboard-remote";
68
- const loadMultiReactor = () => import("./multi-reactor-Dvwv69u1.js");
85
+ const loadMultiReactor = () => import("./multi-reactor-91g8OeBB.js");
69
86
  function planReactorClient(mode = resolveReactorClientMode()) {
70
87
  const needsLocalReactor = mode !== "remote";
71
88
  return {
@@ -192,10 +209,10 @@ function switchboardRemotes(params) {
192
209
  }] : [];
193
210
  const remotes = [];
194
211
  const unparsed = [];
195
- for (const { name, url } of listed) {
212
+ for (const { url, ...remote } of listed) {
196
213
  const graphqlUrl = switchboardOfDrive(url)?.graphql;
197
214
  if (graphqlUrl) remotes.push({
198
- name,
215
+ ...remote,
199
216
  graphqlUrl
200
217
  });
201
218
  else unparsed.push(url);
@@ -208,7 +225,9 @@ function switchboardRemotes(params) {
208
225
  async function buildRouter(params) {
209
226
  const { remotes, unparsed } = switchboardRemotes(params);
210
227
  for (const url of unparsed) logger.warn("multiReactor is on but the remote drive URL @url does not parse; skipping it", url);
228
+ const newDrives = params.router?.newDrives;
211
229
  if (remotes.length === 0) {
230
+ if (newDrives !== void 0) throw new Error(`New drives go to ${newDrives}, but this Connect has no address for it, so it can't start.`);
212
231
  logger.warn("multiReactor is on but no remote drive URL is configured; using the local reactor only");
213
232
  return;
214
233
  }
@@ -216,6 +235,7 @@ async function buildRouter(params) {
216
235
  try {
217
236
  multiReactor = await (params.loadRouter ?? loadMultiReactor)();
218
237
  } catch (error) {
238
+ if (newDrives !== void 0) throw new Error(`New drives go to ${newDrives}, but the router that reaches it didn't load, so Connect can't start.`, { cause: error });
219
239
  logger.error("Could not load the multi-reactor router: @error", error);
220
240
  return;
221
241
  }
@@ -224,6 +244,7 @@ async function buildRouter(params) {
224
244
  module: requireModule(params),
225
245
  remotes,
226
246
  collections: params.collections,
247
+ ...params.router,
227
248
  signer: params.signer,
228
249
  documentModelModules: params.documentModelModules
229
250
  });
@@ -245,14 +266,89 @@ async function buildRemoteOnly(params) {
245
266
  module: void 0,
246
267
  remotes,
247
268
  collections: params.collections,
269
+ ...params.router,
248
270
  signer: params.signer,
249
271
  documentModelModules: params.documentModelModules
250
272
  });
251
273
  }
252
274
  //#endregion
275
+ //#region src/runtime/new-drive.ts
276
+ /** A drive create the switchboard new drives go to did not answer. */
277
+ var NewDriveUnansweredError = class extends Error {
278
+ backend;
279
+ name = "NewDriveUnansweredError";
280
+ constructor(backend, options) {
281
+ super(`${backend} isn't answering, so the drive wasn't created.`, options);
282
+ this.backend = backend;
283
+ }
284
+ };
285
+ /** `auth`: the switchboard refused the caller, so signing in may help. */
286
+ var NewDriveRefusedError = class extends Error {
287
+ backend;
288
+ auth;
289
+ name = "NewDriveRefusedError";
290
+ constructor(backend, auth, reason, options) {
291
+ super(reason ? `${backend} refused the new drive: ${reason}` : `${backend} refused the new drive.`, options);
292
+ this.backend = backend;
293
+ this.auth = auth;
294
+ }
295
+ };
296
+ const NETWORK_FAILURE = /fetch failed|failed to fetch|networkerror|load failed/i;
297
+ /** Each error in the cause chain, outermost first. */
298
+ function* chain(error) {
299
+ for (let at = error; at; at = at.cause) yield at;
300
+ }
301
+ function statusOf(at) {
302
+ const status = at.response?.status ?? at.statusCode;
303
+ return typeof status === "number" ? status : void 0;
304
+ }
305
+ /** A failure to reach a switchboard, not an answer from it. */
306
+ function isUnanswered(error) {
307
+ for (const at of chain(error)) {
308
+ if (at.name === "SwitchboardUnreachableError" || at.name === "TimeoutError" || at.name === "ProbeTimeoutError" || at.category === "network" || at instanceof TypeError && NETWORK_FAILURE.test(at.message)) return true;
309
+ const status = statusOf(at);
310
+ if (status !== void 0 && status >= 500) return true;
311
+ }
312
+ return false;
313
+ }
314
+ function isAuthRefusal(error) {
315
+ for (const at of chain(error)) {
316
+ if (isDriveAuthError(at)) return true;
317
+ const status = statusOf(at);
318
+ if (status === 401 || status === 403) return true;
319
+ }
320
+ return false;
321
+ }
322
+ /** An answer from a server, not a failure in this browser. */
323
+ function isServerAnswer(error) {
324
+ for (const at of chain(error)) if (at.response !== void 0 || statusOf(at) !== void 0 || at.name === "GraphQLRequestError" || at.name === "MisrouteUnresolvedError") return true;
325
+ return false;
326
+ }
327
+ /** The first reason the switchboard gave, if it gave one. */
328
+ function reasonOf(error) {
329
+ for (const at of chain(error)) {
330
+ const message = at.response?.errors?.[0]?.message;
331
+ if (typeof message === "string" && message !== "") return message;
332
+ if (at.name === "GraphQLRequestError" && typeof at.message === "string") return at.message;
333
+ }
334
+ }
335
+ /** A failed drive create, named for the switchboard `client` creates new drives on; else `error` itself. */
336
+ function newDriveError(client, error) {
337
+ const backend = client?.newDrives;
338
+ if (typeof backend !== "string") return error;
339
+ if (isUnanswered(error)) return new NewDriveUnansweredError(backend, { cause: error });
340
+ if (!isServerAnswer(error)) return error;
341
+ return new NewDriveRefusedError(backend, isAuthRefusal(error), reasonOf(error), { cause: error });
342
+ }
343
+ //#endregion
253
344
  //#region src/runtime/drive-placement.ts
254
345
  /** The router backend of the reactor in this browser. */
255
346
  const LOCAL_BACKEND_NAME = "connect-local";
347
+ /** The config's local default drives, placed on this browser so a
348
+ * switchboard `newDrives` doesn't take them. */
349
+ function localDrivePlacements(defaultDrives) {
350
+ return Object.fromEntries(defaultDrives.flatMap((drive) => !("url" in drive) && drive.id ? [[drive.id, LOCAL_BACKEND_NAME]] : []));
351
+ }
256
352
  function keepsLocalCopy(drive) {
257
353
  return !("url" in drive) || drive.sync !== false;
258
354
  }
@@ -604,6 +700,6 @@ function loadLocalPackage(source) {
604
700
  return pkg;
605
701
  }
606
702
  //#endregion
607
- export { isMultiReactorEnabled as A, REACTOR_CLIENT_QUERY_KEY as C, REACTOR_WORKER_STORAGE_KEY as D, REACTOR_WORKER_QUERY_KEY as E, isReactorWorkerEnabled as O, selectAppReactorClient as S, resolveReactorClientMode as T, createAppReactorClient as _, effectiveBackend as a, refreshAppDrives as b, LOCAL_BACKEND_NAME as c, placementKeys as d, removeLocalCopies as f, switchboardDrives as g, servesSlug as h, caughtUp as i, resolveReactorWorkerEnabled as k, applyPlacementEntries as l, servedUrl as m, getConnectPHStore as n, findServedDrive as o, resolveSwitchboardDrives as p, DrivePlacements as r, needsCopy as s, loadLocalPackage as t, keepsLocalCopy as u, getAppDrives as v, REACTOR_CLIENT_STORAGE_KEY as w, relistAppDrives as x, planReactorClient as y };
703
+ export { resolveReactorClientMode as A, planReactorClient as C, REACTOR_CLIENT_QUERY_KEY as D, selectAppReactorClient as E, isMultiReactorEnabled as F, REACTOR_WORKER_STORAGE_KEY as M, isReactorWorkerEnabled as N, REACTOR_CLIENT_STORAGE_KEY as O, resolveReactorWorkerEnabled as P, getAppDrives as S, relistAppDrives as T, switchboardDrives as _, effectiveBackend as a, newDriveError as b, LOCAL_BACKEND_NAME as c, localDrivePlacements as d, placementKeys as f, servesSlug as g, servedUrl as h, caughtUp as i, REACTOR_WORKER_QUERY_KEY as j, newDrivesBlocked as k, applyPlacementEntries as l, resolveSwitchboardDrives as m, getConnectPHStore as n, findServedDrive as o, removeLocalCopies as p, DrivePlacements as r, needsCopy as s, loadLocalPackage as t, keepsLocalCopy as u, NewDriveRefusedError as v, refreshAppDrives as w, createAppReactorClient as x, NewDriveUnansweredError as y };
608
704
 
609
- //# sourceMappingURL=runtime-LvAkxbdf.js.map
705
+ //# sourceMappingURL=runtime-CtZfHUnR.js.map