@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,7 +1,7 @@
|
|
|
1
|
-
import { A as __toESM, D as __commonJSMin, t as capitalCase } from "./dist-B4FWbuEM.js";
|
|
2
|
-
import {
|
|
1
|
+
import { A as __toESM, D as __commonJSMin, r as pascalCase, t as capitalCase } from "./dist-B4FWbuEM.js";
|
|
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-ZQzPQfEL.js";
|
|
3
3
|
import { a as SyncStatus, o as DriveCollectionId, s as ModuleNotFoundError, t as gql } from "./lib-ewnRj2dJ.js";
|
|
4
|
-
import "./parser-CkF6Qt8V.js";
|
|
4
|
+
import { c as Kind, t as parse } from "./parser-CkF6Qt8V.js";
|
|
5
5
|
import "./printer-CEYr4JOg.js";
|
|
6
6
|
import { createContext, use, useCallback, useContext, useEffect, useMemo, useState, useSyncExternalStore } from "react";
|
|
7
7
|
import "react/jsx-runtime";
|
|
@@ -1029,7 +1029,7 @@ slug.setLocale = function(locale) {
|
|
|
1029
1029
|
defaultLocale = locales[locale] || {};
|
|
1030
1030
|
};
|
|
1031
1031
|
//#endregion
|
|
1032
|
-
//#region ../reactor-browser/dist/document-model-modules-
|
|
1032
|
+
//#region ../reactor-browser/dist/document-model-modules-DfQBNGc-.js
|
|
1033
1033
|
var UnsupportedDocumentTypeError = class extends Error {
|
|
1034
1034
|
constructor(documentType) {
|
|
1035
1035
|
super(`Document type ${documentType} is not supported`);
|
|
@@ -1249,10 +1249,18 @@ function useSelectedNode() {
|
|
|
1249
1249
|
}
|
|
1250
1250
|
const vetraPackageManagerFunctions = makePHEventFunctions("vetraPackageManager");
|
|
1251
1251
|
const useVetraPackageManager = vetraPackageManagerFunctions.useValue;
|
|
1252
|
-
|
|
1252
|
+
const EMPTY_VETRA_PACKAGES = [];
|
|
1253
|
+
const noPackageManagerUnsubscribe = () => {};
|
|
1254
|
+
/**
|
|
1255
|
+
* Returns all of the Vetra packages loaded by the Connect instance.
|
|
1256
|
+
*
|
|
1257
|
+
* The snapshot and subscription must keep stable identity while no package
|
|
1258
|
+
* manager is registered: `useSyncExternalStore` loops when the snapshot
|
|
1259
|
+
* changes on every read, which a fresh `[]` does.
|
|
1260
|
+
*/
|
|
1253
1261
|
const useVetraPackages = () => {
|
|
1254
1262
|
const packageManager = useVetraPackageManager();
|
|
1255
|
-
return useSyncExternalStore((cb) => packageManager ? packageManager.subscribe(cb) :
|
|
1263
|
+
return useSyncExternalStore((cb) => packageManager ? packageManager.subscribe(cb) : noPackageManagerUnsubscribe, () => packageManager?.packages ?? EMPTY_VETRA_PACKAGES);
|
|
1256
1264
|
};
|
|
1257
1265
|
vetraPackageManagerFunctions.addEventHandler;
|
|
1258
1266
|
function useDocumentModelModules() {
|
|
@@ -2057,7 +2065,7 @@ var MessageType = /* @__PURE__ */ ((MessageType2) => {
|
|
|
2057
2065
|
})(MessageType || {});
|
|
2058
2066
|
Error;
|
|
2059
2067
|
//#endregion
|
|
2060
|
-
//#region ../reactor-browser/dist/document-operations-
|
|
2068
|
+
//#region ../reactor-browser/dist/document-operations-CBExT76y.js
|
|
2061
2069
|
const modalEventFunctions = makePHEventFunctions("modal");
|
|
2062
2070
|
modalEventFunctions.useValue;
|
|
2063
2071
|
/** Sets the current modal */
|
|
@@ -3131,7 +3139,7 @@ const usePHToast = toastEventFunctions.useValue;
|
|
|
3131
3139
|
toastEventFunctions.setValue;
|
|
3132
3140
|
toastEventFunctions.addEventHandler;
|
|
3133
3141
|
//#endregion
|
|
3134
|
-
//#region ../reactor-browser/dist/
|
|
3142
|
+
//#region ../reactor-browser/dist/switchboard-D4-_jwk-.js
|
|
3135
3143
|
/** Returns a document of a specific type, throws an error if the found document has a different type */
|
|
3136
3144
|
function useDocumentOfType(documentId, documentType) {
|
|
3137
3145
|
const [document, dispatch] = useDocumentById(documentId);
|
|
@@ -3846,6 +3854,117 @@ var import_lz_string = /* @__PURE__ */ __toESM((/* @__PURE__ */ __commonJSMin(((
|
|
|
3846
3854
|
return LZString;
|
|
3847
3855
|
});
|
|
3848
3856
|
})))(), 1);
|
|
3857
|
+
const sanitize = (segment) => segment.replace(/\//g, "-");
|
|
3858
|
+
/**
|
|
3859
|
+
* Name segments from the exported folder (exclusive) down to `node`
|
|
3860
|
+
* (inclusive), in top-down order. `root === undefined` means the drive root:
|
|
3861
|
+
* all ancestors. A node that IS the exported folder yields no segments.
|
|
3862
|
+
*/
|
|
3863
|
+
function segmentsBelow(root, node, allNodes) {
|
|
3864
|
+
const segments = [];
|
|
3865
|
+
let current = node;
|
|
3866
|
+
while (current && current.id !== root?.id) {
|
|
3867
|
+
segments.push(sanitize(current.name));
|
|
3868
|
+
const parentId = current.parentFolder;
|
|
3869
|
+
current = parentId ? allNodes.find((n) => n.id === parentId) : void 0;
|
|
3870
|
+
}
|
|
3871
|
+
return segments.reverse();
|
|
3872
|
+
}
|
|
3873
|
+
/**
|
|
3874
|
+
* Assemble the archive zip for a folder (or the whole drive when
|
|
3875
|
+
* `folderNode` is undefined). Every folder in the subtree becomes a
|
|
3876
|
+
* directory entry (empty folders survive); every file becomes a standard
|
|
3877
|
+
* single-document zip named after the node (drive naming convention:
|
|
3878
|
+
* `${name}.${extension}.phd`, ` (copy) N` on a same-folder collision).
|
|
3879
|
+
*
|
|
3880
|
+
* `fetchDocument` must return the document WITH its full operations and
|
|
3881
|
+
* initialState (see downloadFolderZip).
|
|
3882
|
+
*/
|
|
3883
|
+
async function buildFolderZip(drive, folderNode, fetchDocument, onProgress) {
|
|
3884
|
+
const allNodes = drive.state.global.nodes;
|
|
3885
|
+
const topName = sanitize(folderNode?.name ?? (drive.state.global.name || drive.header.name));
|
|
3886
|
+
const subtree = folderNode ? [folderNode, ...getDescendants(folderNode, allNodes)] : allNodes;
|
|
3887
|
+
const entries = { [topName + "/"]: new Uint8Array(0) };
|
|
3888
|
+
for (const node of subtree) {
|
|
3889
|
+
if (!isFolderNode(node)) continue;
|
|
3890
|
+
const dir = [topName, ...segmentsBelow(folderNode, node, allNodes)].join("/");
|
|
3891
|
+
entries[dir + "/"] = new Uint8Array(0);
|
|
3892
|
+
}
|
|
3893
|
+
const files = subtree.filter(isFileNode);
|
|
3894
|
+
const failed = [];
|
|
3895
|
+
const usedNamesByDir = /* @__PURE__ */ new Map();
|
|
3896
|
+
let done = 0;
|
|
3897
|
+
for (const node of files) try {
|
|
3898
|
+
const doc = await fetchDocument(node.id);
|
|
3899
|
+
const extension = await getDocumentExtension(doc);
|
|
3900
|
+
const parent = node.parentFolder ? allNodes.find((n) => n.id === node.parentFolder) : void 0;
|
|
3901
|
+
const dir = [topName, ...parent ? segmentsBelow(folderNode, parent, allNodes) : []].join("/");
|
|
3902
|
+
let usedNames = usedNamesByDir.get(dir);
|
|
3903
|
+
if (!usedNames) {
|
|
3904
|
+
usedNames = /* @__PURE__ */ new Set();
|
|
3905
|
+
usedNamesByDir.set(dir, usedNames);
|
|
3906
|
+
}
|
|
3907
|
+
const base = sanitize(node.name);
|
|
3908
|
+
let candidate = base;
|
|
3909
|
+
let count = getNextCopyNumber([...usedNames], base);
|
|
3910
|
+
while (usedNames.has(candidate)) {
|
|
3911
|
+
candidate = `${base} (copy) ${count}`;
|
|
3912
|
+
count += 1;
|
|
3913
|
+
}
|
|
3914
|
+
usedNames.add(candidate);
|
|
3915
|
+
const leaf = extension ? `${candidate}.${extension}.phd` : `${candidate}.phd`;
|
|
3916
|
+
entries[`${dir}/${leaf}`] = await createZip(doc);
|
|
3917
|
+
} catch {
|
|
3918
|
+
failed.push(node.name);
|
|
3919
|
+
} finally {
|
|
3920
|
+
done += 1;
|
|
3921
|
+
onProgress?.(done, files.length);
|
|
3922
|
+
}
|
|
3923
|
+
return {
|
|
3924
|
+
zip: await zipEntries(entries),
|
|
3925
|
+
archiveName: `${topName}.zip`,
|
|
3926
|
+
entryCount: files.length - failed.length,
|
|
3927
|
+
failed
|
|
3928
|
+
};
|
|
3929
|
+
}
|
|
3930
|
+
/**
|
|
3931
|
+
* Export a folder (or whole drive) to disk: fetches every document with its
|
|
3932
|
+
* full operation history, builds the archive, and saves it via
|
|
3933
|
+
* showSaveFilePicker (fallback: blob download), mirroring exportFile.
|
|
3934
|
+
*/
|
|
3935
|
+
async function downloadFolderZip(drive, folderNode, onProgress) {
|
|
3936
|
+
const reactorClient = window.ph?.reactorClient;
|
|
3937
|
+
if (!reactorClient) throw new Error("ReactorClient not initialized");
|
|
3938
|
+
const result = await buildFolderZip(drive, folderNode, async (id) => {
|
|
3939
|
+
const doc = await reactorClient.get(id);
|
|
3940
|
+
const operations = await fetchDocumentOperations(reactorClient, doc);
|
|
3941
|
+
const initialState = extractInitialState(operations["document"] ?? []);
|
|
3942
|
+
return {
|
|
3943
|
+
...doc,
|
|
3944
|
+
operations,
|
|
3945
|
+
initialState
|
|
3946
|
+
};
|
|
3947
|
+
}, onProgress);
|
|
3948
|
+
if (!window.showSaveFilePicker) {
|
|
3949
|
+
const blob = new Blob([new Uint8Array(result.zip)], { type: "application/zip" });
|
|
3950
|
+
const link = window.document.createElement("a");
|
|
3951
|
+
link.style.display = "none";
|
|
3952
|
+
link.href = URL.createObjectURL(blob);
|
|
3953
|
+
link.download = result.archiveName;
|
|
3954
|
+
window.document.body.appendChild(link);
|
|
3955
|
+
link.click();
|
|
3956
|
+
window.document.body.removeChild(link);
|
|
3957
|
+
return result;
|
|
3958
|
+
}
|
|
3959
|
+
try {
|
|
3960
|
+
const writable = await (await window.showSaveFilePicker({ suggestedName: result.archiveName })).createWritable();
|
|
3961
|
+
await writable.write(new Uint8Array(result.zip));
|
|
3962
|
+
await writable.close();
|
|
3963
|
+
} catch (e) {
|
|
3964
|
+
if (!(e instanceof DOMException && e.name === "AbortError")) throw e;
|
|
3965
|
+
}
|
|
3966
|
+
return result;
|
|
3967
|
+
}
|
|
3849
3968
|
/** Document types that represent a "drive": a container of nodes. */
|
|
3850
3969
|
const DRIVE_DOCUMENT_TYPES = ["powerhouse/document-drive", "powerhouse/reactor-drive"];
|
|
3851
3970
|
function useAllowedDocumentModelModules() {
|
|
@@ -4023,6 +4142,25 @@ function useDownloadDocument(id) {
|
|
|
4023
4142
|
}
|
|
4024
4143
|
};
|
|
4025
4144
|
}
|
|
4145
|
+
/**
|
|
4146
|
+
* Downloads the selected drive's folder (or the whole drive when no folder
|
|
4147
|
+
* is given) as a single zip archive mirroring the folder tree.
|
|
4148
|
+
*/
|
|
4149
|
+
function useDownloadFolder(folderNode) {
|
|
4150
|
+
const [selectedDrive] = useSelectedDriveSafe();
|
|
4151
|
+
const toast = usePHToast();
|
|
4152
|
+
return async () => {
|
|
4153
|
+
if (!selectedDrive) return;
|
|
4154
|
+
const name = folderNode?.name ?? selectedDrive.header.name;
|
|
4155
|
+
toast?.(`Downloading "${name}"…`);
|
|
4156
|
+
try {
|
|
4157
|
+
const { entryCount, failed } = await downloadFolderZip(selectedDrive, folderNode);
|
|
4158
|
+
toast?.(failed.length ? `Downloaded ${entryCount} files (${failed.length} failed)` : `Downloaded ${entryCount} files`);
|
|
4159
|
+
} catch (error) {
|
|
4160
|
+
toast?.(`Failed to download "${name}": ${error.message}`);
|
|
4161
|
+
}
|
|
4162
|
+
};
|
|
4163
|
+
}
|
|
4026
4164
|
/** An editor is a drive "app" if it targets any supported drive document type. */
|
|
4027
4165
|
function isDriveEditor(module) {
|
|
4028
4166
|
const driveTypes = DRIVE_DOCUMENT_TYPES;
|
|
@@ -4245,8 +4383,134 @@ function getDocumentGraphqlQuery() {
|
|
|
4245
4383
|
if (!loc) throw new Error("GetDocumentWithOperationsDocument is misconfigured, loc is missing.");
|
|
4246
4384
|
return loc.source.body;
|
|
4247
4385
|
}
|
|
4248
|
-
|
|
4249
|
-
|
|
4386
|
+
/**
|
|
4387
|
+
* The base URL of the switchboard that serves a drive's GraphQL channel.
|
|
4388
|
+
*
|
|
4389
|
+
* The channel URL is `<origin>[<proxy-prefix>]/graphql/r`, so stripping the
|
|
4390
|
+
* suffix preserves any proxy prefix (e.g. `/api/reactor`). A URL that does
|
|
4391
|
+
* not end with the suffix is unexpected — fall back to its origin.
|
|
4392
|
+
*/
|
|
4393
|
+
function getSwitchboardBaseFromChannelUrl(channelUrl) {
|
|
4394
|
+
if (channelUrl.endsWith("/graphql/r")) return channelUrl.slice(0, -10);
|
|
4395
|
+
return new URL(channelUrl).origin;
|
|
4396
|
+
}
|
|
4397
|
+
/**
|
|
4398
|
+
* The GraphQL name the switchboard exposes a document model under. Mirrors
|
|
4399
|
+
* `getDocumentModelSchemaName` on the server (`create-schema.ts`): the root
|
|
4400
|
+
* query field and the state type names are all derived from the model's
|
|
4401
|
+
* `global.name`.
|
|
4402
|
+
*/
|
|
4403
|
+
function getDocumentModelSchemaName(model) {
|
|
4404
|
+
return pascalCase(model.documentModel.global.name.replaceAll("/", " "));
|
|
4405
|
+
}
|
|
4406
|
+
function buildStateTypeMap(definitions) {
|
|
4407
|
+
const typeMap = /* @__PURE__ */ new Map();
|
|
4408
|
+
for (const def of definitions) if (def.kind === Kind.OBJECT_TYPE_DEFINITION) typeMap.set(def.name.value, def);
|
|
4409
|
+
return typeMap;
|
|
4410
|
+
}
|
|
4411
|
+
/**
|
|
4412
|
+
* Recursively expands the fields of a state object type into a GraphQL
|
|
4413
|
+
* selection. Objects expand their sub-selection (lists expand their item
|
|
4414
|
+
* type); enums, scalars, and built-ins are leaves.
|
|
4415
|
+
*/
|
|
4416
|
+
function expandStateFields(typeDef, typeMap) {
|
|
4417
|
+
return (typeDef.fields ?? []).map((field) => {
|
|
4418
|
+
const fieldName = field.name.value;
|
|
4419
|
+
let typeNode = field.type;
|
|
4420
|
+
if (typeNode.kind === Kind.NON_NULL_TYPE) typeNode = typeNode.type;
|
|
4421
|
+
if (typeNode.kind === Kind.LIST_TYPE) {
|
|
4422
|
+
let itemType = typeNode.type;
|
|
4423
|
+
if (itemType.kind === Kind.NON_NULL_TYPE) itemType = itemType.type;
|
|
4424
|
+
if (itemType.kind === Kind.LIST_TYPE) throw new Error(`Nested lists are not supported in state selections: ${fieldName}`);
|
|
4425
|
+
if (itemType.kind !== Kind.NAMED_TYPE) return fieldName;
|
|
4426
|
+
const itemTypeDef = typeMap.get(itemType.name.value);
|
|
4427
|
+
if (!itemTypeDef) return fieldName;
|
|
4428
|
+
return `${fieldName} { ${expandStateFields(itemTypeDef, typeMap)} }`;
|
|
4429
|
+
}
|
|
4430
|
+
if (typeNode.kind !== Kind.NAMED_TYPE) return fieldName;
|
|
4431
|
+
const typeDef = typeMap.get(typeNode.name.value);
|
|
4432
|
+
if (!typeDef) return fieldName;
|
|
4433
|
+
return `${fieldName} { ${expandStateFields(typeDef, typeMap)} }`;
|
|
4434
|
+
}).join(" ");
|
|
4435
|
+
}
|
|
4436
|
+
/**
|
|
4437
|
+
* Finds the root state object type in a state SDL. Root state types follow
|
|
4438
|
+
* the `<Name>State` / `<Name>GlobalState` conventions, and are defined last
|
|
4439
|
+
* by convention — the same resolution order the server uses
|
|
4440
|
+
* (`extractRootTypeName` in `create-schema.ts`).
|
|
4441
|
+
*/
|
|
4442
|
+
function findRootStateType(definitions, candidates) {
|
|
4443
|
+
let lastObjectType = null;
|
|
4444
|
+
for (const def of definitions) {
|
|
4445
|
+
if (def.kind !== Kind.OBJECT_TYPE_DEFINITION) continue;
|
|
4446
|
+
if (candidates.includes(def.name.value)) return def;
|
|
4447
|
+
lastObjectType = def;
|
|
4448
|
+
}
|
|
4449
|
+
if (!lastObjectType) throw new Error("No root state type found in the document model schema");
|
|
4450
|
+
return lastObjectType;
|
|
4451
|
+
}
|
|
4452
|
+
/**
|
|
4453
|
+
* Derives the subselection for the document's `global` state scope from the
|
|
4454
|
+
* model's state SDL (e.g. `name total`), expanding object fields
|
|
4455
|
+
* recursively. Throws when the schema is missing, unparseable, or has no
|
|
4456
|
+
* root object type — the caller falls back to the generic document query.
|
|
4457
|
+
*/
|
|
4458
|
+
function getDocumentStateSelection(model) {
|
|
4459
|
+
const schema = model.documentModel.global.specifications.at(-1)?.state.global.schema;
|
|
4460
|
+
if (!schema || !schema.trim()) throw new Error("Document model has no global state schema");
|
|
4461
|
+
const ast = parse(schema);
|
|
4462
|
+
const typeMap = buildStateTypeMap(ast.definitions);
|
|
4463
|
+
const documentName = getDocumentModelSchemaName(model);
|
|
4464
|
+
return expandStateFields(findRootStateType(ast.definitions, [`${documentName}State`, `${documentName}GlobalState`]), typeMap);
|
|
4465
|
+
}
|
|
4466
|
+
function getLocalStateSelection(localSchema, documentName) {
|
|
4467
|
+
const ast = parse(localSchema);
|
|
4468
|
+
const typeMap = buildStateTypeMap(ast.definitions);
|
|
4469
|
+
return expandStateFields(findRootStateType(ast.definitions, [`${documentName}LocalState`]), typeMap);
|
|
4470
|
+
}
|
|
4471
|
+
/**
|
|
4472
|
+
* Builds a query scoped to a document type's own subgraph root field,
|
|
4473
|
+
* selecting the document and its full typed state. The shape mirrors what
|
|
4474
|
+
* the switchboard generates per model (`generateNewApiSchema` in
|
|
4475
|
+
* `create-schema.ts`): `<Name> { document(identifier:) { document { ...
|
|
4476
|
+
* state { auth document global local } } } childIds }`.
|
|
4477
|
+
*/
|
|
4478
|
+
function buildModelScopedQuery(model) {
|
|
4479
|
+
const globalState = model.documentModel.global;
|
|
4480
|
+
const documentName = getDocumentModelSchemaName(model);
|
|
4481
|
+
const globalSelection = getDocumentStateSelection(model);
|
|
4482
|
+
const localSchema = globalState.specifications.at(-1)?.state.local.schema ?? "";
|
|
4483
|
+
const localSelection = localSchema.includes(`type ${documentName}LocalState`) ? getLocalStateSelection(localSchema, documentName) : null;
|
|
4484
|
+
return [
|
|
4485
|
+
"query GetDocument($identifier: String!) {",
|
|
4486
|
+
` ${documentName} {`,
|
|
4487
|
+
" document(identifier: $identifier) {",
|
|
4488
|
+
" document {",
|
|
4489
|
+
" id",
|
|
4490
|
+
" name",
|
|
4491
|
+
" documentType",
|
|
4492
|
+
" state {",
|
|
4493
|
+
" auth",
|
|
4494
|
+
" document { version hash { algorithm encoding } isDeleted deletedAtUtcIso deletedBy deletionReason }",
|
|
4495
|
+
` global { ${globalSelection} }`,
|
|
4496
|
+
` ${localSelection ? `local { ${localSelection} }` : "local"}`,
|
|
4497
|
+
" }",
|
|
4498
|
+
" }",
|
|
4499
|
+
" childIds",
|
|
4500
|
+
" }",
|
|
4501
|
+
" }",
|
|
4502
|
+
"}"
|
|
4503
|
+
].join("\n");
|
|
4504
|
+
}
|
|
4505
|
+
function buildDocumentSubgraphQuery(documentType, identifier, model, authToken) {
|
|
4506
|
+
let query;
|
|
4507
|
+
if (model && model.documentModel.global.id === documentType) try {
|
|
4508
|
+
query = buildModelScopedQuery(model);
|
|
4509
|
+
} catch (error) {
|
|
4510
|
+
console.warn("Could not derive a document-scoped query from the document model, falling back to the generic document query:", error);
|
|
4511
|
+
query = getDocumentGraphqlQuery();
|
|
4512
|
+
}
|
|
4513
|
+
else query = getDocumentGraphqlQuery();
|
|
4250
4514
|
const variables = { identifier };
|
|
4251
4515
|
const headers = authToken ? { Authorization: `Bearer ${authToken}` } : void 0;
|
|
4252
4516
|
const payload = {
|
|
@@ -4254,10 +4518,11 @@ function buildDocumentSubgraphQuery(identifier, authToken) {
|
|
|
4254
4518
|
variables: JSON.stringify(variables, null, 2)
|
|
4255
4519
|
};
|
|
4256
4520
|
if (headers) payload.headers = JSON.stringify(headers);
|
|
4257
|
-
return import_lz_string.compressToEncodedURIComponent(JSON.stringify(payload));
|
|
4521
|
+
return import_lz_string.default.compressToEncodedURIComponent(JSON.stringify(payload));
|
|
4258
4522
|
}
|
|
4259
|
-
function buildDocumentSubgraphUrl(
|
|
4260
|
-
|
|
4523
|
+
function buildDocumentSubgraphUrl(channelUrl, documentType, identifier, model, authToken) {
|
|
4524
|
+
const encodedQuery = buildDocumentSubgraphQuery(documentType, identifier, model, authToken);
|
|
4525
|
+
return `${getSwitchboardBaseFromChannelUrl(channelUrl)}/explorer?explorerURLState=${encodedQuery}`;
|
|
4261
4526
|
}
|
|
4262
4527
|
/**
|
|
4263
4528
|
* Hook that returns a function to generate a document's switchboard URL.
|
|
@@ -4273,6 +4538,7 @@ function buildDocumentSubgraphUrl(driveUrl, identifier, authToken) {
|
|
|
4273
4538
|
function useGetSwitchboardLink(document) {
|
|
4274
4539
|
const [drive] = useSelectedDriveSafe();
|
|
4275
4540
|
const remotes = useSyncList();
|
|
4541
|
+
const documentModelModule = useDocumentModelModuleById(document?.header.documentType);
|
|
4276
4542
|
const isRemoteDrive = useMemo(() => {
|
|
4277
4543
|
if (!e$4(drive)) return false;
|
|
4278
4544
|
return remotes.some((remote) => remote.meta.collectionId.equals(DriveCollectionId.forDrive(drive.header.id)));
|
|
@@ -4297,12 +4563,13 @@ function useGetSwitchboardLink(document) {
|
|
|
4297
4563
|
expiresIn: 600,
|
|
4298
4564
|
aud: remoteUrl
|
|
4299
4565
|
}) : void 0;
|
|
4300
|
-
return buildDocumentSubgraphUrl(remoteUrl, document.header.id, token);
|
|
4566
|
+
return buildDocumentSubgraphUrl(remoteUrl, document.header.documentType, document.header.id, documentModelModule, token);
|
|
4301
4567
|
};
|
|
4302
4568
|
}, [
|
|
4303
4569
|
isRemoteDrive,
|
|
4304
4570
|
remoteUrl,
|
|
4305
4571
|
document,
|
|
4572
|
+
documentModelModule,
|
|
4306
4573
|
user,
|
|
4307
4574
|
renown
|
|
4308
4575
|
]);
|
|
@@ -4369,6 +4636,6 @@ function createDebouncedRefreshReactorDataClient(debounceDelayMs = DEFAULT_DEBOU
|
|
|
4369
4636
|
createDebouncedRefreshReactorData();
|
|
4370
4637
|
createDebouncedRefreshReactorDataClient();
|
|
4371
4638
|
//#endregion
|
|
4372
|
-
export {
|
|
4639
|
+
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 };
|
|
4373
4640
|
|
|
4374
|
-
//# sourceMappingURL=dist-
|
|
4641
|
+
//# sourceMappingURL=dist-C1pi89al.js.map
|