@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.
- package/dist/browser/{connect-1nygQZWX.js → connect-DqkYyEcC.js} +14 -5
- package/dist/browser/{connect-1nygQZWX.js.map → connect-DqkYyEcC.js.map} +1 -1
- package/dist/browser/{dist-Bw_lDsJV.js → dist-C1pi89al.js} +283 -16
- package/dist/browser/dist-C1pi89al.js.map +1 -0
- package/dist/browser/{document-drive-BVYCdu_5.js → document-drive-ZQzPQfEL.js} +12 -5
- package/dist/browser/{document-drive-BVYCdu_5.js.map → document-drive-ZQzPQfEL.js.map} +1 -1
- package/dist/browser/document-models/index.js +1 -1
- package/dist/browser/{editor-CTCBSOqH.js → editor-Bl02Hko1.js} +6 -6
- package/dist/browser/{editor-CTCBSOqH.js.map → editor-Bl02Hko1.js.map} +1 -1
- package/dist/browser/{editor-2AtEs-xj.js → editor-CbtY05JH.js} +5 -5
- package/dist/browser/{editor-2AtEs-xj.js.map → editor-CbtY05JH.js.map} +1 -1
- package/dist/browser/editors/document-model-editor/module.js +1 -1
- package/dist/browser/editors/generic-drive-explorer/index.js +4 -4
- package/dist/browser/editors/generic-drive-explorer/module.js +1 -1
- package/dist/browser/{folder-view-CCyyB3dV.js → folder-view-BBm_YnKn.js} +3 -3
- package/dist/browser/{folder-view-CCyyB3dV.js.map → folder-view-BBm_YnKn.js.map} +1 -1
- package/dist/browser/{graphql-editor-BZKrpGCA.js → graphql-editor-LSj3LCtL.js} +3 -3
- package/dist/browser/{graphql-editor-BZKrpGCA.js.map → graphql-editor-LSj3LCtL.js.map} +1 -1
- package/dist/browser/index.js +1 -1
- package/dist/browser/{json-editor-NoPucS8U.js → json-editor-TVSHA4PZ.js} +3 -3
- package/dist/browser/{json-editor-NoPucS8U.js.map → json-editor-TVSHA4PZ.js.map} +1 -1
- package/dist/browser/lib-ewnRj2dJ.js.map +1 -1
- package/dist/browser/{state-schemas-C2mNqcqS.js → state-schemas-Bsryt22c.js} +3 -3
- package/dist/browser/{state-schemas-C2mNqcqS.js.map → state-schemas-Bsryt22c.js.map} +1 -1
- package/dist/node/{connect-BSP5dXkb.mjs → connect-B2yHg8VF.mjs} +14 -5
- package/dist/node/{connect-BSP5dXkb.mjs.map → connect-B2yHg8VF.mjs.map} +1 -1
- package/dist/node/{dist-Bhd_mrZ1.mjs → dist-BAXIB1_k.mjs} +285 -16
- package/dist/node/dist-BAXIB1_k.mjs.map +1 -0
- package/dist/node/{document-drive-lf_0SP-H.mjs → document-drive-D1NMjQQc.mjs} +12 -5
- package/dist/node/{document-drive-lf_0SP-H.mjs.map → document-drive-D1NMjQQc.mjs.map} +1 -1
- package/dist/node/document-models/index.mjs +1 -1
- package/dist/node/{editor-CYh6uL6E.mjs → editor--v67sph0.mjs} +6 -6
- package/dist/node/{editor-CYh6uL6E.mjs.map → editor--v67sph0.mjs.map} +1 -1
- package/dist/node/{editor-DHVhjQec.mjs → editor-BY22Tx5_.mjs} +5 -5
- package/dist/node/{editor-DHVhjQec.mjs.map → editor-BY22Tx5_.mjs.map} +1 -1
- package/dist/node/editors/document-model-editor/module.mjs +1 -1
- package/dist/node/editors/generic-drive-explorer/index.mjs +4 -4
- package/dist/node/editors/generic-drive-explorer/module.mjs +1 -1
- package/dist/node/{folder-view-ixx50l3H.mjs → folder-view-D_99HJFI.mjs} +3 -3
- package/dist/node/{folder-view-ixx50l3H.mjs.map → folder-view-D_99HJFI.mjs.map} +1 -1
- package/dist/node/{graphql-editor-CqMkJcop.mjs → graphql-editor-Bzs-PolA.mjs} +3 -3
- package/dist/node/{graphql-editor-CqMkJcop.mjs.map → graphql-editor-Bzs-PolA.mjs.map} +1 -1
- package/dist/node/index.mjs +1 -1
- package/dist/node/{json-editor-D4NRHMbo.mjs → json-editor-CCsBXZ6y.mjs} +3 -3
- package/dist/node/{json-editor-D4NRHMbo.mjs.map → json-editor-CCsBXZ6y.mjs.map} +1 -1
- package/dist/node/main-B1tRsYOp.mjs.map +1 -1
- package/dist/node/{state-schemas-CbidCieI.mjs → state-schemas-DxJBYOC0.mjs} +3 -3
- package/dist/node/{state-schemas-CbidCieI.mjs.map → state-schemas-DxJBYOC0.mjs.map} +1 -1
- package/package.json +7 -7
- package/dist/browser/dist-Bw_lDsJV.js.map +0 -1
- 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 {
|
|
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-
|
|
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
|
-
|
|
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) :
|
|
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
|
-
|
|
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-
|
|
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/
|
|
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
|
-
|
|
4255
|
-
|
|
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(
|
|
4266
|
-
|
|
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 {
|
|
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-
|
|
4649
|
+
//# sourceMappingURL=dist-BAXIB1_k.mjs.map
|