@powerhousedao/powerhouse-vetra-packages 6.2.2-dev.83 → 6.2.2-dev.85

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 (51) hide show
  1. package/dist/browser/{connect-1nygQZWX.js → connect-DqkYyEcC.js} +14 -5
  2. package/dist/browser/{connect-1nygQZWX.js.map → connect-DqkYyEcC.js.map} +1 -1
  3. package/dist/browser/{dist-Bw_lDsJV.js → dist-C1pi89al.js} +283 -16
  4. package/dist/browser/dist-C1pi89al.js.map +1 -0
  5. package/dist/browser/{document-drive-BVYCdu_5.js → document-drive-ZQzPQfEL.js} +12 -5
  6. package/dist/browser/{document-drive-BVYCdu_5.js.map → document-drive-ZQzPQfEL.js.map} +1 -1
  7. package/dist/browser/document-models/index.js +1 -1
  8. package/dist/browser/{editor-CTCBSOqH.js → editor-Bl02Hko1.js} +6 -6
  9. package/dist/browser/{editor-CTCBSOqH.js.map → editor-Bl02Hko1.js.map} +1 -1
  10. package/dist/browser/{editor-2AtEs-xj.js → editor-CbtY05JH.js} +5 -5
  11. package/dist/browser/{editor-2AtEs-xj.js.map → editor-CbtY05JH.js.map} +1 -1
  12. package/dist/browser/editors/document-model-editor/module.js +1 -1
  13. package/dist/browser/editors/generic-drive-explorer/index.js +4 -4
  14. package/dist/browser/editors/generic-drive-explorer/module.js +1 -1
  15. package/dist/browser/{folder-view-CCyyB3dV.js → folder-view-BBm_YnKn.js} +3 -3
  16. package/dist/browser/{folder-view-CCyyB3dV.js.map → folder-view-BBm_YnKn.js.map} +1 -1
  17. package/dist/browser/{graphql-editor-BZKrpGCA.js → graphql-editor-LSj3LCtL.js} +3 -3
  18. package/dist/browser/{graphql-editor-BZKrpGCA.js.map → graphql-editor-LSj3LCtL.js.map} +1 -1
  19. package/dist/browser/index.js +1 -1
  20. package/dist/browser/{json-editor-NoPucS8U.js → json-editor-TVSHA4PZ.js} +3 -3
  21. package/dist/browser/{json-editor-NoPucS8U.js.map → json-editor-TVSHA4PZ.js.map} +1 -1
  22. package/dist/browser/lib-ewnRj2dJ.js.map +1 -1
  23. package/dist/browser/{state-schemas-C2mNqcqS.js → state-schemas-Bsryt22c.js} +3 -3
  24. package/dist/browser/{state-schemas-C2mNqcqS.js.map → state-schemas-Bsryt22c.js.map} +1 -1
  25. package/dist/node/{connect-BSP5dXkb.mjs → connect-B2yHg8VF.mjs} +14 -5
  26. package/dist/node/{connect-BSP5dXkb.mjs.map → connect-B2yHg8VF.mjs.map} +1 -1
  27. package/dist/node/{dist-Bhd_mrZ1.mjs → dist-BAXIB1_k.mjs} +285 -16
  28. package/dist/node/dist-BAXIB1_k.mjs.map +1 -0
  29. package/dist/node/{document-drive-lf_0SP-H.mjs → document-drive-D1NMjQQc.mjs} +12 -5
  30. package/dist/node/{document-drive-lf_0SP-H.mjs.map → document-drive-D1NMjQQc.mjs.map} +1 -1
  31. package/dist/node/document-models/index.mjs +1 -1
  32. package/dist/node/{editor-CYh6uL6E.mjs → editor--v67sph0.mjs} +6 -6
  33. package/dist/node/{editor-CYh6uL6E.mjs.map → editor--v67sph0.mjs.map} +1 -1
  34. package/dist/node/{editor-DHVhjQec.mjs → editor-BY22Tx5_.mjs} +5 -5
  35. package/dist/node/{editor-DHVhjQec.mjs.map → editor-BY22Tx5_.mjs.map} +1 -1
  36. package/dist/node/editors/document-model-editor/module.mjs +1 -1
  37. package/dist/node/editors/generic-drive-explorer/index.mjs +4 -4
  38. package/dist/node/editors/generic-drive-explorer/module.mjs +1 -1
  39. package/dist/node/{folder-view-ixx50l3H.mjs → folder-view-D_99HJFI.mjs} +3 -3
  40. package/dist/node/{folder-view-ixx50l3H.mjs.map → folder-view-D_99HJFI.mjs.map} +1 -1
  41. package/dist/node/{graphql-editor-CqMkJcop.mjs → graphql-editor-Bzs-PolA.mjs} +3 -3
  42. package/dist/node/{graphql-editor-CqMkJcop.mjs.map → graphql-editor-Bzs-PolA.mjs.map} +1 -1
  43. package/dist/node/index.mjs +1 -1
  44. package/dist/node/{json-editor-D4NRHMbo.mjs → json-editor-CCsBXZ6y.mjs} +3 -3
  45. package/dist/node/{json-editor-D4NRHMbo.mjs.map → json-editor-CCsBXZ6y.mjs.map} +1 -1
  46. package/dist/node/main-B1tRsYOp.mjs.map +1 -1
  47. package/dist/node/{state-schemas-CbidCieI.mjs → state-schemas-DxJBYOC0.mjs} +3 -3
  48. package/dist/node/{state-schemas-CbidCieI.mjs.map → state-schemas-DxJBYOC0.mjs.map} +1 -1
  49. package/package.json +7 -7
  50. package/dist/browser/dist-Bw_lDsJV.js.map +0 -1
  51. package/dist/node/dist-Bhd_mrZ1.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
- import { D as __commonJSMin, M as __toESM, t as capitalCase } from "./dist-DT7jI9ol.mjs";
2
- import { C as baseLoadFromInputVersioned, O as createPresignedHeader, Q as setName, S as baseLoadFromInput, T as buildSignedAction, U as replayDocumentVersioned, a as handleTargetNameCollisions, ct as validateStateSchemaName, f as logger, h as UnsupportedDocumentModelVersionError, i as generateNodesCopy, j as createZip, l as moveNode, lt as generateId, n as copyNode, o as isFileNode, ot as validateInitialState, s as isFolderNode, st as validateModules, t as addFolder, u as updateNode, w as baseSaveToFileHandle, y as assertAuthPreservedOnDuplicate } from "./document-drive-lf_0SP-H.mjs";
1
+ import { D as __commonJSMin, M as __toESM, r as pascalCase, t as capitalCase } from "./dist-DT7jI9ol.mjs";
2
+ import { A as createPresignedHeader, D as buildSignedAction, E as baseSaveToFileHandle, G as replayDocumentVersioned, N as createZip, T as baseLoadFromInputVersioned, _ as UnsupportedDocumentModelVersionError, a as getDescendants, c as isFileNode, ct as validateInitialState, d as moveNode, dt as zipEntries, et as setName, f as updateNode, ft as generateId, i as generateNodesCopy, l as isFolderNode, lt as validateModules, m as logger, n as copyNode, o as getNextCopyNumber, s as handleTargetNameCollisions, t as addFolder, ut as validateStateSchemaName, w as baseLoadFromInput, x as assertAuthPreservedOnDuplicate } from "./document-drive-D1NMjQQc.mjs";
3
3
  import { a as DriveCollectionId, i as SyncStatus, o as ModuleNotFoundError, t as require_main } from "./main-B1tRsYOp.mjs";
4
4
  import { t as require_graphql } from "./graphql-BfAoPeWM.mjs";
5
5
  import { createContext, use, useCallback, useContext, useEffect, useMemo, useState, useSyncExternalStore } from "react";
@@ -1028,7 +1028,7 @@ slug.setLocale = function(locale) {
1028
1028
  defaultLocale = locales[locale] || {};
1029
1029
  };
1030
1030
  //#endregion
1031
- //#region ../reactor-browser/dist/document-model-modules-DMIR-uSD.js
1031
+ //#region ../reactor-browser/dist/document-model-modules-DfQBNGc-.js
1032
1032
  var UnsupportedDocumentTypeError = class extends Error {
1033
1033
  constructor(documentType) {
1034
1034
  super(`Document type ${documentType} is not supported`);
@@ -1248,10 +1248,18 @@ function useSelectedNode() {
1248
1248
  }
1249
1249
  const vetraPackageManagerFunctions = makePHEventFunctions("vetraPackageManager");
1250
1250
  const useVetraPackageManager = vetraPackageManagerFunctions.useValue;
1251
- /** Returns all of the Vetra packages loaded by the Connect instance */
1251
+ const EMPTY_VETRA_PACKAGES = [];
1252
+ const noPackageManagerUnsubscribe = () => {};
1253
+ /**
1254
+ * Returns all of the Vetra packages loaded by the Connect instance.
1255
+ *
1256
+ * The snapshot and subscription must keep stable identity while no package
1257
+ * manager is registered: `useSyncExternalStore` loops when the snapshot
1258
+ * changes on every read, which a fresh `[]` does.
1259
+ */
1252
1260
  const useVetraPackages = () => {
1253
1261
  const packageManager = useVetraPackageManager();
1254
- return useSyncExternalStore((cb) => packageManager ? packageManager.subscribe(cb) : () => {}, () => packageManager?.packages ?? []);
1262
+ return useSyncExternalStore((cb) => packageManager ? packageManager.subscribe(cb) : noPackageManagerUnsubscribe, () => packageManager?.packages ?? EMPTY_VETRA_PACKAGES);
1255
1263
  };
1256
1264
  vetraPackageManagerFunctions.addEventHandler;
1257
1265
  function useDocumentModelModules() {
@@ -1285,7 +1293,9 @@ function useDocumentModelModuleById(id, version) {
1285
1293
  return latestModule;
1286
1294
  }
1287
1295
  Error;
1288
- require_graphql();
1296
+ //#endregion
1297
+ //#region ../../node_modules/.pnpm/graphql-request@7.4.0_graphql@16.12.0/node_modules/graphql-request/build/legacy/lib/graphql.js
1298
+ var import_graphql = require_graphql();
1289
1299
  JSON;
1290
1300
  //#endregion
1291
1301
  //#region ../reactor-browser/dist/client-D66jVnot.js
@@ -2058,7 +2068,7 @@ var MessageType = /* @__PURE__ */ ((MessageType2) => {
2058
2068
  })(MessageType || {});
2059
2069
  Error;
2060
2070
  //#endregion
2061
- //#region ../reactor-browser/dist/document-operations-BAJGXn6w.js
2071
+ //#region ../reactor-browser/dist/document-operations-CBExT76y.js
2062
2072
  const modalEventFunctions = makePHEventFunctions("modal");
2063
2073
  modalEventFunctions.useValue;
2064
2074
  /** Sets the current modal */
@@ -3137,7 +3147,7 @@ const usePHToast = toastEventFunctions.useValue;
3137
3147
  toastEventFunctions.setValue;
3138
3148
  toastEventFunctions.addEventHandler;
3139
3149
  //#endregion
3140
- //#region ../reactor-browser/dist/selected-document-xFBNPc9Q.js
3150
+ //#region ../reactor-browser/dist/switchboard-D4-_jwk-.js
3141
3151
  /** Returns a document of a specific type, throws an error if the found document has a different type */
3142
3152
  function useDocumentOfType(documentId, documentType) {
3143
3153
  const [document, dispatch] = useDocumentById(documentId);
@@ -3852,6 +3862,117 @@ var import_lz_string = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((
3852
3862
  return LZString;
3853
3863
  });
3854
3864
  })))(), 1);
3865
+ const sanitize = (segment) => segment.replace(/\//g, "-");
3866
+ /**
3867
+ * Name segments from the exported folder (exclusive) down to `node`
3868
+ * (inclusive), in top-down order. `root === undefined` means the drive root:
3869
+ * all ancestors. A node that IS the exported folder yields no segments.
3870
+ */
3871
+ function segmentsBelow(root, node, allNodes) {
3872
+ const segments = [];
3873
+ let current = node;
3874
+ while (current && current.id !== root?.id) {
3875
+ segments.push(sanitize(current.name));
3876
+ const parentId = current.parentFolder;
3877
+ current = parentId ? allNodes.find((n) => n.id === parentId) : void 0;
3878
+ }
3879
+ return segments.reverse();
3880
+ }
3881
+ /**
3882
+ * Assemble the archive zip for a folder (or the whole drive when
3883
+ * `folderNode` is undefined). Every folder in the subtree becomes a
3884
+ * directory entry (empty folders survive); every file becomes a standard
3885
+ * single-document zip named after the node (drive naming convention:
3886
+ * `${name}.${extension}.phd`, ` (copy) N` on a same-folder collision).
3887
+ *
3888
+ * `fetchDocument` must return the document WITH its full operations and
3889
+ * initialState (see downloadFolderZip).
3890
+ */
3891
+ async function buildFolderZip(drive, folderNode, fetchDocument, onProgress) {
3892
+ const allNodes = drive.state.global.nodes;
3893
+ const topName = sanitize(folderNode?.name ?? (drive.state.global.name || drive.header.name));
3894
+ const subtree = folderNode ? [folderNode, ...getDescendants(folderNode, allNodes)] : allNodes;
3895
+ const entries = { [topName + "/"]: new Uint8Array(0) };
3896
+ for (const node of subtree) {
3897
+ if (!isFolderNode(node)) continue;
3898
+ const dir = [topName, ...segmentsBelow(folderNode, node, allNodes)].join("/");
3899
+ entries[dir + "/"] = new Uint8Array(0);
3900
+ }
3901
+ const files = subtree.filter(isFileNode);
3902
+ const failed = [];
3903
+ const usedNamesByDir = /* @__PURE__ */ new Map();
3904
+ let done = 0;
3905
+ for (const node of files) try {
3906
+ const doc = await fetchDocument(node.id);
3907
+ const extension = await getDocumentExtension(doc);
3908
+ const parent = node.parentFolder ? allNodes.find((n) => n.id === node.parentFolder) : void 0;
3909
+ const dir = [topName, ...parent ? segmentsBelow(folderNode, parent, allNodes) : []].join("/");
3910
+ let usedNames = usedNamesByDir.get(dir);
3911
+ if (!usedNames) {
3912
+ usedNames = /* @__PURE__ */ new Set();
3913
+ usedNamesByDir.set(dir, usedNames);
3914
+ }
3915
+ const base = sanitize(node.name);
3916
+ let candidate = base;
3917
+ let count = getNextCopyNumber([...usedNames], base);
3918
+ while (usedNames.has(candidate)) {
3919
+ candidate = `${base} (copy) ${count}`;
3920
+ count += 1;
3921
+ }
3922
+ usedNames.add(candidate);
3923
+ const leaf = extension ? `${candidate}.${extension}.phd` : `${candidate}.phd`;
3924
+ entries[`${dir}/${leaf}`] = await createZip(doc);
3925
+ } catch {
3926
+ failed.push(node.name);
3927
+ } finally {
3928
+ done += 1;
3929
+ onProgress?.(done, files.length);
3930
+ }
3931
+ return {
3932
+ zip: await zipEntries(entries),
3933
+ archiveName: `${topName}.zip`,
3934
+ entryCount: files.length - failed.length,
3935
+ failed
3936
+ };
3937
+ }
3938
+ /**
3939
+ * Export a folder (or whole drive) to disk: fetches every document with its
3940
+ * full operation history, builds the archive, and saves it via
3941
+ * showSaveFilePicker (fallback: blob download), mirroring exportFile.
3942
+ */
3943
+ async function downloadFolderZip(drive, folderNode, onProgress) {
3944
+ const reactorClient = window.ph?.reactorClient;
3945
+ if (!reactorClient) throw new Error("ReactorClient not initialized");
3946
+ const result = await buildFolderZip(drive, folderNode, async (id) => {
3947
+ const doc = await reactorClient.get(id);
3948
+ const operations = await fetchDocumentOperations(reactorClient, doc);
3949
+ const initialState = extractInitialState(operations["document"] ?? []);
3950
+ return {
3951
+ ...doc,
3952
+ operations,
3953
+ initialState
3954
+ };
3955
+ }, onProgress);
3956
+ if (!window.showSaveFilePicker) {
3957
+ const blob = new Blob([new Uint8Array(result.zip)], { type: "application/zip" });
3958
+ const link = window.document.createElement("a");
3959
+ link.style.display = "none";
3960
+ link.href = URL.createObjectURL(blob);
3961
+ link.download = result.archiveName;
3962
+ window.document.body.appendChild(link);
3963
+ link.click();
3964
+ window.document.body.removeChild(link);
3965
+ return result;
3966
+ }
3967
+ try {
3968
+ const writable = await (await window.showSaveFilePicker({ suggestedName: result.archiveName })).createWritable();
3969
+ await writable.write(new Uint8Array(result.zip));
3970
+ await writable.close();
3971
+ } catch (e) {
3972
+ if (!(e instanceof DOMException && e.name === "AbortError")) throw e;
3973
+ }
3974
+ return result;
3975
+ }
3855
3976
  /** Document types that represent a "drive": a container of nodes. */
3856
3977
  const DRIVE_DOCUMENT_TYPES = ["powerhouse/document-drive", "powerhouse/reactor-drive"];
3857
3978
  function useAllowedDocumentModelModules() {
@@ -4029,6 +4150,25 @@ function useDownloadDocument(id) {
4029
4150
  }
4030
4151
  };
4031
4152
  }
4153
+ /**
4154
+ * Downloads the selected drive's folder (or the whole drive when no folder
4155
+ * is given) as a single zip archive mirroring the folder tree.
4156
+ */
4157
+ function useDownloadFolder(folderNode) {
4158
+ const [selectedDrive] = useSelectedDriveSafe();
4159
+ const toast = usePHToast();
4160
+ return async () => {
4161
+ if (!selectedDrive) return;
4162
+ const name = folderNode?.name ?? selectedDrive.header.name;
4163
+ toast?.(`Downloading "${name}"…`);
4164
+ try {
4165
+ const { entryCount, failed } = await downloadFolderZip(selectedDrive, folderNode);
4166
+ toast?.(failed.length ? `Downloaded ${entryCount} files (${failed.length} failed)` : `Downloaded ${entryCount} files`);
4167
+ } catch (error) {
4168
+ toast?.(`Failed to download "${name}": ${error.message}`);
4169
+ }
4170
+ };
4171
+ }
4032
4172
  /** An editor is a drive "app" if it targets any supported drive document type. */
4033
4173
  function isDriveEditor(module) {
4034
4174
  const driveTypes = DRIVE_DOCUMENT_TYPES;
@@ -4251,8 +4391,134 @@ function getDocumentGraphqlQuery() {
4251
4391
  if (!loc) throw new Error("GetDocumentWithOperationsDocument is misconfigured, loc is missing.");
4252
4392
  return loc.source.body;
4253
4393
  }
4254
- function buildDocumentSubgraphQuery(identifier, authToken) {
4255
- const query = getDocumentGraphqlQuery();
4394
+ /**
4395
+ * The base URL of the switchboard that serves a drive's GraphQL channel.
4396
+ *
4397
+ * The channel URL is `<origin>[<proxy-prefix>]/graphql/r`, so stripping the
4398
+ * suffix preserves any proxy prefix (e.g. `/api/reactor`). A URL that does
4399
+ * not end with the suffix is unexpected — fall back to its origin.
4400
+ */
4401
+ function getSwitchboardBaseFromChannelUrl(channelUrl) {
4402
+ if (channelUrl.endsWith("/graphql/r")) return channelUrl.slice(0, -10);
4403
+ return new URL(channelUrl).origin;
4404
+ }
4405
+ /**
4406
+ * The GraphQL name the switchboard exposes a document model under. Mirrors
4407
+ * `getDocumentModelSchemaName` on the server (`create-schema.ts`): the root
4408
+ * query field and the state type names are all derived from the model's
4409
+ * `global.name`.
4410
+ */
4411
+ function getDocumentModelSchemaName(model) {
4412
+ return pascalCase(model.documentModel.global.name.replaceAll("/", " "));
4413
+ }
4414
+ function buildStateTypeMap(definitions) {
4415
+ const typeMap = /* @__PURE__ */ new Map();
4416
+ for (const def of definitions) if (def.kind === import_graphql.Kind.OBJECT_TYPE_DEFINITION) typeMap.set(def.name.value, def);
4417
+ return typeMap;
4418
+ }
4419
+ /**
4420
+ * Recursively expands the fields of a state object type into a GraphQL
4421
+ * selection. Objects expand their sub-selection (lists expand their item
4422
+ * type); enums, scalars, and built-ins are leaves.
4423
+ */
4424
+ function expandStateFields(typeDef, typeMap) {
4425
+ return (typeDef.fields ?? []).map((field) => {
4426
+ const fieldName = field.name.value;
4427
+ let typeNode = field.type;
4428
+ if (typeNode.kind === import_graphql.Kind.NON_NULL_TYPE) typeNode = typeNode.type;
4429
+ if (typeNode.kind === import_graphql.Kind.LIST_TYPE) {
4430
+ let itemType = typeNode.type;
4431
+ if (itemType.kind === import_graphql.Kind.NON_NULL_TYPE) itemType = itemType.type;
4432
+ if (itemType.kind === import_graphql.Kind.LIST_TYPE) throw new Error(`Nested lists are not supported in state selections: ${fieldName}`);
4433
+ if (itemType.kind !== import_graphql.Kind.NAMED_TYPE) return fieldName;
4434
+ const itemTypeDef = typeMap.get(itemType.name.value);
4435
+ if (!itemTypeDef) return fieldName;
4436
+ return `${fieldName} { ${expandStateFields(itemTypeDef, typeMap)} }`;
4437
+ }
4438
+ if (typeNode.kind !== import_graphql.Kind.NAMED_TYPE) return fieldName;
4439
+ const typeDef = typeMap.get(typeNode.name.value);
4440
+ if (!typeDef) return fieldName;
4441
+ return `${fieldName} { ${expandStateFields(typeDef, typeMap)} }`;
4442
+ }).join(" ");
4443
+ }
4444
+ /**
4445
+ * Finds the root state object type in a state SDL. Root state types follow
4446
+ * the `<Name>State` / `<Name>GlobalState` conventions, and are defined last
4447
+ * by convention — the same resolution order the server uses
4448
+ * (`extractRootTypeName` in `create-schema.ts`).
4449
+ */
4450
+ function findRootStateType(definitions, candidates) {
4451
+ let lastObjectType = null;
4452
+ for (const def of definitions) {
4453
+ if (def.kind !== import_graphql.Kind.OBJECT_TYPE_DEFINITION) continue;
4454
+ if (candidates.includes(def.name.value)) return def;
4455
+ lastObjectType = def;
4456
+ }
4457
+ if (!lastObjectType) throw new Error("No root state type found in the document model schema");
4458
+ return lastObjectType;
4459
+ }
4460
+ /**
4461
+ * Derives the subselection for the document's `global` state scope from the
4462
+ * model's state SDL (e.g. `name total`), expanding object fields
4463
+ * recursively. Throws when the schema is missing, unparseable, or has no
4464
+ * root object type — the caller falls back to the generic document query.
4465
+ */
4466
+ function getDocumentStateSelection(model) {
4467
+ const schema = model.documentModel.global.specifications.at(-1)?.state.global.schema;
4468
+ if (!schema || !schema.trim()) throw new Error("Document model has no global state schema");
4469
+ const ast = (0, import_graphql.parse)(schema);
4470
+ const typeMap = buildStateTypeMap(ast.definitions);
4471
+ const documentName = getDocumentModelSchemaName(model);
4472
+ return expandStateFields(findRootStateType(ast.definitions, [`${documentName}State`, `${documentName}GlobalState`]), typeMap);
4473
+ }
4474
+ function getLocalStateSelection(localSchema, documentName) {
4475
+ const ast = (0, import_graphql.parse)(localSchema);
4476
+ const typeMap = buildStateTypeMap(ast.definitions);
4477
+ return expandStateFields(findRootStateType(ast.definitions, [`${documentName}LocalState`]), typeMap);
4478
+ }
4479
+ /**
4480
+ * Builds a query scoped to a document type's own subgraph root field,
4481
+ * selecting the document and its full typed state. The shape mirrors what
4482
+ * the switchboard generates per model (`generateNewApiSchema` in
4483
+ * `create-schema.ts`): `<Name> { document(identifier:) { document { ...
4484
+ * state { auth document global local } } } childIds }`.
4485
+ */
4486
+ function buildModelScopedQuery(model) {
4487
+ const globalState = model.documentModel.global;
4488
+ const documentName = getDocumentModelSchemaName(model);
4489
+ const globalSelection = getDocumentStateSelection(model);
4490
+ const localSchema = globalState.specifications.at(-1)?.state.local.schema ?? "";
4491
+ const localSelection = localSchema.includes(`type ${documentName}LocalState`) ? getLocalStateSelection(localSchema, documentName) : null;
4492
+ return [
4493
+ "query GetDocument($identifier: String!) {",
4494
+ ` ${documentName} {`,
4495
+ " document(identifier: $identifier) {",
4496
+ " document {",
4497
+ " id",
4498
+ " name",
4499
+ " documentType",
4500
+ " state {",
4501
+ " auth",
4502
+ " document { version hash { algorithm encoding } isDeleted deletedAtUtcIso deletedBy deletionReason }",
4503
+ ` global { ${globalSelection} }`,
4504
+ ` ${localSelection ? `local { ${localSelection} }` : "local"}`,
4505
+ " }",
4506
+ " }",
4507
+ " childIds",
4508
+ " }",
4509
+ " }",
4510
+ "}"
4511
+ ].join("\n");
4512
+ }
4513
+ function buildDocumentSubgraphQuery(documentType, identifier, model, authToken) {
4514
+ let query;
4515
+ if (model && model.documentModel.global.id === documentType) try {
4516
+ query = buildModelScopedQuery(model);
4517
+ } catch (error) {
4518
+ console.warn("Could not derive a document-scoped query from the document model, falling back to the generic document query:", error);
4519
+ query = getDocumentGraphqlQuery();
4520
+ }
4521
+ else query = getDocumentGraphqlQuery();
4256
4522
  const variables = { identifier };
4257
4523
  const headers = authToken ? { Authorization: `Bearer ${authToken}` } : void 0;
4258
4524
  const payload = {
@@ -4260,10 +4526,11 @@ function buildDocumentSubgraphQuery(identifier, authToken) {
4260
4526
  variables: JSON.stringify(variables, null, 2)
4261
4527
  };
4262
4528
  if (headers) payload.headers = JSON.stringify(headers);
4263
- return import_lz_string.compressToEncodedURIComponent(JSON.stringify(payload));
4529
+ return import_lz_string.default.compressToEncodedURIComponent(JSON.stringify(payload));
4264
4530
  }
4265
- function buildDocumentSubgraphUrl(driveUrl, identifier, authToken) {
4266
- return `${driveUrl}?explorerURLState=${buildDocumentSubgraphQuery(identifier, authToken)}`;
4531
+ function buildDocumentSubgraphUrl(channelUrl, documentType, identifier, model, authToken) {
4532
+ const encodedQuery = buildDocumentSubgraphQuery(documentType, identifier, model, authToken);
4533
+ return `${getSwitchboardBaseFromChannelUrl(channelUrl)}/explorer?explorerURLState=${encodedQuery}`;
4267
4534
  }
4268
4535
  /**
4269
4536
  * Hook that returns a function to generate a document's switchboard URL.
@@ -4279,6 +4546,7 @@ function buildDocumentSubgraphUrl(driveUrl, identifier, authToken) {
4279
4546
  function useGetSwitchboardLink(document) {
4280
4547
  const [drive] = useSelectedDriveSafe();
4281
4548
  const remotes = useSyncList();
4549
+ const documentModelModule = useDocumentModelModuleById(document?.header.documentType);
4282
4550
  const isRemoteDrive = useMemo(() => {
4283
4551
  if (!e$4(drive)) return false;
4284
4552
  return remotes.some((remote) => remote.meta.collectionId.equals(DriveCollectionId.forDrive(drive.header.id)));
@@ -4303,12 +4571,13 @@ function useGetSwitchboardLink(document) {
4303
4571
  expiresIn: 600,
4304
4572
  aud: remoteUrl
4305
4573
  }) : void 0;
4306
- return buildDocumentSubgraphUrl(remoteUrl, document.header.id, token);
4574
+ return buildDocumentSubgraphUrl(remoteUrl, document.header.documentType, document.header.id, documentModelModule, token);
4307
4575
  };
4308
4576
  }, [
4309
4577
  isRemoteDrive,
4310
4578
  remoteUrl,
4311
4579
  document,
4580
+ documentModelModule,
4312
4581
  user,
4313
4582
  renown
4314
4583
  ]);
@@ -4375,6 +4644,6 @@ function createDebouncedRefreshReactorDataClient(debounceDelayMs = DEFAULT_DEBOU
4375
4644
  createDebouncedRefreshReactorData();
4376
4645
  createDebouncedRefreshReactorDataClient();
4377
4646
  //#endregion
4378
- export { usePHToast as A, useSelectedDriveId as B, addFolder$1 as C, useDisabledEditors as D, showRevisionHistory as E, t$5 as F, useDocumentById as H, isFileNodeKind as I, isFolderNodeKind as L, e$1 as M, e$4 as N, useDragNode as O, t$2 as P, setSelectedDrive as R, addDocument as S, showPHModal as T, useSelectedDriveSafe as V, useSetPHDocumentEditorConfig as _, useDownloadDocument as a, useSelectedDocumentOfType as b, useGetSwitchboardLink as c, useNodeParentFolderById as d, useNodesInSelectedDriveOrFolder as f, useSetPHAppConfig as g, useSelectedNodePath as h, useDocumentVersionStatus as i, useStudioMode as j, useDropNode as k, useNodeActions as l, useSelectedFolder as m, preloadEditorModule as n, useEditorModules as o, useParentFolderForSelectedNode as p, useAllowedDocumentModelModules as r, useEditorModulesForDocumentType as s, getSyncStatusSync as t, useNodeById as u, useTheme as v, showDeleteNodeModal as w, useSelectedDocumentSafe as x, useUserPermissions as y, setSelectedNode as z };
4647
+ export { useDropNode as A, setSelectedNode as B, addDocument as C, showRevisionHistory as D, showPHModal as E, t$2 as F, useSelectedDriveSafe as H, t$5 as I, isFileNodeKind as L, useStudioMode as M, e$1 as N, useDisabledEditors as O, e$4 as P, isFolderNodeKind as R, useSelectedDocumentSafe as S, showDeleteNodeModal as T, useDocumentById as U, useSelectedDriveId as V, useSetPHAppConfig as _, useDownloadDocument as a, useUserPermissions as b, useEditorModulesForDocumentType as c, useNodeById as d, useNodeParentFolderById as f, useSelectedNodePath as g, useSelectedFolder as h, useDocumentVersionStatus as i, usePHToast as j, useDragNode as k, useGetSwitchboardLink as l, useParentFolderForSelectedNode as m, preloadEditorModule as n, useDownloadFolder as o, useNodesInSelectedDriveOrFolder as p, useAllowedDocumentModelModules as r, useEditorModules as s, getSyncStatusSync as t, useNodeActions as u, useSetPHDocumentEditorConfig as v, addFolder$1 as w, useSelectedDocumentOfType as x, useTheme as y, setSelectedDrive as z };
4379
4648
 
4380
- //# sourceMappingURL=dist-Bhd_mrZ1.mjs.map
4649
+ //# sourceMappingURL=dist-BAXIB1_k.mjs.map