@powerhousedao/reactor-browser 6.2.2-dev.52 → 6.2.2-dev.54
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/{attachment-service-BImio0aq.d.ts → attachment-service-DTFJRf5j.d.ts} +91 -16
- package/dist/attachment-service-DTFJRf5j.d.ts.map +1 -0
- package/dist/{client-s_ISz_Zs.js → client-DB8gP4hz.js} +50 -10
- package/dist/client-DB8gP4hz.js.map +1 -0
- package/dist/{client-BaHKLGy5.d.ts → client-DjkEpwu_.d.ts} +2 -2
- package/dist/{client-BaHKLGy5.d.ts.map → client-DjkEpwu_.d.ts.map} +1 -1
- package/dist/{document-operations-ZLuPOV3H.js → document-operations-C6nce9dH.js} +280 -130
- package/dist/document-operations-C6nce9dH.js.map +1 -0
- package/dist/{global-CbyAMlZd.d.ts → global-pg5gy2eZ.d.ts} +2 -2
- package/dist/{global-CbyAMlZd.d.ts.map → global-pg5gy2eZ.d.ts.map} +1 -1
- package/dist/{index-DPq1VjpB.d.ts → index-DjloxNSR.d.ts} +2 -2
- package/dist/{index-DPq1VjpB.d.ts.map → index-DjloxNSR.d.ts.map} +1 -1
- package/dist/index.d.ts +15 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -7
- package/dist/index.js.map +1 -1
- package/dist/src/graphql/client.d.ts +2 -2
- package/dist/src/graphql/client.js +1 -1
- package/dist/src/graphql-client/entry.d.ts +4 -4
- package/dist/src/graphql-client/entry.js +2 -2
- package/dist/src/renown/index.d.ts +1 -1
- package/dist/src/rpc/index.d.ts +1 -0
- package/dist/src/rpc/index.d.ts.map +1 -1
- package/dist/src/rpc/index.js +4 -0
- package/dist/src/rpc/index.js.map +1 -1
- package/dist/{types-Bitg5Z5j.d.ts → types-4rfAFZQd.d.ts} +64 -8
- package/dist/types-4rfAFZQd.d.ts.map +1 -0
- package/package.json +9 -9
- package/dist/attachment-service-BImio0aq.d.ts.map +0 -1
- package/dist/client-s_ISz_Zs.js.map +0 -1
- package/dist/document-operations-ZLuPOV3H.js.map +0 -1
- package/dist/types-Bitg5Z5j.d.ts.map +0 -1
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { S as uploadOperations, _ as isDuplicateManifestError, a as setDocumentCache, b as queueActions, g as DOCUMENT_CHANGE_TYPE, i as addDocumentCacheEventHandler, n as useDocumentsByIds, p as DocumentCache, r as useDispatch, v as isDuplicateModuleError, x as queueOperations } from "./document-by-id-BSZqTN66.js";
|
|
2
2
|
import { t as makePHEventFunctions } from "./make-ph-event-functions-DBq3iWYn.js";
|
|
3
|
-
import { a as PhDocumentFieldsFragmentDoc, n as DocumentChangeType, o as PropagationMode, r as DocumentChangesDocument, t as createClient$1 } from "./client-
|
|
3
|
+
import { a as PhDocumentFieldsFragmentDoc, n as DocumentChangeType, o as PropagationMode, r as DocumentChangesDocument, t as createClient$1 } from "./client-DB8gP4hz.js";
|
|
4
4
|
import { f as addLoadingEventHandler, t as addRenownEventHandler } from "./renown-BZabzj4l.js";
|
|
5
5
|
import { logger } from "document-model";
|
|
6
|
-
import { UnsupportedDocumentModelVersionError, assertAuthPreservedOnDuplicate, baseLoadFromInput, baseLoadFromInputVersioned, baseSaveToFileHandle, createPresignedHeader, createZip, documentModelDocumentType, generateId, hashDocumentStateForScope, replayDocumentVersioned, setName } from "@powerhousedao/shared/document-model";
|
|
6
|
+
import { UnsupportedDocumentModelVersionError, assertAuthPreservedOnDuplicate, baseLoadFromInput, baseLoadFromInputVersioned, baseSaveToFileHandle, createPresignedHeader, createZip, deserializeSignature, documentModelDocumentType, generateId, hashDocumentStateForScope, normalizeDocumentModelVersion, replayDocumentVersioned, setName, toTransportAction } from "@powerhousedao/shared/document-model";
|
|
7
7
|
import { addFolder, copyNode, generateNodesCopy, handleTargetNameCollisions, isFileNode, isFolderNode, moveNode, updateNode } from "@powerhousedao/shared/document-drive";
|
|
8
8
|
import { allPass, conditional, constant, forEachObj, funnel, isDefined, isNot, isStrictEqual, isString, isTruthy, once } from "remeda";
|
|
9
9
|
import { useCallback, useEffect, useRef, useState, useSyncExternalStore } from "react";
|
|
@@ -723,20 +723,6 @@ function remoteOperationToLocal(remote) {
|
|
|
723
723
|
}
|
|
724
724
|
};
|
|
725
725
|
}
|
|
726
|
-
/**
|
|
727
|
-
* Deserialize a signature string back to a 5-element tuple.
|
|
728
|
-
* The server serializes tuples via `tuple.join(", ")`.
|
|
729
|
-
*/
|
|
730
|
-
function deserializeSignature(s) {
|
|
731
|
-
const parts = s.split(", ");
|
|
732
|
-
return [
|
|
733
|
-
parts[0] ?? "",
|
|
734
|
-
parts[1] ?? "",
|
|
735
|
-
parts[2] ?? "",
|
|
736
|
-
parts[3] ?? "",
|
|
737
|
-
parts[4] ?? ""
|
|
738
|
-
];
|
|
739
|
-
}
|
|
740
726
|
/** Convert remote operations to local DocumentOperations format. */
|
|
741
727
|
function convertRemoteOperations(operationsByScope) {
|
|
742
728
|
const operations = {};
|
|
@@ -942,23 +928,24 @@ const ReactorOperationFieldsFragmentDoc = gql`
|
|
|
942
928
|
* - `scopes` limits the response to the scopes the pushed actions target,
|
|
943
929
|
* without it the server walks every scope of the document
|
|
944
930
|
* (`packages/reactor/src/core/reactor.ts` `getOperations`);
|
|
945
|
-
* - `branch`
|
|
946
|
-
*
|
|
947
|
-
*
|
|
931
|
+
* - `branch` selects the branch the operations are read from, and is the same
|
|
932
|
+
* variable the mutation writes to. It used to be two - the write went through
|
|
933
|
+
* a `view`, the filter took its own `branch` - and they had to be kept equal
|
|
934
|
+
* by hand or the operations came from `main` while the actions were applied
|
|
935
|
+
* elsewhere. One variable cannot disagree with itself.
|
|
948
936
|
*/
|
|
949
937
|
const MutateDocumentWithOperationsDocument = gql`
|
|
950
938
|
mutation MutateDocumentWithOperations(
|
|
951
939
|
$documentIdentifier: String!
|
|
952
|
-
$actions: [
|
|
953
|
-
$view: ViewFilterInput
|
|
940
|
+
$actions: [ActionInput!]!
|
|
954
941
|
$sinceRevision: Int
|
|
955
942
|
$scopes: [String!]
|
|
956
943
|
$branch: String
|
|
957
944
|
) {
|
|
958
|
-
mutateDocument(
|
|
945
|
+
mutateDocument: execute(
|
|
959
946
|
documentIdentifier: $documentIdentifier
|
|
960
947
|
actions: $actions
|
|
961
|
-
|
|
948
|
+
branch: $branch
|
|
962
949
|
) {
|
|
963
950
|
...PHDocumentFields
|
|
964
951
|
operations(
|
|
@@ -988,9 +975,13 @@ const MutateDocumentWithOperationsDocument = gql`
|
|
|
988
975
|
* `prevOpIndex` is the index of that last operation: revisions count
|
|
989
976
|
* operations and indices are zero based, so an empty scope stamps `-1`, which
|
|
990
977
|
* matches what the remote controller records.
|
|
978
|
+
*
|
|
979
|
+
* `revision` overrides the scope revision the index is derived from. Only a
|
|
980
|
+
* batch needs it - {@link prepareSignedActions} stamps action N at the revision
|
|
981
|
+
* the N actions before it will have produced, which the document itself does
|
|
982
|
+
* not know yet. `prevOpHash` always comes from the supplied document's state.
|
|
991
983
|
*/
|
|
992
|
-
function stampAction(action, document) {
|
|
993
|
-
const revision = document.header.revision[action.scope] ?? 0;
|
|
984
|
+
function stampAction(action, document, revision = document.header.revision[action.scope] ?? 0) {
|
|
994
985
|
return {
|
|
995
986
|
...action,
|
|
996
987
|
context: {
|
|
@@ -1006,12 +997,12 @@ function stampAction(action, document) {
|
|
|
1006
997
|
* The signer reads `context.prevOpHash` off the action, so this must run after
|
|
1007
998
|
* {@link stampAction}.
|
|
1008
999
|
*/
|
|
1009
|
-
async function signStampedAction(action, signer) {
|
|
1000
|
+
async function signStampedAction(action, signer, signal) {
|
|
1010
1001
|
const actionSigner = action.context?.signer;
|
|
1011
1002
|
const user = actionSigner?.user ?? signer.user;
|
|
1012
1003
|
const app = actionSigner?.app ?? signer.app;
|
|
1013
1004
|
if (!user || !app) throw new Error("cannot sign an action: the signer has no user or app identity");
|
|
1014
|
-
const signature = await signer.signAction(action);
|
|
1005
|
+
const signature = await signer.signAction(action, signal);
|
|
1015
1006
|
return {
|
|
1016
1007
|
...action,
|
|
1017
1008
|
context: {
|
|
@@ -1024,6 +1015,229 @@ async function signStampedAction(action, signer) {
|
|
|
1024
1015
|
}
|
|
1025
1016
|
};
|
|
1026
1017
|
}
|
|
1018
|
+
/**
|
|
1019
|
+
* Actions a snapshot batch cannot predict the next state for.
|
|
1020
|
+
*
|
|
1021
|
+
* `UNDO`, `REDO` and `PRUNE` rewrite history the light read path never fetched
|
|
1022
|
+
* (and the reducer appends no operation for them); `NOOP` is only ever produced
|
|
1023
|
+
* by an undo chain; the document-scope actions run through the reactor's
|
|
1024
|
+
* document-action handler rather than a document-model reducer
|
|
1025
|
+
* (`DOCUMENT_SCOPE_ACTIONS` in packages/reactor/src/executor/util.ts) and
|
|
1026
|
+
* `UPGRADE_DOCUMENT` changes which reducer applies mid-batch.
|
|
1027
|
+
*/
|
|
1028
|
+
const unsupportedBatchActions = new Set([
|
|
1029
|
+
"UNDO",
|
|
1030
|
+
"REDO",
|
|
1031
|
+
"PRUNE",
|
|
1032
|
+
"NOOP",
|
|
1033
|
+
"CREATE_DOCUMENT",
|
|
1034
|
+
"DELETE_DOCUMENT",
|
|
1035
|
+
"UPGRADE_DOCUMENT",
|
|
1036
|
+
"ADD_RELATIONSHIP",
|
|
1037
|
+
"REMOVE_RELATIONSHIP",
|
|
1038
|
+
"UPDATE_RELATIONSHIP"
|
|
1039
|
+
]);
|
|
1040
|
+
/**
|
|
1041
|
+
* The base-reducer protocol version to predict with when the snapshot's header
|
|
1042
|
+
* carries none.
|
|
1043
|
+
*
|
|
1044
|
+
* `baseReducer` reads `baseReducerVersion(document.header)` for every action and
|
|
1045
|
+
* throws when the header has no `protocolVersions` - and a header built by
|
|
1046
|
+
* {@link phDocumentFromGetDocument} never has one, because the GraphQL
|
|
1047
|
+
* `PHDocument` type does not expose it. The version only selects between the v1
|
|
1048
|
+
* and v2 UNDO/NOOP branches, and every action reaching the prediction loop is an
|
|
1049
|
+
* ordinary append-only one, so it cannot change the predicted state here; it is
|
|
1050
|
+
* passed purely so the lookup does not throw.
|
|
1051
|
+
*/
|
|
1052
|
+
const predictionProtocolVersion = 2;
|
|
1053
|
+
/**
|
|
1054
|
+
* Stamps and signs a batch of actions against one document snapshot, so every
|
|
1055
|
+
* action carries the head its predecessor will leave behind.
|
|
1056
|
+
*
|
|
1057
|
+
* The server executes the array in order, each action against the state the one
|
|
1058
|
+
* before it produced. The snapshot the light client reads has correct state and
|
|
1059
|
+
* per-scope revisions but NO operation history (see `adapter.ts`), so the chain
|
|
1060
|
+
* is predicted here: reduce action N over the working document to get the state
|
|
1061
|
+
* action N+1 hashes, and carry a virtual revision alongside it. The revision has
|
|
1062
|
+
* to be tracked separately because the reducer derives operation indices from
|
|
1063
|
+
* the last stored operation, and with an empty history that counts from zero
|
|
1064
|
+
* rather than from the document's real revision.
|
|
1065
|
+
*
|
|
1066
|
+
* A single action needs no prediction and therefore no `module`, which keeps
|
|
1067
|
+
* today's callers working unchanged. Two or more require the document's exact
|
|
1068
|
+
* reducer, one shared scope (the reactor rejects mixed-scope jobs) and only
|
|
1069
|
+
* append-only actions. Anything else rejects: a batch that cannot be predicted
|
|
1070
|
+
* must fail before the mutation, never be downgraded to unsigned.
|
|
1071
|
+
*/
|
|
1072
|
+
async function prepareSignedActions(actions, snapshot, signer, module, signal) {
|
|
1073
|
+
if (actions.length === 0) return [];
|
|
1074
|
+
if (actions.length === 1) return [await signStampedAction(stampAction(actions[0], snapshot), signer, signal)];
|
|
1075
|
+
const scope = sharedScope(actions);
|
|
1076
|
+
assertSupportedBatch(actions);
|
|
1077
|
+
if (!module) throw new Error(`cannot sign ${actions.length} actions: no document model module for ${snapshot.header.documentType} was supplied, so the batch state cannot be predicted`);
|
|
1078
|
+
let working = {
|
|
1079
|
+
...snapshot,
|
|
1080
|
+
operations: {
|
|
1081
|
+
...snapshot.operations,
|
|
1082
|
+
[scope]: [...snapshot.operations[scope] ?? []]
|
|
1083
|
+
}
|
|
1084
|
+
};
|
|
1085
|
+
let revision = snapshot.header.revision[scope] ?? 0;
|
|
1086
|
+
const signed = [];
|
|
1087
|
+
for (const [index, action] of actions.entries()) {
|
|
1088
|
+
throwIfAborted(signal, index);
|
|
1089
|
+
const signedAction = await signStampedAction(stampAction(action, working, revision), signer, signal);
|
|
1090
|
+
signed.push(signedAction);
|
|
1091
|
+
const before = scopeOperationCount(working, scope);
|
|
1092
|
+
let next;
|
|
1093
|
+
try {
|
|
1094
|
+
next = module.reducer(working, signedAction, void 0, { protocolVersion: working.header.protocolVersions?.["base-reducer"] ?? predictionProtocolVersion });
|
|
1095
|
+
} catch (error) {
|
|
1096
|
+
throw new Error(`cannot sign action ${index} (${action.type}): the ${snapshot.header.documentType} reducer rejected it, so the rest of the batch cannot be predicted`, { cause: error });
|
|
1097
|
+
}
|
|
1098
|
+
const after = scopeOperationCount(next, scope);
|
|
1099
|
+
if (after !== before + 1) throw new Error(`cannot sign action ${index} (${action.type}): the reducer appended ${after - before} operations to ${scope}, expected exactly 1`);
|
|
1100
|
+
working = next;
|
|
1101
|
+
revision += 1;
|
|
1102
|
+
}
|
|
1103
|
+
return signed;
|
|
1104
|
+
}
|
|
1105
|
+
/**
|
|
1106
|
+
* How many operations a scope holds.
|
|
1107
|
+
*
|
|
1108
|
+
* The index signature types the array as always present, but a module's reducer
|
|
1109
|
+
* is arbitrary code: one that hands back a document without the scope should
|
|
1110
|
+
* produce the actionable error above, not a `TypeError` on `.length`.
|
|
1111
|
+
*/
|
|
1112
|
+
function scopeOperationCount(document, scope) {
|
|
1113
|
+
return document.operations[scope]?.length ?? 0;
|
|
1114
|
+
}
|
|
1115
|
+
/** The one scope a reactor job may span (`getSharedActionScope`). */
|
|
1116
|
+
function sharedScope(actions) {
|
|
1117
|
+
const scope = actions[0].scope;
|
|
1118
|
+
const mixed = actions.find((action) => action.scope !== scope);
|
|
1119
|
+
if (mixed) throw new Error(`cannot sign a batch spanning scopes "${scope}" and "${mixed.scope}": every action in one request must share a scope`);
|
|
1120
|
+
return scope;
|
|
1121
|
+
}
|
|
1122
|
+
function assertSupportedBatch(actions) {
|
|
1123
|
+
const unsupported = actions.find((action) => unsupportedBatchActions.has(action.type));
|
|
1124
|
+
if (unsupported) throw new Error(`cannot sign a batch containing ${unsupported.type}: it needs operation history or an alternate executor path, so send it as a single action`);
|
|
1125
|
+
}
|
|
1126
|
+
function throwIfAborted(signal, index) {
|
|
1127
|
+
if (signal?.aborted) throw new Error(`signing aborted before action ${index}`, { cause: signal.reason });
|
|
1128
|
+
}
|
|
1129
|
+
//#endregion
|
|
1130
|
+
//#region src/graphql-client/static-package-manager.ts
|
|
1131
|
+
/**
|
|
1132
|
+
* A fixed set of packages presented through the `IPackageManager` interface,
|
|
1133
|
+
* so the package-derived hooks - `useDocumentModelModules`,
|
|
1134
|
+
* `useDocumentModelModuleById`, `useEditorModules`, `useVetraPackages` - work
|
|
1135
|
+
* below `GraphQLReactorProvider` exactly as they do below Connect.
|
|
1136
|
+
*
|
|
1137
|
+
* Connect's package manager installs, updates and removes packages at runtime.
|
|
1138
|
+
* A light app instead declares its packages once, as code it imports itself
|
|
1139
|
+
* (every generated package root exports `manifest`, `documentModels`, `editors`
|
|
1140
|
+
* and `upgradeManifests` by name), so every mutating member throws and
|
|
1141
|
+
* `subscribe` never emits. For hand-picked modules without package artifacts,
|
|
1142
|
+
* {@link packageFromDocumentModels} wraps them in one synthetic package.
|
|
1143
|
+
*/
|
|
1144
|
+
var StaticPackageManager = class {
|
|
1145
|
+
registryUrl = null;
|
|
1146
|
+
packages;
|
|
1147
|
+
constructor(packages) {
|
|
1148
|
+
this.packages = [...packages];
|
|
1149
|
+
}
|
|
1150
|
+
/**
|
|
1151
|
+
* Resolves a module by document type across all packages. Mirrors the
|
|
1152
|
+
* registry's semantics (`IDocumentModelRegistry.getModule`): the LATEST
|
|
1153
|
+
* version wins, with `version ?? 1` as each module's default.
|
|
1154
|
+
*/
|
|
1155
|
+
load(documentType) {
|
|
1156
|
+
const modules = this.packages.flatMap((pkg) => pkg.documentModels);
|
|
1157
|
+
try {
|
|
1158
|
+
return Promise.resolve(resolveDocumentModelModule(modules, documentType));
|
|
1159
|
+
} catch (error) {
|
|
1160
|
+
return Promise.reject(error);
|
|
1161
|
+
}
|
|
1162
|
+
}
|
|
1163
|
+
subscribe(_handler) {
|
|
1164
|
+
return () => {};
|
|
1165
|
+
}
|
|
1166
|
+
getPackageSource(_packageName) {
|
|
1167
|
+
return null;
|
|
1168
|
+
}
|
|
1169
|
+
getPackageVersion(_packageName) {}
|
|
1170
|
+
getRegistryPackages() {
|
|
1171
|
+
return [];
|
|
1172
|
+
}
|
|
1173
|
+
addPackage(_packageName) {
|
|
1174
|
+
throw staticPackageManagerError("addPackage");
|
|
1175
|
+
}
|
|
1176
|
+
addPackages(_packageNames) {
|
|
1177
|
+
throw staticPackageManagerError("addPackages");
|
|
1178
|
+
}
|
|
1179
|
+
removePackage(_name) {
|
|
1180
|
+
throw staticPackageManagerError("removePackage");
|
|
1181
|
+
}
|
|
1182
|
+
updateLocalPackage(_pkg, _version) {
|
|
1183
|
+
throw staticPackageManagerError("updateLocalPackage");
|
|
1184
|
+
}
|
|
1185
|
+
addLocalPackage(_name, _loadedPackage, _version) {
|
|
1186
|
+
throw staticPackageManagerError("addLocalPackage");
|
|
1187
|
+
}
|
|
1188
|
+
};
|
|
1189
|
+
/**
|
|
1190
|
+
* Resolves one document-model module out of a flat module list, with the same
|
|
1191
|
+
* rule the reactor registry uses (`IDocumentModelRegistry.getModule`, at
|
|
1192
|
+
* packages/reactor/src/registry/implementation.ts): with a `version`, only an
|
|
1193
|
+
* EXACT `version ?? 1` match resolves; without one, the LATEST version wins.
|
|
1194
|
+
*
|
|
1195
|
+
* Signing an existing document needs the exact rule. A document carries the
|
|
1196
|
+
* model version it was written with in `state.document.version`, and its
|
|
1197
|
+
* reducer is the only one whose operations that document's history can accept -
|
|
1198
|
+
* so "latest" is correct only when no version is asked for.
|
|
1199
|
+
*
|
|
1200
|
+
* Pure and dependency-free on purpose: this is reachable from the browser
|
|
1201
|
+
* entry, so it must not pull the reactor registry in as a value.
|
|
1202
|
+
*/
|
|
1203
|
+
function resolveDocumentModelModule(modules, documentType, version) {
|
|
1204
|
+
let latestModule;
|
|
1205
|
+
let latestVersion = -1;
|
|
1206
|
+
for (const module of modules) {
|
|
1207
|
+
if (module.documentModel.global.id !== documentType) continue;
|
|
1208
|
+
const moduleVersion = module.version ?? 1;
|
|
1209
|
+
if (version !== void 0 && moduleVersion === version) return module;
|
|
1210
|
+
if (moduleVersion > latestVersion) {
|
|
1211
|
+
latestVersion = moduleVersion;
|
|
1212
|
+
latestModule = module;
|
|
1213
|
+
}
|
|
1214
|
+
}
|
|
1215
|
+
if (version === void 0 && latestModule) return latestModule;
|
|
1216
|
+
throw new Error(version === void 0 ? `Unknown document type: ${documentType}` : `Unknown document model version: ${documentType} v${version}` + (latestModule ? ` (available: ${availableVersions(modules, documentType).join(", ")})` : " (no module for this document type)"));
|
|
1217
|
+
}
|
|
1218
|
+
function availableVersions(modules, documentType) {
|
|
1219
|
+
return modules.filter((module) => module.documentModel.global.id === documentType).map((module) => module.version ?? 1).sort((a, b) => a - b);
|
|
1220
|
+
}
|
|
1221
|
+
function staticPackageManagerError(member) {
|
|
1222
|
+
return /* @__PURE__ */ new Error(`${member} is not supported: StaticPackageManager holds a fixed set of packages`);
|
|
1223
|
+
}
|
|
1224
|
+
/**
|
|
1225
|
+
* Wraps hand-picked modules in one synthetic `DocumentModelLib`, for apps that
|
|
1226
|
+
* assemble their model list from mixed sources instead of passing whole
|
|
1227
|
+
* packages. The manifest is fabricated - loose modules carry none - so prefer
|
|
1228
|
+
* the `packages` prop with the real package exports when you have them: a real
|
|
1229
|
+
* package also carries `editors`, which makes the editor hooks work.
|
|
1230
|
+
*/
|
|
1231
|
+
function packageFromDocumentModels(documentModels) {
|
|
1232
|
+
return {
|
|
1233
|
+
manifest: {
|
|
1234
|
+
name: "graphql-reactor-provider",
|
|
1235
|
+
description: "Document models passed to GraphQLReactorProvider"
|
|
1236
|
+
},
|
|
1237
|
+
documentModels,
|
|
1238
|
+
editors: []
|
|
1239
|
+
};
|
|
1240
|
+
}
|
|
1027
1241
|
//#endregion
|
|
1028
1242
|
//#region src/graphql-client/subgraph.ts
|
|
1029
1243
|
/** What {@link describeGraphQLDocument} could not read off a document. */
|
|
@@ -1210,12 +1424,16 @@ var GraphQLReactorClient = class {
|
|
|
1210
1424
|
listeners = [];
|
|
1211
1425
|
tokenProvider;
|
|
1212
1426
|
subscriptionsUrl;
|
|
1427
|
+
documentModels;
|
|
1428
|
+
signer;
|
|
1213
1429
|
stopRealtime;
|
|
1214
1430
|
realtimeStarted = false;
|
|
1215
1431
|
realtimeGeneration = 0;
|
|
1216
1432
|
realtimeErrorLogged = false;
|
|
1217
1433
|
constructor(options) {
|
|
1218
1434
|
this.tokenProvider = options.tokenProvider ?? ambientRenownTokenProvider;
|
|
1435
|
+
this.documentModels = [...options.documentModels ?? []];
|
|
1436
|
+
this.signer = options.signer;
|
|
1219
1437
|
this.subscriptionsUrl = options.realtime === false ? void 0 : options.subscriptionsUrl ?? subscriptionsUrlFromGraphqlUrl(options.url);
|
|
1220
1438
|
const middleware = makeAuthMiddleware(this.tokenProvider);
|
|
1221
1439
|
this.sdk = options.graphqlClient ?? createClient$1(options.url, middleware);
|
|
@@ -1285,8 +1503,7 @@ var GraphQLReactorClient = class {
|
|
|
1285
1503
|
const document = await this.get(documentIdentifier, { branch }, signal);
|
|
1286
1504
|
const variables = {
|
|
1287
1505
|
documentIdentifier,
|
|
1288
|
-
actions: await prepareActionsForPush(actions, document),
|
|
1289
|
-
view: { branch },
|
|
1506
|
+
actions: (await prepareActionsForPush(actions, document, this.documentModels, this.signer, signal)).map(toTransportAction),
|
|
1290
1507
|
sinceRevision: sinceRevisionForActions(document, actions),
|
|
1291
1508
|
scopes: scopesForActions(actions),
|
|
1292
1509
|
branch
|
|
@@ -1583,18 +1800,33 @@ function propagationModeInput(propagate) {
|
|
|
1583
1800
|
/**
|
|
1584
1801
|
* Stamps and signs the actions about to be pushed.
|
|
1585
1802
|
*
|
|
1586
|
-
*
|
|
1587
|
-
*
|
|
1588
|
-
*
|
|
1803
|
+
* With no signer the actions go out exactly as given, batch or not - this
|
|
1804
|
+
* client does not require signatures. With one, every action is signed:
|
|
1805
|
+
* {@link prepareSignedActions} predicts the chain a batch will produce by
|
|
1806
|
+
* running the document's own reducer between signatures, which is why a batch
|
|
1807
|
+
* needs the module matching the document's type and exact version.
|
|
1808
|
+
*
|
|
1809
|
+
* A batch that cannot be predicted - no matching module, mixed scopes, an
|
|
1810
|
+
* action needing history - throws here, before the mutation. Sending it
|
|
1811
|
+
* unsigned instead would silently drop the signatures the caller asked for.
|
|
1589
1812
|
*/
|
|
1590
|
-
async function prepareActionsForPush(actions, document) {
|
|
1591
|
-
const signer = resolveAmbientSigner();
|
|
1813
|
+
async function prepareActionsForPush(actions, document, documentModels, explicitSigner, signal) {
|
|
1814
|
+
const signer = explicitSigner ?? resolveAmbientSigner();
|
|
1592
1815
|
if (!signer || actions.length === 0) return actions;
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1816
|
+
return prepareSignedActions(actions, document, signer, actions.length > 1 ? resolveDocumentModelModule(documentModels, document.header.documentType, documentModelVersion(document)) : void 0, signal);
|
|
1817
|
+
}
|
|
1818
|
+
/**
|
|
1819
|
+
* The document-model version the document's actions must be reduced with.
|
|
1820
|
+
*
|
|
1821
|
+
* `state` arrives as JSON over GraphQL, so its `document` scope is only as
|
|
1822
|
+
* reliable as the server that sent it - one written before that scope existed
|
|
1823
|
+
* carries no version at all. `normalizeDocumentModelVersion` maps that, and 0,
|
|
1824
|
+
* to 1: the same rule `SimpleJobExecutor` applies before asking the registry
|
|
1825
|
+
* for a module, so client and server cannot resolve different reducers.
|
|
1826
|
+
*/
|
|
1827
|
+
function documentModelVersion(document) {
|
|
1828
|
+
const documentScope = document.state.document;
|
|
1829
|
+
return normalizeDocumentModelVersion(documentScope?.version);
|
|
1598
1830
|
}
|
|
1599
1831
|
/** Resolves the signer of the logged-in user, if there is one. */
|
|
1600
1832
|
function resolveAmbientSigner() {
|
|
@@ -2489,91 +2721,6 @@ function callEventHandlerRegisterFunctions(registerFunctions) {
|
|
|
2489
2721
|
forEachObj(registerFunctions, (fn) => fn());
|
|
2490
2722
|
}
|
|
2491
2723
|
//#endregion
|
|
2492
|
-
//#region src/graphql-client/static-package-manager.ts
|
|
2493
|
-
/**
|
|
2494
|
-
* A fixed set of packages presented through the `IPackageManager` interface,
|
|
2495
|
-
* so the package-derived hooks - `useDocumentModelModules`,
|
|
2496
|
-
* `useDocumentModelModuleById`, `useEditorModules`, `useVetraPackages` - work
|
|
2497
|
-
* below `GraphQLReactorProvider` exactly as they do below Connect.
|
|
2498
|
-
*
|
|
2499
|
-
* Connect's package manager installs, updates and removes packages at runtime.
|
|
2500
|
-
* A light app instead declares its packages once, as code it imports itself
|
|
2501
|
-
* (every generated package root exports `manifest`, `documentModels`, `editors`
|
|
2502
|
-
* and `upgradeManifests` by name), so every mutating member throws and
|
|
2503
|
-
* `subscribe` never emits. For hand-picked modules without package artifacts,
|
|
2504
|
-
* {@link packageFromDocumentModels} wraps them in one synthetic package.
|
|
2505
|
-
*/
|
|
2506
|
-
var StaticPackageManager = class {
|
|
2507
|
-
registryUrl = null;
|
|
2508
|
-
packages;
|
|
2509
|
-
constructor(packages) {
|
|
2510
|
-
this.packages = [...packages];
|
|
2511
|
-
}
|
|
2512
|
-
/**
|
|
2513
|
-
* Resolves a module by document type across all packages. Mirrors the
|
|
2514
|
-
* registry's semantics (`IDocumentModelRegistry.getModule`): the LATEST
|
|
2515
|
-
* version wins, with `version ?? 1` as each module's default.
|
|
2516
|
-
*/
|
|
2517
|
-
load(documentType) {
|
|
2518
|
-
let latestModule;
|
|
2519
|
-
let latestVersion = -1;
|
|
2520
|
-
for (const pkg of this.packages) for (const module of pkg.documentModels) {
|
|
2521
|
-
if (module.documentModel.global.id !== documentType) continue;
|
|
2522
|
-
const moduleVersion = module.version ?? 1;
|
|
2523
|
-
if (moduleVersion > latestVersion) {
|
|
2524
|
-
latestVersion = moduleVersion;
|
|
2525
|
-
latestModule = module;
|
|
2526
|
-
}
|
|
2527
|
-
}
|
|
2528
|
-
return latestModule ? Promise.resolve(latestModule) : Promise.reject(/* @__PURE__ */ new Error(`Unknown document type: ${documentType}`));
|
|
2529
|
-
}
|
|
2530
|
-
subscribe(_handler) {
|
|
2531
|
-
return () => {};
|
|
2532
|
-
}
|
|
2533
|
-
getPackageSource(_packageName) {
|
|
2534
|
-
return null;
|
|
2535
|
-
}
|
|
2536
|
-
getPackageVersion(_packageName) {}
|
|
2537
|
-
getRegistryPackages() {
|
|
2538
|
-
return [];
|
|
2539
|
-
}
|
|
2540
|
-
addPackage(_packageName) {
|
|
2541
|
-
throw staticPackageManagerError("addPackage");
|
|
2542
|
-
}
|
|
2543
|
-
addPackages(_packageNames) {
|
|
2544
|
-
throw staticPackageManagerError("addPackages");
|
|
2545
|
-
}
|
|
2546
|
-
removePackage(_name) {
|
|
2547
|
-
throw staticPackageManagerError("removePackage");
|
|
2548
|
-
}
|
|
2549
|
-
updateLocalPackage(_pkg, _version) {
|
|
2550
|
-
throw staticPackageManagerError("updateLocalPackage");
|
|
2551
|
-
}
|
|
2552
|
-
addLocalPackage(_name, _loadedPackage, _version) {
|
|
2553
|
-
throw staticPackageManagerError("addLocalPackage");
|
|
2554
|
-
}
|
|
2555
|
-
};
|
|
2556
|
-
function staticPackageManagerError(member) {
|
|
2557
|
-
return /* @__PURE__ */ new Error(`${member} is not supported: StaticPackageManager holds a fixed set of packages`);
|
|
2558
|
-
}
|
|
2559
|
-
/**
|
|
2560
|
-
* Wraps hand-picked modules in one synthetic `DocumentModelLib`, for apps that
|
|
2561
|
-
* assemble their model list from mixed sources instead of passing whole
|
|
2562
|
-
* packages. The manifest is fabricated - loose modules carry none - so prefer
|
|
2563
|
-
* the `packages` prop with the real package exports when you have them: a real
|
|
2564
|
-
* package also carries `editors`, which makes the editor hooks work.
|
|
2565
|
-
*/
|
|
2566
|
-
function packageFromDocumentModels(documentModels) {
|
|
2567
|
-
return {
|
|
2568
|
-
manifest: {
|
|
2569
|
-
name: "graphql-reactor-provider",
|
|
2570
|
-
description: "Document models passed to GraphQLReactorProvider"
|
|
2571
|
-
},
|
|
2572
|
-
documentModels,
|
|
2573
|
-
editors: []
|
|
2574
|
-
};
|
|
2575
|
-
}
|
|
2576
|
-
//#endregion
|
|
2577
2724
|
//#region src/graphql-client/graphql-reactor-provider.tsx
|
|
2578
2725
|
/**
|
|
2579
2726
|
* Registers the `window.ph` event handlers once per page.
|
|
@@ -2596,9 +2743,11 @@ function ensurePHEventHandlers() {
|
|
|
2596
2743
|
*
|
|
2597
2744
|
* It fills the document slots, plus `window.ph.vetraPackageManager` when
|
|
2598
2745
|
* `documentModels` is given (a fixed {@link StaticPackageManager}, which makes
|
|
2599
|
-
* the document-model hooks work).
|
|
2600
|
-
*
|
|
2601
|
-
*
|
|
2746
|
+
* the document-model hooks work). The same modules go to the client itself, so
|
|
2747
|
+
* a dispatch of two or more actions is signed rather than refused.
|
|
2748
|
+
* `window.ph.reactorClientModule` always stays empty, so full-reactor surfaces
|
|
2749
|
+
* (drives, jobs, editor auto-discovery) find nothing - an app below this
|
|
2750
|
+
* provider renders components it imports itself.
|
|
2602
2751
|
*
|
|
2603
2752
|
* The client is built on the client only: on the server the slots stay empty
|
|
2604
2753
|
* and the hooks report their normal loading states. The props are read once,
|
|
@@ -2613,7 +2762,8 @@ function GraphQLReactorProvider({ url, tokenProvider, subscriptionsUrl, realtime
|
|
|
2613
2762
|
url,
|
|
2614
2763
|
tokenProvider,
|
|
2615
2764
|
subscriptionsUrl,
|
|
2616
|
-
realtime
|
|
2765
|
+
realtime,
|
|
2766
|
+
documentModels
|
|
2617
2767
|
}));
|
|
2618
2768
|
useEffect(() => {
|
|
2619
2769
|
if (!client) return;
|
|
@@ -2773,6 +2923,6 @@ function useDocumentOperations(documentId) {
|
|
|
2773
2923
|
};
|
|
2774
2924
|
}
|
|
2775
2925
|
//#endregion
|
|
2776
|
-
export {
|
|
2926
|
+
export { useGraphQLReactorClient as $, ReactorOperationFieldsFragmentDoc as $i, setIsDeletePublicDrivesEnabled as $n, useIsEditorReadModeEnabled as $r, addIsCloudDrivesEnabledEventHandler as $t, isFolderNodeKind as A, showPHModal as Aa, phDocumentEditorConfigSetters as Ai, addWarnOutdatedAppEventHandler as An, useBasePath as Ar, addFeaturesEventHandler as At, setReactorClientModule as B, makeAuthConnectionParams as Bi, setEnabledEditors as Bn, useIsAddLocalDrivesEnabled as Br, addDefaultDrivesUrlEventHandler as Bt, useSelectedNode as C, getUserPermissions as Ca, addAllowedDocumentTypesEventHandler as Ci, addSentryDsnEventHandler as Cn, setStudioMode as Cr, extractNodeIdFromSlug as Ct, useFolderNodesInSelectedDrive as D, setPHModal as Da, phAppConfigHooks as Di, addSwitchboardUrlEventHandler as Dn, setWarnOutdatedApp as Dr, makeDriveUrlComponent as Dt, useFileNodesInSelectedDrive as E, closePHModal as Ea, isExternalControlsEnabledEventFunctions as Ei, addStudioModeEventHandler as En, setVersionCheckInterval as Er, getPathWithoutBase as Et, showRevisionHistory as F, NoSelectedDocumentError as Fa, useIsDragAndDropEnabled as Fi, setBasePath as Fn, useEnabledEditors as Fr, useAttachmentService as Ft, useReactorClientModule as G, subgraphUrlFromGraphqlUrl as Gi, setIsAddLocalDrivesEnabled as Gn, useIsCloudDrivesEnabled as Gr, addGaTrackingIdEventHandler as Gt, useModelRegistry as H, subscriptionsUrlFromGraphqlUrl as Hi, setGaTrackingId as Hn, useIsAnalyticsDatabaseWorkerEnabled as Hr, addDrivesPreserveStrategyEventHandler as Ht, useRevisionHistoryVisible as I, UnsupportedDocumentTypeError as Ia, useIsExternalControlsEnabled as Ii, setCliVersion as In, useFileUploadOperationsChunkSize as Ir, addAllowListEventHandler as It, addPackageDiscoveryServiceEventHandler as J, resolveDocumentModelModule as Ji, setIsAnalyticsEnabled as Jn, useIsDeletePublicDrivesEnabled as Jr, addIsAddLocalDrivesEnabledEventHandler as Jt, useSync as K, StaticPackageManager as Ki, setIsAddPublicDrivesEnabled as Kn, useIsDeleteCloudDrivesEnabled as Kr, addIsAddCloudDrivesEnabledEventHandler as Kt, addReactorClientEventHandler as L, GraphQLReactorClient as Li, setDefaultDrivesUrl as Ln, useGaTrackingId as Lr, addAnalyticsDatabaseNameEventHandler as Lt, addRevisionHistoryVisibleEventHandler as M, DocumentModelNotFoundError as Ma, setIsDragAndDropEnabled as Mi, phGlobalConfigSetters as Mn, useDefaultDrivesUrl as Mr, useFeatures as Mt, hideRevisionHistory as N, DocumentNotFoundError as Na, setIsExternalControlsEnabled as Ni, setAllowList as Nn, useDisabledEditors as Nr, addAttachmentServiceEventHandler as Nt, useNodesInSelectedDrive as O, showCreateDocumentModal as Oa, phAppConfigSetters as Oi, addVersionCheckIntervalEventHandler as On, useAllowList as Or, makeNodeSlug as Ot, setRevisionHistoryVisible as P, DocumentTypeMismatchError as Pa, useAllowedDocumentTypes as Pi, setAnalyticsDatabaseName as Pn, useDrivesPreserveStrategy as Pr, setAttachmentService as Pt, setGraphQLReactorClient as Q, MutateDocumentWithOperationsDocument as Qi, setIsDeleteLocalDrivesEnabled as Qn, useIsEditorDebugModeEnabled as Qr, addIsAnalyticsExternalProcessorsEnabledEventHandler as Qt, addReactorClientModuleEventHandler as R, isGraphQLReactorClient as Ri, setDisabledEditors as Rn, useIsAddCloudDrivesEnabled as Rr, addBasePathEventHandler as Rt, useSelectedTimelineItem as S, upgradeDocument as Sa, useWarnOutdatedApp as Si, addRouterBasenameEventHandler as Sn, setSentryRelease as Sr, extractNodeIdFromPath as St, useDocumentsInSelectedDrive as T, addModalEventHandler as Ta, addIsExternalControlsEnabledEventHandler as Ti, addSentryReleaseEventHandler as Tn, setVersion as Tr, findUuid as Tt, usePGlite as U, SubgraphSdkRegistry as Ui, setIsAddCloudDrivesEnabled as Un, useIsAnalyticsEnabled as Ur, addEnabledEditorsEventHandler as Ut, useDatabase as V, startDocumentChangesSubscription as Vi, setFileUploadOperationsChunkSize as Vn, useIsAddPublicDrivesEnabled as Vr, addDisabledEditorsEventHandler as Vt, useReactorClient as W, describeGraphQLDocument as Wi, setIsAddDriveEnabled as Wn, useIsAnalyticsExternalProcessorsEnabled as Wr, addFileUploadOperationsChunkSizeEventHandler as Wt, usePackageDiscoveryService as X, signStampedAction as Xi, setIsCloudDrivesEnabled as Xn, useIsDocumentModelSelectionSettingsEnabled as Xr, addIsAnalyticsDatabaseWorkerEnabledEventHandler as Xt, setPackageDiscoveryService as Y, prepareSignedActions as Yi, setIsAnalyticsExternalProcessorsEnabled as Yn, useIsDiffAnalyticsEnabled as Yr, addIsAddPublicDrivesEnabledEventHandler as Yt, addGraphQLReactorClientEventHandler as Z, stampAction as Zi, setIsDeleteCloudDrivesEnabled as Zn, useIsDriveAnalyticsEnabled as Zr, addIsAnalyticsEnabledEventHandler as Zt, addSelectedTimelineRevisionEventHandler as _, exportFile as _a, useSentryRelease as _i, addRenownAdaptersEventHandler as _n, setRenownUrl as _r, useDrives as _t, ensurePHEventHandlers as a, ConflictError as aa, useIsRelationalProcessorsEnabled as ai, addIsDriveAnalyticsEnabledEventHandler as an, setIsExternalPackagesEnabled as ar, addSetSelectedDriveOnPopStateEventHandler as at, addSelectedTimelineItemEventHandler as b, renameDriveNode as ba, useVersion as bi, addRenownUrlEventHandler as bn, setSentryDsn as br, extractDriveIdFromSlug as bt, callEventHandlerRegisterFunctions as c, extractRevisionMap as ca, useLogLevel as ci, addIsExternalPackagesEnabledEventHandler as cn, setIsLocalDrivesEnabled as cr, useSelectedDrive as ct, setVetraPackageManager as d, addDocument as da, useRenownNetworkId as di, addIsLocalDrivesEnabledEventHandler as dn, setIsSentryTracingEnabled as dr, addResetSelectedNodeEventHandler as dt, ambientRenownTokenProvider as ea, useIsExternalPackagesEnabled as ei, addIsDeleteCloudDrivesEnabledEventHandler as en, setIsDiffAnalyticsEnabled as er, addDraggingNodeEventHandler as et, useVetraPackageManager as f, addFile as fa, useRenownUrl as fi, addIsPublicDrivesEnabledEventHandler as fn, setLocalDrivesEnabled as fr, addSelectedNodeIdEventHandler as ft, usePHToast as g, deleteNode as ga, useSentryEnv as gi, addLogLevelEventHandler as gn, setRenownNetworkId as gr, setDrives as gt, setPHToast as h, copyNode$1 as ha, useSentryDsn as hi, addLocalDrivesEnabledEventHandler as hn, setRenownChainId as hr, addDrivesEventHandler as ht, GraphQLReactorProvider as i, revisionMapFromRevisionsList as ia, useIsPublicDrivesEnabled as ii, addIsDocumentModelSelectionSettingsEnabledEventHandler as in, setIsEditorReadModeEnabled as ir, addSelectedDriveIdEventHandler as it, sortNodesByName as j, usePHModal as ja, setAllowedDocumentTypes as ji, phGlobalConfigHooks as jn, useCliVersion as jr, setFeatures as jt, isFileNodeKind as k, showDeleteNodeModal as ka, phDocumentEditorConfigHooks as ki, addVersionEventHandler as kn, useAnalyticsDatabaseName as kr, resolveUrlPathname as kt, commonGlobalEventHandlerFunctions as l, hasRevisionConflict as la, useRenownAdapters as li, addIsExternalProcessorsEnabledEventHandler as ln, setIsPublicDrivesEnabled as lr, useSelectedDriveId as lt, addToastEventHandler as m, addFolder$1 as ma, useRouterBasename as mi, addIsSentryTracingEnabledEventHandler as mn, setRenownAdapters as mr, setSelectedNode as mt, useDocumentModelModuleById as n, phDocumentFromGetDocument as na, useIsExternalRelationalProcessorsEnabled as ni, addIsDeletePublicDrivesEnabledEventHandler as nn, setIsDriveAnalyticsEnabled as nr, useDropNode as nt, useSwitchboardClient as o, buildPulledDocument as oa, useIsSentryTracingEnabled as oi, addIsEditorDebugModeEnabledEventHandler as on, setIsExternalProcessorsEnabled as or, setSelectedDrive as ot, useVetraPackages as p, addFileWithProgress as pa, useRequiresHardRefresh as pi, addIsRelationalProcessorsEnabledEventHandler as pn, setLogLevel as pr, addSetSelectedNodeOnPopStateEventHandler as pt, useSyncList as q, packageFromDocumentModels as qi, setIsAnalyticsDatabaseWorkerEnabled as qn, useIsDeleteLocalDrivesEnabled as qr, addIsAddDriveEnabledEventHandler as qt, useDocumentModelModules as r, phDocumentFromMutation as ra, useIsLocalDrivesEnabled as ri, addIsDiffAnalyticsEnabledEventHandler as rn, setIsEditorDebugModeEnabled as rr, useDropTarget as rt, addPHEventHandlers as s, convertRemoteOperations as sa, useLocalDrivesEnabled as si, addIsEditorReadModeEnabledEventHandler as sn, setIsExternalRelationalProcessorsEnabled as sr, setSelectedDriveId as st, useDocumentOperations as t, makeAuthMiddleware as ta, useIsExternalProcessorsEnabled as ti, addIsDeleteLocalDrivesEnabledEventHandler as tn, setIsDocumentModelSelectionSettingsEnabled as tr, useDragNode as tt, addVetraPackageManagerEventHandler as u, screamingSnakeToCamel as ua, useRenownChainId as ui, addIsExternalRelationalProcessorsEnabledEventHandler as un, setIsRelationalProcessorsEnabled as ur, useSelectedDriveSafe as ut, setSelectedTimelineRevision as v, loadFile as va, useStudioMode as vi, addRenownChainIdEventHandler as vn, setRequiresHardRefresh as vr, createUrlWithPreservedParams as vt, useDocumentTypesInSelectedDrive as w, isDocumentTypeSupported as wa, addIsDragAndDropEnabledEventHandler as wi, addSentryEnvEventHandler as wn, setSwitchboardUrl as wr, extractNodeSlugFromPath as wt, setSelectedTimelineItem as x, renameNode as xa, useVersionCheckInterval as xi, addRequiresHardRefreshEventHandler as xn, setSentryEnv as xr, extractDriveSlugFromPath as xt, useSelectedTimelineRevision as y, moveNode$1 as ya, useSwitchboardUrl as yi, addRenownNetworkIdEventHandler as yn, setRouterBasename as yr, extractDriveIdFromPath as yt, setReactorClient as z, viewFilterInputFromViewFilter as zi, setDrivesPreserveStrategy as zn, useIsAddDriveEnabled as zr, addCliVersionEventHandler as zt };
|
|
2777
2927
|
|
|
2778
|
-
//# sourceMappingURL=document-operations-
|
|
2928
|
+
//# sourceMappingURL=document-operations-C6nce9dH.js.map
|