@portabletext/plugin-sdk-value 7.0.35-crx.0 → 7.0.36-crx.0
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/index.d.ts +17 -0
- package/dist/index.js +198 -15
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {DocumentHandle} from '@sanity/sdk-react'
|
|
2
2
|
import {JSX} from 'react'
|
|
3
|
+
import {Patch} from '@portabletext/editor'
|
|
3
4
|
import {PortableTextBlock} from '@portabletext/editor'
|
|
4
5
|
|
|
5
6
|
/**
|
|
@@ -18,6 +19,22 @@ declare type ValueSyncConfig = {
|
|
|
18
19
|
getRemoteValue: () => PortableTextBlock[] | null | undefined
|
|
19
20
|
pushValue: (value: PortableTextBlock[]) => void
|
|
20
21
|
onRemoteValueChange: (callback: () => void) => () => void
|
|
22
|
+
/**
|
|
23
|
+
* Optional patch channel. When provided, operational patches from other
|
|
24
|
+
* clients are applied directly to the editor (in every state) instead of
|
|
25
|
+
* waiting for a whole-value diff, and local editor patches are pushed
|
|
26
|
+
* through `pushPatches`. The whole-value sync remains as a fallback for
|
|
27
|
+
* anything the patch channel cannot express.
|
|
28
|
+
*/
|
|
29
|
+
onRemotePatches?: (
|
|
30
|
+
callback: (patches: Patch[]) => void,
|
|
31
|
+
) => (() => void) | undefined
|
|
32
|
+
/**
|
|
33
|
+
* Pushes the editor's own operational patches to the remote store. May
|
|
34
|
+
* throw when a patch cannot be converted, in which case the plugin falls
|
|
35
|
+
* back to pushing the whole value.
|
|
36
|
+
*/
|
|
37
|
+
pushPatches?: (patches: Patch[]) => void
|
|
21
38
|
}
|
|
22
39
|
|
|
23
40
|
/**
|
package/dist/index.js
CHANGED
|
@@ -3,8 +3,9 @@ import { c } from "react/compiler-runtime";
|
|
|
3
3
|
import { useEditor } from "@portabletext/editor";
|
|
4
4
|
import { diffValue } from "@sanity/diff-patch";
|
|
5
5
|
import { parsePath } from "@sanity/json-match";
|
|
6
|
-
import { useEditDocument, useSanityInstance, getDocumentState } from "@sanity/sdk-react";
|
|
6
|
+
import { useEditDocument, useSanityInstance, useApplyDocumentActions, getDocumentState, subscribeDocumentEvents, editDocument } from "@sanity/sdk-react";
|
|
7
7
|
import { useActorRef } from "@xstate/react";
|
|
8
|
+
import "react";
|
|
8
9
|
import { fromCallback, setup } from "xstate";
|
|
9
10
|
function* getSegments(node) {
|
|
10
11
|
node.base && (yield* getSegments(node.base)), node.segment.type !== "This" && (yield node.segment);
|
|
@@ -100,6 +101,106 @@ function convertPatches(patches) {
|
|
|
100
101
|
incomplete
|
|
101
102
|
};
|
|
102
103
|
}
|
|
104
|
+
const STRINGIFY_ERROR_MESSAGE = "Unable to convert an editor patch path to a Sanity path expression.";
|
|
105
|
+
function stringifyPatchPath(path) {
|
|
106
|
+
let result = "";
|
|
107
|
+
for (const segment of path)
|
|
108
|
+
if (typeof segment == "string")
|
|
109
|
+
result = result === "" ? segment : `${result}.${segment}`;
|
|
110
|
+
else if (typeof segment == "number")
|
|
111
|
+
result = `${result}[${segment}]`;
|
|
112
|
+
else if (typeof segment == "object" && segment !== null && "_key" in segment)
|
|
113
|
+
result = `${result}[_key=="${segment._key}"]`;
|
|
114
|
+
else
|
|
115
|
+
throw new Error(STRINGIFY_ERROR_MESSAGE);
|
|
116
|
+
return result;
|
|
117
|
+
}
|
|
118
|
+
function prefixPathExpression(prefix, expression) {
|
|
119
|
+
return expression === "" ? prefix : expression.startsWith("[") ? `${prefix}${expression}` : `${prefix}.${expression}`;
|
|
120
|
+
}
|
|
121
|
+
function convertPatchesToSanity(patches, options) {
|
|
122
|
+
return patches.map((patch) => {
|
|
123
|
+
const pathExpression = prefixPathExpression(options.prefix, stringifyPatchPath(patch.path));
|
|
124
|
+
switch (patch.type) {
|
|
125
|
+
case "set":
|
|
126
|
+
return {
|
|
127
|
+
set: {
|
|
128
|
+
[pathExpression]: patch.value
|
|
129
|
+
}
|
|
130
|
+
};
|
|
131
|
+
case "setIfMissing":
|
|
132
|
+
return {
|
|
133
|
+
setIfMissing: {
|
|
134
|
+
[pathExpression]: patch.value
|
|
135
|
+
}
|
|
136
|
+
};
|
|
137
|
+
case "diffMatchPatch":
|
|
138
|
+
return {
|
|
139
|
+
diffMatchPatch: {
|
|
140
|
+
[pathExpression]: patch.value
|
|
141
|
+
}
|
|
142
|
+
};
|
|
143
|
+
case "inc":
|
|
144
|
+
return {
|
|
145
|
+
inc: {
|
|
146
|
+
[pathExpression]: patch.value
|
|
147
|
+
}
|
|
148
|
+
};
|
|
149
|
+
case "dec":
|
|
150
|
+
return {
|
|
151
|
+
dec: {
|
|
152
|
+
[pathExpression]: patch.value
|
|
153
|
+
}
|
|
154
|
+
};
|
|
155
|
+
case "unset":
|
|
156
|
+
return {
|
|
157
|
+
unset: [pathExpression]
|
|
158
|
+
};
|
|
159
|
+
case "insert":
|
|
160
|
+
return {
|
|
161
|
+
insert: {
|
|
162
|
+
[patch.position]: pathExpression,
|
|
163
|
+
items: patch.items
|
|
164
|
+
}
|
|
165
|
+
};
|
|
166
|
+
default:
|
|
167
|
+
throw new Error(STRINGIFY_ERROR_MESSAGE);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
}
|
|
171
|
+
function segmentsEqual(a, b) {
|
|
172
|
+
return typeof a == "string" || typeof a == "number" ? a === b : typeof b == "string" || typeof b == "number" || Array.isArray(a) || Array.isArray(b) ? !1 : a._key === b._key;
|
|
173
|
+
}
|
|
174
|
+
function scopeRemotePatches(patches, fieldPath) {
|
|
175
|
+
const prefix = arrayifyPath(fieldPath);
|
|
176
|
+
if (!prefix)
|
|
177
|
+
return null;
|
|
178
|
+
const {
|
|
179
|
+
patches: converted,
|
|
180
|
+
incomplete
|
|
181
|
+
} = convertPatches(patches);
|
|
182
|
+
if (incomplete)
|
|
183
|
+
return null;
|
|
184
|
+
const scoped = [];
|
|
185
|
+
for (const patch of converted) {
|
|
186
|
+
const overlap = Math.min(patch.path.length, prefix.length);
|
|
187
|
+
let touchesField = !0;
|
|
188
|
+
for (let index = 0; index < overlap; index++)
|
|
189
|
+
if (!segmentsEqual(patch.path[index], prefix[index])) {
|
|
190
|
+
touchesField = !1;
|
|
191
|
+
break;
|
|
192
|
+
}
|
|
193
|
+
if (touchesField) {
|
|
194
|
+
if (patch.path.length <= prefix.length)
|
|
195
|
+
return null;
|
|
196
|
+
scoped.push({
|
|
197
|
+
...patch,
|
|
198
|
+
path: patch.path.slice(prefix.length)
|
|
199
|
+
});
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
return scoped;
|
|
203
|
+
}
|
|
103
204
|
function applySync({
|
|
104
205
|
editor,
|
|
105
206
|
getRemoteValue
|
|
@@ -144,7 +245,8 @@ const listenToEditor = fromCallback(({
|
|
|
144
245
|
}), mutationSubscription = input.editor.on("mutation", (event) => {
|
|
145
246
|
sendBack({
|
|
146
247
|
type: "mutation flushed",
|
|
147
|
-
value: event.value
|
|
248
|
+
value: event.value,
|
|
249
|
+
patches: event.patches
|
|
148
250
|
});
|
|
149
251
|
});
|
|
150
252
|
return () => {
|
|
@@ -157,6 +259,14 @@ const listenToEditor = fromCallback(({
|
|
|
157
259
|
sendBack({
|
|
158
260
|
type: "remote value changed"
|
|
159
261
|
});
|
|
262
|
+
})), listenToRemotePatches = fromCallback(({
|
|
263
|
+
sendBack,
|
|
264
|
+
input
|
|
265
|
+
}) => input.onRemotePatches?.((patches) => {
|
|
266
|
+
sendBack({
|
|
267
|
+
type: "remote patches received",
|
|
268
|
+
patches
|
|
269
|
+
});
|
|
160
270
|
})), valueSyncMachine = setup({
|
|
161
271
|
types: {
|
|
162
272
|
context: {},
|
|
@@ -192,11 +302,22 @@ const listenToEditor = fromCallback(({
|
|
|
192
302
|
getRemoteValue: context.getRemoteValue
|
|
193
303
|
});
|
|
194
304
|
});
|
|
305
|
+
},
|
|
306
|
+
"apply remote patches": ({
|
|
307
|
+
context,
|
|
308
|
+
event
|
|
309
|
+
}) => {
|
|
310
|
+
event.type === "remote patches received" && event.patches.length !== 0 && context.editor.send({
|
|
311
|
+
type: "patches",
|
|
312
|
+
patches: event.patches,
|
|
313
|
+
snapshot: context.editor.getSnapshot().context.value
|
|
314
|
+
});
|
|
195
315
|
}
|
|
196
316
|
},
|
|
197
317
|
actors: {
|
|
198
318
|
"listen to editor": listenToEditor,
|
|
199
|
-
"listen to remote": listenToRemote
|
|
319
|
+
"listen to remote": listenToRemote,
|
|
320
|
+
"listen to remote patches": listenToRemotePatches
|
|
200
321
|
}
|
|
201
322
|
}).createMachine({
|
|
202
323
|
id: "value sync",
|
|
@@ -205,7 +326,8 @@ const listenToEditor = fromCallback(({
|
|
|
205
326
|
}) => ({
|
|
206
327
|
editor: input.editor,
|
|
207
328
|
getRemoteValue: input.getRemoteValue,
|
|
208
|
-
onRemoteValueChange: input.onRemoteValueChange
|
|
329
|
+
onRemoteValueChange: input.onRemoteValueChange,
|
|
330
|
+
onRemotePatches: input.onRemotePatches
|
|
209
331
|
}),
|
|
210
332
|
entry: ["send initial value"],
|
|
211
333
|
invoke: [{
|
|
@@ -222,7 +344,21 @@ const listenToEditor = fromCallback(({
|
|
|
222
344
|
}) => ({
|
|
223
345
|
onRemoteValueChange: context.onRemoteValueChange
|
|
224
346
|
})
|
|
347
|
+
}, {
|
|
348
|
+
src: "listen to remote patches",
|
|
349
|
+
input: ({
|
|
350
|
+
context
|
|
351
|
+
}) => ({
|
|
352
|
+
onRemotePatches: context.onRemotePatches
|
|
353
|
+
})
|
|
225
354
|
}],
|
|
355
|
+
// operational patches from other clients apply immediately in every state;
|
|
356
|
+
// the editor merges them with any in-flight local changes
|
|
357
|
+
on: {
|
|
358
|
+
"remote patches received": {
|
|
359
|
+
actions: ["apply remote patches"]
|
|
360
|
+
}
|
|
361
|
+
},
|
|
226
362
|
initial: "idle",
|
|
227
363
|
states: {
|
|
228
364
|
idle: {
|
|
@@ -269,12 +405,18 @@ const listenToEditor = fromCallback(({
|
|
|
269
405
|
}
|
|
270
406
|
}
|
|
271
407
|
});
|
|
408
|
+
function isRemotePatchesEvent(event) {
|
|
409
|
+
return event.type === "remote-patches";
|
|
410
|
+
}
|
|
411
|
+
function getPublishedDocumentId(id) {
|
|
412
|
+
return id.startsWith("drafts.") ? id.slice(7) : id.startsWith("versions.") ? id.split(".").slice(2).join(".") : id;
|
|
413
|
+
}
|
|
272
414
|
function SDKValuePlugin(props) {
|
|
273
|
-
const $ = c(
|
|
415
|
+
const $ = c(20), {
|
|
274
416
|
documentId,
|
|
275
417
|
documentType,
|
|
276
418
|
path
|
|
277
|
-
} = props, setSdkValue = useEditDocument(props), instance = useSanityInstance(props);
|
|
419
|
+
} = props, setSdkValue = useEditDocument(props), instance = useSanityInstance(props), applyActions = useApplyDocumentActions();
|
|
278
420
|
let t0;
|
|
279
421
|
$[0] !== documentId || $[1] !== documentType || $[2] !== instance || $[3] !== path ? (t0 = getDocumentState(instance, {
|
|
280
422
|
documentId,
|
|
@@ -286,34 +428,75 @@ function SDKValuePlugin(props) {
|
|
|
286
428
|
subscribe
|
|
287
429
|
} = t0;
|
|
288
430
|
let t1;
|
|
289
|
-
|
|
431
|
+
$[5] !== documentId || $[6] !== instance || $[7] !== path ? (t1 = (callback) => subscribeDocumentEvents(instance, {
|
|
432
|
+
eventHandler: (event) => {
|
|
433
|
+
const candidate = event;
|
|
434
|
+
if (!isRemotePatchesEvent(candidate) || candidate.origin !== "remote" || getPublishedDocumentId(candidate.documentId) !== getPublishedDocumentId(documentId))
|
|
435
|
+
return;
|
|
436
|
+
let patches;
|
|
437
|
+
try {
|
|
438
|
+
patches = scopeRemotePatches(candidate.patches, path);
|
|
439
|
+
} catch {
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
patches && patches.length > 0 && callback(patches);
|
|
443
|
+
}
|
|
444
|
+
}), $[5] = documentId, $[6] = instance, $[7] = path, $[8] = t1) : t1 = $[8];
|
|
445
|
+
const onRemotePatches = t1;
|
|
446
|
+
let t2;
|
|
447
|
+
$[9] !== applyActions || $[10] !== documentId || $[11] !== documentType || $[12] !== path ? (t2 = (patches_0) => {
|
|
448
|
+
const sanityPatches = convertPatchesToSanity(patches_0, {
|
|
449
|
+
prefix: path
|
|
450
|
+
}), action = {
|
|
451
|
+
...editDocument({
|
|
452
|
+
documentId,
|
|
453
|
+
documentType
|
|
454
|
+
}, sanityPatches),
|
|
455
|
+
preserveOperations: !0
|
|
456
|
+
};
|
|
457
|
+
applyActions(action);
|
|
458
|
+
}, $[9] = applyActions, $[10] = documentId, $[11] = documentType, $[12] = path, $[13] = t2) : t2 = $[13];
|
|
459
|
+
const pushPatches = t2;
|
|
460
|
+
let t3;
|
|
461
|
+
return $[14] !== getCurrent || $[15] !== onRemotePatches || $[16] !== pushPatches || $[17] !== setSdkValue || $[18] !== subscribe ? (t3 = /* @__PURE__ */ jsx(ValueSyncPlugin, { getRemoteValue: getCurrent, pushValue: setSdkValue, onRemoteValueChange: subscribe, onRemotePatches, pushPatches }), $[14] = getCurrent, $[15] = onRemotePatches, $[16] = pushPatches, $[17] = setSdkValue, $[18] = subscribe, $[19] = t3) : t3 = $[19], t3;
|
|
290
462
|
}
|
|
291
463
|
function ValueSyncPlugin(props) {
|
|
292
|
-
const $ = c(
|
|
464
|
+
const $ = c(8), {
|
|
293
465
|
getRemoteValue,
|
|
294
466
|
pushValue,
|
|
295
|
-
onRemoteValueChange
|
|
467
|
+
onRemoteValueChange,
|
|
468
|
+
onRemotePatches,
|
|
469
|
+
pushPatches
|
|
296
470
|
} = props, editor = useEditor();
|
|
297
471
|
let t0;
|
|
298
|
-
$[0] !== pushValue ? (t0 = valueSyncMachine.provide({
|
|
472
|
+
$[0] !== pushPatches || $[1] !== pushValue ? (t0 = valueSyncMachine.provide({
|
|
299
473
|
actions: {
|
|
300
474
|
"push to remote": (t12) => {
|
|
301
475
|
const {
|
|
302
476
|
context,
|
|
303
477
|
event
|
|
304
478
|
} = t12;
|
|
305
|
-
event.type === "mutation flushed"
|
|
479
|
+
if (event.type === "mutation flushed") {
|
|
480
|
+
if (pushPatches && event.patches.length > 0)
|
|
481
|
+
try {
|
|
482
|
+
pushPatches(event.patches);
|
|
483
|
+
return;
|
|
484
|
+
} catch {
|
|
485
|
+
}
|
|
486
|
+
pushValue(event.value ?? context.editor.getSnapshot().context.value);
|
|
487
|
+
}
|
|
306
488
|
}
|
|
307
489
|
}
|
|
308
|
-
}), $[0] =
|
|
490
|
+
}), $[0] = pushPatches, $[1] = pushValue, $[2] = t0) : t0 = $[2];
|
|
309
491
|
let t1;
|
|
310
|
-
return $[
|
|
492
|
+
return $[3] !== editor || $[4] !== getRemoteValue || $[5] !== onRemotePatches || $[6] !== onRemoteValueChange ? (t1 = {
|
|
311
493
|
input: {
|
|
312
494
|
editor,
|
|
313
495
|
getRemoteValue,
|
|
314
|
-
onRemoteValueChange
|
|
496
|
+
onRemoteValueChange,
|
|
497
|
+
onRemotePatches
|
|
315
498
|
}
|
|
316
|
-
}, $[
|
|
499
|
+
}, $[3] = editor, $[4] = getRemoteValue, $[5] = onRemotePatches, $[6] = onRemoteValueChange, $[7] = t1) : t1 = $[7], useActorRef(t0, t1), null;
|
|
317
500
|
}
|
|
318
501
|
export {
|
|
319
502
|
SDKValuePlugin,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/plugin.sdk-value.tsx"],"sourcesContent":["import {\n useEditor,\n type Editor,\n type PortableTextBlock,\n type Patch as PtePatch,\n} from '@portabletext/editor'\nimport type {\n JSONValue,\n Path,\n InsertPatch as PteInsertPatch,\n} from '@portabletext/patches'\nimport {diffValue, type SanityPatchOperations} from '@sanity/diff-patch'\nimport {\n parsePath,\n type ExprNode,\n type PathNode,\n type SegmentNode,\n type ThisNode,\n} from '@sanity/json-match'\nimport {\n getDocumentState,\n useEditDocument,\n useSanityInstance,\n type DocumentHandle,\n} from '@sanity/sdk-react'\nimport {useActorRef} from '@xstate/react'\nimport {fromCallback, setup, type AnyEventObject} from 'xstate'\n\ntype InsertPatch = Required<Pick<SanityPatchOperations, 'insert'>>\n\nfunction* getSegments(\n node: PathNode,\n): Generator<Exclude<SegmentNode, ThisNode>> {\n if (node.base) {\n yield* getSegments(node.base)\n }\n if (node.segment.type !== 'This') {\n yield node.segment\n }\n}\n\nfunction isKeyPath(node: ExprNode): node is PathNode {\n if (node.type !== 'Path') {\n return false\n }\n if (node.base) {\n return false\n }\n if (node.recursive) {\n return false\n }\n if (node.segment.type !== 'Identifier') {\n return false\n }\n return node.segment.name === '_key'\n}\n\n/**\n * Converts a `diffValue` path expression (e.g. `[_key==\"a\"].children[0]`) into\n * a keyed Portable Text Editor path.\n *\n * Returns `null` – rather than throwing – for any expression that can't be\n * represented as a keyed PTE path. `diffValue` can emit such expressions in\n * practice: removing several non-keyed array items at once (e.g. clearing\n * multiple span `marks`) produces an array slice like `...marks[1:]`. Throwing\n * here would escape the synchronous `applySync` and break syncing entirely, so\n * we signal failure via `null` and let the caller skip the offending patch and\n * recover.\n */\nexport function arrayifyPath(pathExpr: string): Path | null {\n let node: ExprNode | undefined\n try {\n node = parsePath(pathExpr)\n } catch {\n // `parsePath` throws on malformed input such as an empty expression.\n return null\n }\n if (!node) {\n return null\n }\n if (node.type !== 'Path') {\n return null\n }\n\n const path: Path = []\n for (const segment of getSegments(node)) {\n if (segment.type === 'Identifier') {\n path.push(segment.name)\n continue\n }\n if (segment.type !== 'Subscript') {\n return null\n }\n if (segment.elements.length !== 1) {\n return null\n }\n\n const [element] = segment.elements\n if (element.type === 'Number') {\n path.push(element.value)\n continue\n }\n if (element.type !== 'Comparison') {\n // e.g. an array slice (`Slice`) that `diffValue` emits when removing\n // multiple non-keyed items at once.\n return null\n }\n if (element.operator !== '==') {\n return null\n }\n const keyPathNode = [element.left, element.right].find(isKeyPath)\n if (!keyPathNode) {\n return null\n }\n const other = element.left === keyPathNode ? element.right : element.left\n if (other.type !== 'String') {\n return null\n }\n path.push({_key: other.value})\n }\n\n return path\n}\n\n/**\n * Converts a batch of `diffValue` patch operations into PTE patches.\n *\n * `incomplete` is `true` when one or more operations had to be dropped because\n * their path couldn't be converted (see `arrayifyPath`). The caller uses this\n * to fall back to an authoritative full value update instead of persisting a\n * partial diff.\n */\nexport function convertPatches(patches: SanityPatchOperations[]): {\n patches: PtePatch[]\n incomplete: boolean\n} {\n let incomplete = false\n\n const converted = patches.flatMap((operation) => {\n return Object.entries(operation).flatMap(([type, values]): PtePatch[] => {\n const origin = 'remote'\n\n switch (type) {\n case 'set':\n case 'setIfMissing':\n case 'diffMatchPatch':\n case 'inc':\n case 'dec': {\n return Object.entries(values).flatMap(([pathExpr, value]) => {\n const path = arrayifyPath(pathExpr)\n if (!path) {\n incomplete = true\n return []\n }\n return [{type, value, origin, path} as PtePatch]\n })\n }\n case 'unset': {\n if (!Array.isArray(values)) {\n return []\n }\n return values.flatMap((pathExpr) => {\n const path = arrayifyPath(pathExpr)\n if (!path) {\n incomplete = true\n return []\n }\n return [{type, origin, path} as PtePatch]\n })\n }\n case 'insert': {\n const {items, ...rest} = values as InsertPatch['insert']\n type InsertPosition = PteInsertPatch['position']\n const position = Object.keys(rest).at(0) as InsertPosition | undefined\n\n if (!position) {\n return []\n }\n const pathExpr = (rest as {[K in InsertPosition]: string})[position]\n const path = arrayifyPath(pathExpr)\n if (!path) {\n incomplete = true\n return []\n }\n const insertPatch: PteInsertPatch = {\n type,\n origin,\n position,\n path,\n items: items as JSONValue[],\n }\n\n return [insertPatch]\n }\n\n default: {\n return []\n }\n }\n })\n })\n\n return {patches: converted, incomplete}\n}\n\nfunction applySync({\n editor,\n getRemoteValue,\n}: {\n editor: Editor\n getRemoteValue: () => PortableTextBlock[] | null | undefined\n}) {\n const remoteValue = getRemoteValue()\n\n if (!remoteValue) {\n return\n }\n\n const snapshot = editor.getSnapshot().context.value\n const {patches, incomplete} = convertPatches(diffValue(snapshot, remoteValue))\n\n // Recover with an authoritative full value update when the diff can't be\n // applied faithfully. Either a patch was dropped – replaying the rest would\n // leave the editor in a partial/garbled state – or the editor moved on from\n // `snapshot` while we were diffing, so the patches were computed against a\n // value the editor no longer holds and can't be reconciled safely.\n if (incomplete || editor.getSnapshot().context.value !== snapshot) {\n updateValueFromRemote({editor, getRemoteValue})\n return\n }\n\n if (patches.length) {\n editor.send({type: 'patches', patches, snapshot})\n }\n}\n\nfunction updateValueFromRemote({\n editor,\n getRemoteValue,\n}: {\n editor: Editor\n getRemoteValue: () => PortableTextBlock[] | null | undefined\n}) {\n editor.send({type: 'update value', value: getRemoteValue() ?? []})\n}\n\nconst listenToEditor = fromCallback<AnyEventObject, {editor: Editor}>(\n ({sendBack, input}) => {\n const patchSubscription = input.editor.on('patch', () => {\n sendBack({type: 'patch emitted'})\n })\n\n const mutationSubscription = input.editor.on('mutation', (event) => {\n sendBack({type: 'mutation flushed', value: event.value})\n })\n\n return () => {\n patchSubscription.unsubscribe()\n mutationSubscription.unsubscribe()\n }\n },\n)\n\nconst listenToRemote = fromCallback<\n AnyEventObject,\n {onRemoteValueChange: ValueSyncConfig['onRemoteValueChange']}\n>(({sendBack, input}) => {\n return input.onRemoteValueChange(() => {\n sendBack({type: 'remote value changed'})\n })\n})\n\nconst valueSyncMachine = setup({\n types: {\n context: {} as {\n editor: Editor\n getRemoteValue: ValueSyncConfig['getRemoteValue']\n onRemoteValueChange: ValueSyncConfig['onRemoteValueChange']\n },\n input: {} as {\n editor: Editor\n getRemoteValue: ValueSyncConfig['getRemoteValue']\n onRemoteValueChange: ValueSyncConfig['onRemoteValueChange']\n },\n events: {} as\n | {type: 'patch emitted'}\n | {type: 'mutation flushed'; value: PortableTextBlock[] | undefined}\n | {type: 'remote value changed'},\n },\n actions: {\n 'send initial value': ({context}) => {\n updateValueFromRemote({\n editor: context.editor,\n getRemoteValue: context.getRemoteValue,\n })\n },\n 'push to remote': () => {\n throw new Error('push to remote must be provided via .provide()')\n },\n 'apply sync': ({context}) => {\n applySync({\n editor: context.editor,\n getRemoteValue: context.getRemoteValue,\n })\n },\n 'defer then apply sync': ({context}) => {\n queueMicrotask(() => {\n applySync({\n editor: context.editor,\n getRemoteValue: context.getRemoteValue,\n })\n })\n },\n },\n actors: {\n 'listen to editor': listenToEditor,\n 'listen to remote': listenToRemote,\n },\n}).createMachine({\n id: 'value sync',\n context: ({input}) => ({\n editor: input.editor,\n getRemoteValue: input.getRemoteValue,\n onRemoteValueChange: input.onRemoteValueChange,\n }),\n entry: ['send initial value'],\n invoke: [\n {\n src: 'listen to editor',\n input: ({context}) => ({editor: context.editor}),\n },\n {\n src: 'listen to remote',\n input: ({context}) => ({\n onRemoteValueChange: context.onRemoteValueChange,\n }),\n },\n ],\n initial: 'idle',\n states: {\n 'idle': {\n on: {\n 'patch emitted': {\n target: 'local write',\n },\n 'remote value changed': {\n actions: ['apply sync'],\n },\n },\n },\n 'local write': {\n on: {\n 'patch emitted': {},\n 'mutation flushed': {\n target: 'pushing to remote',\n actions: ['push to remote'],\n },\n 'remote value changed': {\n target: 'pending sync',\n },\n },\n },\n 'pushing to remote': {\n on: {\n 'patch emitted': {\n target: 'local write',\n },\n 'remote value changed': {\n target: 'idle',\n },\n },\n },\n 'pending sync': {\n on: {\n 'patch emitted': {},\n 'mutation flushed': {\n target: 'pushing to remote',\n actions: ['push to remote', 'defer then apply sync'],\n },\n 'remote value changed': {},\n },\n },\n },\n})\n\ninterface SDKValuePluginProps extends DocumentHandle {\n path: string\n}\n\n/**\n * @public\n */\nexport function SDKValuePlugin(props: SDKValuePluginProps) {\n const {documentId, documentType, path} = props\n const setSdkValue = useEditDocument(props)\n const instance = useSanityInstance(props)\n\n const handle = {documentId, documentType, path}\n const {getCurrent, subscribe} = getDocumentState<PortableTextBlock[]>(\n instance,\n handle,\n )\n\n return (\n <ValueSyncPlugin\n getRemoteValue={getCurrent}\n pushValue={setSdkValue}\n onRemoteValueChange={subscribe}\n />\n )\n}\n\n/**\n * @internal\n */\ntype ValueSyncConfig = {\n getRemoteValue: () => PortableTextBlock[] | null | undefined\n pushValue: (value: PortableTextBlock[]) => void\n onRemoteValueChange: (callback: () => void) => () => void\n}\n\n/**\n * NOTE: You are probably looking for SDKValuePlugin instead of this.\n * This is a lower-level plugin that only handles syncing the value\n * between the editor and a remote source. It does not know anything\n * about Sanity documents or how to fetch/update them.\n *\n * May be removed in the future, do not rely on this directly.\n *\n * @internal\n */\nexport function ValueSyncPlugin(props: ValueSyncConfig) {\n const {getRemoteValue, pushValue, onRemoteValueChange} = props\n const editor = useEditor()\n\n useActorRef(\n valueSyncMachine.provide({\n actions: {\n 'push to remote': ({context, event}) => {\n if (event.type !== 'mutation flushed') {\n return\n }\n\n pushValue(event.value ?? context.editor.getSnapshot().context.value)\n },\n },\n }),\n {\n input: {\n editor,\n getRemoteValue,\n onRemoteValueChange,\n },\n },\n )\n\n return null\n}\n"],"names":["getSegments","node","base","segment","type","isKeyPath","recursive","name","arrayifyPath","pathExpr","parsePath","path","push","elements","length","element","value","operator","keyPathNode","left","right","find","other","_key","convertPatches","patches","incomplete","flatMap","operation","Object","entries","values","origin","Array","isArray","items","rest","position","keys","at","applySync","editor","getRemoteValue","remoteValue","snapshot","getSnapshot","context","diffValue","updateValueFromRemote","send","listenToEditor","fromCallback","sendBack","input","patchSubscription","on","mutationSubscription","event","unsubscribe","listenToRemote","onRemoteValueChange","valueSyncMachine","setup","types","events","actions","send initial value","push to remote","Error","apply sync","defer then apply sync","queueMicrotask","actors","createMachine","id","entry","invoke","src","initial","states","target","SDKValuePlugin","props","$","_c","documentId","documentType","setSdkValue","useEditDocument","instance","useSanityInstance","t0","getDocumentState","getCurrent","subscribe","t1","ValueSyncPlugin","pushValue","useEditor","provide","useActorRef"],"mappings":";;;;;;;;AA8BA,UAAUA,YACRC,MAC2C;AACvCA,OAAKC,SACP,OAAOF,YAAYC,KAAKC,IAAI,IAE1BD,KAAKE,QAAQC,SAAS,WACxB,MAAMH,KAAKE;AAEf;AAEA,SAASE,UAAUJ,MAAkC;AAUnD,SATIA,KAAKG,SAAS,UAGdH,KAAKC,QAGLD,KAAKK,aAGLL,KAAKE,QAAQC,SAAS,eACjB,KAEFH,KAAKE,QAAQI,SAAS;AAC/B;AAcO,SAASC,aAAaC,UAA+B;AAC1D,MAAIR;AACJ,MAAI;AACFA,WAAOS,UAAUD,QAAQ;AAAA,EAC3B,QAAQ;AAEN,WAAO;AAAA,EACT;AAIA,MAHI,CAACR,QAGDA,KAAKG,SAAS;AAChB,WAAO;AAGT,QAAMO,OAAa,CAAA;AACnB,aAAWR,WAAWH,YAAYC,IAAI,GAAG;AACvC,QAAIE,QAAQC,SAAS,cAAc;AACjCO,WAAKC,KAAKT,QAAQI,IAAI;AACtB;AAAA,IACF;AAIA,QAHIJ,QAAQC,SAAS,eAGjBD,QAAQU,SAASC,WAAW;AAC9B,aAAO;AAGT,UAAM,CAACC,OAAO,IAAIZ,QAAQU;AAC1B,QAAIE,QAAQX,SAAS,UAAU;AAC7BO,WAAKC,KAAKG,QAAQC,KAAK;AACvB;AAAA,IACF;AAMA,QALID,QAAQX,SAAS,gBAKjBW,QAAQE,aAAa;AACvB,aAAO;AAET,UAAMC,cAAc,CAACH,QAAQI,MAAMJ,QAAQK,KAAK,EAAEC,KAAKhB,SAAS;AAChE,QAAI,CAACa;AACH,aAAO;AAET,UAAMI,QAAQP,QAAQI,SAASD,cAAcH,QAAQK,QAAQL,QAAQI;AACrE,QAAIG,MAAMlB,SAAS;AACjB,aAAO;AAETO,SAAKC,KAAK;AAAA,MAACW,MAAMD,MAAMN;AAAAA,IAAAA,CAAM;AAAA,EAC/B;AAEA,SAAOL;AACT;AAUO,SAASa,eAAeC,SAG7B;AACA,MAAIC,aAAa;AAkEjB,SAAO;AAAA,IAACD,SAhEUA,QAAQE,QAASC,CAAAA,cAC1BC,OAAOC,QAAQF,SAAS,EAAED,QAAQ,CAAC,CAACvB,MAAM2B,MAAM,MAAkB;AACvE,YAAMC,SAAS;AAEf,cAAQ5B,MAAAA;AAAAA,QACN,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AAAA,QACL,KAAK;AACH,iBAAOyB,OAAOC,QAAQC,MAAM,EAAEJ,QAAQ,CAAC,CAAClB,UAAUO,KAAK,MAAM;AAC3D,kBAAML,OAAOH,aAAaC,QAAQ;AAClC,mBAAKE,OAIE,CAAC;AAAA,cAACP;AAAAA,cAAMY;AAAAA,cAAOgB;AAAAA,cAAQrB;AAAAA,YAAAA,CAAK,KAHjCe,aAAa,IACN;UAGX,CAAC;AAAA,QAEH,KAAK;AACH,iBAAKO,MAAMC,QAAQH,MAAM,IAGlBA,OAAOJ,QAASlB,CAAAA,aAAa;AAClC,kBAAME,OAAOH,aAAaC,QAAQ;AAClC,mBAAKE,OAIE,CAAC;AAAA,cAACP;AAAAA,cAAM4B;AAAAA,cAAQrB;AAAAA,YAAAA,CAAK,KAH1Be,aAAa,IACN;UAGX,CAAC,IATQ,CAAA;AAAA,QAWX,KAAK,UAAU;AACb,gBAAM;AAAA,YAACS;AAAAA,YAAO,GAAGC;AAAAA,UAAAA,IAAQL,QAEnBM,WAAWR,OAAOS,KAAKF,IAAI,EAAEG,GAAG,CAAC;AAEvC,cAAI,CAACF;AACH,mBAAO,CAAA;AAET,gBAAM5B,WAAY2B,KAAyCC,QAAQ,GAC7D1B,OAAOH,aAAaC,QAAQ;AAClC,iBAAKE,OAYE,CAR6B;AAAA,YAClCP;AAAAA,YACA4B;AAAAA,YACAK;AAAAA,YACA1B;AAAAA,YACAwB;AAAAA,UAAAA,CAGiB,KAXjBT,aAAa,IACN;QAWX;AAAA,QAEA;AACE,iBAAO,CAAA;AAAA,MAAA;AAAA,IAGb,CAAC,CACF;AAAA,IAE2BA;AAAAA,EAAAA;AAC9B;AAEA,SAASc,UAAU;AAAA,EACjBC;AAAAA,EACAC;AAIF,GAAG;AACD,QAAMC,cAAcD,eAAAA;AAEpB,MAAI,CAACC;AACH;AAGF,QAAMC,WAAWH,OAAOI,YAAAA,EAAcC,QAAQ9B,OACxC;AAAA,IAACS;AAAAA,IAASC;AAAAA,EAAAA,IAAcF,eAAeuB,UAAUH,UAAUD,WAAW,CAAC;AAO7E,MAAIjB,cAAce,OAAOI,YAAAA,EAAcC,QAAQ9B,UAAU4B,UAAU;AACjEI,0BAAsB;AAAA,MAACP;AAAAA,MAAQC;AAAAA,IAAAA,CAAe;AAC9C;AAAA,EACF;AAEIjB,UAAQX,UACV2B,OAAOQ,KAAK;AAAA,IAAC7C,MAAM;AAAA,IAAWqB;AAAAA,IAASmB;AAAAA,EAAAA,CAAS;AAEpD;AAEA,SAASI,sBAAsB;AAAA,EAC7BP;AAAAA,EACAC;AAIF,GAAG;AACDD,SAAOQ,KAAK;AAAA,IAAC7C,MAAM;AAAA,IAAgBY,OAAO0B,eAAAA,KAAoB,CAAA;AAAA,EAAA,CAAG;AACnE;AAEA,MAAMQ,iBAAiBC,aACrB,CAAC;AAAA,EAACC;AAAAA,EAAUC;AAAK,MAAM;AACrB,QAAMC,oBAAoBD,MAAMZ,OAAOc,GAAG,SAAS,MAAM;AACvDH,aAAS;AAAA,MAAChD,MAAM;AAAA,IAAA,CAAgB;AAAA,EAClC,CAAC,GAEKoD,uBAAuBH,MAAMZ,OAAOc,GAAG,YAAaE,CAAAA,UAAU;AAClEL,aAAS;AAAA,MAAChD,MAAM;AAAA,MAAoBY,OAAOyC,MAAMzC;AAAAA,IAAAA,CAAM;AAAA,EACzD,CAAC;AAED,SAAO,MAAM;AACXsC,sBAAkBI,YAAAA,GAClBF,qBAAqBE,YAAAA;AAAAA,EACvB;AACF,CACF,GAEMC,iBAAiBR,aAGrB,CAAC;AAAA,EAACC;AAAAA,EAAUC;AAAK,MACVA,MAAMO,oBAAoB,MAAM;AACrCR,WAAS;AAAA,IAAChD,MAAM;AAAA,EAAA,CAAuB;AACzC,CAAC,CACF,GAEKyD,mBAAmBC,MAAM;AAAA,EAC7BC,OAAO;AAAA,IACLjB,SAAS,CAAA;AAAA,IAKTO,OAAO,CAAA;AAAA,IAKPW,QAAQ,CAAA;AAAA,EAAC;AAAA,EAKXC,SAAS;AAAA,IACP,sBAAsBC,CAAC;AAAA,MAACpB;AAAAA,IAAAA,MAAa;AACnCE,4BAAsB;AAAA,QACpBP,QAAQK,QAAQL;AAAAA,QAChBC,gBAAgBI,QAAQJ;AAAAA,MAAAA,CACzB;AAAA,IACH;AAAA,IACA,kBAAkByB,MAAM;AACtB,YAAM,IAAIC,MAAM,gDAAgD;AAAA,IAClE;AAAA,IACA,cAAcC,CAAC;AAAA,MAACvB;AAAAA,IAAAA,MAAa;AAC3BN,gBAAU;AAAA,QACRC,QAAQK,QAAQL;AAAAA,QAChBC,gBAAgBI,QAAQJ;AAAAA,MAAAA,CACzB;AAAA,IACH;AAAA,IACA,yBAAyB4B,CAAC;AAAA,MAACxB;AAAAA,IAAAA,MAAa;AACtCyB,qBAAe,MAAM;AACnB/B,kBAAU;AAAA,UACRC,QAAQK,QAAQL;AAAAA,UAChBC,gBAAgBI,QAAQJ;AAAAA,QAAAA,CACzB;AAAA,MACH,CAAC;AAAA,IACH;AAAA,EAAA;AAAA,EAEF8B,QAAQ;AAAA,IACN,oBAAoBtB;AAAAA,IACpB,oBAAoBS;AAAAA,EAAAA;AAExB,CAAC,EAAEc,cAAc;AAAA,EACfC,IAAI;AAAA,EACJ5B,SAASA,CAAC;AAAA,IAACO;AAAAA,EAAAA,OAAY;AAAA,IACrBZ,QAAQY,MAAMZ;AAAAA,IACdC,gBAAgBW,MAAMX;AAAAA,IACtBkB,qBAAqBP,MAAMO;AAAAA,EAAAA;AAAAA,EAE7Be,OAAO,CAAC,oBAAoB;AAAA,EAC5BC,QAAQ,CACN;AAAA,IACEC,KAAK;AAAA,IACLxB,OAAOA,CAAC;AAAA,MAACP;AAAAA,IAAAA,OAAc;AAAA,MAACL,QAAQK,QAAQL;AAAAA,IAAAA;AAAAA,EAAM,GAEhD;AAAA,IACEoC,KAAK;AAAA,IACLxB,OAAOA,CAAC;AAAA,MAACP;AAAAA,IAAAA,OAAc;AAAA,MACrBc,qBAAqBd,QAAQc;AAAAA,IAAAA;AAAAA,EAC/B,CACD;AAAA,EAEHkB,SAAS;AAAA,EACTC,QAAQ;AAAA,IACN,MAAQ;AAAA,MACNxB,IAAI;AAAA,QACF,iBAAiB;AAAA,UACfyB,QAAQ;AAAA,QAAA;AAAA,QAEV,wBAAwB;AAAA,UACtBf,SAAS,CAAC,YAAY;AAAA,QAAA;AAAA,MACxB;AAAA,IACF;AAAA,IAEF,eAAe;AAAA,MACbV,IAAI;AAAA,QACF,iBAAiB,CAAA;AAAA,QACjB,oBAAoB;AAAA,UAClByB,QAAQ;AAAA,UACRf,SAAS,CAAC,gBAAgB;AAAA,QAAA;AAAA,QAE5B,wBAAwB;AAAA,UACtBe,QAAQ;AAAA,QAAA;AAAA,MACV;AAAA,IACF;AAAA,IAEF,qBAAqB;AAAA,MACnBzB,IAAI;AAAA,QACF,iBAAiB;AAAA,UACfyB,QAAQ;AAAA,QAAA;AAAA,QAEV,wBAAwB;AAAA,UACtBA,QAAQ;AAAA,QAAA;AAAA,MACV;AAAA,IACF;AAAA,IAEF,gBAAgB;AAAA,MACdzB,IAAI;AAAA,QACF,iBAAiB,CAAA;AAAA,QACjB,oBAAoB;AAAA,UAClByB,QAAQ;AAAA,UACRf,SAAS,CAAC,kBAAkB,uBAAuB;AAAA,QAAA;AAAA,QAErD,wBAAwB,CAAA;AAAA,MAAC;AAAA,IAC3B;AAAA,EACF;AAEJ,CAAC;AASM,SAAAgB,eAAAC,OAAA;AAAA,QAAAC,IAAAC,EAAA,CAAA,GACL;AAAA,IAAAC;AAAAA,IAAAC;AAAAA,IAAA3E;AAAAA,EAAAA,IAAyCuE,OACzCK,cAAoBC,gBAAgBN,KAAK,GACzCO,WAAiBC,kBAAkBR,KAAK;AAAC,MAAAS;AAAAR,IAAA,CAAA,MAAAE,cAAAF,EAAA,CAAA,MAAAG,gBAAAH,EAAA,CAAA,MAAAM,YAAAN,SAAAxE,QAGTgF,KAAAC,iBAC9BH,UAFa;AAAA,IAAAJ;AAAAA,IAAAC;AAAAA,IAAA3E;AAAAA,EAAAA,CAIf,GAACwE,OAAAE,YAAAF,OAAAG,cAAAH,OAAAM,UAAAN,OAAAxE,MAAAwE,OAAAQ,MAAAA,KAAAR,EAAA,CAAA;AAHD,QAAA;AAAA,IAAAU;AAAAA,IAAAC;AAAAA,EAAAA,IAAgCH;AAG/B,MAAAI;AAAA,SAAAZ,EAAA,CAAA,MAAAU,cAAAV,SAAAI,eAAAJ,EAAA,CAAA,MAAAW,aAGCC,yBAAC,mBACiBF,4BACLN,wBACUO,qBAAAA,UAAAA,CAAS,GAC9BX,OAAAU,YAAAV,OAAAI,aAAAJ,OAAAW,WAAAX,OAAAY,MAAAA,KAAAZ,EAAA,CAAA,GAJFY;AAIE;AAuBC,SAAAC,gBAAAd,OAAA;AAAA,QAAAC,IAAAC,EAAA,CAAA,GACL;AAAA,IAAA1C;AAAAA,IAAAuD;AAAAA,IAAArC;AAAAA,EAAAA,IAAyDsB,OACzDzC,SAAeyD,UAAAA;AAAW,MAAAP;AAAAR,WAAAc,aAGxBN,KAAA9B,iBAAgBsC,QAAS;AAAA,IAAAlC,SACd;AAAA,MAAA,kBACW8B,CAAAA,QAAA;AAAC,cAAA;AAAA,UAAAjD;AAAAA,UAAAW;AAAAA,QAAAA,IAAAsC;AACbtC,cAAKrD,SAAU,sBAInB6F,UAAUxC,MAAKzC,SAAU8B,QAAOL,OAAOI,cAAcC,QAAQ9B,KAAM;AAAA,MAAC;AAAA,IAAA;AAAA,EAExE,CACD,GAACmE,OAAAc,WAAAd,OAAAQ,MAAAA,KAAAR,EAAA,CAAA;AAAA,MAAAY;AAAA,SAAAZ,EAAA,CAAA,MAAA1C,UAAA0C,SAAAzC,kBAAAyC,EAAA,CAAA,MAAAvB,uBACFmC,KAAA;AAAA,IAAA1C,OACS;AAAA,MAAAZ;AAAAA,MAAAC;AAAAA,MAAAkB;AAAAA,IAAAA;AAAAA,EAIP,GACDuB,OAAA1C,QAAA0C,OAAAzC,gBAAAyC,OAAAvB,qBAAAuB,OAAAY,MAAAA,KAAAZ,EAAA,CAAA,GAlBHiB,YACET,IAWAI,EAOF,GAEO;AAAI;"}
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/plugin.sdk-value.tsx"],"sourcesContent":["import {\n useEditor,\n type Editor,\n type PortableTextBlock,\n type Patch as PtePatch,\n} from '@portabletext/editor'\nimport type {\n JSONValue,\n Path,\n PathSegment,\n InsertPatch as PteInsertPatch,\n} from '@portabletext/patches'\nimport {diffValue, type SanityPatchOperations} from '@sanity/diff-patch'\nimport {\n parsePath,\n type ExprNode,\n type PathNode,\n type SegmentNode,\n type ThisNode,\n} from '@sanity/json-match'\nimport {\n editDocument,\n getDocumentState,\n subscribeDocumentEvents,\n useApplyDocumentActions,\n useEditDocument,\n useSanityInstance,\n type DocumentHandle,\n type EditDocumentAction,\n} from '@sanity/sdk-react'\nimport {useActorRef} from '@xstate/react'\nimport {useCallback} from 'react'\nimport {fromCallback, setup, type AnyEventObject} from 'xstate'\n\ntype InsertPatch = Required<Pick<SanityPatchOperations, 'insert'>>\n\nfunction* getSegments(\n node: PathNode,\n): Generator<Exclude<SegmentNode, ThisNode>> {\n if (node.base) {\n yield* getSegments(node.base)\n }\n if (node.segment.type !== 'This') {\n yield node.segment\n }\n}\n\nfunction isKeyPath(node: ExprNode): node is PathNode {\n if (node.type !== 'Path') {\n return false\n }\n if (node.base) {\n return false\n }\n if (node.recursive) {\n return false\n }\n if (node.segment.type !== 'Identifier') {\n return false\n }\n return node.segment.name === '_key'\n}\n\n/**\n * Converts a `diffValue` path expression (e.g. `[_key==\"a\"].children[0]`) into\n * a keyed Portable Text Editor path.\n *\n * Returns `null` – rather than throwing – for any expression that can't be\n * represented as a keyed PTE path. `diffValue` can emit such expressions in\n * practice: removing several non-keyed array items at once (e.g. clearing\n * multiple span `marks`) produces an array slice like `...marks[1:]`. Throwing\n * here would escape the synchronous `applySync` and break syncing entirely, so\n * we signal failure via `null` and let the caller skip the offending patch and\n * recover.\n */\nexport function arrayifyPath(pathExpr: string): Path | null {\n let node: ExprNode | undefined\n try {\n node = parsePath(pathExpr)\n } catch {\n // `parsePath` throws on malformed input such as an empty expression.\n return null\n }\n if (!node) {\n return null\n }\n if (node.type !== 'Path') {\n return null\n }\n\n const path: Path = []\n for (const segment of getSegments(node)) {\n if (segment.type === 'Identifier') {\n path.push(segment.name)\n continue\n }\n if (segment.type !== 'Subscript') {\n return null\n }\n if (segment.elements.length !== 1) {\n return null\n }\n\n const [element] = segment.elements\n if (element.type === 'Number') {\n path.push(element.value)\n continue\n }\n if (element.type !== 'Comparison') {\n // e.g. an array slice (`Slice`) that `diffValue` emits when removing\n // multiple non-keyed items at once.\n return null\n }\n if (element.operator !== '==') {\n return null\n }\n const keyPathNode = [element.left, element.right].find(isKeyPath)\n if (!keyPathNode) {\n return null\n }\n const other = element.left === keyPathNode ? element.right : element.left\n if (other.type !== 'String') {\n return null\n }\n path.push({_key: other.value})\n }\n\n return path\n}\n\n/**\n * Converts a batch of `diffValue` patch operations into PTE patches.\n *\n * `incomplete` is `true` when one or more operations had to be dropped because\n * their path couldn't be converted (see `arrayifyPath`). The caller uses this\n * to fall back to an authoritative full value update instead of persisting a\n * partial diff.\n */\nexport function convertPatches(patches: SanityPatchOperations[]): {\n patches: PtePatch[]\n incomplete: boolean\n} {\n let incomplete = false\n\n const converted = patches.flatMap((operation) => {\n return Object.entries(operation).flatMap(([type, values]): PtePatch[] => {\n const origin = 'remote'\n\n switch (type) {\n case 'set':\n case 'setIfMissing':\n case 'diffMatchPatch':\n case 'inc':\n case 'dec': {\n return Object.entries(values).flatMap(([pathExpr, value]) => {\n const path = arrayifyPath(pathExpr)\n if (!path) {\n incomplete = true\n return []\n }\n return [{type, value, origin, path} as PtePatch]\n })\n }\n case 'unset': {\n if (!Array.isArray(values)) {\n return []\n }\n return values.flatMap((pathExpr) => {\n const path = arrayifyPath(pathExpr)\n if (!path) {\n incomplete = true\n return []\n }\n return [{type, origin, path} as PtePatch]\n })\n }\n case 'insert': {\n const {items, ...rest} = values as InsertPatch['insert']\n type InsertPosition = PteInsertPatch['position']\n const position = Object.keys(rest).at(0) as InsertPosition | undefined\n\n if (!position) {\n return []\n }\n const pathExpr = (rest as {[K in InsertPosition]: string})[position]\n const path = arrayifyPath(pathExpr)\n if (!path) {\n incomplete = true\n return []\n }\n const insertPatch: PteInsertPatch = {\n type,\n origin,\n position,\n path,\n items: items as JSONValue[],\n }\n\n return [insertPatch]\n }\n\n default: {\n return []\n }\n }\n })\n })\n\n return {patches: converted, incomplete}\n}\n\nconst STRINGIFY_ERROR_MESSAGE =\n 'Unable to convert an editor patch path to a Sanity path expression.'\n\n/**\n * Converts a Portable Text Editor patch path (an array of segments) into a\n * Sanity json-match path expression. The inverse of `arrayifyPath`.\n *\n * @internal\n */\nexport function stringifyPatchPath(path: Path): string {\n let result = ''\n for (const segment of path) {\n if (typeof segment === 'string') {\n result = result === '' ? segment : `${result}.${segment}`\n } else if (typeof segment === 'number') {\n result = `${result}[${segment}]`\n } else if (\n typeof segment === 'object' &&\n segment !== null &&\n '_key' in segment\n ) {\n result = `${result}[_key==\"${segment._key}\"]`\n } else {\n throw new Error(STRINGIFY_ERROR_MESSAGE)\n }\n }\n return result\n}\n\nfunction prefixPathExpression(prefix: string, expression: string): string {\n if (expression === '') {\n return prefix\n }\n return expression.startsWith('[')\n ? `${prefix}${expression}`\n : `${prefix}.${expression}`\n}\n\n/**\n * `SanityPatchOperations` from `@sanity/diff-patch` only covers the\n * operations `diffValue` emits; the editor can additionally produce these.\n */\ntype SanityPatchOperationsWithExtras = SanityPatchOperations & {\n setIfMissing?: {[path: string]: unknown}\n inc?: {[path: string]: number}\n dec?: {[path: string]: number}\n}\n\n/**\n * Converts Portable Text Editor patches into Sanity patch operations rooted\n * at the given document field path. Throws if a patch cannot be converted;\n * callers should fall back to pushing the whole value.\n *\n * @internal\n */\nexport function convertPatchesToSanity(\n patches: PtePatch[],\n options: {prefix: string},\n): SanityPatchOperationsWithExtras[] {\n return patches.map((patch): SanityPatchOperationsWithExtras => {\n const pathExpression = prefixPathExpression(\n options.prefix,\n stringifyPatchPath(patch.path),\n )\n\n switch (patch.type) {\n case 'set':\n return {set: {[pathExpression]: patch.value}}\n case 'setIfMissing':\n return {setIfMissing: {[pathExpression]: patch.value}}\n case 'diffMatchPatch':\n return {diffMatchPatch: {[pathExpression]: patch.value}}\n case 'inc':\n return {inc: {[pathExpression]: patch.value as number}}\n case 'dec':\n return {dec: {[pathExpression]: patch.value as number}}\n case 'unset':\n return {unset: [pathExpression]}\n case 'insert':\n return {\n insert: {\n [patch.position]: pathExpression,\n items: patch.items,\n } as SanityPatchOperations['insert'],\n }\n default:\n throw new Error(STRINGIFY_ERROR_MESSAGE)\n }\n })\n}\n\nfunction segmentsEqual(a: PathSegment, b: PathSegment): boolean {\n if (typeof a === 'string' || typeof a === 'number') {\n return a === b\n }\n if (typeof b === 'string' || typeof b === 'number') {\n return false\n }\n if (Array.isArray(a) || Array.isArray(b)) {\n return false\n }\n return a._key === b._key\n}\n\n/**\n * Scopes document-rooted Sanity patches to the given field path, returning\n * field-relative Portable Text Editor patches. Patches outside the field are\n * dropped. Returns `null` when the field (or an ancestor of it) is replaced\n * wholesale, when the field path itself can't be converted, or when any patch\n * op can't be converted to a keyed editor path — in all of which the caller\n * should fall back to a full value sync rather than apply a partial batch.\n *\n * @internal\n */\nexport function scopeRemotePatches(\n patches: SanityPatchOperations[],\n fieldPath: string,\n): PtePatch[] | null {\n const prefix = arrayifyPath(fieldPath)\n if (!prefix) {\n return null\n }\n const {patches: converted, incomplete} = convertPatches(patches)\n if (incomplete) {\n // a patch op couldn't be converted to a keyed editor path; applying the\n // rest would leave the field partially updated, so fall back to full sync\n return null\n }\n const scoped: PtePatch[] = []\n\n for (const patch of converted) {\n const overlap = Math.min(patch.path.length, prefix.length)\n let touchesField = true\n for (let index = 0; index < overlap; index++) {\n if (!segmentsEqual(patch.path[index], prefix[index])) {\n touchesField = false\n break\n }\n }\n if (!touchesField) {\n continue\n }\n if (patch.path.length <= prefix.length) {\n // the patch targets the field itself or an ancestor of it, which\n // cannot be expressed as a field-relative operation\n return null\n }\n scoped.push({...patch, path: patch.path.slice(prefix.length)})\n }\n\n return scoped\n}\n\nfunction applySync({\n editor,\n getRemoteValue,\n}: {\n editor: Editor\n getRemoteValue: () => PortableTextBlock[] | null | undefined\n}) {\n const remoteValue = getRemoteValue()\n\n if (!remoteValue) {\n return\n }\n\n const snapshot = editor.getSnapshot().context.value\n const {patches, incomplete} = convertPatches(diffValue(snapshot, remoteValue))\n\n // Recover with an authoritative full value update when the diff can't be\n // applied faithfully. Either a patch was dropped – replaying the rest would\n // leave the editor in a partial/garbled state – or the editor moved on from\n // `snapshot` while we were diffing, so the patches were computed against a\n // value the editor no longer holds and can't be reconciled safely.\n if (incomplete || editor.getSnapshot().context.value !== snapshot) {\n updateValueFromRemote({editor, getRemoteValue})\n return\n }\n\n if (patches.length) {\n editor.send({type: 'patches', patches, snapshot})\n }\n}\n\nfunction updateValueFromRemote({\n editor,\n getRemoteValue,\n}: {\n editor: Editor\n getRemoteValue: () => PortableTextBlock[] | null | undefined\n}) {\n editor.send({type: 'update value', value: getRemoteValue() ?? []})\n}\n\nconst listenToEditor = fromCallback<AnyEventObject, {editor: Editor}>(\n ({sendBack, input}) => {\n const patchSubscription = input.editor.on('patch', () => {\n sendBack({type: 'patch emitted'})\n })\n\n const mutationSubscription = input.editor.on('mutation', (event) => {\n sendBack({\n type: 'mutation flushed',\n value: event.value,\n patches: event.patches,\n })\n })\n\n return () => {\n patchSubscription.unsubscribe()\n mutationSubscription.unsubscribe()\n }\n },\n)\n\nconst listenToRemote = fromCallback<\n AnyEventObject,\n {onRemoteValueChange: ValueSyncConfig['onRemoteValueChange']}\n>(({sendBack, input}) => {\n return input.onRemoteValueChange(() => {\n sendBack({type: 'remote value changed'})\n })\n})\n\nconst listenToRemotePatches = fromCallback<\n AnyEventObject,\n {onRemotePatches: ValueSyncConfig['onRemotePatches']}\n>(({sendBack, input}) => {\n return input.onRemotePatches?.((patches) => {\n sendBack({type: 'remote patches received', patches})\n })\n})\n\nconst valueSyncMachine = setup({\n types: {\n context: {} as {\n editor: Editor\n getRemoteValue: ValueSyncConfig['getRemoteValue']\n onRemoteValueChange: ValueSyncConfig['onRemoteValueChange']\n onRemotePatches: ValueSyncConfig['onRemotePatches']\n },\n input: {} as {\n editor: Editor\n getRemoteValue: ValueSyncConfig['getRemoteValue']\n onRemoteValueChange: ValueSyncConfig['onRemoteValueChange']\n onRemotePatches: ValueSyncConfig['onRemotePatches']\n },\n events: {} as\n | {type: 'patch emitted'}\n | {\n type: 'mutation flushed'\n value: PortableTextBlock[] | undefined\n patches: PtePatch[]\n }\n | {type: 'remote value changed'}\n | {type: 'remote patches received'; patches: PtePatch[]},\n },\n actions: {\n 'send initial value': ({context}) => {\n updateValueFromRemote({\n editor: context.editor,\n getRemoteValue: context.getRemoteValue,\n })\n },\n 'push to remote': () => {\n throw new Error('push to remote must be provided via .provide()')\n },\n 'apply sync': ({context}) => {\n applySync({\n editor: context.editor,\n getRemoteValue: context.getRemoteValue,\n })\n },\n 'defer then apply sync': ({context}) => {\n queueMicrotask(() => {\n applySync({\n editor: context.editor,\n getRemoteValue: context.getRemoteValue,\n })\n })\n },\n 'apply remote patches': ({context, event}) => {\n if (event.type !== 'remote patches received') {\n return\n }\n if (event.patches.length === 0) {\n return\n }\n context.editor.send({\n type: 'patches',\n patches: event.patches,\n snapshot: context.editor.getSnapshot().context.value,\n })\n },\n },\n actors: {\n 'listen to editor': listenToEditor,\n 'listen to remote': listenToRemote,\n 'listen to remote patches': listenToRemotePatches,\n },\n}).createMachine({\n id: 'value sync',\n context: ({input}) => ({\n editor: input.editor,\n getRemoteValue: input.getRemoteValue,\n onRemoteValueChange: input.onRemoteValueChange,\n onRemotePatches: input.onRemotePatches,\n }),\n entry: ['send initial value'],\n invoke: [\n {\n src: 'listen to editor',\n input: ({context}) => ({editor: context.editor}),\n },\n {\n src: 'listen to remote',\n input: ({context}) => ({\n onRemoteValueChange: context.onRemoteValueChange,\n }),\n },\n {\n src: 'listen to remote patches',\n input: ({context}) => ({\n onRemotePatches: context.onRemotePatches,\n }),\n },\n ],\n // operational patches from other clients apply immediately in every state;\n // the editor merges them with any in-flight local changes\n on: {\n 'remote patches received': {\n actions: ['apply remote patches'],\n },\n },\n initial: 'idle',\n states: {\n 'idle': {\n on: {\n 'patch emitted': {\n target: 'local write',\n },\n 'remote value changed': {\n actions: ['apply sync'],\n },\n },\n },\n 'local write': {\n on: {\n 'patch emitted': {},\n 'mutation flushed': {\n target: 'pushing to remote',\n actions: ['push to remote'],\n },\n 'remote value changed': {\n target: 'pending sync',\n },\n },\n },\n 'pushing to remote': {\n on: {\n 'patch emitted': {\n target: 'local write',\n },\n 'remote value changed': {\n target: 'idle',\n },\n },\n },\n 'pending sync': {\n on: {\n 'patch emitted': {},\n 'mutation flushed': {\n target: 'pushing to remote',\n actions: ['push to remote', 'defer then apply sync'],\n },\n 'remote value changed': {},\n },\n },\n },\n})\n\ninterface SDKValuePluginProps extends DocumentHandle {\n path: string\n}\n\n/**\n * The shape of the `remote-patches` document event emitted by\n * `@sanity/sdk` >= 2.17. Declared structurally so the plugin stays\n * compatible with older SDK typings until its dependency is bumped.\n */\ntype RemotePatchesDocumentEvent = {\n type: 'remote-patches'\n documentId: string\n transactionId: string\n timestamp: string\n previousRev?: string\n patches: SanityPatchOperations[]\n origin: 'local' | 'remote'\n}\n\nfunction isRemotePatchesEvent(event: {\n type: string\n}): event is RemotePatchesDocumentEvent {\n return event.type === 'remote-patches'\n}\n\nfunction getPublishedDocumentId(id: string): string {\n if (id.startsWith('drafts.')) {\n return id.slice('drafts.'.length)\n }\n if (id.startsWith('versions.')) {\n return id.split('.').slice(2).join('.')\n }\n return id\n}\n\n/**\n * @public\n */\nexport function SDKValuePlugin(props: SDKValuePluginProps) {\n const {documentId, documentType, path} = props\n const setSdkValue = useEditDocument(props)\n const instance = useSanityInstance(props)\n const applyActions = useApplyDocumentActions()\n\n const handle = {documentId, documentType, path}\n const {getCurrent, subscribe} = getDocumentState<PortableTextBlock[]>(\n instance,\n handle,\n )\n\n const onRemotePatches = useCallback(\n (callback: (patches: PtePatch[]) => void) => {\n return subscribeDocumentEvents(instance, {\n eventHandler: (event) => {\n // widen before narrowing: `remote-patches` is not part of the\n // `DocumentEvent` union in older SDK typings\n const candidate: {type: string} = event\n if (!isRemotePatchesEvent(candidate)) {\n return\n }\n // our own transactions are already reflected in the editor\n if (candidate.origin !== 'remote') {\n return\n }\n if (\n getPublishedDocumentId(candidate.documentId) !==\n getPublishedDocumentId(documentId)\n ) {\n return\n }\n\n let patches: PtePatch[] | null\n try {\n patches = scopeRemotePatches(candidate.patches, path)\n } catch {\n // unconvertible patch shapes fall back to the whole-value sync\n // driven by `onRemoteValueChange`\n return\n }\n if (patches && patches.length > 0) {\n callback(patches)\n }\n },\n })\n },\n [instance, documentId, path],\n )\n\n const pushPatches = useCallback(\n (patches: PtePatch[]) => {\n const sanityPatches = convertPatchesToSanity(patches, {prefix: path})\n // `preserveOperations` ships in @sanity/sdk >= 2.17; the intersection\n // type keeps the plugin compatible with older SDK typings\n const action: EditDocumentAction & {preserveOperations?: boolean} = {\n ...editDocument(\n {documentId, documentType},\n sanityPatches as Parameters<typeof editDocument>[1],\n ),\n preserveOperations: true,\n }\n applyActions(action)\n },\n [applyActions, documentId, documentType, path],\n )\n\n return (\n <ValueSyncPlugin\n getRemoteValue={getCurrent}\n pushValue={setSdkValue}\n onRemoteValueChange={subscribe}\n onRemotePatches={onRemotePatches}\n pushPatches={pushPatches}\n />\n )\n}\n\n/**\n * @internal\n */\ntype ValueSyncConfig = {\n getRemoteValue: () => PortableTextBlock[] | null | undefined\n pushValue: (value: PortableTextBlock[]) => void\n onRemoteValueChange: (callback: () => void) => () => void\n /**\n * Optional patch channel. When provided, operational patches from other\n * clients are applied directly to the editor (in every state) instead of\n * waiting for a whole-value diff, and local editor patches are pushed\n * through `pushPatches`. The whole-value sync remains as a fallback for\n * anything the patch channel cannot express.\n */\n onRemotePatches?: (\n callback: (patches: PtePatch[]) => void,\n ) => (() => void) | undefined\n /**\n * Pushes the editor's own operational patches to the remote store. May\n * throw when a patch cannot be converted, in which case the plugin falls\n * back to pushing the whole value.\n */\n pushPatches?: (patches: PtePatch[]) => void\n}\n\n/**\n * NOTE: You are probably looking for SDKValuePlugin instead of this.\n * This is a lower-level plugin that only handles syncing the value\n * between the editor and a remote source. It does not know anything\n * about Sanity documents or how to fetch/update them.\n *\n * May be removed in the future, do not rely on this directly.\n *\n * @internal\n */\nexport function ValueSyncPlugin(props: ValueSyncConfig) {\n const {\n getRemoteValue,\n pushValue,\n onRemoteValueChange,\n onRemotePatches,\n pushPatches,\n } = props\n const editor = useEditor()\n\n useActorRef(\n valueSyncMachine.provide({\n actions: {\n 'push to remote': ({context, event}) => {\n if (event.type !== 'mutation flushed') {\n return\n }\n\n if (pushPatches && event.patches.length > 0) {\n try {\n pushPatches(event.patches)\n return\n } catch {\n // fall back to pushing the whole value below\n }\n }\n\n pushValue(event.value ?? context.editor.getSnapshot().context.value)\n },\n },\n }),\n {\n input: {\n editor,\n getRemoteValue,\n onRemoteValueChange,\n onRemotePatches,\n },\n },\n )\n\n return null\n}\n"],"names":["getSegments","node","base","segment","type","isKeyPath","recursive","name","arrayifyPath","pathExpr","parsePath","path","push","elements","length","element","value","operator","keyPathNode","left","right","find","other","_key","convertPatches","patches","incomplete","flatMap","operation","Object","entries","values","origin","Array","isArray","items","rest","position","keys","at","STRINGIFY_ERROR_MESSAGE","stringifyPatchPath","result","Error","prefixPathExpression","prefix","expression","startsWith","convertPatchesToSanity","options","map","patch","pathExpression","set","setIfMissing","diffMatchPatch","inc","dec","unset","insert","segmentsEqual","a","b","scopeRemotePatches","fieldPath","converted","scoped","overlap","Math","min","touchesField","index","slice","applySync","editor","getRemoteValue","remoteValue","snapshot","getSnapshot","context","diffValue","updateValueFromRemote","send","listenToEditor","fromCallback","sendBack","input","patchSubscription","on","mutationSubscription","event","unsubscribe","listenToRemote","onRemoteValueChange","listenToRemotePatches","onRemotePatches","valueSyncMachine","setup","types","events","actions","send initial value","push to remote","apply sync","defer then apply sync","queueMicrotask","apply remote patches","actors","createMachine","id","entry","invoke","src","initial","states","target","isRemotePatchesEvent","getPublishedDocumentId","split","join","SDKValuePlugin","props","$","_c","documentId","documentType","setSdkValue","useEditDocument","instance","useSanityInstance","applyActions","useApplyDocumentActions","t0","getDocumentState","getCurrent","subscribe","t1","callback","subscribeDocumentEvents","eventHandler","candidate","t2","patches_0","sanityPatches","action","editDocument","preserveOperations","pushPatches","t3","ValueSyncPlugin","pushValue","useEditor","provide","useActorRef"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@portabletext/plugin-sdk-value",
|
|
3
|
-
"version": "7.0.
|
|
3
|
+
"version": "7.0.36-crx.0",
|
|
4
4
|
"description": "Connect a Portable Text Editor with a Sanity document using the SDK",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"@sanity/sdk",
|
|
@@ -59,8 +59,8 @@
|
|
|
59
59
|
"vitest": "^4.1.10",
|
|
60
60
|
"vitest-browser-react": "^2.2.0",
|
|
61
61
|
"@portabletext/editor": "^7.10.8-crx.0",
|
|
62
|
-
"@portabletext/schema": "^2.2.3",
|
|
63
62
|
"@portabletext/patches": "^2.0.5",
|
|
63
|
+
"@portabletext/schema": "^2.2.3",
|
|
64
64
|
"@portabletext/test": "^1.0.4"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|