@powerhousedao/shared 6.2.3-dev.22 → 6.2.3-dev.24
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/clis/args/{access-token-Bf1K1Fpc.mjs → access-token-l4ne3id6.mjs} +2 -2
- package/dist/clis/args/{access-token-Bf1K1Fpc.mjs.map → access-token-l4ne3id6.mjs.map} +1 -1
- package/dist/clis/args/access-token.mjs +1 -1
- package/dist/clis/args/{common-rEpM4Oqq.d.mts → common-Bc6Phg3O.d.mts} +6 -3
- package/dist/clis/args/common-Bc6Phg3O.d.mts.map +1 -0
- package/dist/clis/args/{common-BpnFLR-_.mjs → common-BnSmBXOm.mjs} +8 -1
- package/dist/clis/args/{common-BpnFLR-_.mjs.map → common-BnSmBXOm.mjs.map} +1 -1
- package/dist/clis/args/common.d.mts +1 -1
- package/dist/clis/args/common.mjs +1 -1
- package/dist/clis/args/{connect-_FQWS7p3.d.mts → connect-BD-C5BkE.d.mts} +6 -6
- package/dist/clis/args/{connect-_FQWS7p3.d.mts.map → connect-BD-C5BkE.d.mts.map} +1 -1
- package/dist/clis/args/{connect-ByiLv365.mjs → connect-CkPZNzui.mjs} +2 -2
- package/dist/clis/args/{connect-ByiLv365.mjs.map → connect-CkPZNzui.mjs.map} +1 -1
- package/dist/clis/args/connect.d.mts +1 -1
- package/dist/clis/args/connect.mjs +1 -1
- package/dist/clis/args/{generate-C51i00At.mjs → generate-BzRnsIbV.mjs} +2 -2
- package/dist/clis/args/{generate-C51i00At.mjs.map → generate-BzRnsIbV.mjs.map} +1 -1
- package/dist/clis/args/generate.mjs +1 -1
- package/dist/clis/args/{help-D2SeQC09.mjs → help-DnzLlEb7.mjs} +15 -15
- package/dist/clis/args/{help-D2SeQC09.mjs.map → help-DnzLlEb7.mjs.map} +1 -1
- package/dist/clis/args/help.mjs +1 -1
- package/dist/clis/args/index.d.mts +3 -3
- package/dist/clis/args/index.mjs +18 -18
- package/dist/clis/args/{init-DBYYsV0Y.mjs → init-Q3FOdRyY.mjs} +2 -2
- package/dist/clis/args/{init-DBYYsV0Y.mjs.map → init-Q3FOdRyY.mjs.map} +1 -1
- package/dist/clis/args/init.mjs +1 -1
- package/dist/clis/args/{inspect-BzBsZ0UO.mjs → inspect-99GSVTTt.mjs} +2 -2
- package/dist/clis/args/{inspect-BzBsZ0UO.mjs.map → inspect-99GSVTTt.mjs.map} +1 -1
- package/dist/clis/args/inspect.mjs +1 -1
- package/dist/clis/args/{install-D0jaysiP.mjs → install-Dcal76Iq.mjs} +2 -2
- package/dist/clis/args/{install-D0jaysiP.mjs.map → install-Dcal76Iq.mjs.map} +1 -1
- package/dist/clis/args/install.mjs +1 -1
- package/dist/clis/args/{list-BaO47Btz.mjs → list-BFbHTSf3.mjs} +2 -2
- package/dist/clis/args/{list-BaO47Btz.mjs.map → list-BFbHTSf3.mjs.map} +1 -1
- package/dist/clis/args/list.mjs +1 -1
- package/dist/clis/args/{login-DM-qhiYI.mjs → login-BB0WTY2n.mjs} +2 -2
- package/dist/clis/args/{login-DM-qhiYI.mjs.map → login-BB0WTY2n.mjs.map} +1 -1
- package/dist/clis/args/login.mjs +1 -1
- package/dist/clis/args/{migrate-EitaI7jq.mjs → migrate-0xLgeOxh.mjs} +2 -2
- package/dist/clis/args/{migrate-EitaI7jq.mjs.map → migrate-0xLgeOxh.mjs.map} +1 -1
- package/dist/clis/args/migrate.mjs +1 -1
- package/dist/clis/args/{publish-DfMF3Nmc.mjs → publish-BJF3ET2v.mjs} +2 -2
- package/dist/clis/args/{publish-DfMF3Nmc.mjs.map → publish-BJF3ET2v.mjs.map} +1 -1
- package/dist/clis/args/publish.mjs +1 -1
- package/dist/clis/args/{registry-Di1tZqbn.mjs → registry-CbORgFD8.mjs} +2 -2
- package/dist/clis/args/{registry-Di1tZqbn.mjs.map → registry-CbORgFD8.mjs.map} +1 -1
- package/dist/clis/args/registry.mjs +1 -1
- package/dist/clis/args/{service-jRX2qPul.mjs → service-BfDN3YBu.mjs} +2 -2
- package/dist/clis/args/{service-jRX2qPul.mjs.map → service-BfDN3YBu.mjs.map} +1 -1
- package/dist/clis/args/service.mjs +1 -1
- package/dist/clis/args/{switchboard-BhR-ZwGV.mjs → switchboard-tj30Z45Y.mjs} +2 -2
- package/dist/clis/args/{switchboard-BhR-ZwGV.mjs.map → switchboard-tj30Z45Y.mjs.map} +1 -1
- package/dist/clis/args/switchboard.mjs +1 -1
- package/dist/clis/args/{uninstall-diefi70g.mjs → uninstall-CjVkOmXN.mjs} +2 -2
- package/dist/clis/args/{uninstall-diefi70g.mjs.map → uninstall-CjVkOmXN.mjs.map} +1 -1
- package/dist/clis/args/uninstall.mjs +1 -1
- package/dist/clis/args/{unpublish-C6eNRzsU.mjs → unpublish-DSvGNHhr.mjs} +2 -2
- package/dist/clis/args/{unpublish-C6eNRzsU.mjs.map → unpublish-DSvGNHhr.mjs.map} +1 -1
- package/dist/clis/args/unpublish.mjs +1 -1
- package/dist/clis/args/{vetra-DV0zQzba.mjs → vetra-CMIe5hyF.mjs} +2 -2
- package/dist/clis/args/{vetra-DV0zQzba.mjs.map → vetra-CMIe5hyF.mjs.map} +1 -1
- package/dist/clis/args/{vetra-DLQ6lhLl.d.mts → vetra-CoMvTJK7.d.mts} +2 -2
- package/dist/clis/args/{vetra-DLQ6lhLl.d.mts.map → vetra-CoMvTJK7.d.mts.map} +1 -1
- package/dist/clis/args/vetra.d.mts +1 -1
- package/dist/clis/args/vetra.mjs +1 -1
- package/dist/clis/build-pieces.d.mts +1 -1
- package/dist/clis/constants.d.mts +1 -1
- package/dist/clis/constants.mjs +1 -1
- package/dist/clis/constants.mjs.map +1 -1
- package/dist/clis/index.d.mts +12 -2
- package/dist/clis/index.d.mts.map +1 -1
- package/dist/clis/index.mjs +41 -26
- package/dist/clis/index.mjs.map +1 -1
- package/dist/clis/{types-DXhVHupa.d.mts → types-B-Il50oC.d.mts} +4 -3
- package/dist/clis/{types-DXhVHupa.d.mts.map → types-B-Il50oC.d.mts.map} +1 -1
- package/dist/{config-loader-e4-qdVVI.js → config-loader-DcwNJiBB.js} +10 -7
- package/dist/config-loader-DcwNJiBB.js.map +1 -0
- package/dist/connect/config-loader.d.ts +1 -1
- package/dist/connect/config-loader.js +1 -1
- package/dist/connect/index.d.ts +7 -1
- package/dist/connect/index.d.ts.map +1 -1
- package/dist/connect/index.js +34 -26
- package/dist/connect/index.js.map +1 -1
- package/dist/document-drive/index.d.ts +5 -4
- package/dist/document-drive/index.d.ts.map +1 -1
- package/dist/document-drive/index.js +15 -4
- package/dist/document-drive/index.js.map +1 -1
- package/dist/document-model/index.d.ts +3 -3
- package/dist/document-model/index.js +390 -182
- package/dist/document-model/index.js.map +1 -1
- package/dist/{index-ChZbyPGQ.d.ts → index-BmL07S5O.d.ts} +25 -16
- package/dist/{index-ChZbyPGQ.d.ts.map → index-BmL07S5O.d.ts.map} +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/processors/index.d.ts +1 -1
- package/dist/registry/index.d.ts +2 -2
- package/dist/registry/index.js.map +1 -1
- package/dist/registry/manifest-slim.d.ts +1 -1
- package/dist/{types-Cphf695h.d.ts → types-COsoOK42.d.ts} +287 -248
- package/dist/types-COsoOK42.d.ts.map +1 -0
- package/dist/{types-Dh7xKo_B.d.ts → types-DhOXIQ4c.d.ts} +8 -3
- package/dist/types-DhOXIQ4c.d.ts.map +1 -0
- package/package.json +2 -1
- package/dist/clis/args/common-rEpM4Oqq.d.mts.map +0 -1
- package/dist/config-loader-e4-qdVVI.js.map +0 -1
- package/dist/types-Cphf695h.d.ts.map +0 -1
- package/dist/types-Dh7xKo_B.d.ts.map +0 -1
|
@@ -1,9 +1,176 @@
|
|
|
1
1
|
import { a as base58Decode, c as buildOperationSignatureParams, d as hex2ab, i as ab2hex, l as getUnixTimestamp, n as generateId, o as base64UrlToBytes, r as generateMock, s as buildOperationSignatureMessage, t as deriveOperationId, u as hashBrowser } from "../utils-aaTmfxFW.js";
|
|
2
2
|
import { ZodError, z } from "zod";
|
|
3
3
|
import { stringify } from "safe-stable-stringify";
|
|
4
|
+
import { sha256 } from "@noble/hashes/sha2.js";
|
|
4
5
|
import { strFromU8, strToU8, unzip, zip } from "fflate";
|
|
5
|
-
import { castDraft, create, unsafe } from "mutative";
|
|
6
|
+
import { castDraft, create, isDraft, original, unsafe } from "mutative";
|
|
6
7
|
import { constantCase, pascalCase } from "change-case";
|
|
8
|
+
//#region document-model/action-signature.ts
|
|
9
|
+
const ACTION_SIGNATURE_V2_PREFIX = "v2:";
|
|
10
|
+
const V2_HASH = /^v2:[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$/;
|
|
11
|
+
const V2_TIMESTAMP = /^[0-9]+$/;
|
|
12
|
+
const V2_SIGNATURE = /^0x[0-9a-f]{128}$/;
|
|
13
|
+
const LONE_SURROGATE = /\p{Cs}/u;
|
|
14
|
+
const PREIMAGE_FIELDS = [
|
|
15
|
+
"version",
|
|
16
|
+
"documentId",
|
|
17
|
+
"branch",
|
|
18
|
+
"scope",
|
|
19
|
+
"type",
|
|
20
|
+
"id",
|
|
21
|
+
"timestampUtcMs",
|
|
22
|
+
"input",
|
|
23
|
+
"signer.user.address",
|
|
24
|
+
"signer.user.networkId",
|
|
25
|
+
"signer.user.chainId",
|
|
26
|
+
"signer.app.key"
|
|
27
|
+
];
|
|
28
|
+
/** A value that would not survive a JSON store round trip unchanged. */
|
|
29
|
+
var CanonicalJsonError = class extends Error {
|
|
30
|
+
constructor(path, detail) {
|
|
31
|
+
super(`Cannot canonicalize ${path}: ${detail}`);
|
|
32
|
+
this.name = "CanonicalJsonError";
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
/** Sorted-key JSON, as the state hash encodes; drops `undefined` properties. */
|
|
36
|
+
function canonicalJson(value, label = "value") {
|
|
37
|
+
assertCanonical(value, label, /* @__PURE__ */ new Set());
|
|
38
|
+
return stringify(value);
|
|
39
|
+
}
|
|
40
|
+
/** Actions the reactor reduces itself, onto the document scope. */
|
|
41
|
+
const DOCUMENT_SCOPE_ACTION_TYPES = new Set([
|
|
42
|
+
"CREATE_DOCUMENT",
|
|
43
|
+
"DELETE_DOCUMENT",
|
|
44
|
+
"UPGRADE_DOCUMENT",
|
|
45
|
+
"ADD_RELATIONSHIP",
|
|
46
|
+
"REMOVE_RELATIONSHIP",
|
|
47
|
+
"UPDATE_RELATIONSHIP"
|
|
48
|
+
]);
|
|
49
|
+
/** Where a document-scope action writes: `sourceId` or `documentId`. */
|
|
50
|
+
function targetDocumentId(action, fallback) {
|
|
51
|
+
const input = action.input;
|
|
52
|
+
if (action.type === "ADD_RELATIONSHIP" || action.type === "REMOVE_RELATIONSHIP" || action.type === "UPDATE_RELATIONSHIP") return typeof input?.sourceId === "string" && input.sourceId.length > 0 ? input.sourceId : fallback;
|
|
53
|
+
return typeof input?.documentId === "string" && input.documentId.length > 0 ? input.documentId : fallback;
|
|
54
|
+
}
|
|
55
|
+
/** The log an action submitted to a job on `documentId` is stored in. */
|
|
56
|
+
function actionSigningTarget(action, documentId, branch) {
|
|
57
|
+
return {
|
|
58
|
+
documentId: DOCUMENT_SCOPE_ACTION_TYPES.has(action.type) ? targetDocumentId(action, documentId) : documentId,
|
|
59
|
+
branch
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
/** The identity a signer writes into `context.signer`, and signs over. */
|
|
63
|
+
function actionSignerIdentity(signer) {
|
|
64
|
+
return {
|
|
65
|
+
user: {
|
|
66
|
+
address: signer.user?.address ?? "",
|
|
67
|
+
networkId: signer.user?.networkId ?? "",
|
|
68
|
+
chainId: signer.user?.chainId ?? 0
|
|
69
|
+
},
|
|
70
|
+
app: {
|
|
71
|
+
name: signer.app?.name ?? "",
|
|
72
|
+
key: signer.app?.key ?? ""
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
/** The v2 preimage; throws `CanonicalJsonError` on an unsignable action. */
|
|
77
|
+
function actionPreimageV2(action, target, signer) {
|
|
78
|
+
if (!target.documentId) throw new CanonicalJsonError("documentId", "must not be empty");
|
|
79
|
+
if (!target.branch) throw new CanonicalJsonError("branch", "must not be empty");
|
|
80
|
+
if (action.input === void 0) throw new CanonicalJsonError("input", `action ${action.id} (${action.type}) has no input`);
|
|
81
|
+
const fields = [
|
|
82
|
+
"v2",
|
|
83
|
+
target.documentId,
|
|
84
|
+
target.branch,
|
|
85
|
+
action.scope,
|
|
86
|
+
action.type,
|
|
87
|
+
action.id,
|
|
88
|
+
action.timestampUtcMs,
|
|
89
|
+
action.input,
|
|
90
|
+
signer.user.address,
|
|
91
|
+
signer.user.networkId,
|
|
92
|
+
signer.user.chainId,
|
|
93
|
+
signer.app.key
|
|
94
|
+
];
|
|
95
|
+
fields.forEach((field, i) => {
|
|
96
|
+
assertCanonical(field, PREIMAGE_FIELDS[i], /* @__PURE__ */ new Set());
|
|
97
|
+
});
|
|
98
|
+
return stringify(fields);
|
|
99
|
+
}
|
|
100
|
+
/** `"v2:" + base64url(sha256(preimage))`, unpadded. */
|
|
101
|
+
async function hashActionV2(action, target, signer) {
|
|
102
|
+
const preimage = actionPreimageV2(action, target, signer);
|
|
103
|
+
const digest = await crypto.subtle.digest("SHA-256", new TextEncoder().encode(preimage));
|
|
104
|
+
return "v2:" + bytesToBase64Url$1(new Uint8Array(digest));
|
|
105
|
+
}
|
|
106
|
+
/** Signs `action` as a v2 tuple; the message layout is the legacy one. */
|
|
107
|
+
async function signActionV2(params) {
|
|
108
|
+
const { action, target, signer, sign } = params;
|
|
109
|
+
const previousStateHash = params.previousStateHash ?? "";
|
|
110
|
+
if (previousStateHash.includes(", ")) throw new Error(`Cannot sign action ${action.id}: the previous state hash contains ", "`);
|
|
111
|
+
const tuple = [
|
|
112
|
+
(Date.now() / 1e3).toFixed(0),
|
|
113
|
+
signer.app.key,
|
|
114
|
+
await hashActionV2(action, target, signer),
|
|
115
|
+
previousStateHash
|
|
116
|
+
];
|
|
117
|
+
const signature = await sign(buildOperationSignatureMessage(tuple));
|
|
118
|
+
if (signature.length !== 64) throw new Error(`Cannot sign action ${action.id}: expected a 64-byte P-256 signature, got ${signature.length} bytes`);
|
|
119
|
+
return [...tuple, `0x${bytesToHex(signature)}`];
|
|
120
|
+
}
|
|
121
|
+
/** Element [2] carries the v2 prefix, whether or not it is well formed. */
|
|
122
|
+
function isV2ActionHash(hash) {
|
|
123
|
+
return hash.startsWith("v2:");
|
|
124
|
+
}
|
|
125
|
+
/** The strict shape of a v2 tuple, apart from what its hash covers. */
|
|
126
|
+
function v2TupleProblem(tuple) {
|
|
127
|
+
if (!V2_TIMESTAMP.test(tuple[0])) return "signing time is not decimal seconds";
|
|
128
|
+
if (!V2_HASH.test(tuple[2])) return "hash is not v2: and 43 base64url characters";
|
|
129
|
+
if (!V2_SIGNATURE.test(tuple[4])) return "signature is not 0x and 128 lowercase hex digits";
|
|
130
|
+
}
|
|
131
|
+
function assertCanonical(value, path, ancestors) {
|
|
132
|
+
switch (typeof value) {
|
|
133
|
+
case "string":
|
|
134
|
+
if (LONE_SURROGATE.test(value)) throw new CanonicalJsonError(path, "string holds a lone surrogate");
|
|
135
|
+
return;
|
|
136
|
+
case "boolean": return;
|
|
137
|
+
case "number":
|
|
138
|
+
if (!Number.isFinite(value)) throw new CanonicalJsonError(path, `${value} is not a JSON number`);
|
|
139
|
+
return;
|
|
140
|
+
case "undefined": throw new CanonicalJsonError(path, "undefined is not a JSON value");
|
|
141
|
+
case "bigint": throw new CanonicalJsonError(path, "BigInt is not a JSON value");
|
|
142
|
+
case "function":
|
|
143
|
+
case "symbol": throw new CanonicalJsonError(path, `${typeof value} is not a JSON value`);
|
|
144
|
+
}
|
|
145
|
+
if (value === null) return;
|
|
146
|
+
const object = value;
|
|
147
|
+
if (ancestors.has(object)) throw new CanonicalJsonError(path, "value is circular");
|
|
148
|
+
const toJSON = object.toJSON;
|
|
149
|
+
if (typeof toJSON === "function") {
|
|
150
|
+
assertCanonical(toJSON.call(object), path, new Set(ancestors).add(object));
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
ancestors.add(object);
|
|
154
|
+
if (Array.isArray(object)) for (let i = 0; i < object.length; i++) {
|
|
155
|
+
if (!(i in object)) throw new CanonicalJsonError(`${path}[${i}]`, "array is sparse");
|
|
156
|
+
assertCanonical(object[i], `${path}[${i}]`, ancestors);
|
|
157
|
+
}
|
|
158
|
+
else for (const [key, child] of Object.entries(object)) {
|
|
159
|
+
if (LONE_SURROGATE.test(key)) throw new CanonicalJsonError(path, "key holds a lone surrogate");
|
|
160
|
+
if (child === void 0) continue;
|
|
161
|
+
assertCanonical(child, `${path}.${key}`, ancestors);
|
|
162
|
+
}
|
|
163
|
+
ancestors.delete(object);
|
|
164
|
+
}
|
|
165
|
+
function bytesToBase64Url$1(bytes) {
|
|
166
|
+
let binary = "";
|
|
167
|
+
for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
|
|
168
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
169
|
+
}
|
|
170
|
+
function bytesToHex(bytes) {
|
|
171
|
+
return Array.from(bytes).map((byte) => byte.toString(16).padStart(2, "0")).join("");
|
|
172
|
+
}
|
|
173
|
+
//#endregion
|
|
7
174
|
//#region document-model/signatures.ts
|
|
8
175
|
/**
|
|
9
176
|
* What separates a signature's params when it travels as one string.
|
|
@@ -198,7 +365,7 @@ var GrantNotFoundError = class extends Error {
|
|
|
198
365
|
}
|
|
199
366
|
};
|
|
200
367
|
/**
|
|
201
|
-
* Thrown when a disallowed action (UNDO, REDO
|
|
368
|
+
* Thrown when a disallowed action (UNDO, REDO) targets the auth scope.
|
|
202
369
|
*/
|
|
203
370
|
var AuthActionNotAllowedError = class extends Error {
|
|
204
371
|
actionType;
|
|
@@ -257,8 +424,6 @@ var UnsupportedDocumentModelVersionError = class extends Error {
|
|
|
257
424
|
//#region document-model/schemas.ts
|
|
258
425
|
const isDefinedNonNullAny = (v) => v !== void 0 && v !== null;
|
|
259
426
|
const definedNonNullAnySchema = z.any().refine((v) => isDefinedNonNullAny(v));
|
|
260
|
-
const Load_StateSchema = z.enum(["LOAD_STATE"]);
|
|
261
|
-
const PruneSchema = z.enum(["PRUNE"]);
|
|
262
427
|
const RedoSchema = z.enum(["REDO"]);
|
|
263
428
|
const Set_NameSchema = z.enum(["SET_NAME"]);
|
|
264
429
|
const Set_PreferredEditorSchema = z.enum(["SET_PREFERRED_EDITOR"]);
|
|
@@ -268,50 +433,12 @@ function OperationScopeSchema() {
|
|
|
268
433
|
}
|
|
269
434
|
function DocumentActionSchema() {
|
|
270
435
|
return z.union([
|
|
271
|
-
LoadStateActionSchema(),
|
|
272
|
-
PruneActionSchema(),
|
|
273
436
|
RedoActionSchema(),
|
|
274
437
|
SetNameActionSchema(),
|
|
275
438
|
SetPreferredEditorActionSchema(),
|
|
276
439
|
UndoActionSchema()
|
|
277
440
|
]);
|
|
278
441
|
}
|
|
279
|
-
function LoadStateActionSchema() {
|
|
280
|
-
return z.object({
|
|
281
|
-
id: z.string(),
|
|
282
|
-
timestampUtcMs: z.string(),
|
|
283
|
-
input: z.lazy(() => LoadStateActionInputSchema()),
|
|
284
|
-
type: Load_StateSchema,
|
|
285
|
-
scope: OperationScopeSchema()
|
|
286
|
-
});
|
|
287
|
-
}
|
|
288
|
-
function LoadStateActionInputSchema() {
|
|
289
|
-
return z.object({
|
|
290
|
-
operations: z.number(),
|
|
291
|
-
state: z.lazy(() => LoadStateActionStateInputSchema())
|
|
292
|
-
});
|
|
293
|
-
}
|
|
294
|
-
function LoadStateActionStateInputSchema() {
|
|
295
|
-
return z.object({
|
|
296
|
-
data: z.unknown().nullish(),
|
|
297
|
-
name: z.string()
|
|
298
|
-
});
|
|
299
|
-
}
|
|
300
|
-
function PruneActionSchema() {
|
|
301
|
-
return z.object({
|
|
302
|
-
id: z.string(),
|
|
303
|
-
timestampUtcMs: z.string(),
|
|
304
|
-
input: z.lazy(() => PruneActionInputSchema()),
|
|
305
|
-
type: PruneSchema,
|
|
306
|
-
scope: OperationScopeSchema()
|
|
307
|
-
});
|
|
308
|
-
}
|
|
309
|
-
function PruneActionInputSchema() {
|
|
310
|
-
return z.object({
|
|
311
|
-
end: z.number().nullish(),
|
|
312
|
-
start: z.number().nullish()
|
|
313
|
-
});
|
|
314
|
-
}
|
|
315
442
|
function RedoActionInputSchema() {
|
|
316
443
|
return z.object({ count: z.number() });
|
|
317
444
|
}
|
|
@@ -862,35 +989,6 @@ const undo = (count = 1, scope = "global") => createAction("UNDO", { count }, vo
|
|
|
862
989
|
* @category Actions
|
|
863
990
|
*/
|
|
864
991
|
const redo = (count = 1, scope = "global") => createAction("REDO", { count }, void 0, RedoActionInputSchema, scope);
|
|
865
|
-
/**
|
|
866
|
-
* Joins multiple operations into a single {@link loadState | LOAD_STATE} operation.
|
|
867
|
-
*
|
|
868
|
-
* @remarks
|
|
869
|
-
* Useful to keep operations history smaller. Operations to prune are selected by index,
|
|
870
|
-
* similar to the {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/slice | slice} method in Arrays.
|
|
871
|
-
*
|
|
872
|
-
* @param start - Index of the first operation to prune
|
|
873
|
-
* @param end - Index of the last operation to prune
|
|
874
|
-
* @category Actions
|
|
875
|
-
*/
|
|
876
|
-
const prune = (start, end, scope = "global") => createAction("PRUNE", {
|
|
877
|
-
start,
|
|
878
|
-
end
|
|
879
|
-
}, void 0, PruneActionInputSchema, scope);
|
|
880
|
-
/**
|
|
881
|
-
* Replaces the state of the document.
|
|
882
|
-
*
|
|
883
|
-
* @remarks
|
|
884
|
-
* This action shouldn't be used directly. It is dispatched by the {@link prune} action.
|
|
885
|
-
*
|
|
886
|
-
* @param state - State to be set in the document.
|
|
887
|
-
* @param operations - Number of operations that were removed from the previous state.
|
|
888
|
-
* @category Actions
|
|
889
|
-
*/
|
|
890
|
-
const loadState = (state, operations) => createAction("LOAD_STATE", {
|
|
891
|
-
state,
|
|
892
|
-
operations
|
|
893
|
-
}, void 0, LoadStateActionInputSchema);
|
|
894
992
|
const noop = (scope = "global") => createAction("NOOP", {}, void 0, void 0, scope);
|
|
895
993
|
/**
|
|
896
994
|
* Helper function to be used by action creators.
|
|
@@ -988,6 +1086,7 @@ async function buildOperationSignature(context, signMethod) {
|
|
|
988
1086
|
const signature = await signMethod(buildOperationSignatureMessage(params));
|
|
989
1087
|
return [...params, `0x${ab2hex(signature)}`];
|
|
990
1088
|
}
|
|
1089
|
+
/** @deprecated Emits a legacy SHA-1 tuple; sign through `ISigner.signAction`. */
|
|
991
1090
|
async function buildSignedAction(action, reducer, document, signer, signHandler) {
|
|
992
1091
|
const scopeOperations = reducer(document, action, void 0, { reuseOperationResultingState: true }).operations[action.scope];
|
|
993
1092
|
if (!scopeOperations) throw new Error(`No operations found for scope: ${action.scope}`);
|
|
@@ -1002,6 +1101,7 @@ async function buildSignedAction(action, reducer, document, signer, signHandler)
|
|
|
1002
1101
|
}, signHandler);
|
|
1003
1102
|
return operationWithContext(operation, { signer: actionSigner(signer.user, signer.app, [...signer.signatures, signature]) });
|
|
1004
1103
|
}
|
|
1104
|
+
/** @deprecated Use `verifyActionSignature` from `@powerhousedao/reactor`. */
|
|
1005
1105
|
async function verifyOperationSignature(signature, signer, verifyHandler) {
|
|
1006
1106
|
const publicKey = signer.app.key;
|
|
1007
1107
|
const params = signature.slice(0, 4);
|
|
@@ -1076,8 +1176,6 @@ const baseActions = {
|
|
|
1076
1176
|
setPreferredEditor,
|
|
1077
1177
|
undo,
|
|
1078
1178
|
redo,
|
|
1079
|
-
prune,
|
|
1080
|
-
loadState,
|
|
1081
1179
|
noop
|
|
1082
1180
|
};
|
|
1083
1181
|
const documentModelActions = {
|
|
@@ -2538,12 +2636,12 @@ function assertAuthPreservedOnDuplicate(documentId, source, duplicated) {
|
|
|
2538
2636
|
* The auth scope a state snapshot may install, given the policy already there.
|
|
2539
2637
|
*
|
|
2540
2638
|
* `applyAuthAction` is the validated door onto `state.auth`, but a whole-state
|
|
2541
|
-
* snapshot (UPGRADE_DOCUMENT's `initialState
|
|
2542
|
-
*
|
|
2543
|
-
*
|
|
2544
|
-
*
|
|
2545
|
-
*
|
|
2546
|
-
*
|
|
2639
|
+
* snapshot (UPGRADE_DOCUMENT's `initialState`) replaces the scope wholesale and
|
|
2640
|
+
* is authorized as a `document`-scope write. Without this, a subject holding
|
|
2641
|
+
* `execute` on `document` and no auth grant at all can install a policy of its
|
|
2642
|
+
* choosing, name itself `creator` (which exempts the policy from the retention
|
|
2643
|
+
* rule for good), or wipe an existing policy by carrying the default
|
|
2644
|
+
* uninitialized one.
|
|
2547
2645
|
*
|
|
2548
2646
|
* Three cases:
|
|
2549
2647
|
*
|
|
@@ -2570,13 +2668,9 @@ function resolveSnapshotAuth(documentId, documentType, current, incoming) {
|
|
|
2570
2668
|
assertValidInitialGrants(incoming.grants, documentType, incoming.creator);
|
|
2571
2669
|
return incoming;
|
|
2572
2670
|
}
|
|
2573
|
-
/** UNDO
|
|
2671
|
+
/** UNDO and REDO are rejected on the auth scope. */
|
|
2574
2672
|
function assertAuthScopeActionAllowed(action) {
|
|
2575
|
-
if (action.scope === "auth" && [
|
|
2576
|
-
"UNDO",
|
|
2577
|
-
"REDO",
|
|
2578
|
-
"PRUNE"
|
|
2579
|
-
].includes(action.type)) throw new AuthActionNotAllowedError(action.type);
|
|
2673
|
+
if (action.scope === "auth" && ["UNDO", "REDO"].includes(action.type)) throw new AuthActionNotAllowedError(action.type);
|
|
2580
2674
|
}
|
|
2581
2675
|
/**
|
|
2582
2676
|
* Evaluates the auth policy for a single request and reports why it refused.
|
|
@@ -2682,6 +2776,68 @@ function assertIsDocumentModelDocument(document) {
|
|
|
2682
2776
|
DocumentModelSchema.parse(document);
|
|
2683
2777
|
}
|
|
2684
2778
|
//#endregion
|
|
2779
|
+
//#region document-model/signature-policy.ts
|
|
2780
|
+
/** The `protocolVersions` key that fixes a document's signature requirement. */
|
|
2781
|
+
const SIGNATURE_PROTOCOL = "signature";
|
|
2782
|
+
/** `protocolVersions.signature` of a document that requires v2 tuples. */
|
|
2783
|
+
const SIGNATURE_PROTOCOL_V2 = 2;
|
|
2784
|
+
/** What a new document is created as unless the caller or host says otherwise. */
|
|
2785
|
+
const DEFAULT_SIGNATURE_POLICY = "v2-required";
|
|
2786
|
+
function isSignaturePolicy(value) {
|
|
2787
|
+
return value === "legacy" || value === "v2-required";
|
|
2788
|
+
}
|
|
2789
|
+
const DERIVED_ID = /^[A-Za-z0-9_-]{42}[AEIMQUYcgkosw048]$/;
|
|
2790
|
+
/** Read from a header, a CREATE_DOCUMENT input or a bare map. */
|
|
2791
|
+
function signaturePolicyOf(source) {
|
|
2792
|
+
const version = (source && "protocolVersions" in source ? source.protocolVersions : source)?.[SIGNATURE_PROTOCOL];
|
|
2793
|
+
return typeof version === "number" && version >= 2 ? "v2-required" : "legacy";
|
|
2794
|
+
}
|
|
2795
|
+
/** `protocolVersions` for a new v2-required document. */
|
|
2796
|
+
function v2RequiredProtocolVersions(base = {}) {
|
|
2797
|
+
return {
|
|
2798
|
+
"base-reducer": 2,
|
|
2799
|
+
...base,
|
|
2800
|
+
[SIGNATURE_PROTOCOL]: 2
|
|
2801
|
+
};
|
|
2802
|
+
}
|
|
2803
|
+
/**
|
|
2804
|
+
* The policy a create call asks for: `signaturePolicy`, else the `signature`
|
|
2805
|
+
* key of its `protocolVersions`, else `fallback`, the host's default.
|
|
2806
|
+
*/
|
|
2807
|
+
function requestedSignaturePolicy(request, fallback) {
|
|
2808
|
+
if (request?.signaturePolicy) return request.signaturePolicy;
|
|
2809
|
+
if (request?.protocolVersions?.["signature"] !== void 0) return signaturePolicyOf(request.protocolVersions);
|
|
2810
|
+
return fallback;
|
|
2811
|
+
}
|
|
2812
|
+
/** `protocolVersions` for a new document under `policy`, over `base`. */
|
|
2813
|
+
function protocolVersionsFor(policy, base = {}) {
|
|
2814
|
+
if (policy === "v2-required") return v2RequiredProtocolVersions(base);
|
|
2815
|
+
const { [SIGNATURE_PROTOCOL]: _signature, ...rest } = base;
|
|
2816
|
+
return {
|
|
2817
|
+
"base-reducer": 2,
|
|
2818
|
+
...rest
|
|
2819
|
+
};
|
|
2820
|
+
}
|
|
2821
|
+
/** `base64url(sha256(canonicalJson(params)))`, unpadded. */
|
|
2822
|
+
function deriveDocumentId(params) {
|
|
2823
|
+
const preimage = canonicalJson({
|
|
2824
|
+
documentType: params.documentType,
|
|
2825
|
+
createdAtUtcIso: params.createdAtUtcIso,
|
|
2826
|
+
nonce: params.nonce,
|
|
2827
|
+
protocolVersions: params.protocolVersions
|
|
2828
|
+
}, "document id");
|
|
2829
|
+
return bytesToBase64Url(sha256(new TextEncoder().encode(preimage)));
|
|
2830
|
+
}
|
|
2831
|
+
/** Whether `id` has the shape `deriveDocumentId` produces. */
|
|
2832
|
+
function isDerivedDocumentId(id) {
|
|
2833
|
+
return DERIVED_ID.test(id);
|
|
2834
|
+
}
|
|
2835
|
+
function bytesToBase64Url(bytes) {
|
|
2836
|
+
let binary = "";
|
|
2837
|
+
for (let i = 0; i < bytes.length; i++) binary += String.fromCharCode(bytes[i]);
|
|
2838
|
+
return btoa(binary).replace(/\+/g, "-").replace(/\//g, "_").replace(/=+$/, "");
|
|
2839
|
+
}
|
|
2840
|
+
//#endregion
|
|
2685
2841
|
//#region document-model/header.ts
|
|
2686
2842
|
/**
|
|
2687
2843
|
* Generates a deterministic payload from signing parameters
|
|
@@ -2701,11 +2857,11 @@ async function createVerificationSigner(pubKey) {
|
|
|
2701
2857
|
}, true, ["verify"]);
|
|
2702
2858
|
return {
|
|
2703
2859
|
publicKey: cryptoKey,
|
|
2704
|
-
|
|
2705
|
-
|
|
2860
|
+
sign(_data) {
|
|
2861
|
+
return Promise.reject(/* @__PURE__ */ new Error("verification-only signer cannot sign data"));
|
|
2706
2862
|
},
|
|
2707
|
-
|
|
2708
|
-
|
|
2863
|
+
signAction(_action, _target, _abortSignal) {
|
|
2864
|
+
return Promise.reject(/* @__PURE__ */ new Error("verification-only signer cannot sign actions"));
|
|
2709
2865
|
},
|
|
2710
2866
|
async verify(data, signature) {
|
|
2711
2867
|
let isValid;
|
|
@@ -2775,26 +2931,68 @@ const validateHeader = async (header) => {
|
|
|
2775
2931
|
* Creates a header that has yet to be signed. This header is not valid, but
|
|
2776
2932
|
* can be input into {@link createSignedHeader} to create a signed header.
|
|
2777
2933
|
*
|
|
2934
|
+
* With `protocolVersions` requiring v2 signatures the header takes a random
|
|
2935
|
+
* nonce and the id {@link deriveDocumentId} gives, so `id` must be omitted.
|
|
2936
|
+
*
|
|
2778
2937
|
* @returns An unsigned header for a document.
|
|
2779
2938
|
*/
|
|
2780
|
-
const createPresignedHeader = (id
|
|
2781
|
-
|
|
2782
|
-
|
|
2939
|
+
const createPresignedHeader = (id, documentType = "", protocolVersions) => {
|
|
2940
|
+
const createdAtUtcIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
2941
|
+
const header = {
|
|
2942
|
+
id: id ?? generateId(),
|
|
2783
2943
|
sig: {
|
|
2784
2944
|
publicKey: {},
|
|
2785
2945
|
nonce: ""
|
|
2786
2946
|
},
|
|
2787
2947
|
documentType,
|
|
2788
|
-
createdAtUtcIso
|
|
2948
|
+
createdAtUtcIso,
|
|
2789
2949
|
slug: "",
|
|
2790
2950
|
name: "",
|
|
2791
2951
|
branch: "main",
|
|
2792
2952
|
revision: { document: 0 },
|
|
2793
|
-
lastModifiedAtUtcIso:
|
|
2953
|
+
lastModifiedAtUtcIso: createdAtUtcIso,
|
|
2794
2954
|
meta: {}
|
|
2795
2955
|
};
|
|
2956
|
+
if (protocolVersions === void 0) return header;
|
|
2957
|
+
header.protocolVersions = { ...protocolVersions };
|
|
2958
|
+
if (signaturePolicyOf(header) === "legacy") return header;
|
|
2959
|
+
if (id !== void 0) throw new Error(`A v2-required document's id is derived from its header; cannot use ${id}`);
|
|
2960
|
+
header.sig.nonce = generateId();
|
|
2961
|
+
header.id = deriveDocumentId({
|
|
2962
|
+
documentType,
|
|
2963
|
+
createdAtUtcIso,
|
|
2964
|
+
nonce: header.sig.nonce,
|
|
2965
|
+
protocolVersions: header.protocolVersions
|
|
2966
|
+
});
|
|
2967
|
+
return header;
|
|
2796
2968
|
};
|
|
2797
2969
|
/**
|
|
2970
|
+
* A header for a copy of a document headed `source`. A copy is v2-required
|
|
2971
|
+
* when its source is or when `policy` asks for it, and then takes a derived id;
|
|
2972
|
+
* otherwise it takes `id`. It keeps the source's other protocol versions.
|
|
2973
|
+
*/
|
|
2974
|
+
function createCopyHeader(source, id, policy = DEFAULT_SIGNATURE_POLICY) {
|
|
2975
|
+
const base = source.protocolVersions ?? {};
|
|
2976
|
+
if (signaturePolicyOf(source) === "v2-required" || policy === "v2-required") return createPresignedHeader(void 0, source.documentType, protocolVersionsFor("v2-required", base));
|
|
2977
|
+
const header = createPresignedHeader(id, source.documentType);
|
|
2978
|
+
if (source.protocolVersions) header.protocolVersions = { ...source.protocolVersions };
|
|
2979
|
+
return header;
|
|
2980
|
+
}
|
|
2981
|
+
/** Whether a v2-required `header` carries the id its params derive. */
|
|
2982
|
+
function hasDerivedDocumentId(header) {
|
|
2983
|
+
if (signaturePolicyOf(header) === "legacy" || !header.protocolVersions) return false;
|
|
2984
|
+
try {
|
|
2985
|
+
return deriveDocumentId({
|
|
2986
|
+
documentType: header.documentType,
|
|
2987
|
+
createdAtUtcIso: header.createdAtUtcIso,
|
|
2988
|
+
nonce: header.sig.nonce,
|
|
2989
|
+
protocolVersions: header.protocolVersions
|
|
2990
|
+
}) === header.id;
|
|
2991
|
+
} catch {
|
|
2992
|
+
return false;
|
|
2993
|
+
}
|
|
2994
|
+
}
|
|
2995
|
+
/**
|
|
2798
2996
|
* Creates a new, signed header for a document. This will replace the id of the
|
|
2799
2997
|
* document.
|
|
2800
2998
|
*
|
|
@@ -2855,9 +3053,7 @@ function isDocumentAction(action) {
|
|
|
2855
3053
|
"SET_NAME",
|
|
2856
3054
|
"SET_PREFERRED_EDITOR",
|
|
2857
3055
|
"UNDO",
|
|
2858
|
-
"REDO"
|
|
2859
|
-
"PRUNE",
|
|
2860
|
-
"LOAD_STATE"
|
|
3056
|
+
"REDO"
|
|
2861
3057
|
].includes(action.type);
|
|
2862
3058
|
}
|
|
2863
3059
|
/**
|
|
@@ -2913,12 +3109,16 @@ function createDocumentScopeOperations(header, state) {
|
|
|
2913
3109
|
}
|
|
2914
3110
|
/**
|
|
2915
3111
|
* Creates a new document. When `documentType` is given the header is stamped
|
|
2916
|
-
* with it and the document-scope operations are seeded.
|
|
3112
|
+
* with it and the document-scope operations are seeded. Without
|
|
3113
|
+
* `protocolVersions` the document is v2-required and takes a derived id; with
|
|
3114
|
+
* them it is v2-required only if they say so (see {@link protocolVersionsFor}).
|
|
2917
3115
|
*/
|
|
2918
|
-
function baseCreateDocument(createState, initialState, documentType = "") {
|
|
3116
|
+
function baseCreateDocument(createState, initialState, documentType = "", protocolVersions) {
|
|
2919
3117
|
const state = createState(initialState);
|
|
2920
|
-
const header = createPresignedHeader(
|
|
2921
|
-
|
|
3118
|
+
const header = createPresignedHeader(void 0, documentType, protocolVersions === void 0 ? protocolVersionsFor("v2-required") : {
|
|
3119
|
+
"base-reducer": 2,
|
|
3120
|
+
...protocolVersions
|
|
3121
|
+
});
|
|
2922
3122
|
return {
|
|
2923
3123
|
header,
|
|
2924
3124
|
state,
|
|
@@ -2934,6 +3134,36 @@ function baseCreateDocument(createState, initialState, documentType = "") {
|
|
|
2934
3134
|
clipboard: []
|
|
2935
3135
|
};
|
|
2936
3136
|
}
|
|
3137
|
+
/**
|
|
3138
|
+
* `document`, not yet created, under a fresh header for `policy`. A legacy
|
|
3139
|
+
* header takes `id` when given; a v2-required one ignores `id` and derives its
|
|
3140
|
+
* own, so a caller that needs a fixed id must ask for legacy.
|
|
3141
|
+
* `protocolVersions` are merged over the document's. Name, slug, branch and
|
|
3142
|
+
* meta carry over. A document already under `policy` is returned as is unless
|
|
3143
|
+
* a legacy `id` or `protocolVersions` are given.
|
|
3144
|
+
*/
|
|
3145
|
+
function withSignaturePolicy(document, policy, options = {}) {
|
|
3146
|
+
const id = policy === "legacy" ? options.id : void 0;
|
|
3147
|
+
if (id === void 0 && options.protocolVersions === void 0 && signaturePolicyOf(document.header) === policy) return document;
|
|
3148
|
+
const source = document.header;
|
|
3149
|
+
const header = createPresignedHeader(id, source.documentType, protocolVersionsFor(policy, {
|
|
3150
|
+
...source.protocolVersions,
|
|
3151
|
+
...options.protocolVersions
|
|
3152
|
+
}));
|
|
3153
|
+
header.name = source.name;
|
|
3154
|
+
header.slug = source.slug;
|
|
3155
|
+
header.branch = source.branch;
|
|
3156
|
+
header.meta = source.meta;
|
|
3157
|
+
const operations = document.operations.document ? {
|
|
3158
|
+
...document.operations,
|
|
3159
|
+
document: createDocumentScopeOperations(header, document.state)
|
|
3160
|
+
} : document.operations;
|
|
3161
|
+
return {
|
|
3162
|
+
...document,
|
|
3163
|
+
header,
|
|
3164
|
+
operations
|
|
3165
|
+
};
|
|
3166
|
+
}
|
|
2937
3167
|
function hashDocumentStateForScope(document, scope = "global") {
|
|
2938
3168
|
return hashBrowser(stringify(document.state[scope] || ""));
|
|
2939
3169
|
}
|
|
@@ -3628,18 +3858,6 @@ function redoOperation(document, action, skip) {
|
|
|
3628
3858
|
});
|
|
3629
3859
|
});
|
|
3630
3860
|
}
|
|
3631
|
-
function loadStateOperation(document, action) {
|
|
3632
|
-
const loaded = backfillAuthState(action.state.data);
|
|
3633
|
-
loaded.auth = resolveSnapshotAuth(document.header.id, document.header.documentType, backfillAuthState({ ...document.state }).auth, loaded.auth);
|
|
3634
|
-
return {
|
|
3635
|
-
...document,
|
|
3636
|
-
header: {
|
|
3637
|
-
...document.header,
|
|
3638
|
-
name: action.state.name
|
|
3639
|
-
},
|
|
3640
|
-
state: loaded
|
|
3641
|
-
};
|
|
3642
|
-
}
|
|
3643
3861
|
/**
|
|
3644
3862
|
* Reads an operation's outcome. A denial takes precedence over a reducer
|
|
3645
3863
|
* error, since a denied operation never reaches its reducer.
|
|
@@ -3672,11 +3890,7 @@ function replayOperations(initialState, clearedOperations, stateReducer, header,
|
|
|
3672
3890
|
* @returns The updated document state.
|
|
3673
3891
|
*/
|
|
3674
3892
|
function updateOperationsForAction(document, action, reuseLastOperationIndex, skip, context) {
|
|
3675
|
-
if ([
|
|
3676
|
-
"UNDO",
|
|
3677
|
-
"REDO",
|
|
3678
|
-
"PRUNE"
|
|
3679
|
-
].includes(action.type)) return document;
|
|
3893
|
+
if (["UNDO", "REDO"].includes(action.type)) return document;
|
|
3680
3894
|
const scope = action.scope;
|
|
3681
3895
|
const existing = document.operations[scope];
|
|
3682
3896
|
const lastOperationIndex = existing?.at(-1)?.index ?? -1;
|
|
@@ -3724,20 +3938,17 @@ function updateDocument(document, action, reuseLastOperationIndex, skip, context
|
|
|
3724
3938
|
return newDocument;
|
|
3725
3939
|
}
|
|
3726
3940
|
/**
|
|
3727
|
-
* The base document reducer function
|
|
3941
|
+
* The base document reducer function.
|
|
3728
3942
|
*
|
|
3729
3943
|
* @param state The current state of the document.
|
|
3730
3944
|
* @param action The action being applied to the document.
|
|
3731
|
-
* @param wrappedReducer The custom reducer function being wrapped by the base reducer.
|
|
3732
3945
|
* @returns The updated document state.
|
|
3733
3946
|
*/
|
|
3734
|
-
function _baseReducer(document, action
|
|
3947
|
+
function _baseReducer(document, action) {
|
|
3735
3948
|
const parsedAction = DocumentActionSchema().parse(action);
|
|
3736
3949
|
switch (parsedAction.type) {
|
|
3737
3950
|
case "SET_NAME": return setNameOperation(document, parsedAction.input);
|
|
3738
3951
|
case "SET_PREFERRED_EDITOR": return setPreferredEditorOperation(document, parsedAction.input);
|
|
3739
|
-
case "PRUNE": return pruneOperation(document, parsedAction.input, wrappedReducer);
|
|
3740
|
-
case "LOAD_STATE": return loadStateOperation(document, parsedAction.input);
|
|
3741
3952
|
default: return document;
|
|
3742
3953
|
}
|
|
3743
3954
|
}
|
|
@@ -3815,7 +4026,7 @@ function processUndoOperation(document, scope, customReducer, reuseOperationResu
|
|
|
3815
4026
|
}
|
|
3816
4027
|
/**
|
|
3817
4028
|
* Base document reducer that wraps a custom document reducer and handles
|
|
3818
|
-
* document-level actions such as undo, redo,
|
|
4029
|
+
* document-level actions such as undo, redo, and set name.
|
|
3819
4030
|
*
|
|
3820
4031
|
* @template TGlobalState - The type of the state of the custom reducer.
|
|
3821
4032
|
* @template TAction - The type of the actions of the custom reducer.
|
|
@@ -3843,7 +4054,7 @@ function baseReducer(document, action, customReducer, dispatch, options = {}) {
|
|
|
3843
4054
|
...newDocument,
|
|
3844
4055
|
clipboard: []
|
|
3845
4056
|
};
|
|
3846
|
-
if (isDocumentAction(_action)) newDocument = _baseReducer(newDocument, _action
|
|
4057
|
+
if (isDocumentAction(_action)) newDocument = _baseReducer(newDocument, _action);
|
|
3847
4058
|
const operationContext = {
|
|
3848
4059
|
documentId: document.header.id,
|
|
3849
4060
|
scope: _action.scope,
|
|
@@ -3906,11 +4117,7 @@ function baseReducer(document, action, customReducer, dispatch, options = {}) {
|
|
|
3906
4117
|
}
|
|
3907
4118
|
}
|
|
3908
4119
|
});
|
|
3909
|
-
if ([
|
|
3910
|
-
"UNDO",
|
|
3911
|
-
"REDO",
|
|
3912
|
-
"PRUNE"
|
|
3913
|
-
].includes(_action.type)) return newDocument;
|
|
4120
|
+
if (["UNDO", "REDO"].includes(_action.type)) return newDocument;
|
|
3914
4121
|
const scope = _action.scope || "global";
|
|
3915
4122
|
const replayHash = options.replayOptions?.operation.hash;
|
|
3916
4123
|
const hash = replayHash ? replayHash : hashDocumentStateForScope(newDocument, scope);
|
|
@@ -3930,7 +4137,6 @@ function baseReducer(document, action, customReducer, dispatch, options = {}) {
|
|
|
3930
4137
|
* - `SET_NAME`
|
|
3931
4138
|
* - `UNDO`
|
|
3932
4139
|
* - `REDO`
|
|
3933
|
-
* - `PRUNE`
|
|
3934
4140
|
*
|
|
3935
4141
|
* It also updates the document-related attributes on every operation.
|
|
3936
4142
|
*
|
|
@@ -3945,46 +4151,6 @@ function createReducer(stateReducer, documentReducer = baseReducer) {
|
|
|
3945
4151
|
};
|
|
3946
4152
|
return reducer;
|
|
3947
4153
|
}
|
|
3948
|
-
function pruneOperation(document, input, wrappedReducer) {
|
|
3949
|
-
const operations = document.operations.global;
|
|
3950
|
-
if (!operations) throw new Error("No global operations found");
|
|
3951
|
-
let { start, end } = input;
|
|
3952
|
-
start = start || 0;
|
|
3953
|
-
end = end || operations.length;
|
|
3954
|
-
const actionsToPrune = operations.slice(start, end);
|
|
3955
|
-
const actionsToKeepStart = operations.slice(0, start);
|
|
3956
|
-
const actionsToKeepEnd = operations.slice(end);
|
|
3957
|
-
const newDocument = replayOperations(document.initialState, {
|
|
3958
|
-
...document.operations,
|
|
3959
|
-
global: actionsToKeepStart.concat(actionsToPrune)
|
|
3960
|
-
}, wrappedReducer, document.header);
|
|
3961
|
-
const newState = newDocument.state;
|
|
3962
|
-
const name = newDocument.header.name;
|
|
3963
|
-
const loadStateIndex = actionsToKeepStart.length;
|
|
3964
|
-
const loadStateTimestamp = actionsToKeepStart.length ? actionsToKeepStart[actionsToKeepStart.length - 1].timestampUtcMs : actionsToKeepEnd.length ? actionsToKeepEnd[0].timestampUtcMs : (/* @__PURE__ */ new Date()).toISOString();
|
|
3965
|
-
const action = loadState({
|
|
3966
|
-
name,
|
|
3967
|
-
...newState
|
|
3968
|
-
}, actionsToPrune.length);
|
|
3969
|
-
return replayOperations(document.initialState, {
|
|
3970
|
-
...document.operations,
|
|
3971
|
-
global: [
|
|
3972
|
-
...actionsToKeepStart,
|
|
3973
|
-
{
|
|
3974
|
-
skip: 0,
|
|
3975
|
-
...action,
|
|
3976
|
-
action,
|
|
3977
|
-
timestampUtcMs: loadStateTimestamp,
|
|
3978
|
-
index: loadStateIndex,
|
|
3979
|
-
hash: hashDocumentStateForScope({ state: newState }, "global")
|
|
3980
|
-
},
|
|
3981
|
-
...actionsToKeepEnd.map((action, index) => ({
|
|
3982
|
-
...action,
|
|
3983
|
-
index: loadStateIndex + index + 1
|
|
3984
|
-
}))
|
|
3985
|
-
]
|
|
3986
|
-
}, wrappedReducer, document.header);
|
|
3987
|
-
}
|
|
3988
4154
|
//#endregion
|
|
3989
4155
|
//#region document-model/validation.ts
|
|
3990
4156
|
/**
|
|
@@ -3994,8 +4160,6 @@ function pruneOperation(document, input, wrappedReducer) {
|
|
|
3994
4160
|
const RESERVED_OPERATION_NAMES = [
|
|
3995
4161
|
"UNDO",
|
|
3996
4162
|
"REDO",
|
|
3997
|
-
"PRUNE",
|
|
3998
|
-
"LOAD_STATE",
|
|
3999
4163
|
"SET_NAME",
|
|
4000
4164
|
"SET_PREFERRED_EDITOR",
|
|
4001
4165
|
"NOOP"
|
|
@@ -4234,6 +4398,15 @@ function orderBy(items, order) {
|
|
|
4234
4398
|
return (rank.get(a.item.id) ?? Number.MAX_SAFE_INTEGER) - (rank.get(b.item.id) ?? Number.MAX_SAFE_INTEGER) || a.index - b.index;
|
|
4235
4399
|
}).map(({ item }) => item);
|
|
4236
4400
|
}
|
|
4401
|
+
/**
|
|
4402
|
+
* The untouched base of a mutative draft, or the value itself when it is not a
|
|
4403
|
+
* draft. Build replacement lists from it and freeze them before assigning, as
|
|
4404
|
+
* the drive node reducer does, so finalize skips the walk over the assigned
|
|
4405
|
+
* list. Read before writing: the base does not see this action's mutations.
|
|
4406
|
+
*/
|
|
4407
|
+
function readBase(value) {
|
|
4408
|
+
return isDraft(value) ? original(value) : value;
|
|
4409
|
+
}
|
|
4237
4410
|
const documentModelHeaderReducer = {
|
|
4238
4411
|
setModelNameOperation(state, action) {
|
|
4239
4412
|
state.name = action.input.name;
|
|
@@ -4283,7 +4456,8 @@ const documentModelModuleReducer = {
|
|
|
4283
4456
|
deleteModuleOperation(state, action) {
|
|
4284
4457
|
findModuleOrThrow(state, action.input.id);
|
|
4285
4458
|
const latestSpec = state.specifications[state.specifications.length - 1];
|
|
4286
|
-
|
|
4459
|
+
const modules = readBase(latestSpec).modules.filter((m) => m.id != action.input.id);
|
|
4460
|
+
latestSpec.modules = Object.freeze(modules);
|
|
4287
4461
|
},
|
|
4288
4462
|
reorderModulesOperation(state, action) {
|
|
4289
4463
|
const latestSpec = state.specifications[state.specifications.length - 1];
|
|
@@ -4401,14 +4575,20 @@ const documentModelOperationReducer = {
|
|
|
4401
4575
|
const matches = latestSpec.modules.flatMap((mod) => mod.operations.filter((op) => op.id === action.input.operationId));
|
|
4402
4576
|
if (matches.length === 0) throw new Error(`Operation "${action.input.operationId}" not found in the latest specification`);
|
|
4403
4577
|
if (matches.length > 1) throw new Error(`Operation "${action.input.operationId}" is duplicated in the latest specification`);
|
|
4404
|
-
const moved = matches[0];
|
|
4405
|
-
for (const mod of latestSpec.modules)
|
|
4406
|
-
|
|
4578
|
+
const moved = readBase(matches[0]);
|
|
4579
|
+
for (const mod of latestSpec.modules) {
|
|
4580
|
+
const operations = readBase(mod).operations.filter((op) => op.id !== action.input.operationId);
|
|
4581
|
+
if (mod === targetModule) operations.push(moved);
|
|
4582
|
+
mod.operations = Object.freeze(operations);
|
|
4583
|
+
}
|
|
4407
4584
|
},
|
|
4408
4585
|
deleteOperationOperation(state, action) {
|
|
4409
4586
|
findOperationOrThrow(state, action.input.id);
|
|
4410
4587
|
const latestSpec = state.specifications[state.specifications.length - 1];
|
|
4411
|
-
for (const mod of latestSpec.modules)
|
|
4588
|
+
for (const mod of latestSpec.modules) {
|
|
4589
|
+
const operations = readBase(mod).operations.filter((operation) => operation.id != action.input.id);
|
|
4590
|
+
mod.operations = Object.freeze(operations);
|
|
4591
|
+
}
|
|
4412
4592
|
},
|
|
4413
4593
|
reorderModuleOperationsOperation(state, action) {
|
|
4414
4594
|
const targetModule = findModuleOrThrow(state, action.input.moduleId);
|
|
@@ -4446,7 +4626,8 @@ const documentModelStateSchemaReducer = {
|
|
|
4446
4626
|
if (!Object.keys(latestSpec.state).includes(action.input.scope)) throw new Error(`Invalid scope: ${action.input.scope}`);
|
|
4447
4627
|
const scopeState = latestSpec.state[action.input.scope];
|
|
4448
4628
|
if (!scopeState.examples.some((e) => e.id == action.input.id)) throw new Error(`State example "${action.input.id}" not found in scope "${action.input.scope}"`);
|
|
4449
|
-
|
|
4629
|
+
const examples = readBase(scopeState).examples.filter((e) => e.id != action.input.id);
|
|
4630
|
+
scopeState.examples = Object.freeze(examples);
|
|
4450
4631
|
},
|
|
4451
4632
|
reorderStateExamplesOperation(state, action) {
|
|
4452
4633
|
const latestSpec = state.specifications[state.specifications.length - 1];
|
|
@@ -4716,7 +4897,11 @@ function applyUpgradeDocumentAction(document, action, upgradePath) {
|
|
|
4716
4897
|
const toVersion = action.input.toVersion;
|
|
4717
4898
|
if (fromVersion === toVersion && fromVersion > 0) return document;
|
|
4718
4899
|
if (fromVersion > toVersion) throw new DowngradeNotSupportedError(document.header.documentType, fromVersion, toVersion);
|
|
4719
|
-
if (upgradePath)
|
|
4900
|
+
if (upgradePath) {
|
|
4901
|
+
const protocolVersions = document.header.protocolVersions;
|
|
4902
|
+
for (const transition of upgradePath) document = transition.upgradeReducer(document, action);
|
|
4903
|
+
document = withProtocolVersions(document, protocolVersions);
|
|
4904
|
+
}
|
|
4720
4905
|
applyInitialState(document, action);
|
|
4721
4906
|
document.state.document = {
|
|
4722
4907
|
...document.state.document,
|
|
@@ -4724,6 +4909,16 @@ function applyUpgradeDocumentAction(document, action, upgradePath) {
|
|
|
4724
4909
|
};
|
|
4725
4910
|
return document;
|
|
4726
4911
|
}
|
|
4912
|
+
/** CREATE_DOCUMENT fixes `protocolVersions`; this puts them back after a reducer. */
|
|
4913
|
+
function withProtocolVersions(document, protocolVersions) {
|
|
4914
|
+
const header = { ...document.header };
|
|
4915
|
+
if (protocolVersions === void 0) delete header.protocolVersions;
|
|
4916
|
+
else header.protocolVersions = { ...protocolVersions };
|
|
4917
|
+
return {
|
|
4918
|
+
...document,
|
|
4919
|
+
header
|
|
4920
|
+
};
|
|
4921
|
+
}
|
|
4727
4922
|
/**
|
|
4728
4923
|
* Applies a DELETE_DOCUMENT action to a document.
|
|
4729
4924
|
* Marks the document as deleted in the document scope state.
|
|
@@ -5059,7 +5254,9 @@ async function parseZipData(data) {
|
|
|
5059
5254
|
if (!files["header.json"]) throw new Error("Document header not found - file format may be outdated");
|
|
5060
5255
|
const header = JSON.parse(readEntry(files, "header.json"));
|
|
5061
5256
|
if (!files["operations.json"]) throw new Error("Operations history not found");
|
|
5062
|
-
const
|
|
5257
|
+
const operations = JSON.parse(readEntry(files, "operations.json"));
|
|
5258
|
+
const clearedOperations = garbageCollectDocumentOperations(operations);
|
|
5259
|
+
pinProtocolVersionsToCreate(header, operations);
|
|
5063
5260
|
const operationsError = validateOperations(clearedOperations);
|
|
5064
5261
|
if (operationsError.length) {
|
|
5065
5262
|
const errorMessages = operationsError.map((err) => err.message);
|
|
@@ -5071,6 +5268,17 @@ async function parseZipData(data) {
|
|
|
5071
5268
|
clearedOperations
|
|
5072
5269
|
};
|
|
5073
5270
|
}
|
|
5271
|
+
/** header.json is a snapshot; the stored CREATE_DOCUMENT input wins. */
|
|
5272
|
+
function pinProtocolVersionsToCreate(header, operations) {
|
|
5273
|
+
const create = operations.document?.find((operation) => operation.action.type === "CREATE_DOCUMENT");
|
|
5274
|
+
if (!create) return;
|
|
5275
|
+
const input = create.action.input;
|
|
5276
|
+
if (input?.protocolVersions) header.protocolVersions = { ...input.protocolVersions };
|
|
5277
|
+
else if (header.protocolVersions) {
|
|
5278
|
+
const { [SIGNATURE_PROTOCOL]: _dropped, ...rest } = header.protocolVersions;
|
|
5279
|
+
header.protocolVersions = rest;
|
|
5280
|
+
}
|
|
5281
|
+
}
|
|
5074
5282
|
async function loadFromZipData(data, reducer, options) {
|
|
5075
5283
|
const { initialState, header, clearedOperations } = await parseZipData(data);
|
|
5076
5284
|
return {
|
|
@@ -5146,6 +5354,6 @@ const getFileBrowser = (file) => {
|
|
|
5146
5354
|
return Promise.resolve().then(() => readFileBrowser(file));
|
|
5147
5355
|
};
|
|
5148
5356
|
//#endregion
|
|
5149
|
-
export { AUTH_ACTION_TYPES, AUTH_DENIED_BY_GRANT_REASON, AUTH_NO_GRANT_REASON, AUTH_VERSION_UNSUPPORTED_REASON, AddChangeLogItemInputSchema, AddModuleInputSchema, AddOperationErrorInputSchema, AddOperationExampleInputSchema, AddOperationInputSchema, AddStateExampleInputSchema, AuthActionNotAllowedError, AuthAdministrationLockoutError, AuthAdministrationMissingError, AuthAlreadyInitializedError, AuthInitializerNotCreatorError, AuthPolicyNotPreservedError, AuthorSchema, BaseDocumentHeaderSchema, BaseDocumentStateSchema, CodeExampleSchema, ConfigEntrySchema, ConfigEntryTypeSchema, DOCUMENT_DELETED_REASON, DeleteChangeLogItemInputSchema, DeleteModuleInputSchema, DeleteOperationErrorInputSchema, DeleteOperationExampleInputSchema, DeleteOperationInputSchema, DeleteStateExampleInputSchema, DocumentActionSchema, DocumentModelGlobalStateSchema, DocumentModelHeaderSchema, DocumentModelInputSchema, DocumentModelPHStateSchema, DocumentModelSchema, DocumentSpecificationSchema, DowngradeNotSupportedError, FileSystemError, GrantNotFoundError, GrantSchema, GroupPrincipalNotAllowedError, HASH_ALGORITHM_SHA1, HASH_ALGORITHM_SHA256, HASH_ALGORITHM_SHA512, HASH_ENCODING_BASE64, HASH_ENCODING_HEX, HashMismatchError, InitializeAuthActionInputSchema, IntegrityIssueSubType, IntegrityIssueType, InvalidActionInputError, InvalidActionInputZodError, InvalidAuthVersionError, InvalidGrantError,
|
|
5357
|
+
export { ACTION_SIGNATURE_V2_PREFIX, AUTH_ACTION_TYPES, AUTH_DENIED_BY_GRANT_REASON, AUTH_NO_GRANT_REASON, AUTH_VERSION_UNSUPPORTED_REASON, AddChangeLogItemInputSchema, AddModuleInputSchema, AddOperationErrorInputSchema, AddOperationExampleInputSchema, AddOperationInputSchema, AddStateExampleInputSchema, AuthActionNotAllowedError, AuthAdministrationLockoutError, AuthAdministrationMissingError, AuthAlreadyInitializedError, AuthInitializerNotCreatorError, AuthPolicyNotPreservedError, AuthorSchema, BaseDocumentHeaderSchema, BaseDocumentStateSchema, CanonicalJsonError, CodeExampleSchema, ConfigEntrySchema, ConfigEntryTypeSchema, DEFAULT_SIGNATURE_POLICY, DOCUMENT_DELETED_REASON, DOCUMENT_SCOPE_ACTION_TYPES, DeleteChangeLogItemInputSchema, DeleteModuleInputSchema, DeleteOperationErrorInputSchema, DeleteOperationExampleInputSchema, DeleteOperationInputSchema, DeleteStateExampleInputSchema, DocumentActionSchema, DocumentModelGlobalStateSchema, DocumentModelHeaderSchema, DocumentModelInputSchema, DocumentModelPHStateSchema, DocumentModelSchema, DocumentSpecificationSchema, DowngradeNotSupportedError, FileSystemError, GrantNotFoundError, GrantSchema, GroupPrincipalNotAllowedError, HASH_ALGORITHM_SHA1, HASH_ALGORITHM_SHA256, HASH_ALGORITHM_SHA512, HASH_ENCODING_BASE64, HASH_ENCODING_HEX, HashMismatchError, InitializeAuthActionInputSchema, IntegrityIssueSubType, IntegrityIssueType, InvalidActionInputError, InvalidActionInputZodError, InvalidAuthVersionError, InvalidGrantError, MAX_AUTH_GRANTS, MAX_CAPABILITY_OPERATIONS, MAX_CONDITION_DEPTH, MAX_CONDITION_NODES, MAX_SUPPORTED_AUTH_VERSION, ManifestSchema, ModuleSchema, MoveGrantActionInputSchema, MoveOperationInputSchema, OPERATION_NAME_PATTERN, OperationErrorSchema, OperationScopeSchema, OperationSpecificationSchema, PieceModuleSchema, PieceModulesSchema, PowerhouseModuleSchema, PowerhouseModulesSchema, PublisherSchema, PwaConfigSchema, RESERVED_OPERATION_NAMES, RedoActionInputSchema, RedoActionSchema, RedoSchema, RemoveGrantActionInputSchema, ReorderChangeLogItemsInputSchema, ReorderModuleOperationsInputSchema, ReorderModulesInputSchema, ReorderOperationErrorsInputSchema, ReorderOperationExamplesInputSchema, ReorderStateExamplesInputSchema, SIGNATURE_PROTOCOL, SIGNATURE_PROTOCOL_V2, ScopeStateSchema, SetAuthorNameInputSchema, SetAuthorWebsiteInputSchema, SetGrantActionInputSchema, SetInitialStateInputSchema, SetModelDescriptionInputSchema, SetModelExtensionInputSchema, SetModelIdInputSchema, SetModelNameInputSchema, SetModuleDescriptionInputSchema, SetModuleNameInputSchema, SetNameActionInputSchema, SetNameActionSchema, SetOperationDescriptionInputSchema, SetOperationErrorCodeInputSchema, SetOperationErrorDescriptionInputSchema, SetOperationErrorNameInputSchema, SetOperationErrorTemplateInputSchema, SetOperationNameInputSchema, SetOperationReducerInputSchema, SetOperationSchemaInputSchema, SetOperationScopeInputSchema, SetOperationTemplateInputSchema, SetPreferredEditorActionInputSchema, SetPreferredEditorActionSchema, SetStateSchemaInputSchema, Set_NameSchema, Set_PreferredEditorSchema, StateSchema, UndoActionInputSchema, UndoActionSchema, UndoSchema, UnsupportedDocumentModelVersionError, UpdateChangeLogItemInputSchema, UpdateOperationExampleInputSchema, UpdateStateExampleInputSchema, ab2hex, actionContext, actionFromAction, actionPreimageV2, actionSigner, actionSignerIdentity, actionSigningTarget, actions, addChangeLogItem, addModule, addOperation, addOperationError, addOperationExample, addStateExample, addUndo, appendWithoutApplying, applyAuthAction, applyDeleteDocumentAction, applyInitializeAuthAction, applyMoveGrantAction, applyRemoveGrantAction, applySetGrantAction, applyUpgradeDocumentAction, assertAuthAdministrationRetained, assertAuthPreservedOnDuplicate, assertAuthScopeActionAllowed, assertIsDocumentModelDocument, assertIsDocumentModelState, assertModuleIdUnique, assertOperationErrorIdUnique, assertOperationExampleIdUnique, assertOperationIdUnique, assertValidGrant, assertValidGrantUpsert, assertValidInitialGrants, attachBranch, backfillAuthState, base58Decode, base64UrlToBytes, baseActions, baseCreateDocument, baseLoadFromInput, baseLoadFromInputVersioned, baseReducer, baseReducerVersion, baseSaveToFileHandle, buildOperationSignature, buildOperationSignatureMessage, buildOperationSignatureParams, buildSignedAction, canonicalJson, checkCleanedOperationsIntegrity, checkOperationsIntegrity, computeUpgradeTransitions, createAction, createAuthState, createBaseState, createCopyHeader, createDocumentState, createGlobalState, createLocalState, createMinimalZip, createPresignedHeader, createReducer, createSignedHeader, createSignedHeaderForSigner, createState, createVerificationSigner, createZip, decide, defaultAuthState, defaultBaseState, defaultDocumentState, defaultGlobalState, defaultLocalState, defaultPHState, definedNonNullAnySchema, deleteChangeLogItem, deleteModule, deleteOperation, deleteOperationError, deleteOperationExample, deleteStateExample, deriveDocumentId, deriveOperationId, deserializeSignature, diffOperations, documentModelActions, documentModelDocumentType, documentModelFileExtension, documentModelGlobalState, documentModelHeaderReducer, documentModelInitialGlobalState, documentModelInitialLocalState, documentModelLoadFromInput, documentModelModuleReducer, documentModelOperationErrorReducer, documentModelOperationExampleReducer, documentModelOperationReducer, documentModelReducer, documentModelSaveToFileHandle, documentModelStateReducer, documentModelStateSchemaReducer, documentModelVersioningReducer, evaluate, evaluateCondition, evaluateGrantStack, evaluateGrants, fetchFileBrowser, filterDocumentOperationsResultingState, filterDuplicatedOperations, findModuleOrThrow, findOperationErrorOrThrow, findOperationExampleOrThrow, findOperationOrThrow, garbageCollect, garbageCollectDocumentOperations, garbageCollectV2, generateId, generateMock, getAllOperationNames, getDocumentLastModified, getFileBrowser, getUnixTimestamp, grantProblem, groupDocumentType, groupMembershipActionTypes, groupOperationsByScope, hasDerivedDocumentId, hashActionV2, hashBrowser, hashDocumentStateForScope, hex2ab, initializeAuth, isAuthAction, isDefinedNonNullAny, isDenied, isDerivedDocumentId, isDocumentAction, isDocumentCreator, isDocumentModelDocument, isDocumentModelState, isDocumentZip, isNoopOperation, isPlainValue, isReservedOperationName, isSignaturePolicy, isUndo, isUndoRedo, isV2ActionHash, isValidOperationNameFormat, mapSkippedOperations, mapSkippedOperationsV2, mentionedGroupIds, merge, moveGrant, moveOperation, nextSkipNumber, noop, normalizeDocumentModelVersion, operationExampleCreators, operationFromAction, operationFromOperation, operationOutcome, operationWithContext, operationsAreEqual, parseBulkArchive, parseResultingState, precedes, prepareOperations, processUndoRedo, protocolVersionsFor, readFileBrowser, readOnly, redo, redoOperation, referencedGroupIds, releaseNewVersion, removeExistingOperations, removeGrant, reorderChangeLogItems, reorderModuleOperations, reorderModules, reorderOperationErrors, reorderOperationExamples, reorderStateExamples, replayDocument, replayDocumentVersioned, replayOperations, requestedSignaturePolicy, reshuffleByTimestamp, reshuffleByTimestampAndIndex, resolveSnapshotAuth, serializeSignature, setAuthorName, setAuthorWebsite, setGrant, setInitialState, setModelDescription, setModelExtension, setModelId, setModelName, setModuleDescription, setModuleName, setName, setNameOperation, setOperationDescription, setOperationErrorCode, setOperationErrorDescription, setOperationErrorName, setOperationErrorTemplate, setOperationName, setOperationReducer, setOperationSchema, setOperationScope, setOperationTemplate, setPreferredEditor, setPreferredEditorOperation, setStateSchema, sign, signActionV2, signaturePolicyOf, skipHeaderOperations, sortMappedOperations, sortOperations, split, targetDocumentId, toTransportAction, undo, undoOperation, undoOperationV2, updateChangeLogItem, updateDocument, updateHeaderRevision, updateOperationExample, updateStateExample, v2RequiredProtocolVersions, v2TupleProblem, validateHeader, validateInitialState, validateModule, validateModuleOperation, validateModules, validateOperationName, validateOperations, validateStateSchemaName, verify, verifyOperationSignature, withProtocolVersions, withSignaturePolicy, writeFileBrowser, zipEntries };
|
|
5150
5358
|
|
|
5151
5359
|
//# sourceMappingURL=index.js.map
|