@superdoc-dev/cli 1.0.2 → 1.0.3

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.
Files changed (2) hide show
  1. package/dist/index.js +2537 -1059
  2. package/package.json +7 -7
package/dist/index.js CHANGED
@@ -502,7 +502,7 @@ function mutationOperation(options) {
502
502
  function projectFromDefinitions(fn) {
503
503
  return Object.fromEntries(OPERATION_IDS.map((id) => [id, fn(id, OPERATION_DEFINITIONS[id])]));
504
504
  }
505
- var NONE_FAILURES, NONE_THROWS, T_NOT_FOUND, T_COMMAND, T_NOT_FOUND_COMMAND, T_NOT_FOUND_TRACKED, T_NOT_FOUND_COMMAND_TRACKED, OPERATION_DEFINITIONS, OPERATION_IDS, SINGLETON_OPERATION_IDS, NAMESPACED_OPERATION_IDS;
505
+ var NONE_FAILURES, NONE_THROWS, T_NOT_FOUND, T_COMMAND, T_NOT_FOUND_COMMAND, T_NOT_FOUND_TRACKED, T_NOT_FOUND_COMMAND_TRACKED, T_PLAN_ENGINE, T_QUERY_MATCH, OPERATION_DEFINITIONS, OPERATION_IDS, SINGLETON_OPERATION_IDS, NAMESPACED_OPERATION_IDS;
506
506
  var init_operation_definitions = __esm(() => {
507
507
  NONE_FAILURES = [];
508
508
  NONE_THROWS = [];
@@ -516,6 +516,19 @@ var init_operation_definitions = __esm(() => {
516
516
  "TRACK_CHANGE_COMMAND_UNAVAILABLE",
517
517
  "CAPABILITY_UNAVAILABLE"
518
518
  ];
519
+ T_PLAN_ENGINE = [
520
+ "REVISION_MISMATCH",
521
+ "MATCH_NOT_FOUND",
522
+ "AMBIGUOUS_MATCH",
523
+ "STYLE_CONFLICT",
524
+ "PRECONDITION_FAILED",
525
+ "INVALID_INPUT",
526
+ "CROSS_BLOCK_MATCH",
527
+ "PLAN_CONFLICT_OVERLAP",
528
+ "INVALID_STEP_COMBINATION",
529
+ "CAPABILITY_UNAVAILABLE"
530
+ ];
531
+ T_QUERY_MATCH = ["MATCH_NOT_FOUND", "AMBIGUOUS_MATCH", "INVALID_INPUT"];
519
532
  OPERATION_DEFINITIONS = {
520
533
  find: {
521
534
  memberPath: "find",
@@ -1019,6 +1032,45 @@ var init_operation_definitions = __esm(() => {
1019
1032
  referenceDocPath: "track-changes/reject-all.mdx",
1020
1033
  referenceGroup: "trackChanges"
1021
1034
  },
1035
+ "query.match": {
1036
+ memberPath: "query.match",
1037
+ description: "Deterministic selector-based search with cardinality contracts for mutation targeting.",
1038
+ requiresDocumentContext: true,
1039
+ metadata: readOperation({
1040
+ idempotency: "idempotent",
1041
+ throws: T_QUERY_MATCH,
1042
+ deterministicTargetResolution: true
1043
+ }),
1044
+ referenceDocPath: "query/match.mdx",
1045
+ referenceGroup: "query"
1046
+ },
1047
+ "mutations.preview": {
1048
+ memberPath: "mutations.preview",
1049
+ description: "Dry-run a mutation plan, returning resolved targets without applying changes.",
1050
+ requiresDocumentContext: true,
1051
+ metadata: readOperation({
1052
+ idempotency: "idempotent",
1053
+ throws: T_PLAN_ENGINE,
1054
+ deterministicTargetResolution: true
1055
+ }),
1056
+ referenceDocPath: "mutations/preview.mdx",
1057
+ referenceGroup: "mutations"
1058
+ },
1059
+ "mutations.apply": {
1060
+ memberPath: "mutations.apply",
1061
+ description: "Execute a mutation plan atomically against the document.",
1062
+ requiresDocumentContext: true,
1063
+ metadata: mutationOperation({
1064
+ idempotency: "non-idempotent",
1065
+ supportsDryRun: false,
1066
+ supportsTrackedMode: true,
1067
+ possibleFailureCodes: NONE_FAILURES,
1068
+ throws: T_PLAN_ENGINE,
1069
+ deterministicTargetResolution: true
1070
+ }),
1071
+ referenceDocPath: "mutations/apply.mdx",
1072
+ referenceGroup: "mutations"
1073
+ },
1022
1074
  "capabilities.get": {
1023
1075
  memberPath: "capabilities",
1024
1076
  description: "Query runtime capabilities supported by the current document engine.",
@@ -1858,6 +1910,71 @@ var init_schemas = __esm(() => {
1858
1910
  success: receiptSuccessSchema,
1859
1911
  failure: receiptFailureResultSchemaFor("trackChanges.rejectAll")
1860
1912
  },
1913
+ "query.match": {
1914
+ input: objectSchema({
1915
+ select: { oneOf: [textSelectorSchema, nodeSelectorSchema] },
1916
+ within: nodeAddressSchema,
1917
+ require: { enum: ["any", "first", "exactlyOne", "all"] },
1918
+ includeNodes: { type: "boolean" },
1919
+ includeStyle: { type: "boolean" },
1920
+ limit: { type: "integer", minimum: 1 },
1921
+ offset: { type: "integer", minimum: 0 }
1922
+ }, ["select"]),
1923
+ output: objectSchema({
1924
+ evaluatedRevision: { type: "string" },
1925
+ matches: arraySchema(objectSchema({
1926
+ address: nodeAddressSchema,
1927
+ textRanges: arraySchema(textAddressSchema),
1928
+ ref: { type: "string" },
1929
+ refStability: { enum: ["ephemeral", "stable"] },
1930
+ style: objectSchema({
1931
+ marks: objectSchema({
1932
+ bold: { type: "boolean" },
1933
+ italic: { type: "boolean" },
1934
+ underline: { type: "boolean" },
1935
+ strike: { type: "boolean" }
1936
+ }),
1937
+ isUniform: { type: "boolean" }
1938
+ }, ["marks", "isUniform"])
1939
+ })),
1940
+ totalMatches: { type: "integer", minimum: 0 }
1941
+ }, ["evaluatedRevision", "matches", "totalMatches"])
1942
+ },
1943
+ "mutations.preview": {
1944
+ input: objectSchema({
1945
+ expectedRevision: { type: "string" },
1946
+ atomic: { const: true },
1947
+ changeMode: { enum: ["direct", "tracked"] },
1948
+ steps: arraySchema({ type: "object" })
1949
+ }, ["expectedRevision", "atomic", "changeMode", "steps"]),
1950
+ output: objectSchema({
1951
+ evaluatedRevision: { type: "string" },
1952
+ steps: arraySchema({ type: "object" }),
1953
+ valid: { type: "boolean" },
1954
+ failures: arraySchema({ type: "object" })
1955
+ }, ["evaluatedRevision", "steps", "valid"])
1956
+ },
1957
+ "mutations.apply": {
1958
+ input: objectSchema({
1959
+ expectedRevision: { type: "string" },
1960
+ atomic: { const: true },
1961
+ changeMode: { enum: ["direct", "tracked"] },
1962
+ steps: arraySchema({ type: "object" })
1963
+ }, ["expectedRevision", "atomic", "changeMode", "steps"]),
1964
+ output: objectSchema({
1965
+ success: { const: true },
1966
+ revision: objectSchema({ before: { type: "string" }, after: { type: "string" } }, ["before", "after"]),
1967
+ steps: arraySchema({ type: "object" }),
1968
+ trackedChanges: arraySchema({ type: "object" }),
1969
+ timing: objectSchema({ totalMs: { type: "number" } }, ["totalMs"])
1970
+ }, ["success", "revision", "steps", "timing"]),
1971
+ success: objectSchema({
1972
+ success: { const: true },
1973
+ revision: objectSchema({ before: { type: "string" }, after: { type: "string" } }, ["before", "after"]),
1974
+ steps: arraySchema({ type: "object" }),
1975
+ timing: objectSchema({ totalMs: { type: "number" } }, ["totalMs"])
1976
+ }, ["success", "revision", "steps", "timing"])
1977
+ },
1861
1978
  "capabilities.get": {
1862
1979
  input: strictEmptyObjectSchema,
1863
1980
  output: capabilitiesOutputSchema
@@ -1915,6 +2032,16 @@ var init_reference_doc_map = __esm(() => {
1915
2032
  title: "Track Changes",
1916
2033
  description: "Tracked-change inspection and review operations.",
1917
2034
  pagePath: "track-changes/index.mdx"
2035
+ },
2036
+ query: {
2037
+ title: "Query",
2038
+ description: "Deterministic selector-based queries for mutation targeting.",
2039
+ pagePath: "query/index.mdx"
2040
+ },
2041
+ mutations: {
2042
+ title: "Mutations",
2043
+ description: "Atomic mutation plan preview and execution.",
2044
+ pagePath: "mutations/index.mdx"
1918
2045
  }
1919
2046
  };
1920
2047
  REFERENCE_OPERATION_GROUPS = Object.keys(GROUP_METADATA).map((key) => ({
@@ -2142,33 +2269,33 @@ function normalizeCommentTarget(input) {
2142
2269
  const { blockId: _b, start: _s, end: _e, ...rest } = input;
2143
2270
  return { ...rest, target };
2144
2271
  }
2145
- function executeAddComment(adapter, input) {
2272
+ function executeAddComment(adapter, input, options) {
2146
2273
  validateAddCommentInput(input);
2147
2274
  const normalized = normalizeCommentTarget(input);
2148
- return adapter.add(normalized);
2275
+ return adapter.add(normalized, options);
2149
2276
  }
2150
- function executeEditComment(adapter, input) {
2151
- return adapter.edit(input);
2277
+ function executeEditComment(adapter, input, options) {
2278
+ return adapter.edit(input, options);
2152
2279
  }
2153
- function executeReplyToComment(adapter, input) {
2154
- return adapter.reply(input);
2280
+ function executeReplyToComment(adapter, input, options) {
2281
+ return adapter.reply(input, options);
2155
2282
  }
2156
- function executeMoveComment(adapter, input) {
2283
+ function executeMoveComment(adapter, input, options) {
2157
2284
  validateMoveCommentInput(input);
2158
2285
  const normalized = normalizeCommentTarget(input);
2159
- return adapter.move(normalized);
2286
+ return adapter.move(normalized, options);
2160
2287
  }
2161
- function executeResolveComment(adapter, input) {
2162
- return adapter.resolve(input);
2288
+ function executeResolveComment(adapter, input, options) {
2289
+ return adapter.resolve(input, options);
2163
2290
  }
2164
- function executeRemoveComment(adapter, input) {
2165
- return adapter.remove(input);
2291
+ function executeRemoveComment(adapter, input, options) {
2292
+ return adapter.remove(input, options);
2166
2293
  }
2167
- function executeSetCommentInternal(adapter, input) {
2168
- return adapter.setInternal(input);
2294
+ function executeSetCommentInternal(adapter, input, options) {
2295
+ return adapter.setInternal(input, options);
2169
2296
  }
2170
- function executeSetCommentActive(adapter, input) {
2171
- return adapter.setActive(input);
2297
+ function executeSetCommentActive(adapter, input, options) {
2298
+ return adapter.setActive(input, options);
2172
2299
  }
2173
2300
  function executeGoToComment(adapter, input) {
2174
2301
  return adapter.goTo(input);
@@ -2232,6 +2359,7 @@ function executeFind(adapter, selectorOrQuery, options) {
2232
2359
  // ../../packages/document-api/src/write/write.ts
2233
2360
  function normalizeMutationOptions(options) {
2234
2361
  return {
2362
+ expectedRevision: options?.expectedRevision,
2235
2363
  changeMode: options?.changeMode ?? "direct",
2236
2364
  dryRun: options?.dryRun ?? false
2237
2365
  };
@@ -2676,17 +2804,17 @@ function executeTrackChangesList(adapter, input) {
2676
2804
  function executeTrackChangesGet(adapter, input) {
2677
2805
  return adapter.get(input);
2678
2806
  }
2679
- function executeTrackChangesAccept(adapter, input) {
2680
- return adapter.accept(input);
2807
+ function executeTrackChangesAccept(adapter, input, options) {
2808
+ return adapter.accept(input, options);
2681
2809
  }
2682
- function executeTrackChangesReject(adapter, input) {
2683
- return adapter.reject(input);
2810
+ function executeTrackChangesReject(adapter, input, options) {
2811
+ return adapter.reject(input, options);
2684
2812
  }
2685
- function executeTrackChangesAcceptAll(adapter, input) {
2686
- return adapter.acceptAll(input);
2813
+ function executeTrackChangesAcceptAll(adapter, input, options) {
2814
+ return adapter.acceptAll(input, options);
2687
2815
  }
2688
- function executeTrackChangesRejectAll(adapter, input) {
2689
- return adapter.rejectAll(input);
2816
+ function executeTrackChangesRejectAll(adapter, input, options) {
2817
+ return adapter.rejectAll(input, options);
2690
2818
  }
2691
2819
 
2692
2820
  // ../../packages/document-api/src/invoke/invoke.ts
@@ -2714,23 +2842,26 @@ function buildDispatchTable(api) {
2714
2842
  "lists.outdent": (input, options) => api.lists.outdent(input, options),
2715
2843
  "lists.restart": (input, options) => api.lists.restart(input, options),
2716
2844
  "lists.exit": (input, options) => api.lists.exit(input, options),
2717
- "comments.add": (input) => api.comments.add(input),
2718
- "comments.edit": (input) => api.comments.edit(input),
2719
- "comments.reply": (input) => api.comments.reply(input),
2720
- "comments.move": (input) => api.comments.move(input),
2721
- "comments.resolve": (input) => api.comments.resolve(input),
2722
- "comments.remove": (input) => api.comments.remove(input),
2723
- "comments.setInternal": (input) => api.comments.setInternal(input),
2724
- "comments.setActive": (input) => api.comments.setActive(input),
2845
+ "comments.add": (input, options) => api.comments.add(input, options),
2846
+ "comments.edit": (input, options) => api.comments.edit(input, options),
2847
+ "comments.reply": (input, options) => api.comments.reply(input, options),
2848
+ "comments.move": (input, options) => api.comments.move(input, options),
2849
+ "comments.resolve": (input, options) => api.comments.resolve(input, options),
2850
+ "comments.remove": (input, options) => api.comments.remove(input, options),
2851
+ "comments.setInternal": (input, options) => api.comments.setInternal(input, options),
2852
+ "comments.setActive": (input, options) => api.comments.setActive(input, options),
2725
2853
  "comments.goTo": (input) => api.comments.goTo(input),
2726
2854
  "comments.get": (input) => api.comments.get(input),
2727
2855
  "comments.list": (input) => api.comments.list(input),
2728
2856
  "trackChanges.list": (input) => api.trackChanges.list(input),
2729
2857
  "trackChanges.get": (input) => api.trackChanges.get(input),
2730
- "trackChanges.accept": (input) => api.trackChanges.accept(input),
2731
- "trackChanges.reject": (input) => api.trackChanges.reject(input),
2732
- "trackChanges.acceptAll": (input) => api.trackChanges.acceptAll(input),
2733
- "trackChanges.rejectAll": (input) => api.trackChanges.rejectAll(input),
2858
+ "trackChanges.accept": (input, options) => api.trackChanges.accept(input, options),
2859
+ "trackChanges.reject": (input, options) => api.trackChanges.reject(input, options),
2860
+ "trackChanges.acceptAll": (input, options) => api.trackChanges.acceptAll(input, options),
2861
+ "trackChanges.rejectAll": (input, options) => api.trackChanges.rejectAll(input, options),
2862
+ "query.match": (input) => api.query.match(input),
2863
+ "mutations.preview": (input) => api.mutations.preview(input),
2864
+ "mutations.apply": (input) => api.mutations.apply(input),
2734
2865
  "capabilities.get": () => api.capabilities()
2735
2866
  };
2736
2867
  }
@@ -2763,29 +2894,29 @@ function createDocumentApi(adapters) {
2763
2894
  return executeInfo(adapters.info, input);
2764
2895
  },
2765
2896
  comments: {
2766
- add(input) {
2767
- return executeAddComment(adapters.comments, input);
2897
+ add(input, options) {
2898
+ return executeAddComment(adapters.comments, input, options);
2768
2899
  },
2769
- edit(input) {
2770
- return executeEditComment(adapters.comments, input);
2900
+ edit(input, options) {
2901
+ return executeEditComment(adapters.comments, input, options);
2771
2902
  },
2772
- reply(input) {
2773
- return executeReplyToComment(adapters.comments, input);
2903
+ reply(input, options) {
2904
+ return executeReplyToComment(adapters.comments, input, options);
2774
2905
  },
2775
- move(input) {
2776
- return executeMoveComment(adapters.comments, input);
2906
+ move(input, options) {
2907
+ return executeMoveComment(adapters.comments, input, options);
2777
2908
  },
2778
- resolve(input) {
2779
- return executeResolveComment(adapters.comments, input);
2909
+ resolve(input, options) {
2910
+ return executeResolveComment(adapters.comments, input, options);
2780
2911
  },
2781
- remove(input) {
2782
- return executeRemoveComment(adapters.comments, input);
2912
+ remove(input, options) {
2913
+ return executeRemoveComment(adapters.comments, input, options);
2783
2914
  },
2784
- setInternal(input) {
2785
- return executeSetCommentInternal(adapters.comments, input);
2915
+ setInternal(input, options) {
2916
+ return executeSetCommentInternal(adapters.comments, input, options);
2786
2917
  },
2787
- setActive(input) {
2788
- return executeSetCommentActive(adapters.comments, input);
2918
+ setActive(input, options) {
2919
+ return executeSetCommentActive(adapters.comments, input, options);
2789
2920
  },
2790
2921
  goTo(input) {
2791
2922
  return executeGoToComment(adapters.comments, input);
@@ -2827,17 +2958,17 @@ function createDocumentApi(adapters) {
2827
2958
  get(input) {
2828
2959
  return executeTrackChangesGet(adapters.trackChanges, input);
2829
2960
  },
2830
- accept(input) {
2831
- return executeTrackChangesAccept(adapters.trackChanges, input);
2961
+ accept(input, options) {
2962
+ return executeTrackChangesAccept(adapters.trackChanges, input, options);
2832
2963
  },
2833
- reject(input) {
2834
- return executeTrackChangesReject(adapters.trackChanges, input);
2964
+ reject(input, options) {
2965
+ return executeTrackChangesReject(adapters.trackChanges, input, options);
2835
2966
  },
2836
- acceptAll(input) {
2837
- return executeTrackChangesAcceptAll(adapters.trackChanges, input);
2967
+ acceptAll(input, options) {
2968
+ return executeTrackChangesAcceptAll(adapters.trackChanges, input, options);
2838
2969
  },
2839
- rejectAll(input) {
2840
- return executeTrackChangesRejectAll(adapters.trackChanges, input);
2970
+ rejectAll(input, options) {
2971
+ return executeTrackChangesRejectAll(adapters.trackChanges, input, options);
2841
2972
  }
2842
2973
  },
2843
2974
  create: {
@@ -2848,6 +2979,19 @@ function createDocumentApi(adapters) {
2848
2979
  return executeCreateHeading(adapters.create, input, options);
2849
2980
  }
2850
2981
  },
2982
+ query: {
2983
+ match(input) {
2984
+ return adapters.query.match(input);
2985
+ }
2986
+ },
2987
+ mutations: {
2988
+ preview(input) {
2989
+ return adapters.mutations.preview(input);
2990
+ },
2991
+ apply(input) {
2992
+ return adapters.mutations.apply(input);
2993
+ }
2994
+ },
2851
2995
  capabilities: capabilities2,
2852
2996
  lists: {
2853
2997
  list(query2) {
@@ -3521,6 +3665,7 @@ var init_operation_hints = __esm(() => {
3521
3665
  find: "completed search",
3522
3666
  getNode: "resolved node",
3523
3667
  getNodeById: "resolved node",
3668
+ getText: "extracted text",
3524
3669
  info: "retrieved info",
3525
3670
  insert: "inserted text",
3526
3671
  replace: "replaced text",
@@ -3530,6 +3675,7 @@ var init_operation_hints = __esm(() => {
3530
3675
  "format.underline": "applied underline",
3531
3676
  "format.strikethrough": "applied strikethrough",
3532
3677
  "create.paragraph": "created paragraph",
3678
+ "create.heading": "created heading",
3533
3679
  "lists.list": "listed items",
3534
3680
  "lists.get": "resolved list item",
3535
3681
  "lists.insert": "inserted list item",
@@ -3554,12 +3700,14 @@ var init_operation_hints = __esm(() => {
3554
3700
  "trackChanges.accept": "accepted tracked change",
3555
3701
  "trackChanges.reject": "rejected tracked change",
3556
3702
  "trackChanges.acceptAll": "accepted all tracked changes",
3557
- "trackChanges.rejectAll": "rejected all tracked changes"
3703
+ "trackChanges.rejectAll": "rejected all tracked changes",
3704
+ "capabilities.get": "retrieved capabilities"
3558
3705
  };
3559
3706
  OUTPUT_FORMAT = {
3560
3707
  find: "queryResult",
3561
3708
  getNode: "nodeInfo",
3562
3709
  getNodeById: "nodeInfo",
3710
+ getText: "plain",
3563
3711
  info: "documentInfo",
3564
3712
  insert: "mutationReceipt",
3565
3713
  replace: "mutationReceipt",
@@ -3569,6 +3717,7 @@ var init_operation_hints = __esm(() => {
3569
3717
  "format.underline": "mutationReceipt",
3570
3718
  "format.strikethrough": "mutationReceipt",
3571
3719
  "create.paragraph": "createResult",
3720
+ "create.heading": "createResult",
3572
3721
  "lists.list": "listResult",
3573
3722
  "lists.get": "listItemInfo",
3574
3723
  "lists.insert": "listsMutationResult",
@@ -3593,12 +3742,14 @@ var init_operation_hints = __esm(() => {
3593
3742
  "trackChanges.accept": "trackChangeMutationReceipt",
3594
3743
  "trackChanges.reject": "trackChangeMutationReceipt",
3595
3744
  "trackChanges.acceptAll": "trackChangeMutationReceipt",
3596
- "trackChanges.rejectAll": "trackChangeMutationReceipt"
3745
+ "trackChanges.rejectAll": "trackChangeMutationReceipt",
3746
+ "capabilities.get": "plain"
3597
3747
  };
3598
3748
  RESPONSE_ENVELOPE_KEY = {
3599
3749
  find: "result",
3600
3750
  getNode: "node",
3601
3751
  getNodeById: "node",
3752
+ getText: "text",
3602
3753
  info: null,
3603
3754
  insert: null,
3604
3755
  replace: null,
@@ -3608,6 +3759,7 @@ var init_operation_hints = __esm(() => {
3608
3759
  "format.underline": null,
3609
3760
  "format.strikethrough": null,
3610
3761
  "create.paragraph": "result",
3762
+ "create.heading": "result",
3611
3763
  "lists.list": "result",
3612
3764
  "lists.get": "item",
3613
3765
  "lists.insert": "result",
@@ -3632,7 +3784,8 @@ var init_operation_hints = __esm(() => {
3632
3784
  "trackChanges.accept": "receipt",
3633
3785
  "trackChanges.reject": "receipt",
3634
3786
  "trackChanges.acceptAll": "receipt",
3635
- "trackChanges.rejectAll": "receipt"
3787
+ "trackChanges.rejectAll": "receipt",
3788
+ "capabilities.get": "capabilities"
3636
3789
  };
3637
3790
  RESPONSE_VALIDATION_KEY = {
3638
3791
  insert: "receipt",
@@ -3647,6 +3800,7 @@ var init_operation_hints = __esm(() => {
3647
3800
  find: "query",
3648
3801
  getNode: "query",
3649
3802
  getNodeById: "query",
3803
+ getText: "query",
3650
3804
  info: "general",
3651
3805
  insert: "textMutation",
3652
3806
  replace: "textMutation",
@@ -3656,6 +3810,7 @@ var init_operation_hints = __esm(() => {
3656
3810
  "format.underline": "textMutation",
3657
3811
  "format.strikethrough": "textMutation",
3658
3812
  "create.paragraph": "create",
3813
+ "create.heading": "create",
3659
3814
  "lists.list": "lists",
3660
3815
  "lists.get": "lists",
3661
3816
  "lists.insert": "lists",
@@ -3680,7 +3835,8 @@ var init_operation_hints = __esm(() => {
3680
3835
  "trackChanges.accept": "trackChanges",
3681
3836
  "trackChanges.reject": "trackChanges",
3682
3837
  "trackChanges.acceptAll": "trackChanges",
3683
- "trackChanges.rejectAll": "trackChanges"
3838
+ "trackChanges.rejectAll": "trackChanges",
3839
+ "capabilities.get": "general"
3684
3840
  };
3685
3841
  });
3686
3842
 
@@ -3985,7 +4141,7 @@ function deriveCategoryFromDocApi(docApiId) {
3985
4141
  const group = REFERENCE_GROUP_BY_OP.get(docApiId);
3986
4142
  if (!group)
3987
4143
  return "query";
3988
- if (group === "core") {
4144
+ if (group === "core" || group === "mutations") {
3989
4145
  return COMMAND_CATALOG[docApiId].mutates ? "mutation" : "query";
3990
4146
  }
3991
4147
  return group;
@@ -4032,11 +4188,7 @@ var init_operation_set = __esm(() => {
4032
4188
  init_cli_only_operation_definitions();
4033
4189
  init_types3();
4034
4190
  init_types3();
4035
- CLI_OPERATION_DENYLIST = [
4036
- "getText",
4037
- "capabilities.get",
4038
- "create.heading"
4039
- ];
4191
+ CLI_OPERATION_DENYLIST = [];
4040
4192
  denySet = new Set(CLI_OPERATION_DENYLIST);
4041
4193
  CLI_DOC_OPERATIONS = OPERATION_IDS.filter((id) => !denySet.has(id));
4042
4194
  CLI_OPERATION_IDS = [
@@ -189149,6 +189301,16 @@ function buildOperationCapabilities2(editor) {
189149
189301
  }
189150
189302
  return operations;
189151
189303
  }
189304
+ function buildPlanEngineCapabilities() {
189305
+ return {
189306
+ supportedStepOps: SUPPORTED_STEP_OPS,
189307
+ supportedNonUniformStrategies: SUPPORTED_NON_UNIFORM_STRATEGIES,
189308
+ supportedSetMarks: SUPPORTED_SET_MARKS,
189309
+ regex: {
189310
+ maxPatternLength: REGEX_MAX_PATTERN_LENGTH
189311
+ }
189312
+ };
189313
+ }
189152
189314
  function getDocumentApiCapabilities2(editor) {
189153
189315
  const operations = buildOperationCapabilities2(editor);
189154
189316
  const commentsEnabled = isCommentsNamespaceEnabled2(editor);
@@ -189174,10 +189336,11 @@ function getDocumentApiCapabilities2(editor) {
189174
189336
  reasons: dryRunEnabled ? undefined : ["DRY_RUN_UNAVAILABLE"]
189175
189337
  }
189176
189338
  },
189177
- operations
189339
+ operations,
189340
+ planEngine: buildPlanEngineCapabilities()
189178
189341
  };
189179
189342
  }
189180
- var REQUIRED_COMMANDS2, VALID_CAPABILITY_REASON_CODES2, FORMAT_MARK_MAP2;
189343
+ var REQUIRED_COMMANDS2, VALID_CAPABILITY_REASON_CODES2, FORMAT_MARK_MAP2, SUPPORTED_STEP_OPS, SUPPORTED_NON_UNIFORM_STRATEGIES, SUPPORTED_SET_MARKS, REGEX_MAX_PATTERN_LENGTH = 1024;
189181
189344
  var init_capabilities_adapter = __esm(() => {
189182
189345
  init_src();
189183
189346
  REQUIRED_COMMANDS2 = {
@@ -189210,6 +189373,17 @@ var init_capabilities_adapter = __esm(() => {
189210
189373
  "format.underline": "underline",
189211
189374
  "format.strikethrough": "strike"
189212
189375
  };
189376
+ SUPPORTED_STEP_OPS = [
189377
+ "text.rewrite",
189378
+ "text.insert",
189379
+ "text.delete",
189380
+ "style.apply",
189381
+ "assert",
189382
+ "create.paragraph",
189383
+ "create.heading"
189384
+ ];
189385
+ SUPPORTED_NON_UNIFORM_STRATEGIES = ["error", "useLeadingRun", "majority", "union"];
189386
+ SUPPORTED_SET_MARKS = ["bold", "italic", "underline", "strike"];
189213
189387
  });
189214
189388
 
189215
189389
  // ../../node_modules/.pnpm/prosemirror-model@1.25.4/node_modules/prosemirror-model/dist/index.js
@@ -194209,8 +194383,8 @@ function toBlockAddress2(candidate) {
194209
194383
  nodeId: candidate.nodeId
194210
194384
  };
194211
194385
  }
194212
- function resolveParagraphAliasId2(node3, primaryId) {
194213
- if (node3.type.name !== "paragraph")
194386
+ function resolveBlockAliasId(node3, nodeType, primaryId) {
194387
+ if (!ALIAS_ELIGIBLE_TYPES.has(nodeType))
194214
194388
  return;
194215
194389
  const attrs = node3.attrs;
194216
194390
  const sdBlockId = toId2(attrs?.sdBlockId);
@@ -194246,7 +194420,7 @@ function buildBlockIndex2(editor) {
194246
194420
  };
194247
194421
  candidates.push(candidate);
194248
194422
  registerKey(`${nodeType}:${nodeId}`, candidate);
194249
- const aliasId = resolveParagraphAliasId2(node3, nodeId);
194423
+ const aliasId = resolveBlockAliasId(node3, nodeType, nodeId);
194250
194424
  if (aliasId) {
194251
194425
  registerKey(`${nodeType}:${aliasId}`, candidate);
194252
194426
  }
@@ -194268,9 +194442,24 @@ function findBlockByNodeIdOnly2(index2, nodeId) {
194268
194442
  count: matches3.length
194269
194443
  });
194270
194444
  }
194445
+ const aliasMatches = new Map;
194271
194446
  for (const [key2, candidate] of index2.byId) {
194272
- if (key2.endsWith(`:${nodeId}`))
194273
- return candidate;
194447
+ if (!key2.endsWith(`:${nodeId}`))
194448
+ continue;
194449
+ aliasMatches.set(`${candidate.nodeType}:${candidate.nodeId}`, candidate);
194450
+ }
194451
+ if (aliasMatches.size === 1) {
194452
+ return Array.from(aliasMatches.values())[0];
194453
+ }
194454
+ if (aliasMatches.size > 1) {
194455
+ throw new DocumentApiAdapterError3("AMBIGUOUS_TARGET", `Multiple blocks share nodeId "${nodeId}" via aliases.`, {
194456
+ nodeId,
194457
+ count: aliasMatches.size,
194458
+ matches: Array.from(aliasMatches.values()).map((candidate) => ({
194459
+ nodeType: candidate.nodeType,
194460
+ nodeId: candidate.nodeId
194461
+ }))
194462
+ });
194274
194463
  }
194275
194464
  throw new DocumentApiAdapterError3("TARGET_NOT_FOUND", `Block with nodeId "${nodeId}" was not found.`, { nodeId });
194276
194465
  }
@@ -194297,7 +194486,7 @@ function findBlockByPos2(index2, pos) {
194297
194486
  }
194298
194487
  return;
194299
194488
  }
194300
- var SUPPORTED_BLOCK_NODE_TYPES;
194489
+ var SUPPORTED_BLOCK_NODE_TYPES, ALIAS_ELIGIBLE_TYPES;
194301
194490
  var init_node_address_resolver = __esm(() => {
194302
194491
  init_errors3();
194303
194492
  SUPPORTED_BLOCK_NODE_TYPES = new Set([
@@ -194310,6 +194499,7 @@ var init_node_address_resolver = __esm(() => {
194310
194499
  "image",
194311
194500
  "sdt"
194312
194501
  ]);
194502
+ ALIAS_ELIGIBLE_TYPES = new Set(["paragraph", "heading", "listItem"]);
194313
194503
  });
194314
194504
 
194315
194505
  // ../../packages/super-editor/src/document-api-adapters/helpers/index-cache.ts
@@ -194537,6 +194727,1627 @@ var init_adapter_utils = __esm(() => {
194537
194727
  init_errors3();
194538
194728
  });
194539
194729
 
194730
+ // ../../packages/super-editor/src/document-api-adapters/plan-engine/executor-registry.ts
194731
+ function registerStepExecutor(opPrefix, executor) {
194732
+ if (registry.has(opPrefix)) {
194733
+ throw new Error(`Step executor already registered for op prefix "${opPrefix}"`);
194734
+ }
194735
+ registry.set(opPrefix, executor);
194736
+ }
194737
+ function getStepExecutor(op) {
194738
+ if (registry.has(op))
194739
+ return registry.get(op);
194740
+ const prefix3 = op.split(".")[0];
194741
+ return registry.get(prefix3);
194742
+ }
194743
+ function hasStepExecutor(op) {
194744
+ return getStepExecutor(op) !== undefined;
194745
+ }
194746
+ var registry;
194747
+ var init_executor_registry = __esm(() => {
194748
+ registry = new Map;
194749
+ });
194750
+
194751
+ // ../../packages/super-editor/src/document-api-adapters/plan-engine/errors.ts
194752
+ function planError(code7, message, stepId, details) {
194753
+ return new PlanError(code7, `${code7} — ${message}`, stepId, details);
194754
+ }
194755
+ var PlanError;
194756
+ var init_errors4 = __esm(() => {
194757
+ PlanError = class PlanError extends Error {
194758
+ code;
194759
+ stepId;
194760
+ details;
194761
+ constructor(code7, message, stepId, details) {
194762
+ super(message);
194763
+ this.name = "PlanError";
194764
+ this.code = code7;
194765
+ this.stepId = stepId;
194766
+ this.details = details;
194767
+ }
194768
+ };
194769
+ });
194770
+
194771
+ // ../../packages/super-editor/src/document-api-adapters/plan-engine/revision-tracker.ts
194772
+ function getRevision(editor) {
194773
+ const rev = revisionMap.get(editor) ?? 0;
194774
+ return String(rev);
194775
+ }
194776
+ function incrementRevision(editor) {
194777
+ const current = revisionMap.get(editor) ?? 0;
194778
+ const next2 = current + 1;
194779
+ revisionMap.set(editor, next2);
194780
+ return String(next2);
194781
+ }
194782
+ function initRevision(editor) {
194783
+ if (!revisionMap.has(editor)) {
194784
+ revisionMap.set(editor, 0);
194785
+ }
194786
+ }
194787
+ function trackRevisions(editor) {
194788
+ if (subscribedEditors.has(editor))
194789
+ return;
194790
+ subscribedEditors.add(editor);
194791
+ editor.on("transaction", ({ transaction }) => {
194792
+ if (transaction.docChanged) {
194793
+ incrementRevision(editor);
194794
+ }
194795
+ });
194796
+ }
194797
+ function checkRevision(editor, expectedRevision) {
194798
+ if (expectedRevision === undefined)
194799
+ return;
194800
+ const current = getRevision(editor);
194801
+ if (expectedRevision !== current) {
194802
+ throw new PlanError("REVISION_MISMATCH", `REVISION_MISMATCH — expected revision "${expectedRevision}" but document is at "${current}"`, undefined, { expectedRevision, currentRevision: current });
194803
+ }
194804
+ }
194805
+ var revisionMap, subscribedEditors;
194806
+ var init_revision_tracker = __esm(() => {
194807
+ init_errors4();
194808
+ revisionMap = new WeakMap;
194809
+ subscribedEditors = new WeakSet;
194810
+ });
194811
+
194812
+ // ../../packages/super-editor/src/document-api-adapters/plan-engine/style-resolver.ts
194813
+ function captureRunsInRange(editor, blockPos, from3, to) {
194814
+ const doc4 = editor.state.doc;
194815
+ const contentStart = blockPos + 1;
194816
+ const absFrom = contentStart + from3;
194817
+ const absTo = contentStart + to;
194818
+ const runs2 = [];
194819
+ doc4.nodesBetween(absFrom, absTo, (node3, pos) => {
194820
+ if (!node3.isText)
194821
+ return true;
194822
+ const nodeStart = Math.max(pos, absFrom);
194823
+ const nodeEnd = Math.min(pos + node3.nodeSize, absTo);
194824
+ if (nodeStart >= nodeEnd)
194825
+ return true;
194826
+ const relFrom = nodeStart - contentStart;
194827
+ const relTo = nodeEnd - contentStart;
194828
+ const formattingMarks = node3.marks.filter((m3) => !METADATA_MARK_NAMES.has(m3.type.name));
194829
+ runs2.push({
194830
+ from: relFrom,
194831
+ to: relTo,
194832
+ charCount: relTo - relFrom,
194833
+ marks: formattingMarks
194834
+ });
194835
+ return true;
194836
+ });
194837
+ const isUniform = checkUniformity(runs2);
194838
+ return { runs: runs2, isUniform };
194839
+ }
194840
+ function checkUniformity(runs2) {
194841
+ if (runs2.length <= 1)
194842
+ return true;
194843
+ const reference2 = runs2[0].marks;
194844
+ for (let i4 = 1;i4 < runs2.length; i4++) {
194845
+ if (!marksEqual(reference2, runs2[i4].marks))
194846
+ return false;
194847
+ }
194848
+ return true;
194849
+ }
194850
+ function marksEqual(a2, b3) {
194851
+ if (a2.length !== b3.length)
194852
+ return false;
194853
+ for (let i4 = 0;i4 < a2.length; i4++) {
194854
+ if (!a2[i4].eq(b3[i4]))
194855
+ return false;
194856
+ }
194857
+ return true;
194858
+ }
194859
+ function resolveInlineStyle(editor, captured, policy2, stepId) {
194860
+ if (policy2.mode === "clear")
194861
+ return [];
194862
+ if (policy2.mode === "set") {
194863
+ return buildMarksFromPolicy(editor, policy2.setMarks);
194864
+ }
194865
+ if (policy2.requireUniform && !captured.isUniform) {
194866
+ throw planError("STYLE_CONFLICT", "matched range has non-uniform inline styles and requireUniform is true", stepId, { runCount: captured.runs.length });
194867
+ }
194868
+ let resolvedMarks;
194869
+ if (captured.isUniform || captured.runs.length === 0) {
194870
+ resolvedMarks = captured.runs.length > 0 ? captured.runs[0].marks : [];
194871
+ } else {
194872
+ const strategy = policy2.onNonUniform ?? "useLeadingRun";
194873
+ if (strategy === "error") {
194874
+ throw planError("STYLE_CONFLICT", 'matched range has non-uniform inline styles and onNonUniform is "error"', stepId, { runCount: captured.runs.length });
194875
+ }
194876
+ resolvedMarks = applyNonUniformStrategy(editor, captured.runs, strategy);
194877
+ }
194878
+ if (policy2.setMarks) {
194879
+ return applySetMarksToResolved(editor, resolvedMarks, policy2.setMarks);
194880
+ }
194881
+ return resolvedMarks;
194882
+ }
194883
+ function applyNonUniformStrategy(editor, runs2, strategy) {
194884
+ switch (strategy) {
194885
+ case "useLeadingRun":
194886
+ return resolveUseLeadingRun(runs2);
194887
+ case "majority":
194888
+ return resolveMajority(editor, runs2);
194889
+ case "union":
194890
+ return resolveUnion(editor, runs2);
194891
+ }
194892
+ }
194893
+ function resolveUseLeadingRun(runs2) {
194894
+ return runs2.length > 0 ? runs2[0].marks : [];
194895
+ }
194896
+ function resolveMajority(editor, runs2) {
194897
+ const totalChars = runs2.reduce((sum, r2) => sum + r2.charCount, 0);
194898
+ if (totalChars === 0)
194899
+ return [];
194900
+ const allMarkNames = new Set;
194901
+ for (const run2 of runs2) {
194902
+ for (const mark2 of run2.marks) {
194903
+ allMarkNames.add(mark2.type.name);
194904
+ }
194905
+ }
194906
+ const resultMarks = [];
194907
+ for (const markName of allMarkNames) {
194908
+ if (CORE_MARK_NAMES.has(markName)) {
194909
+ let activeChars = 0;
194910
+ for (const run2 of runs2) {
194911
+ if (run2.marks.some((m3) => m3.type.name === markName)) {
194912
+ activeChars += run2.charCount;
194913
+ }
194914
+ }
194915
+ if (activeChars > totalChars / 2) {
194916
+ for (const run2 of runs2) {
194917
+ const found3 = run2.marks.find((m3) => m3.type.name === markName);
194918
+ if (found3) {
194919
+ resultMarks.push(found3);
194920
+ break;
194921
+ }
194922
+ }
194923
+ }
194924
+ } else {
194925
+ resolveValueBearingMarkMajority(runs2, markName, totalChars, resultMarks);
194926
+ }
194927
+ }
194928
+ return resultMarks;
194929
+ }
194930
+ function resolveValueBearingMarkMajority(runs2, markName, totalChars, resultMarks) {
194931
+ let anyRunHasMark = false;
194932
+ for (const run2 of runs2) {
194933
+ if (run2.marks.some((m3) => m3.type.name === markName)) {
194934
+ anyRunHasMark = true;
194935
+ break;
194936
+ }
194937
+ }
194938
+ if (!anyRunHasMark)
194939
+ return;
194940
+ const allAttrKeys = new Set;
194941
+ const markInstances = [];
194942
+ for (const run2 of runs2) {
194943
+ const mark2 = run2.marks.find((m3) => m3.type.name === markName);
194944
+ if (mark2) {
194945
+ markInstances.push({ mark: mark2, run: run2 });
194946
+ for (const key2 of Object.keys(mark2.attrs)) {
194947
+ allAttrKeys.add(key2);
194948
+ }
194949
+ }
194950
+ }
194951
+ const resolvedAttrs = {};
194952
+ let hasAnyAttr = false;
194953
+ for (const key2 of allAttrKeys) {
194954
+ const valueTally = new Map;
194955
+ for (let i4 = 0;i4 < runs2.length; i4++) {
194956
+ const run2 = runs2[i4];
194957
+ const mark2 = run2.marks.find((m3) => m3.type.name === markName);
194958
+ const value = mark2 ? mark2.attrs[key2] : undefined;
194959
+ const serialized = JSON.stringify(value);
194960
+ const existing = valueTally.get(serialized);
194961
+ if (existing) {
194962
+ existing.chars += run2.charCount;
194963
+ } else {
194964
+ valueTally.set(serialized, { chars: run2.charCount, firstRunIdx: i4, value });
194965
+ }
194966
+ }
194967
+ let winner;
194968
+ for (const entry of valueTally.values()) {
194969
+ if (!winner || entry.chars > winner.chars || entry.chars === winner.chars && entry.firstRunIdx < winner.firstRunIdx) {
194970
+ winner = entry;
194971
+ }
194972
+ }
194973
+ if (winner && winner.value !== undefined) {
194974
+ resolvedAttrs[key2] = winner.value;
194975
+ hasAnyAttr = true;
194976
+ }
194977
+ }
194978
+ if (hasAnyAttr && markInstances.length > 0) {
194979
+ const templateMark = markInstances[0].mark;
194980
+ try {
194981
+ const resolvedMark = templateMark.type.create(resolvedAttrs);
194982
+ resultMarks.push(resolvedMark);
194983
+ } catch {
194984
+ resultMarks.push(templateMark);
194985
+ }
194986
+ }
194987
+ }
194988
+ function resolveUnion(editor, runs2) {
194989
+ const allMarkNames = new Set;
194990
+ for (const run2 of runs2) {
194991
+ for (const mark2 of run2.marks) {
194992
+ allMarkNames.add(mark2.type.name);
194993
+ }
194994
+ }
194995
+ const resultMarks = [];
194996
+ for (const markName of allMarkNames) {
194997
+ if (CORE_MARK_NAMES.has(markName)) {
194998
+ for (const run2 of runs2) {
194999
+ const found3 = run2.marks.find((m3) => m3.type.name === markName);
195000
+ if (found3) {
195001
+ resultMarks.push(found3);
195002
+ break;
195003
+ }
195004
+ }
195005
+ } else {
195006
+ for (const run2 of runs2) {
195007
+ const found3 = run2.marks.find((m3) => m3.type.name === markName);
195008
+ if (found3) {
195009
+ resultMarks.push(found3);
195010
+ break;
195011
+ }
195012
+ }
195013
+ }
195014
+ }
195015
+ return resultMarks;
195016
+ }
195017
+ function buildMarksFromPolicy(editor, setMarks) {
195018
+ if (!setMarks)
195019
+ return [];
195020
+ const { schema } = editor.state;
195021
+ const marks = [];
195022
+ if (setMarks.bold && schema.marks.bold)
195023
+ marks.push(schema.marks.bold.create());
195024
+ if (setMarks.italic && schema.marks.italic)
195025
+ marks.push(schema.marks.italic.create());
195026
+ if (setMarks.underline && schema.marks.underline)
195027
+ marks.push(schema.marks.underline.create());
195028
+ if (setMarks.strike && schema.marks.strike)
195029
+ marks.push(schema.marks.strike.create());
195030
+ return marks;
195031
+ }
195032
+ function applySetMarksToResolved(editor, existingMarks, setMarks) {
195033
+ const { schema } = editor.state;
195034
+ let marks = [...existingMarks];
195035
+ const overrides = [
195036
+ [setMarks.bold, schema.marks.bold],
195037
+ [setMarks.italic, schema.marks.italic],
195038
+ [setMarks.underline, schema.marks.underline],
195039
+ [setMarks.strike, schema.marks.strike]
195040
+ ];
195041
+ for (const [value, markType] of overrides) {
195042
+ if (value === undefined || !markType)
195043
+ continue;
195044
+ if (value) {
195045
+ if (!marks.some((m3) => m3.type === markType)) {
195046
+ marks.push(markType.create());
195047
+ }
195048
+ } else {
195049
+ marks = marks.filter((m3) => m3.type !== markType);
195050
+ }
195051
+ }
195052
+ return marks;
195053
+ }
195054
+ var CORE_MARK_NAMES, METADATA_MARK_NAMES;
195055
+ var init_style_resolver = __esm(() => {
195056
+ init_errors4();
195057
+ CORE_MARK_NAMES = new Set(["bold", "italic", "underline", "strike"]);
195058
+ METADATA_MARK_NAMES = new Set([
195059
+ "trackInsert",
195060
+ "trackDelete",
195061
+ "trackFormat",
195062
+ "commentMark",
195063
+ "aiMark",
195064
+ "aiAnimationMark"
195065
+ ]);
195066
+ });
195067
+
195068
+ // ../../packages/super-editor/src/document-api-adapters/find/common.ts
195069
+ function resolveUnknownBlockId2(attrs) {
195070
+ if (!attrs)
195071
+ return;
195072
+ return toId2(attrs.paraId) ?? toId2(attrs.sdBlockId) ?? toId2(attrs.blockId) ?? toId2(attrs.id) ?? toId2(attrs.uuid);
195073
+ }
195074
+ function isDualKindType2(nodeType) {
195075
+ return Boolean(nodeType && DUAL_KIND_TYPES2.has(nodeType));
195076
+ }
195077
+ function getAddressStartPos2(editor, index2, address2) {
195078
+ if (address2.kind === "block") {
195079
+ const block = findBlockById2(index2, address2);
195080
+ return block?.pos ?? Number.MAX_SAFE_INTEGER;
195081
+ }
195082
+ const inlineIndex = getInlineIndex2(editor);
195083
+ const inline = findInlineByAnchor2(inlineIndex, address2);
195084
+ return inline?.pos ?? Number.MAX_SAFE_INTEGER;
195085
+ }
195086
+ function buildTextContext2(editor, address2, matchFrom, matchTo, textRanges) {
195087
+ const docSize = editor.state.doc.content.size;
195088
+ const snippetFrom = Math.max(0, matchFrom - SNIPPET_PADDING2);
195089
+ const snippetTo = Math.min(docSize, matchTo + SNIPPET_PADDING2);
195090
+ const rawSnippet = editor.state.doc.textBetween(snippetFrom, snippetTo, " ");
195091
+ const snippet = rawSnippet.replace(/ {2,}/g, " ");
195092
+ const rawPrefix = editor.state.doc.textBetween(snippetFrom, matchFrom, " ");
195093
+ const rawMatch = editor.state.doc.textBetween(matchFrom, matchTo, " ");
195094
+ const prefix3 = rawPrefix.replace(/ {2,}/g, " ");
195095
+ const matchNormalized = rawMatch.replace(/ {2,}/g, " ");
195096
+ return {
195097
+ address: address2,
195098
+ snippet,
195099
+ highlightRange: {
195100
+ start: prefix3.length,
195101
+ end: prefix3.length + matchNormalized.length
195102
+ },
195103
+ textRanges: textRanges?.length ? textRanges : undefined
195104
+ };
195105
+ }
195106
+ function toTextAddress2(editor, block, range) {
195107
+ const blockStart = block.pos + 1;
195108
+ const blockEnd = block.end - 1;
195109
+ if (range.from < blockStart || range.to > blockEnd)
195110
+ return;
195111
+ const start2 = editor.state.doc.textBetween(blockStart, range.from, `
195112
+ `, "").length;
195113
+ const end = editor.state.doc.textBetween(blockStart, range.to, `
195114
+ `, "").length;
195115
+ return {
195116
+ kind: "text",
195117
+ blockId: block.nodeId,
195118
+ range: { start: start2, end }
195119
+ };
195120
+ }
195121
+ function shouldQueryBothKinds2(select2) {
195122
+ if (select2.type === "node") {
195123
+ return !select2.kind && isDualKindType2(select2.nodeType);
195124
+ }
195125
+ return false;
195126
+ }
195127
+ function sortAddressesByPosition2(editor, index2, addresses) {
195128
+ return [...addresses].sort((a2, b3) => {
195129
+ const aPos = getAddressStartPos2(editor, index2, a2);
195130
+ const bPos = getAddressStartPos2(editor, index2, b3);
195131
+ if (aPos !== bPos)
195132
+ return aPos - bPos;
195133
+ if (a2.kind === b3.kind)
195134
+ return 0;
195135
+ return a2.kind === "block" ? -1 : 1;
195136
+ });
195137
+ }
195138
+ function collectUnknownNodeDiagnostics2(editor, index2, diagnostics) {
195139
+ editor.state.doc.descendants((node3, pos) => {
195140
+ if (node3.isBlock && !KNOWN_BLOCK_PM_NODE_TYPES2.has(node3.type.name)) {
195141
+ const blockId = resolveUnknownBlockId2(node3.attrs ?? {});
195142
+ diagnostics.push({
195143
+ message: `Unknown block node type "${node3.type.name}" is not part of the stable Document API match set.`,
195144
+ hint: blockId ? `Skipped unknown block with stable id "${blockId}".` : "Skipped unknown block with no stable id available."
195145
+ });
195146
+ return;
195147
+ }
195148
+ if (node3.isInline && !KNOWN_INLINE_PM_NODE_TYPES2.has(node3.type.name)) {
195149
+ const container = findCandidateByPos2(index2.candidates, pos);
195150
+ diagnostics.push({
195151
+ message: `Unknown inline node type "${node3.type.name}" is not part of the stable Document API match set.`,
195152
+ address: container ? toBlockAddress2(container) : undefined,
195153
+ hint: container ? `Skipped unknown inline node inside block "${container.nodeType}" with id "${container.nodeId}".` : "Skipped unknown inline node outside resolvable block scope."
195154
+ });
195155
+ }
195156
+ });
195157
+ }
195158
+ function isInlineQuery2(select2) {
195159
+ if (select2.type === "node") {
195160
+ if (select2.kind)
195161
+ return select2.kind === "inline";
195162
+ return Boolean(select2.nodeType && isInlineQueryType2(select2.nodeType));
195163
+ }
195164
+ return false;
195165
+ }
195166
+ var SNIPPET_PADDING2 = 30, DUAL_KIND_TYPES2, KNOWN_BLOCK_PM_NODE_TYPES2, KNOWN_INLINE_PM_NODE_TYPES2;
195167
+ var init_common = __esm(() => {
195168
+ init_index_cache();
195169
+ init_node_address_resolver();
195170
+ init_inline_address_resolver();
195171
+ init_adapter_utils();
195172
+ DUAL_KIND_TYPES2 = new Set(["sdt", "image"]);
195173
+ KNOWN_BLOCK_PM_NODE_TYPES2 = new Set([
195174
+ "paragraph",
195175
+ "table",
195176
+ "tableRow",
195177
+ "tableCell",
195178
+ "tableHeader",
195179
+ "structuredContentBlock",
195180
+ "sdt",
195181
+ "image"
195182
+ ]);
195183
+ KNOWN_INLINE_PM_NODE_TYPES2 = new Set([
195184
+ "text",
195185
+ "run",
195186
+ "structuredContent",
195187
+ "image",
195188
+ "tab",
195189
+ "lineBreak",
195190
+ "hardBreak",
195191
+ "hard_break",
195192
+ "footnoteReference",
195193
+ "bookmarkStart",
195194
+ "bookmarkEnd",
195195
+ "commentRangeStart",
195196
+ "commentRangeEnd"
195197
+ ]);
195198
+ });
195199
+
195200
+ // ../../packages/super-editor/src/document-api-adapters/find/text-strategy.ts
195201
+ function compileRegex2(selector, diagnostics) {
195202
+ if (selector.pattern.length > MAX_PATTERN_LENGTH) {
195203
+ addDiagnostic2(diagnostics, `Text query regex pattern exceeds ${MAX_PATTERN_LENGTH} characters.`);
195204
+ return null;
195205
+ }
195206
+ const flags = selector.caseSensitive ? "g" : "gi";
195207
+ try {
195208
+ return new RegExp(selector.pattern, flags);
195209
+ } catch (error) {
195210
+ const reason = error instanceof Error ? error.message : String(error);
195211
+ addDiagnostic2(diagnostics, `Invalid text query regex: ${reason}`);
195212
+ return null;
195213
+ }
195214
+ }
195215
+ function buildSearchPattern2(selector, diagnostics) {
195216
+ const mode = selector.mode ?? "contains";
195217
+ if (mode === "regex") {
195218
+ return compileRegex2(selector, diagnostics);
195219
+ }
195220
+ if (selector.pattern.length > MAX_PATTERN_LENGTH) {
195221
+ addDiagnostic2(diagnostics, `Text query pattern exceeds ${MAX_PATTERN_LENGTH} characters.`);
195222
+ return null;
195223
+ }
195224
+ const escaped = selector.pattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
195225
+ const flags = selector.caseSensitive ? "g" : "gi";
195226
+ return new RegExp(escaped, flags);
195227
+ }
195228
+ function executeTextSelector2(editor, index2, query2, diagnostics) {
195229
+ if (query2.select.type !== "text") {
195230
+ addDiagnostic2(diagnostics, `Text strategy received a non-text selector (type="${query2.select.type}").`);
195231
+ return { matches: [], total: 0 };
195232
+ }
195233
+ const selector = query2.select;
195234
+ if (!selector.pattern.length) {
195235
+ addDiagnostic2(diagnostics, "Text query pattern must be non-empty.");
195236
+ return { matches: [], total: 0 };
195237
+ }
195238
+ const scope = resolveWithinScope2(index2, query2, diagnostics);
195239
+ if (!scope.ok)
195240
+ return { matches: [], total: 0 };
195241
+ const pattern = buildSearchPattern2(selector, diagnostics);
195242
+ if (!pattern)
195243
+ return { matches: [], total: 0 };
195244
+ const search3 = requireEditorCommand2(editor.commands?.search, "find (search)");
195245
+ const rawResult = search3(pattern, {
195246
+ highlight: false,
195247
+ caseSensitive: selector.caseSensitive ?? false,
195248
+ maxMatches: Infinity
195249
+ });
195250
+ if (!Array.isArray(rawResult)) {
195251
+ throw new DocumentApiAdapterError3("CAPABILITY_UNAVAILABLE", "Editor search command returned an unexpected result format.");
195252
+ }
195253
+ const allMatches = rawResult;
195254
+ const scopeRange = scope.range;
195255
+ const matches3 = scopeRange ? allMatches.filter((m3) => m3.from >= scopeRange.start && m3.to <= scopeRange.end) : allMatches;
195256
+ const textBlocks = index2.candidates.filter(isTextBlockCandidate2);
195257
+ const contexts = [];
195258
+ const addresses = [];
195259
+ for (const match2 of matches3) {
195260
+ const ranges = match2.ranges?.length ? match2.ranges : [{ from: match2.from, to: match2.to }];
195261
+ let source;
195262
+ const textRanges = ranges.map((range) => {
195263
+ const block = findCandidateByPos2(textBlocks, range.from);
195264
+ if (!block)
195265
+ return;
195266
+ if (!source)
195267
+ source = block;
195268
+ return toTextAddress2(editor, block, range);
195269
+ }).filter((range) => Boolean(range));
195270
+ if (!source) {
195271
+ source = findCandidateByPos2(textBlocks, match2.from) ?? findBlockByPos2(index2, match2.from);
195272
+ }
195273
+ if (!source)
195274
+ continue;
195275
+ const address2 = toBlockAddress2(source);
195276
+ addresses.push(address2);
195277
+ contexts.push(buildTextContext2(editor, address2, match2.from, match2.to, textRanges));
195278
+ }
195279
+ const paged = paginate2(addresses, query2.offset, query2.limit);
195280
+ const pagedContexts = paginate2(contexts, query2.offset, query2.limit).items;
195281
+ return {
195282
+ matches: paged.items,
195283
+ total: paged.total,
195284
+ context: pagedContexts.length ? pagedContexts : undefined
195285
+ };
195286
+ }
195287
+ var MAX_PATTERN_LENGTH = 1024;
195288
+ var init_text_strategy = __esm(() => {
195289
+ init_node_address_resolver();
195290
+ init_adapter_utils();
195291
+ init_common();
195292
+ init_errors3();
195293
+ init_mutation_helpers();
195294
+ });
195295
+
195296
+ // ../../packages/super-editor/src/document-api-adapters/find/block-strategy.ts
195297
+ function executeBlockSelector2(index2, query2, diagnostics) {
195298
+ const scope = resolveWithinScope2(index2, query2, diagnostics);
195299
+ if (!scope.ok)
195300
+ return { matches: [], total: 0 };
195301
+ const scoped = scopeByRange2(index2.candidates, scope.range);
195302
+ const select2 = query2.select;
195303
+ let filtered = [];
195304
+ if (select2.type === "node") {
195305
+ if (select2.kind && select2.kind !== "block") {
195306
+ addDiagnostic2(diagnostics, "Only block nodes are supported by the current adapter.");
195307
+ } else {
195308
+ filtered = scoped.filter((candidate) => {
195309
+ if (select2.nodeType) {
195310
+ if (candidate.nodeType !== select2.nodeType)
195311
+ return false;
195312
+ }
195313
+ return true;
195314
+ });
195315
+ }
195316
+ }
195317
+ const addresses = filtered.map((candidate) => ({
195318
+ kind: "block",
195319
+ nodeType: candidate.nodeType,
195320
+ nodeId: candidate.nodeId
195321
+ }));
195322
+ const paged = paginate2(addresses, query2.offset, query2.limit);
195323
+ return {
195324
+ matches: paged.items,
195325
+ total: paged.total
195326
+ };
195327
+ }
195328
+ var init_block_strategy = __esm(() => {
195329
+ init_adapter_utils();
195330
+ });
195331
+
195332
+ // ../../packages/super-editor/src/document-api-adapters/plan-engine/compiler.ts
195333
+ function isAssertStep(step) {
195334
+ return step.op === "assert";
195335
+ }
195336
+ function isSelectWhere(where) {
195337
+ return where.by === "select";
195338
+ }
195339
+ function normalizeMatchRanges(stepId, ranges) {
195340
+ if (ranges.length === 0) {
195341
+ throw planError("INVALID_INPUT", "logical match produced zero ranges", stepId);
195342
+ }
195343
+ for (const r2 of ranges) {
195344
+ if (r2.range.start < 0 || r2.range.end < r2.range.start) {
195345
+ throw planError("INVALID_INPUT", `invalid range bounds [${r2.range.start}, ${r2.range.end}) in block "${r2.blockId}"`, stepId);
195346
+ }
195347
+ }
195348
+ const blockId = ranges[0].blockId;
195349
+ if (ranges.some((r2) => r2.blockId !== blockId)) {
195350
+ throw planError("CROSS_BLOCK_MATCH", `mutation target spans multiple blocks`, stepId, {
195351
+ blockIds: [...new Set(ranges.map((r2) => r2.blockId))]
195352
+ });
195353
+ }
195354
+ if (ranges.length === 1) {
195355
+ return { blockId, from: ranges[0].range.start, to: ranges[0].range.end };
195356
+ }
195357
+ const sorted = [...ranges].sort((a2, b3) => a2.range.start - b3.range.start);
195358
+ const from3 = sorted[0].range.start;
195359
+ let to = sorted[0].range.end;
195360
+ for (let i4 = 1;i4 < sorted.length; i4++) {
195361
+ const r2 = sorted[i4];
195362
+ if (r2.range.start > to) {
195363
+ throw planError("INVALID_INPUT", `match ranges are discontiguous within block "${blockId}" (gap between offset ${to} and ${r2.range.start})`, stepId);
195364
+ }
195365
+ if (r2.range.end > to)
195366
+ to = r2.range.end;
195367
+ }
195368
+ return { blockId, from: from3, to };
195369
+ }
195370
+ function resolveTextSelector(editor, index2, selector, within2, stepId) {
195371
+ if (selector.type === "text") {
195372
+ const query3 = {
195373
+ select: selector,
195374
+ within: within2,
195375
+ includeNodes: false
195376
+ };
195377
+ const result2 = executeTextSelector2(editor, index2, query3, []);
195378
+ const addresses2 = [];
195379
+ if (result2.context) {
195380
+ for (const ctx2 of result2.context) {
195381
+ if (!ctx2.textRanges?.length)
195382
+ continue;
195383
+ const coalesced = normalizeMatchRanges(stepId, ctx2.textRanges);
195384
+ const candidate = index2.candidates.find((c2) => c2.nodeId === coalesced.blockId);
195385
+ if (!candidate)
195386
+ continue;
195387
+ const blockText = getBlockText(editor, candidate);
195388
+ const matchText = blockText.slice(coalesced.from, coalesced.to);
195389
+ const captured = captureRunsInRange(editor, candidate.pos, coalesced.from, coalesced.to);
195390
+ addresses2.push({
195391
+ blockId: coalesced.blockId,
195392
+ from: coalesced.from,
195393
+ to: coalesced.to,
195394
+ text: matchText,
195395
+ marks: captured.runs.length > 0 ? captured.runs[0].marks : [],
195396
+ blockPos: candidate.pos
195397
+ });
195398
+ }
195399
+ }
195400
+ return { addresses: addresses2 };
195401
+ }
195402
+ const query2 = {
195403
+ select: selector,
195404
+ within: within2,
195405
+ includeNodes: false
195406
+ };
195407
+ const result = executeBlockSelector2(index2, query2, []);
195408
+ const textBlocks = index2.candidates.filter(isTextBlockCandidate2);
195409
+ const addresses = [];
195410
+ for (const match2 of result.matches) {
195411
+ if (match2.kind !== "block")
195412
+ continue;
195413
+ const candidate = textBlocks.find((c2) => c2.nodeId === match2.nodeId);
195414
+ if (!candidate)
195415
+ continue;
195416
+ const blockText = getBlockText(editor, candidate);
195417
+ addresses.push({
195418
+ blockId: match2.nodeId,
195419
+ from: 0,
195420
+ to: blockText.length,
195421
+ text: blockText,
195422
+ marks: [],
195423
+ blockPos: candidate.pos
195424
+ });
195425
+ }
195426
+ return { addresses };
195427
+ }
195428
+ function getBlockText(editor, candidate) {
195429
+ const blockStart = candidate.pos + 1;
195430
+ const blockEnd = candidate.end - 1;
195431
+ return editor.state.doc.textBetween(blockStart, blockEnd, `
195432
+ `, "");
195433
+ }
195434
+ function applyCardinalityCheck(step, targets) {
195435
+ const where = step.where;
195436
+ if (!("require" in where))
195437
+ return;
195438
+ const require2 = where.require;
195439
+ if (require2 === "first") {
195440
+ if (targets.length === 0) {
195441
+ throw planError("MATCH_NOT_FOUND", `selector matched zero ranges`, step.id);
195442
+ }
195443
+ } else if (require2 === "exactlyOne") {
195444
+ if (targets.length === 0) {
195445
+ throw planError("MATCH_NOT_FOUND", `selector matched zero ranges`, step.id);
195446
+ }
195447
+ if (targets.length > 1) {
195448
+ throw planError("AMBIGUOUS_MATCH", `selector matched ${targets.length} ranges, expected exactly one`, step.id, {
195449
+ matchCount: targets.length
195450
+ });
195451
+ }
195452
+ } else if (require2 === "all") {
195453
+ if (targets.length === 0) {
195454
+ throw planError("MATCH_NOT_FOUND", `selector matched zero ranges`, step.id);
195455
+ }
195456
+ }
195457
+ }
195458
+ function isRefWhere(where) {
195459
+ return where.by === "ref";
195460
+ }
195461
+ function resolveTextRef(editor, index2, step, ref2) {
195462
+ const encoded = ref2.slice(5);
195463
+ let refData;
195464
+ try {
195465
+ refData = JSON.parse(atob(encoded));
195466
+ } catch {
195467
+ throw planError("INVALID_INPUT", `invalid text ref encoding`, step.id);
195468
+ }
195469
+ const currentRevision = getRevision(editor);
195470
+ if (refData.rev !== currentRevision) {
195471
+ throw planError("REVISION_MISMATCH", `text ref was created at revision "${refData.rev}" but document is at "${currentRevision}"`, step.id, { refRevision: refData.rev, currentRevision });
195472
+ }
195473
+ if (!refData.ranges?.length)
195474
+ return [];
195475
+ const coalesced = normalizeMatchRanges(step.id, refData.ranges);
195476
+ const candidate = index2.candidates.find((c2) => c2.nodeId === coalesced.blockId);
195477
+ if (!candidate)
195478
+ return [];
195479
+ const blockText = getBlockText(editor, candidate);
195480
+ const matchText = blockText.slice(coalesced.from, coalesced.to);
195481
+ const capturedStyle = step.op === "text.rewrite" ? captureRunsInRange(editor, candidate.pos, coalesced.from, coalesced.to) : undefined;
195482
+ return [
195483
+ {
195484
+ stepId: step.id,
195485
+ op: step.op,
195486
+ blockId: coalesced.blockId,
195487
+ from: coalesced.from,
195488
+ to: coalesced.to,
195489
+ text: matchText,
195490
+ marks: [],
195491
+ capturedStyle
195492
+ }
195493
+ ];
195494
+ }
195495
+ function resolveBlockRef(editor, index2, step, ref2) {
195496
+ const candidate = index2.candidates.find((c2) => c2.nodeId === ref2);
195497
+ if (!candidate)
195498
+ return [];
195499
+ const blockText = getBlockText(editor, candidate);
195500
+ const capturedStyle = step.op === "text.rewrite" ? captureRunsInRange(editor, candidate.pos, 0, blockText.length) : undefined;
195501
+ return [
195502
+ {
195503
+ stepId: step.id,
195504
+ op: step.op,
195505
+ blockId: candidate.nodeId,
195506
+ from: 0,
195507
+ to: blockText.length,
195508
+ text: blockText,
195509
+ marks: [],
195510
+ capturedStyle
195511
+ }
195512
+ ];
195513
+ }
195514
+ function resolveRefTargets(editor, index2, step, where) {
195515
+ const ref2 = where.ref;
195516
+ if (ref2.startsWith("text:")) {
195517
+ return resolveTextRef(editor, index2, step, ref2);
195518
+ }
195519
+ return resolveBlockRef(editor, index2, step, ref2);
195520
+ }
195521
+ function resolveStepTargets(editor, index2, step) {
195522
+ const where = step.where;
195523
+ let targets;
195524
+ if (isRefWhere(where)) {
195525
+ targets = resolveRefTargets(editor, index2, step, where);
195526
+ } else if (isSelectWhere(where)) {
195527
+ const resolved = resolveTextSelector(editor, index2, where.select, where.within, step.id);
195528
+ targets = resolved.addresses.map((addr) => {
195529
+ const capturedStyle = step.op === "text.rewrite" ? captureRunsInRange(editor, addr.blockPos, addr.from, addr.to) : undefined;
195530
+ return {
195531
+ stepId: step.id,
195532
+ op: step.op,
195533
+ blockId: addr.blockId,
195534
+ from: addr.from,
195535
+ to: addr.to,
195536
+ text: addr.text,
195537
+ marks: addr.marks,
195538
+ capturedStyle
195539
+ };
195540
+ });
195541
+ } else {
195542
+ throw planError("INVALID_INPUT", `unsupported where.by value`, step.id);
195543
+ }
195544
+ targets.sort((a2, b3) => {
195545
+ if (a2.blockId === b3.blockId)
195546
+ return a2.from - b3.from;
195547
+ const posA = index2.candidates.find((c2) => c2.nodeId === a2.blockId)?.pos ?? 0;
195548
+ const posB = index2.candidates.find((c2) => c2.nodeId === b3.blockId)?.pos ?? 0;
195549
+ return posA - posB;
195550
+ });
195551
+ targets = targets.filter((t, i4) => i4 === 0 || t.blockId !== targets[i4 - 1].blockId || t.from !== targets[i4 - 1].from || t.to !== targets[i4 - 1].to);
195552
+ applyCardinalityCheck(step, targets);
195553
+ const require2 = "require" in where ? where.require : undefined;
195554
+ if (require2 === "first" && targets.length > 1) {
195555
+ targets = [targets[0]];
195556
+ }
195557
+ return targets;
195558
+ }
195559
+ function compilePlan(editor, steps) {
195560
+ const index2 = getBlockIndex2(editor);
195561
+ const mutationSteps = [];
195562
+ const assertSteps = [];
195563
+ const seenIds = new Set;
195564
+ for (const step of steps) {
195565
+ if (!step.id) {
195566
+ throw planError("INVALID_INPUT", "step.id is required");
195567
+ }
195568
+ if (seenIds.has(step.id)) {
195569
+ throw planError("INVALID_INPUT", `duplicate step id "${step.id}"`, step.id);
195570
+ }
195571
+ seenIds.add(step.id);
195572
+ }
195573
+ for (const step of steps) {
195574
+ if (isAssertStep(step)) {
195575
+ assertSteps.push(step);
195576
+ continue;
195577
+ }
195578
+ if (!hasStepExecutor(step.op)) {
195579
+ throw planError("INVALID_INPUT", `unknown step op "${step.op}"`, step.id);
195580
+ }
195581
+ const targets = resolveStepTargets(editor, index2, step);
195582
+ mutationSteps.push({ step, targets });
195583
+ }
195584
+ detectOverlaps(mutationSteps);
195585
+ return { mutationSteps, assertSteps };
195586
+ }
195587
+ function detectOverlaps(steps) {
195588
+ const rangesByBlock = new Map;
195589
+ for (const compiled of steps) {
195590
+ for (const target of compiled.targets) {
195591
+ let blockRanges = rangesByBlock.get(target.blockId);
195592
+ if (!blockRanges) {
195593
+ blockRanges = [];
195594
+ rangesByBlock.set(target.blockId, blockRanges);
195595
+ }
195596
+ blockRanges.push({ stepId: target.stepId, from: target.from, to: target.to });
195597
+ }
195598
+ }
195599
+ for (const [blockId, ranges] of rangesByBlock) {
195600
+ ranges.sort((a2, b3) => a2.from - b3.from);
195601
+ for (let i4 = 1;i4 < ranges.length; i4++) {
195602
+ const prev = ranges[i4 - 1];
195603
+ const curr = ranges[i4];
195604
+ if (prev.stepId !== curr.stepId && prev.to > curr.from) {
195605
+ throw planError("PLAN_CONFLICT_OVERLAP", `steps "${prev.stepId}" and "${curr.stepId}" target overlapping ranges in block "${blockId}"`, curr.stepId, { blockId, rangeA: { from: prev.from, to: prev.to }, rangeB: { from: curr.from, to: curr.to } });
195606
+ }
195607
+ }
195608
+ }
195609
+ }
195610
+ var init_compiler = __esm(() => {
195611
+ init_errors4();
195612
+ init_executor_registry();
195613
+ init_style_resolver();
195614
+ init_index_cache();
195615
+ init_revision_tracker();
195616
+ init_text_strategy();
195617
+ init_block_strategy();
195618
+ init_node_address_resolver();
195619
+ });
195620
+
195621
+ // ../../packages/super-editor/src/document-api-adapters/helpers/transaction-meta.ts
195622
+ function applyDirectMutationMeta2(tr) {
195623
+ tr.setMeta("inputType", "programmatic");
195624
+ tr.setMeta("skipTrackChanges", true);
195625
+ return tr;
195626
+ }
195627
+ function applyTrackedMutationMeta2(tr) {
195628
+ tr.setMeta("inputType", "programmatic");
195629
+ tr.setMeta("forceTrackChanges", true);
195630
+ return tr;
195631
+ }
195632
+
195633
+ // ../../packages/super-editor/src/document-api-adapters/plan-engine/executor.ts
195634
+ function resolveMarks(editor, target, step) {
195635
+ if (step.op !== "text.rewrite")
195636
+ return [];
195637
+ const rewriteStep = step;
195638
+ const policy2 = rewriteStep.args.style?.inline ?? DEFAULT_INLINE_POLICY;
195639
+ const captured = target.capturedStyle ?? captureRunsInRange(editor, toAbsoluteBlockPos(editor, target.blockId), target.from, target.to);
195640
+ return resolveInlineStyle(editor, captured, policy2, step.id);
195641
+ }
195642
+ function toAbsoluteBlockPos(editor, blockId) {
195643
+ const index2 = getBlockIndex2(editor);
195644
+ const candidate = index2.candidates.find((c2) => c2.nodeId === blockId);
195645
+ if (!candidate)
195646
+ throw planError("TARGET_NOT_FOUND", `block "${blockId}" not found in style capture fallback`);
195647
+ return candidate.pos;
195648
+ }
195649
+ function buildMarksFromSetMarks(editor, setMarks) {
195650
+ if (!setMarks)
195651
+ return [];
195652
+ const { schema } = editor.state;
195653
+ const marks = [];
195654
+ if (setMarks.bold && schema.marks.bold)
195655
+ marks.push(schema.marks.bold.create());
195656
+ if (setMarks.italic && schema.marks.italic)
195657
+ marks.push(schema.marks.italic.create());
195658
+ if (setMarks.underline && schema.marks.underline)
195659
+ marks.push(schema.marks.underline.create());
195660
+ if (setMarks.strike && schema.marks.strike)
195661
+ marks.push(schema.marks.strike.create());
195662
+ return marks;
195663
+ }
195664
+ function resolveTextRange(editor, blockId, from3, to, stepId) {
195665
+ const index2 = getBlockIndex2(editor);
195666
+ const candidate = index2.candidates.find((c2) => c2.nodeId === blockId);
195667
+ if (!candidate)
195668
+ throw planError("TARGET_NOT_FOUND", `block "${blockId}" not found`, stepId);
195669
+ const resolved = resolveTextRangeInBlock2(candidate.node, candidate.pos, { start: from3, end: to });
195670
+ if (!resolved) {
195671
+ throw planError("INVALID_INPUT", `text offset [${from3}, ${to}) out of range in block "${blockId}"`, stepId);
195672
+ }
195673
+ return { absFrom: resolved.from, absTo: resolved.to };
195674
+ }
195675
+ function resolveTextOffset(editor, blockId, offset2, stepId) {
195676
+ return resolveTextRange(editor, blockId, offset2, offset2, stepId).absFrom;
195677
+ }
195678
+ function toAbsoluteBlockInsertPos(editor, blockId, offset2, stepId) {
195679
+ const index2 = getBlockIndex2(editor);
195680
+ const candidate = index2.candidates.find((c2) => c2.nodeId === blockId);
195681
+ if (!candidate)
195682
+ throw planError("TARGET_NOT_FOUND", `block "${blockId}" not found`, stepId);
195683
+ return candidate.pos + offset2;
195684
+ }
195685
+ function executeTextRewrite(editor, tr, target, step, mapping) {
195686
+ const range = resolveTextRange(editor, target.blockId, target.from, target.to, step.id);
195687
+ const absFrom = mapping.map(range.absFrom);
195688
+ const absTo = mapping.map(range.absTo);
195689
+ const replacementText = step.args.replacement.text;
195690
+ const marks = resolveMarks(editor, target, step);
195691
+ const textNode = editor.state.schema.text(replacementText, marks);
195692
+ tr.replaceWith(absFrom, absTo, textNode);
195693
+ return { changed: replacementText !== target.text };
195694
+ }
195695
+ function executeTextInsert(editor, tr, target, step, mapping) {
195696
+ const position4 = step.args.position;
195697
+ const offset2 = position4 === "before" ? target.from : target.to;
195698
+ const absPos = mapping.map(resolveTextOffset(editor, target.blockId, offset2, step.id));
195699
+ const text4 = step.args.content.text;
195700
+ if (!text4)
195701
+ return { changed: false };
195702
+ let marks = [];
195703
+ const stylePolicy = step.args.style?.inline;
195704
+ if (stylePolicy) {
195705
+ if (stylePolicy.mode === "set") {
195706
+ marks = buildMarksFromSetMarks(editor, stylePolicy.setMarks);
195707
+ } else if (stylePolicy.mode === "clear") {
195708
+ marks = [];
195709
+ } else {
195710
+ const resolvedPos = tr.doc.resolve(absPos);
195711
+ marks = resolvedPos.marks();
195712
+ }
195713
+ } else {
195714
+ const resolvedPos = tr.doc.resolve(absPos);
195715
+ marks = resolvedPos.marks();
195716
+ }
195717
+ const textNode = editor.state.schema.text(text4, marks);
195718
+ tr.insert(absPos, textNode);
195719
+ return { changed: true };
195720
+ }
195721
+ function executeTextDelete(editor, tr, target, _step, mapping) {
195722
+ const range = resolveTextRange(editor, target.blockId, target.from, target.to, _step.id);
195723
+ const absFrom = mapping.map(range.absFrom);
195724
+ const absTo = mapping.map(range.absTo);
195725
+ if (absFrom === absTo)
195726
+ return { changed: false };
195727
+ tr.delete(absFrom, absTo);
195728
+ return { changed: true };
195729
+ }
195730
+ function executeStyleApply(editor, tr, target, step, mapping) {
195731
+ const range = resolveTextRange(editor, target.blockId, target.from, target.to, step.id);
195732
+ const absFrom = mapping.map(range.absFrom);
195733
+ const absTo = mapping.map(range.absTo);
195734
+ const { schema } = editor.state;
195735
+ let changed = false;
195736
+ const markEntries = [
195737
+ ["bold", step.args.marks.bold, schema.marks.bold],
195738
+ ["italic", step.args.marks.italic, schema.marks.italic],
195739
+ ["underline", step.args.marks.underline, schema.marks.underline],
195740
+ ["strike", step.args.marks.strike, schema.marks.strike]
195741
+ ];
195742
+ for (const [, value, markType] of markEntries) {
195743
+ if (value === undefined || !markType)
195744
+ continue;
195745
+ if (value) {
195746
+ tr.addMark(absFrom, absTo, markType.create());
195747
+ } else {
195748
+ tr.removeMark(absFrom, absTo, markType);
195749
+ }
195750
+ changed = true;
195751
+ }
195752
+ return { changed };
195753
+ }
195754
+ function countTextMatches(text4, pattern, mode, caseSensitive) {
195755
+ if (mode === "regex") {
195756
+ if (pattern.length > 1024)
195757
+ return 0;
195758
+ const flags = caseSensitive ? "g" : "gi";
195759
+ try {
195760
+ const regex = new RegExp(pattern, flags);
195761
+ const matches3 = text4.match(regex);
195762
+ return matches3 ? matches3.length : 0;
195763
+ } catch {
195764
+ return 0;
195765
+ }
195766
+ }
195767
+ const searchText = caseSensitive ? text4 : text4.toLowerCase();
195768
+ const searchPattern = caseSensitive ? pattern : pattern.toLowerCase();
195769
+ let count = 0;
195770
+ let pos = 0;
195771
+ while (true) {
195772
+ const idx = searchText.indexOf(searchPattern, pos);
195773
+ if (idx === -1)
195774
+ break;
195775
+ count++;
195776
+ pos = idx + 1;
195777
+ }
195778
+ return count;
195779
+ }
195780
+ function asId(value) {
195781
+ return typeof value === "string" && value.length > 0 ? value : undefined;
195782
+ }
195783
+ function resolveAssertNodeId(node3, mappedType) {
195784
+ const attrs = node3.attrs ?? {};
195785
+ if (mappedType === "paragraph" || mappedType === "heading" || mappedType === "listItem") {
195786
+ return asId(attrs.paraId) ?? asId(attrs.sdBlockId) ?? asId(attrs.nodeId);
195787
+ }
195788
+ return asId(attrs.blockId) ?? asId(attrs.id) ?? asId(attrs.paraId) ?? asId(attrs.uuid) ?? asId(attrs.sdBlockId) ?? asId(attrs.nodeId);
195789
+ }
195790
+ function buildAssertIndex(doc4) {
195791
+ const candidates = [];
195792
+ const byId = new Map;
195793
+ const ambiguous = new Set;
195794
+ function registerKey(key2, candidate) {
195795
+ if (byId.has(key2)) {
195796
+ ambiguous.add(key2);
195797
+ byId.delete(key2);
195798
+ return;
195799
+ }
195800
+ if (!ambiguous.has(key2)) {
195801
+ byId.set(key2, candidate);
195802
+ }
195803
+ }
195804
+ doc4.descendants((node3, pos) => {
195805
+ const nodeType = mapBlockNodeType2(node3);
195806
+ if (!nodeType)
195807
+ return true;
195808
+ const nodeId = resolveAssertNodeId(node3, nodeType);
195809
+ if (!nodeId)
195810
+ return true;
195811
+ const candidate = {
195812
+ node: node3,
195813
+ pos,
195814
+ end: pos + node3.nodeSize,
195815
+ nodeType,
195816
+ nodeId
195817
+ };
195818
+ candidates.push(candidate);
195819
+ registerKey(`${nodeType}:${nodeId}`, candidate);
195820
+ if (nodeType === "paragraph" || nodeType === "heading" || nodeType === "listItem") {
195821
+ const aliasId = asId(node3.attrs?.sdBlockId);
195822
+ if (aliasId && aliasId !== nodeId) {
195823
+ registerKey(`${nodeType}:${aliasId}`, candidate);
195824
+ }
195825
+ }
195826
+ return true;
195827
+ });
195828
+ return { candidates, byId };
195829
+ }
195830
+ function resolveAssertScope(index2, select2, within2) {
195831
+ if (!within2)
195832
+ return { ok: true, range: undefined };
195833
+ const scope = resolveWithinScope2(index2, { select: select2, within: within2 }, []);
195834
+ if (!scope.ok)
195835
+ return { ok: false };
195836
+ return { ok: true, range: scope.range };
195837
+ }
195838
+ function countNodeMatchesInDoc(doc4, selector, within2) {
195839
+ const index2 = buildAssertIndex(doc4);
195840
+ const scope = resolveAssertScope(index2, selector, within2);
195841
+ if (!scope.ok)
195842
+ return 0;
195843
+ if (selector.kind && selector.kind !== "block")
195844
+ return 0;
195845
+ const scoped = scopeByRange2(index2.candidates, scope.range);
195846
+ let count = 0;
195847
+ for (const candidate of scoped) {
195848
+ if (selector.nodeType && candidate.nodeType !== selector.nodeType)
195849
+ continue;
195850
+ count++;
195851
+ }
195852
+ return count;
195853
+ }
195854
+ function resolveScopedTextForAssert(doc4, selector, within2) {
195855
+ const index2 = buildAssertIndex(doc4);
195856
+ const scope = resolveAssertScope(index2, selector, within2);
195857
+ if (!scope.ok)
195858
+ return "";
195859
+ if (!scope.range)
195860
+ return doc4.textContent;
195861
+ return doc4.textBetween(scope.range.start, scope.range.end, `
195862
+ `, "");
195863
+ }
195864
+ function executeAssertStep(_editor, tr, step) {
195865
+ const where = step.where;
195866
+ if (where.by !== "select") {
195867
+ throw planError("INVALID_INPUT", `assert steps only support by: 'select'`, step.id);
195868
+ }
195869
+ const selector = where.select;
195870
+ if (selector.type !== "text") {
195871
+ const count2 = countNodeMatchesInDoc(tr.doc, selector, where.within);
195872
+ return { passed: count2 === step.args.expectCount, actualCount: count2 };
195873
+ }
195874
+ const text4 = resolveScopedTextForAssert(tr.doc, selector, where.within);
195875
+ const pattern = selector.pattern;
195876
+ const mode = selector.mode ?? "contains";
195877
+ const caseSensitive = selector.caseSensitive ?? false;
195878
+ const count = countTextMatches(text4, pattern, mode, caseSensitive);
195879
+ return { passed: count === step.args.expectCount, actualCount: count };
195880
+ }
195881
+ function executeCreateStep(editor, tr, step, targets, mapping) {
195882
+ const target = targets[0];
195883
+ if (!target) {
195884
+ throw planError("INVALID_INPUT", `${step.op} step requires exactly one target`, step.id);
195885
+ }
195886
+ const args3 = step.args;
195887
+ const pos = mapping.map(toAbsoluteBlockInsertPos(editor, target.blockId, target.from, step.id));
195888
+ const paragraphType = editor.state.schema?.nodes?.paragraph;
195889
+ if (!paragraphType) {
195890
+ throw planError("INVALID_INPUT", "paragraph node type not in schema", step.id);
195891
+ }
195892
+ const sdBlockId = args3.sdBlockId;
195893
+ const text4 = args3.text ?? "";
195894
+ const textNode = text4.length > 0 ? editor.state.schema.text(text4) : null;
195895
+ let attrs;
195896
+ if (step.op === "create.heading") {
195897
+ const level = args3.level ?? 1;
195898
+ attrs = {
195899
+ ...sdBlockId ? { sdBlockId } : undefined,
195900
+ paragraphProperties: { styleId: `Heading${level}` }
195901
+ };
195902
+ } else {
195903
+ attrs = sdBlockId ? { sdBlockId } : undefined;
195904
+ }
195905
+ const node3 = paragraphType.createAndFill(attrs, textNode ?? undefined) ?? paragraphType.create(attrs, textNode ? [textNode] : undefined);
195906
+ if (!node3) {
195907
+ throw planError("INVALID_INPUT", `could not create ${step.op} node`, step.id);
195908
+ }
195909
+ tr.insert(pos, node3);
195910
+ return {
195911
+ stepId: step.id,
195912
+ op: step.op,
195913
+ effect: "changed",
195914
+ matchCount: 1,
195915
+ data: { domain: "text", resolutions: [] }
195916
+ };
195917
+ }
195918
+ function runMutationsOnTransaction(editor, tr, compiled, options) {
195919
+ const mapping = tr.mapping;
195920
+ const stepOutcomes = [];
195921
+ const assertFailures = [];
195922
+ const ctx2 = {
195923
+ editor,
195924
+ tr,
195925
+ mapping,
195926
+ changeMode: "direct",
195927
+ planGroupId: "",
195928
+ commandDispatched: false
195929
+ };
195930
+ for (const compiledStep of compiled.mutationSteps) {
195931
+ const { step, targets } = compiledStep;
195932
+ const executor = getStepExecutor(step.op);
195933
+ if (!executor) {
195934
+ throw planError("INVALID_INPUT", `unsupported step op "${step.op}"`, step.id);
195935
+ }
195936
+ const outcome = executor.execute(ctx2, targets, step);
195937
+ stepOutcomes.push(outcome);
195938
+ }
195939
+ for (const assertStep of compiled.assertSteps) {
195940
+ const { passed, actualCount } = executeAssertStep(editor, tr, assertStep);
195941
+ if (!passed) {
195942
+ if (options.throwOnAssertFailure) {
195943
+ throw planError("PRECONDITION_FAILED", `assert "${assertStep.id}" expected ${assertStep.args.expectCount} matches but found ${actualCount}`, assertStep.id, { expectedCount: assertStep.args.expectCount, actualCount });
195944
+ }
195945
+ assertFailures.push({ stepId: assertStep.id, expectedCount: assertStep.args.expectCount, actualCount });
195946
+ }
195947
+ const data = {
195948
+ domain: "assert",
195949
+ expectedCount: assertStep.args.expectCount,
195950
+ actualCount
195951
+ };
195952
+ stepOutcomes.push({
195953
+ stepId: assertStep.id,
195954
+ op: "assert",
195955
+ effect: passed ? "assert_passed" : "assert_failed",
195956
+ matchCount: actualCount,
195957
+ data
195958
+ });
195959
+ }
195960
+ return { stepOutcomes, assertFailures, commandDispatched: ctx2.commandDispatched };
195961
+ }
195962
+ function executeCompiledPlan(editor, compiled, options = {}) {
195963
+ const startTime = performance.now();
195964
+ const revisionBefore = getRevision(editor);
195965
+ checkRevision(editor, options.expectedRevision);
195966
+ const tr = editor.state.tr;
195967
+ const changeMode = options.changeMode ?? "direct";
195968
+ if (changeMode === "tracked") {
195969
+ applyTrackedMutationMeta2(tr);
195970
+ } else {
195971
+ applyDirectMutationMeta2(tr);
195972
+ }
195973
+ const { stepOutcomes } = runMutationsOnTransaction(editor, tr, compiled, { throwOnAssertFailure: true });
195974
+ if (tr.docChanged) {
195975
+ editor.dispatch(tr);
195976
+ }
195977
+ const revisionAfter = getRevision(editor);
195978
+ const totalMs = performance.now() - startTime;
195979
+ return {
195980
+ success: true,
195981
+ revision: {
195982
+ before: revisionBefore,
195983
+ after: revisionAfter
195984
+ },
195985
+ steps: stepOutcomes,
195986
+ timing: { totalMs }
195987
+ };
195988
+ }
195989
+ function executePlan(editor, input2) {
195990
+ if (!input2.steps?.length) {
195991
+ throw planError("INVALID_INPUT", "plan must contain at least one step");
195992
+ }
195993
+ const compiled = compilePlan(editor, input2.steps);
195994
+ return executeCompiledPlan(editor, compiled, {
195995
+ changeMode: input2.changeMode ?? "direct",
195996
+ expectedRevision: input2.expectedRevision
195997
+ });
195998
+ }
195999
+ var DEFAULT_INLINE_POLICY;
196000
+ var init_executor = __esm(() => {
196001
+ init_executor_registry();
196002
+ init_errors4();
196003
+ init_revision_tracker();
196004
+ init_compiler();
196005
+ init_index_cache();
196006
+ init_style_resolver();
196007
+ init_node_address_resolver();
196008
+ init_adapter_utils();
196009
+ DEFAULT_INLINE_POLICY = {
196010
+ mode: "preserve",
196011
+ onNonUniform: "majority"
196012
+ };
196013
+ });
196014
+
196015
+ // ../../packages/super-editor/src/document-api-adapters/helpers/text-mutation-resolution.ts
196016
+ function readTextAtResolvedRange2(editor, range) {
196017
+ return editor.state.doc.textBetween(range.from, range.to, `
196018
+ `, OBJECT_REPLACEMENT_CHAR2);
196019
+ }
196020
+ function buildTextMutationResolution2(input2) {
196021
+ return {
196022
+ ...input2.requestedTarget ? { requestedTarget: input2.requestedTarget } : {},
196023
+ target: input2.target,
196024
+ range: { from: input2.range.from, to: input2.range.to },
196025
+ text: input2.text
196026
+ };
196027
+ }
196028
+ var OBJECT_REPLACEMENT_CHAR2 = "";
196029
+
196030
+ // ../../packages/super-editor/src/document-api-adapters/plan-engine/plan-wrappers.ts
196031
+ function normalizeWriteLocator2(request) {
196032
+ if (request.kind === "insert") {
196033
+ const hasBlockId = request.blockId !== undefined;
196034
+ const hasOffset = request.offset !== undefined;
196035
+ if (hasOffset && request.target) {
196036
+ throw new DocumentApiAdapterError3("INVALID_TARGET", "Cannot combine target with offset on insert request.", {
196037
+ fields: ["target", "offset"]
196038
+ });
196039
+ }
196040
+ if (hasOffset && !hasBlockId) {
196041
+ throw new DocumentApiAdapterError3("INVALID_TARGET", "offset requires blockId on insert request.", {
196042
+ fields: ["offset", "blockId"]
196043
+ });
196044
+ }
196045
+ if (!hasBlockId)
196046
+ return request;
196047
+ if (request.target) {
196048
+ throw new DocumentApiAdapterError3("INVALID_TARGET", "Cannot combine target with blockId on insert request.", {
196049
+ fields: ["target", "blockId"]
196050
+ });
196051
+ }
196052
+ const effectiveOffset = request.offset ?? 0;
196053
+ const target = {
196054
+ kind: "text",
196055
+ blockId: request.blockId,
196056
+ range: { start: effectiveOffset, end: effectiveOffset }
196057
+ };
196058
+ return { kind: "insert", target, text: request.text };
196059
+ }
196060
+ if (request.kind === "replace" || request.kind === "delete") {
196061
+ const hasBlockId = request.blockId !== undefined;
196062
+ const hasStart = request.start !== undefined;
196063
+ const hasEnd = request.end !== undefined;
196064
+ if (request.target && (hasBlockId || hasStart || hasEnd)) {
196065
+ throw new DocumentApiAdapterError3("INVALID_TARGET", `Cannot combine target with blockId/start/end on ${request.kind} request.`, { fields: ["target", "blockId", "start", "end"] });
196066
+ }
196067
+ if (!hasBlockId && (hasStart || hasEnd)) {
196068
+ throw new DocumentApiAdapterError3("INVALID_TARGET", `start/end require blockId on ${request.kind} request.`, {
196069
+ fields: ["blockId", "start", "end"]
196070
+ });
196071
+ }
196072
+ if (!hasBlockId)
196073
+ return request;
196074
+ if (!hasStart || !hasEnd) {
196075
+ throw new DocumentApiAdapterError3("INVALID_TARGET", `blockId requires both start and end on ${request.kind} request.`, { fields: ["blockId", "start", "end"] });
196076
+ }
196077
+ const target = {
196078
+ kind: "text",
196079
+ blockId: request.blockId,
196080
+ range: { start: request.start, end: request.end }
196081
+ };
196082
+ if (request.kind === "replace")
196083
+ return { kind: "replace", target, text: request.text };
196084
+ return { kind: "delete", target, text: "" };
196085
+ }
196086
+ return request;
196087
+ }
196088
+ function normalizeFormatLocator2(input2) {
196089
+ const hasBlockId = input2.blockId !== undefined;
196090
+ const hasStart = input2.start !== undefined;
196091
+ const hasEnd = input2.end !== undefined;
196092
+ if (input2.target && (hasBlockId || hasStart || hasEnd)) {
196093
+ throw new DocumentApiAdapterError3("INVALID_TARGET", "Cannot combine target with blockId/start/end on format request.", { fields: ["target", "blockId", "start", "end"] });
196094
+ }
196095
+ if (!hasBlockId && (hasStart || hasEnd)) {
196096
+ throw new DocumentApiAdapterError3("INVALID_TARGET", "start/end require blockId on format request.", {
196097
+ fields: ["blockId", "start", "end"]
196098
+ });
196099
+ }
196100
+ if (!hasBlockId)
196101
+ return input2;
196102
+ if (!hasStart || !hasEnd) {
196103
+ throw new DocumentApiAdapterError3("INVALID_TARGET", "blockId requires both start and end on format request.", {
196104
+ fields: ["blockId", "start", "end"]
196105
+ });
196106
+ }
196107
+ const target = {
196108
+ kind: "text",
196109
+ blockId: input2.blockId,
196110
+ range: { start: input2.start, end: input2.end }
196111
+ };
196112
+ return { target };
196113
+ }
196114
+ function resolveWriteTarget2(editor, request) {
196115
+ const requestedTarget = request.target;
196116
+ if (request.kind === "insert" && !request.target) {
196117
+ const fallback = resolveDefaultInsertTarget2(editor);
196118
+ if (!fallback)
196119
+ return null;
196120
+ const text5 = readTextAtResolvedRange2(editor, fallback.range);
196121
+ return {
196122
+ requestedTarget,
196123
+ effectiveTarget: fallback.target,
196124
+ range: fallback.range,
196125
+ resolution: buildTextMutationResolution2({
196126
+ requestedTarget,
196127
+ target: fallback.target,
196128
+ range: fallback.range,
196129
+ text: text5
196130
+ })
196131
+ };
196132
+ }
196133
+ const target = request.target;
196134
+ if (!target)
196135
+ return null;
196136
+ const range = resolveTextTarget2(editor, target);
196137
+ if (!range)
196138
+ return null;
196139
+ const text4 = readTextAtResolvedRange2(editor, range);
196140
+ return {
196141
+ requestedTarget,
196142
+ effectiveTarget: target,
196143
+ range,
196144
+ resolution: buildTextMutationResolution2({ requestedTarget, target, range, text: text4 })
196145
+ };
196146
+ }
196147
+ function mapPlanReceiptToTextReceipt(_receipt, resolution) {
196148
+ return { success: true, resolution };
196149
+ }
196150
+ function toCompiledTarget(stepId, op, resolved) {
196151
+ return {
196152
+ stepId,
196153
+ op,
196154
+ blockId: resolved.effectiveTarget.blockId,
196155
+ from: resolved.effectiveTarget.range.start,
196156
+ to: resolved.effectiveTarget.range.end,
196157
+ text: resolved.resolution.text,
196158
+ marks: []
196159
+ };
196160
+ }
196161
+ function executeDomainCommand(editor, handler2, options) {
196162
+ const stepId = v42();
196163
+ const step = {
196164
+ id: stepId,
196165
+ op: "domain.command",
196166
+ where: STUB_WHERE,
196167
+ args: {},
196168
+ _handler: handler2
196169
+ };
196170
+ const compiled = { mutationSteps: [{ step, targets: [] }], assertSteps: [] };
196171
+ return executeCompiledPlan(editor, compiled, { expectedRevision: options?.expectedRevision });
196172
+ }
196173
+ function validateWriteRequest2(request, resolved) {
196174
+ if (request.kind === "insert") {
196175
+ if (!request.text)
196176
+ return { code: "INVALID_TARGET", message: "Insert operations require non-empty text." };
196177
+ if (resolved.range.from !== resolved.range.to) {
196178
+ return { code: "INVALID_TARGET", message: "Insert operations require a collapsed target range." };
196179
+ }
196180
+ return null;
196181
+ }
196182
+ if (request.kind === "replace") {
196183
+ if (request.text == null || request.text.length === 0) {
196184
+ return { code: "INVALID_TARGET", message: "Replace operations require non-empty text. Use delete for removals." };
196185
+ }
196186
+ if (resolved.resolution.text === request.text) {
196187
+ return { code: "NO_OP", message: "Replace operation produced no change." };
196188
+ }
196189
+ return null;
196190
+ }
196191
+ if (resolved.range.from === resolved.range.to) {
196192
+ return { code: "NO_OP", message: "Delete operation produced no change for a collapsed range." };
196193
+ }
196194
+ return null;
196195
+ }
196196
+ function writeWrapper(editor, request, options) {
196197
+ const normalizedRequest = normalizeWriteLocator2(request);
196198
+ const resolved = resolveWriteTarget2(editor, normalizedRequest);
196199
+ if (!resolved) {
196200
+ throw new DocumentApiAdapterError3("TARGET_NOT_FOUND", "Mutation target could not be resolved.", {
196201
+ target: normalizedRequest.target
196202
+ });
196203
+ }
196204
+ const validationFailure = validateWriteRequest2(normalizedRequest, resolved);
196205
+ if (validationFailure) {
196206
+ return { success: false, resolution: resolved.resolution, failure: validationFailure };
196207
+ }
196208
+ const mode = options?.changeMode ?? "direct";
196209
+ if (mode === "tracked")
196210
+ ensureTrackedCapability2(editor, { operation: "write" });
196211
+ if (options?.dryRun) {
196212
+ return { success: true, resolution: resolved.resolution };
196213
+ }
196214
+ const stepId = v42();
196215
+ let op;
196216
+ let stepDef;
196217
+ if (normalizedRequest.kind === "insert") {
196218
+ op = "text.insert";
196219
+ stepDef = {
196220
+ id: stepId,
196221
+ op,
196222
+ where: STUB_WHERE,
196223
+ args: { position: "before", content: { text: normalizedRequest.text ?? "" } }
196224
+ };
196225
+ } else if (normalizedRequest.kind === "replace") {
196226
+ op = "text.rewrite";
196227
+ stepDef = {
196228
+ id: stepId,
196229
+ op,
196230
+ where: STUB_WHERE,
196231
+ args: { replacement: { text: normalizedRequest.text ?? "" }, style: { inline: { mode: "preserve" } } }
196232
+ };
196233
+ } else {
196234
+ op = "text.delete";
196235
+ stepDef = {
196236
+ id: stepId,
196237
+ op,
196238
+ where: STUB_WHERE,
196239
+ args: {}
196240
+ };
196241
+ }
196242
+ const step = stepDef;
196243
+ const target = toCompiledTarget(stepId, op, resolved);
196244
+ const compiled = {
196245
+ mutationSteps: [{ step, targets: [target] }],
196246
+ assertSteps: []
196247
+ };
196248
+ const receipt2 = executeCompiledPlan(editor, compiled, {
196249
+ changeMode: mode,
196250
+ expectedRevision: options?.expectedRevision
196251
+ });
196252
+ return mapPlanReceiptToTextReceipt(receipt2, resolved.resolution);
196253
+ }
196254
+ function formatMarkWrapper(editor, markName, operationId, input2, options) {
196255
+ const normalizedInput = normalizeFormatLocator2(input2);
196256
+ const range = resolveTextTarget2(editor, normalizedInput.target);
196257
+ if (!range) {
196258
+ throw new DocumentApiAdapterError3("TARGET_NOT_FOUND", "Format target could not be resolved.", {
196259
+ target: normalizedInput.target
196260
+ });
196261
+ }
196262
+ const resolution = buildTextMutationResolution2({
196263
+ requestedTarget: input2.target,
196264
+ target: normalizedInput.target,
196265
+ range,
196266
+ text: readTextAtResolvedRange2(editor, range)
196267
+ });
196268
+ if (range.from === range.to) {
196269
+ const label = FORMAT_OPERATION_LABEL2[operationId];
196270
+ return {
196271
+ success: false,
196272
+ resolution,
196273
+ failure: { code: "INVALID_TARGET", message: `${label} formatting requires a non-collapsed target range.` }
196274
+ };
196275
+ }
196276
+ requireSchemaMark2(editor, markName, operationId);
196277
+ const mode = options?.changeMode ?? "direct";
196278
+ if (mode === "tracked") {
196279
+ ensureTrackedCapability2(editor, { operation: operationId, requireMarks: [TrackFormatMarkName2] });
196280
+ }
196281
+ if (options?.dryRun) {
196282
+ return { success: true, resolution };
196283
+ }
196284
+ const stepId = v42();
196285
+ const marks = {};
196286
+ if (markName === "bold")
196287
+ marks.bold = true;
196288
+ else if (markName === "italic")
196289
+ marks.italic = true;
196290
+ else if (markName === "underline")
196291
+ marks.underline = true;
196292
+ else if (markName === "strike")
196293
+ marks.strike = true;
196294
+ const step = {
196295
+ id: stepId,
196296
+ op: "style.apply",
196297
+ where: STUB_WHERE,
196298
+ args: { marks }
196299
+ };
196300
+ const target = {
196301
+ stepId,
196302
+ op: "style.apply",
196303
+ blockId: normalizedInput.target.blockId,
196304
+ from: normalizedInput.target.range.start,
196305
+ to: normalizedInput.target.range.end,
196306
+ text: resolution.text,
196307
+ marks: []
196308
+ };
196309
+ const compiled = {
196310
+ mutationSteps: [{ step, targets: [target] }],
196311
+ assertSteps: []
196312
+ };
196313
+ const receipt2 = executeCompiledPlan(editor, compiled, {
196314
+ changeMode: mode,
196315
+ expectedRevision: options?.expectedRevision
196316
+ });
196317
+ return mapPlanReceiptToTextReceipt(receipt2, resolution);
196318
+ }
196319
+ function formatBoldWrapper(editor, input2, options) {
196320
+ return formatMarkWrapper(editor, "bold", "format.bold", input2, options);
196321
+ }
196322
+ function formatItalicWrapper(editor, input2, options) {
196323
+ return formatMarkWrapper(editor, "italic", "format.italic", input2, options);
196324
+ }
196325
+ function formatUnderlineWrapper(editor, input2, options) {
196326
+ return formatMarkWrapper(editor, "underline", "format.underline", input2, options);
196327
+ }
196328
+ function formatStrikethroughWrapper(editor, input2, options) {
196329
+ return formatMarkWrapper(editor, "strike", "format.strikethrough", input2, options);
196330
+ }
196331
+ var STUB_WHERE, FORMAT_OPERATION_LABEL2;
196332
+ var init_plan_wrappers = __esm(() => {
196333
+ init_wrapper();
196334
+ init_executor();
196335
+ init_errors3();
196336
+ init_adapter_utils();
196337
+ init_mutation_helpers();
196338
+ STUB_WHERE = {
196339
+ by: "select",
196340
+ select: { type: "text", pattern: "", mode: "exact" },
196341
+ require: "exactlyOne"
196342
+ };
196343
+ FORMAT_OPERATION_LABEL2 = {
196344
+ "format.bold": "Bold",
196345
+ "format.italic": "Italic",
196346
+ "format.underline": "Underline",
196347
+ "format.strikethrough": "Strikethrough"
196348
+ };
196349
+ });
196350
+
194540
196351
  // ../../packages/super-editor/src/document-api-adapters/helpers/comment-entity-store.ts
194541
196352
  function ensureFallbackStore2(editor) {
194542
196353
  if (!editor.storage) {
@@ -194693,7 +196504,7 @@ function resolveImportedId2(candidate) {
194693
196504
  const attrs = candidate.attrs ?? {};
194694
196505
  return toNonEmptyString2(attrs.importedId);
194695
196506
  }
194696
- function toTextAddress2(candidate) {
196507
+ function toTextAddress3(candidate) {
194697
196508
  const { start: start2, end } = candidate.anchor;
194698
196509
  if (start2.blockId !== end.blockId)
194699
196510
  return null;
@@ -194715,7 +196526,7 @@ function listCommentAnchors2(editor) {
194715
196526
  const commentId = resolveCommentId2(candidate);
194716
196527
  if (!commentId)
194717
196528
  continue;
194718
- const target = toTextAddress2(candidate);
196529
+ const target = toTextAddress3(candidate);
194719
196530
  if (!target)
194720
196531
  continue;
194721
196532
  const dedupeKey = `${commentId}|${target.blockId}:${target.range.start}:${target.range.end}`;
@@ -194745,7 +196556,7 @@ var init_comment_target_resolver = __esm(() => {
194745
196556
  init_index_cache();
194746
196557
  });
194747
196558
 
194748
- // ../../packages/super-editor/src/document-api-adapters/comments-adapter.ts
196559
+ // ../../packages/super-editor/src/document-api-adapters/plan-engine/comments-wrappers.ts
194749
196560
  function toCommentAddress2(commentId) {
194750
196561
  return {
194751
196562
  kind: "entity",
@@ -194872,7 +196683,7 @@ function buildCommentInfos2(editor) {
194872
196683
  });
194873
196684
  return infos;
194874
196685
  }
194875
- function addCommentHandler2(editor, input2) {
196686
+ function addCommentHandler2(editor, input2, options) {
194876
196687
  requireEditorCommand2(editor.commands?.addComment, "comments.add (addComment)");
194877
196688
  if (input2.target.range.start === input2.target.range.end) {
194878
196689
  return {
@@ -194898,7 +196709,6 @@ function addCommentHandler2(editor, input2) {
194898
196709
  }
194899
196710
  };
194900
196711
  }
194901
- const commentId = v42();
194902
196712
  if (!applyTextSelection2(editor, resolved.from, resolved.to)) {
194903
196713
  return {
194904
196714
  success: false,
@@ -194909,45 +196719,41 @@ function addCommentHandler2(editor, input2) {
194909
196719
  }
194910
196720
  };
194911
196721
  }
194912
- const addComment = requireEditorCommand2(editor.commands?.addComment, "comments.add (addComment)");
194913
- const didInsert = addComment({
194914
- content: input2.text,
194915
- isInternal: false,
194916
- commentId
194917
- }) === true;
194918
- if (!didInsert) {
196722
+ const commentId = v42();
196723
+ const receipt2 = executeDomainCommand(editor, () => {
196724
+ const addComment = requireEditorCommand2(editor.commands?.addComment, "comments.add (addComment)");
196725
+ const didInsert = addComment({ content: input2.text, isInternal: false, commentId }) === true;
196726
+ if (didInsert) {
196727
+ clearIndexCache2(editor);
196728
+ const store = getCommentEntityStore2(editor);
196729
+ const now = Date.now();
196730
+ const user = editor.options?.user ?? {};
196731
+ upsertCommentEntity2(store, commentId, {
196732
+ commentId,
196733
+ commentText: input2.text,
196734
+ commentJSON: buildCommentJsonFromText2(input2.text),
196735
+ parentCommentId: undefined,
196736
+ createdTime: now,
196737
+ creatorName: user.name,
196738
+ creatorEmail: user.email,
196739
+ creatorImage: user.image,
196740
+ isDone: false,
196741
+ isInternal: false,
196742
+ fileId: editor.options?.documentId,
196743
+ documentId: editor.options?.documentId
196744
+ });
196745
+ }
196746
+ return didInsert;
196747
+ }, { expectedRevision: options?.expectedRevision });
196748
+ if (receipt2.steps[0]?.effect !== "changed") {
194919
196749
  return {
194920
196750
  success: false,
194921
- failure: {
194922
- code: "NO_OP",
194923
- message: "Comment insertion produced no change."
194924
- }
196751
+ failure: { code: "NO_OP", message: "Comment insertion produced no change." }
194925
196752
  };
194926
196753
  }
194927
- clearIndexCache2(editor);
194928
- const store = getCommentEntityStore2(editor);
194929
- const now = Date.now();
194930
- const user = editor.options?.user ?? {};
194931
- upsertCommentEntity2(store, commentId, {
194932
- commentId,
194933
- commentText: input2.text,
194934
- commentJSON: buildCommentJsonFromText2(input2.text),
194935
- parentCommentId: undefined,
194936
- createdTime: now,
194937
- creatorName: user.name,
194938
- creatorEmail: user.email,
194939
- creatorImage: user.image,
194940
- isDone: false,
194941
- isInternal: false,
194942
- fileId: editor.options?.documentId,
194943
- documentId: editor.options?.documentId
194944
- });
194945
- return {
194946
- success: true,
194947
- inserted: [toCommentAddress2(commentId)]
194948
- };
196754
+ return { success: true, inserted: [toCommentAddress2(commentId)] };
194949
196755
  }
194950
- function editCommentHandler2(editor, input2) {
196756
+ function editCommentHandler2(editor, input2, options) {
194951
196757
  const editComment = requireEditorCommand2(editor.commands?.editComment, "comments.edit (editComment)");
194952
196758
  const store = getCommentEntityStore2(editor);
194953
196759
  const identity2 = resolveCommentIdentity2(editor, input2.commentId);
@@ -194956,37 +196762,33 @@ function editCommentHandler2(editor, input2) {
194956
196762
  if (existingText === input2.text) {
194957
196763
  return {
194958
196764
  success: false,
194959
- failure: {
194960
- code: "NO_OP",
194961
- message: "Comment edit produced no change."
194962
- }
196765
+ failure: { code: "NO_OP", message: "Comment edit produced no change." }
194963
196766
  };
194964
196767
  }
194965
- const didEdit = editComment({
194966
- commentId: identity2.commentId,
194967
- importedId: identity2.importedId,
194968
- content: input2.text
194969
- });
194970
- if (!didEdit) {
196768
+ const receipt2 = executeDomainCommand(editor, () => {
196769
+ const didEdit = editComment({
196770
+ commentId: identity2.commentId,
196771
+ importedId: identity2.importedId,
196772
+ content: input2.text
196773
+ });
196774
+ if (didEdit) {
196775
+ upsertCommentEntity2(store, identity2.commentId, {
196776
+ commentText: input2.text,
196777
+ commentJSON: buildCommentJsonFromText2(input2.text),
196778
+ importedId: identity2.importedId
196779
+ });
196780
+ }
196781
+ return Boolean(didEdit);
196782
+ }, { expectedRevision: options?.expectedRevision });
196783
+ if (receipt2.steps[0]?.effect !== "changed") {
194971
196784
  return {
194972
196785
  success: false,
194973
- failure: {
194974
- code: "NO_OP",
194975
- message: "Comment edit produced no change."
194976
- }
196786
+ failure: { code: "NO_OP", message: "Comment edit produced no change." }
194977
196787
  };
194978
196788
  }
194979
- upsertCommentEntity2(store, identity2.commentId, {
194980
- commentText: input2.text,
194981
- commentJSON: buildCommentJsonFromText2(input2.text),
194982
- importedId: identity2.importedId
194983
- });
194984
- return {
194985
- success: true,
194986
- updated: [toCommentAddress2(identity2.commentId)]
194987
- };
196789
+ return { success: true, updated: [toCommentAddress2(identity2.commentId)] };
194988
196790
  }
194989
- function replyToCommentHandler2(editor, input2) {
196791
+ function replyToCommentHandler2(editor, input2, options) {
194990
196792
  const addCommentReply = requireEditorCommand2(editor.commands?.addCommentReply, "comments.reply (addCommentReply)");
194991
196793
  if (!input2.parentCommentId) {
194992
196794
  return {
@@ -194999,51 +196801,47 @@ function replyToCommentHandler2(editor, input2) {
194999
196801
  }
195000
196802
  const parentIdentity = resolveCommentIdentity2(editor, input2.parentCommentId);
195001
196803
  const replyId = v42();
195002
- const didReply = addCommentReply({
195003
- parentId: parentIdentity.commentId,
195004
- content: input2.text,
195005
- commentId: replyId
195006
- });
195007
- if (!didReply) {
196804
+ const receipt2 = executeDomainCommand(editor, () => {
196805
+ const didReply = addCommentReply({
196806
+ parentId: parentIdentity.commentId,
196807
+ content: input2.text,
196808
+ commentId: replyId
196809
+ });
196810
+ if (didReply) {
196811
+ const now = Date.now();
196812
+ const user = editor.options?.user ?? {};
196813
+ const store = getCommentEntityStore2(editor);
196814
+ upsertCommentEntity2(store, replyId, {
196815
+ commentId: replyId,
196816
+ parentCommentId: parentIdentity.commentId,
196817
+ commentText: input2.text,
196818
+ commentJSON: buildCommentJsonFromText2(input2.text),
196819
+ createdTime: now,
196820
+ creatorName: user.name,
196821
+ creatorEmail: user.email,
196822
+ creatorImage: user.image,
196823
+ isDone: false,
196824
+ isInternal: false,
196825
+ fileId: editor.options?.documentId,
196826
+ documentId: editor.options?.documentId
196827
+ });
196828
+ }
196829
+ return Boolean(didReply);
196830
+ }, { expectedRevision: options?.expectedRevision });
196831
+ if (receipt2.steps[0]?.effect !== "changed") {
195008
196832
  return {
195009
196833
  success: false,
195010
- failure: {
195011
- code: "INVALID_TARGET",
195012
- message: "Comment reply could not be applied."
195013
- }
196834
+ failure: { code: "INVALID_TARGET", message: "Comment reply could not be applied." }
195014
196835
  };
195015
196836
  }
195016
- const now = Date.now();
195017
- const user = editor.options?.user ?? {};
195018
- const store = getCommentEntityStore2(editor);
195019
- upsertCommentEntity2(store, replyId, {
195020
- commentId: replyId,
195021
- parentCommentId: parentIdentity.commentId,
195022
- commentText: input2.text,
195023
- commentJSON: buildCommentJsonFromText2(input2.text),
195024
- createdTime: now,
195025
- creatorName: user.name,
195026
- creatorEmail: user.email,
195027
- creatorImage: user.image,
195028
- isDone: false,
195029
- isInternal: false,
195030
- fileId: editor.options?.documentId,
195031
- documentId: editor.options?.documentId
195032
- });
195033
- return {
195034
- success: true,
195035
- inserted: [toCommentAddress2(replyId)]
195036
- };
196837
+ return { success: true, inserted: [toCommentAddress2(replyId)] };
195037
196838
  }
195038
- function moveCommentHandler2(editor, input2) {
196839
+ function moveCommentHandler2(editor, input2, options) {
195039
196840
  const moveComment = requireEditorCommand2(editor.commands?.moveComment, "comments.move (moveComment)");
195040
196841
  if (input2.target.range.start === input2.target.range.end) {
195041
196842
  return {
195042
196843
  success: false,
195043
- failure: {
195044
- code: "INVALID_TARGET",
195045
- message: "Comment target range must be non-collapsed."
195046
- }
196844
+ failure: { code: "INVALID_TARGET", message: "Comment target range must be non-collapsed." }
195047
196845
  };
195048
196846
  }
195049
196847
  const resolved = resolveTextTarget2(editor, input2.target);
@@ -195053,20 +196851,14 @@ function moveCommentHandler2(editor, input2) {
195053
196851
  if (resolved.from === resolved.to) {
195054
196852
  return {
195055
196853
  success: false,
195056
- failure: {
195057
- code: "INVALID_TARGET",
195058
- message: "Comment target range must be non-collapsed."
195059
- }
196854
+ failure: { code: "INVALID_TARGET", message: "Comment target range must be non-collapsed." }
195060
196855
  };
195061
196856
  }
195062
196857
  const identity2 = resolveCommentIdentity2(editor, input2.commentId);
195063
196858
  if (!identity2.anchors.length) {
195064
196859
  return {
195065
196860
  success: false,
195066
- failure: {
195067
- code: "INVALID_TARGET",
195068
- message: "Comment cannot be moved because it has no resolvable anchor."
195069
- }
196861
+ failure: { code: "INVALID_TARGET", message: "Comment cannot be moved because it has no resolvable anchor." }
195070
196862
  };
195071
196863
  }
195072
196864
  if (identity2.anchors.length > 1) {
@@ -195082,32 +196874,19 @@ function moveCommentHandler2(editor, input2) {
195082
196874
  if (currentTarget && isSameTarget2(currentTarget, input2.target)) {
195083
196875
  return {
195084
196876
  success: false,
195085
- failure: {
195086
- code: "NO_OP",
195087
- message: "Comment move produced no change."
195088
- }
196877
+ failure: { code: "NO_OP", message: "Comment move produced no change." }
195089
196878
  };
195090
196879
  }
195091
- const didMove = moveComment({
195092
- commentId: identity2.commentId,
195093
- from: resolved.from,
195094
- to: resolved.to
195095
- });
195096
- if (!didMove) {
196880
+ const receipt2 = executeDomainCommand(editor, () => Boolean(moveComment({ commentId: identity2.commentId, from: resolved.from, to: resolved.to })), { expectedRevision: options?.expectedRevision });
196881
+ if (receipt2.steps[0]?.effect !== "changed") {
195097
196882
  return {
195098
196883
  success: false,
195099
- failure: {
195100
- code: "NO_OP",
195101
- message: "Comment move produced no change."
195102
- }
196884
+ failure: { code: "NO_OP", message: "Comment move produced no change." }
195103
196885
  };
195104
196886
  }
195105
- return {
195106
- success: true,
195107
- updated: [toCommentAddress2(identity2.commentId)]
195108
- };
196887
+ return { success: true, updated: [toCommentAddress2(identity2.commentId)] };
195109
196888
  }
195110
- function resolveCommentHandler2(editor, input2) {
196889
+ function resolveCommentHandler2(editor, input2, options) {
195111
196890
  const resolveComment = requireEditorCommand2(editor.commands?.resolveComment, "comments.resolve (resolveComment)");
195112
196891
  const store = getCommentEntityStore2(editor);
195113
196892
  const identity2 = resolveCommentIdentity2(editor, input2.commentId);
@@ -195116,51 +196895,46 @@ function resolveCommentHandler2(editor, input2) {
195116
196895
  if (alreadyResolved) {
195117
196896
  return {
195118
196897
  success: false,
195119
- failure: {
195120
- code: "NO_OP",
195121
- message: "Comment is already resolved."
195122
- }
196898
+ failure: { code: "NO_OP", message: "Comment is already resolved." }
195123
196899
  };
195124
196900
  }
195125
- const didResolve = resolveComment({
195126
- commentId: identity2.commentId,
195127
- importedId: identity2.importedId
195128
- });
195129
- if (!didResolve) {
196901
+ const receipt2 = executeDomainCommand(editor, () => {
196902
+ const didResolve = resolveComment({
196903
+ commentId: identity2.commentId,
196904
+ importedId: identity2.importedId
196905
+ });
196906
+ if (didResolve) {
196907
+ upsertCommentEntity2(store, identity2.commentId, {
196908
+ importedId: identity2.importedId,
196909
+ isDone: true,
196910
+ resolvedTime: Date.now()
196911
+ });
196912
+ }
196913
+ return Boolean(didResolve);
196914
+ }, { expectedRevision: options?.expectedRevision });
196915
+ if (receipt2.steps[0]?.effect !== "changed") {
195130
196916
  return {
195131
196917
  success: false,
195132
- failure: {
195133
- code: "NO_OP",
195134
- message: "Comment resolve produced no change."
195135
- }
196918
+ failure: { code: "NO_OP", message: "Comment resolve produced no change." }
195136
196919
  };
195137
196920
  }
195138
- upsertCommentEntity2(store, identity2.commentId, {
195139
- importedId: identity2.importedId,
195140
- isDone: true,
195141
- resolvedTime: Date.now()
195142
- });
195143
- return {
195144
- success: true,
195145
- updated: [toCommentAddress2(identity2.commentId)]
195146
- };
196921
+ return { success: true, updated: [toCommentAddress2(identity2.commentId)] };
195147
196922
  }
195148
- function removeCommentHandler2(editor, input2) {
196923
+ function removeCommentHandler2(editor, input2, options) {
195149
196924
  const removeComment = requireEditorCommand2(editor.commands?.removeComment, "comments.remove (removeComment)");
195150
196925
  const store = getCommentEntityStore2(editor);
195151
196926
  const identity2 = resolveCommentIdentity2(editor, input2.commentId);
195152
- const didRemove = removeComment({
195153
- commentId: identity2.commentId,
195154
- importedId: identity2.importedId
195155
- }) === true;
195156
- const removedRecords = removeCommentEntityTree2(store, identity2.commentId);
195157
- if (!didRemove && removedRecords.length === 0) {
196927
+ let didRemove = false;
196928
+ let removedRecords = [];
196929
+ const receipt2 = executeDomainCommand(editor, () => {
196930
+ didRemove = removeComment({ commentId: identity2.commentId, importedId: identity2.importedId }) === true;
196931
+ removedRecords = removeCommentEntityTree2(store, identity2.commentId);
196932
+ return didRemove || removedRecords.length > 0;
196933
+ }, { expectedRevision: options?.expectedRevision });
196934
+ if (receipt2.steps[0]?.effect !== "changed") {
195158
196935
  return {
195159
196936
  success: false,
195160
- failure: {
195161
- code: "NO_OP",
195162
- message: "Comment remove produced no change."
195163
- }
196937
+ failure: { code: "NO_OP", message: "Comment remove produced no change." }
195164
196938
  };
195165
196939
  }
195166
196940
  const removedIds = new Set;
@@ -195178,7 +196952,7 @@ function removeCommentHandler2(editor, input2) {
195178
196952
  removed: Array.from(removedIds).map((id2) => toCommentAddress2(id2))
195179
196953
  };
195180
196954
  }
195181
- function setCommentInternalHandler2(editor, input2) {
196955
+ function setCommentInternalHandler2(editor, input2, options) {
195182
196956
  const setCommentInternal = requireEditorCommand2(editor.commands?.setCommentInternal, "comments.setInternal (setCommentInternal)");
195183
196957
  const store = getCommentEntityStore2(editor);
195184
196958
  const identity2 = resolveCommentIdentity2(editor, input2.commentId);
@@ -195187,46 +196961,47 @@ function setCommentInternalHandler2(editor, input2) {
195187
196961
  if (typeof currentInternal === "boolean" && currentInternal === input2.isInternal) {
195188
196962
  return {
195189
196963
  success: false,
195190
- failure: {
195191
- code: "NO_OP",
195192
- message: "Comment internal state is already set to the requested value."
195193
- }
196964
+ failure: { code: "NO_OP", message: "Comment internal state is already set to the requested value." }
195194
196965
  };
195195
196966
  }
195196
196967
  const hasOpenAnchor = identity2.anchors.some((anchor) => anchor.status === "open");
195197
- if (hasOpenAnchor) {
195198
- const didApply = setCommentInternal({
195199
- commentId: identity2.commentId,
196968
+ const receipt2 = executeDomainCommand(editor, () => {
196969
+ if (hasOpenAnchor) {
196970
+ const didApply = setCommentInternal({
196971
+ commentId: identity2.commentId,
196972
+ importedId: identity2.importedId,
196973
+ isInternal: input2.isInternal
196974
+ });
196975
+ if (!didApply)
196976
+ return false;
196977
+ }
196978
+ upsertCommentEntity2(store, identity2.commentId, {
195200
196979
  importedId: identity2.importedId,
195201
196980
  isInternal: input2.isInternal
195202
196981
  });
195203
- if (!didApply) {
195204
- return {
195205
- success: false,
195206
- failure: {
195207
- code: "INVALID_TARGET",
195208
- message: "Comment internal state could not be updated on the current anchor."
195209
- }
195210
- };
195211
- }
196982
+ return true;
196983
+ }, { expectedRevision: options?.expectedRevision });
196984
+ if (receipt2.steps[0]?.effect !== "changed") {
196985
+ return {
196986
+ success: false,
196987
+ failure: {
196988
+ code: "INVALID_TARGET",
196989
+ message: "Comment internal state could not be updated on the current anchor."
196990
+ }
196991
+ };
195212
196992
  }
195213
- upsertCommentEntity2(store, identity2.commentId, {
195214
- importedId: identity2.importedId,
195215
- isInternal: input2.isInternal
195216
- });
195217
- return {
195218
- success: true,
195219
- updated: [toCommentAddress2(identity2.commentId)]
195220
- };
196993
+ return { success: true, updated: [toCommentAddress2(identity2.commentId)] };
195221
196994
  }
195222
- function setCommentActiveHandler2(editor, input2) {
196995
+ function setCommentActiveHandler2(editor, input2, options) {
195223
196996
  const setActiveComment = requireEditorCommand2(editor.commands?.setActiveComment, "comments.setActive (setActiveComment)");
195224
196997
  let resolvedCommentId = null;
195225
196998
  if (input2.commentId != null) {
195226
196999
  resolvedCommentId = resolveCommentIdentity2(editor, input2.commentId).commentId;
195227
197000
  }
195228
- const didSet = setActiveComment({ commentId: resolvedCommentId });
195229
- if (!didSet) {
197001
+ const receipt2 = executeDomainCommand(editor, () => Boolean(setActiveComment({ commentId: resolvedCommentId })), {
197002
+ expectedRevision: options?.expectedRevision
197003
+ });
197004
+ if (receipt2.steps[0]?.effect !== "changed") {
195230
197005
  return {
195231
197006
  success: false,
195232
197007
  failure: {
@@ -195272,28 +197047,29 @@ function listCommentsHandler2(editor, query2) {
195272
197047
  total: matches3.length
195273
197048
  };
195274
197049
  }
195275
- function createCommentsAdapter2(editor) {
197050
+ function createCommentsWrapper(editor) {
195276
197051
  return {
195277
- add: (input2) => addCommentHandler2(editor, input2),
195278
- edit: (input2) => editCommentHandler2(editor, input2),
195279
- reply: (input2) => replyToCommentHandler2(editor, input2),
195280
- move: (input2) => moveCommentHandler2(editor, input2),
195281
- resolve: (input2) => resolveCommentHandler2(editor, input2),
195282
- remove: (input2) => removeCommentHandler2(editor, input2),
195283
- setInternal: (input2) => setCommentInternalHandler2(editor, input2),
195284
- setActive: (input2) => setCommentActiveHandler2(editor, input2),
197052
+ add: (input2, options) => addCommentHandler2(editor, input2, options),
197053
+ edit: (input2, options) => editCommentHandler2(editor, input2, options),
197054
+ reply: (input2, options) => replyToCommentHandler2(editor, input2, options),
197055
+ move: (input2, options) => moveCommentHandler2(editor, input2, options),
197056
+ resolve: (input2, options) => resolveCommentHandler2(editor, input2, options),
197057
+ remove: (input2, options) => removeCommentHandler2(editor, input2, options),
197058
+ setInternal: (input2, options) => setCommentInternalHandler2(editor, input2, options),
197059
+ setActive: (input2, options) => setCommentActiveHandler2(editor, input2, options),
195285
197060
  goTo: (input2) => goToCommentHandler2(editor, input2),
195286
197061
  get: (input2) => getCommentHandler2(editor, input2),
195287
197062
  list: (query2) => listCommentsHandler2(editor, query2)
195288
197063
  };
195289
197064
  }
195290
- var init_comments_adapter = __esm(() => {
197065
+ var init_comments_wrappers = __esm(() => {
195291
197066
  init_dist4();
195292
197067
  init_wrapper();
195293
197068
  init_errors3();
195294
197069
  init_mutation_helpers();
195295
197070
  init_index_cache();
195296
197071
  init_adapter_utils();
197072
+ init_plan_wrappers();
195297
197073
  init_comment_target_resolver();
195298
197074
  });
195299
197075
 
@@ -195443,10 +197219,6 @@ function resolveTrackedChange2(editor, id2) {
195443
197219
  const grouped = groupTrackedChanges2(editor);
195444
197220
  return grouped.find((item) => item.id === id2) ?? null;
195445
197221
  }
195446
- function toCanonicalTrackedChangeId2(editor, rawId) {
195447
- const grouped = groupTrackedChanges2(editor);
195448
- return grouped.find((item) => item.rawId === rawId)?.id ?? null;
195449
- }
195450
197222
  function buildTrackedChangeCanonicalIdMap2(editor) {
195451
197223
  const grouped = groupTrackedChanges2(editor);
195452
197224
  const map6 = new Map;
@@ -195490,9 +197262,9 @@ var init_tracked_change_refs = __esm(() => {
195490
197262
  init_tracked_change_resolver();
195491
197263
  });
195492
197264
 
195493
- // ../../packages/super-editor/src/document-api-adapters/create-adapter.ts
195494
- function resolveParagraphInsertPosition2(editor, input2) {
195495
- const location3 = input2.at ?? { kind: "documentEnd" };
197265
+ // ../../packages/super-editor/src/document-api-adapters/plan-engine/create-wrappers.ts
197266
+ function resolveCreateInsertPosition(editor, at, operationLabel) {
197267
+ const location3 = at ?? { kind: "documentEnd" };
195496
197268
  if (location3.kind === "documentStart")
195497
197269
  return 0;
195498
197270
  if (location3.kind === "documentEnd")
@@ -195501,30 +197273,30 @@ function resolveParagraphInsertPosition2(editor, input2) {
195501
197273
  const hasTarget = "target" in location3 && location3.target != null;
195502
197274
  const target = hasTarget ? findBlockById2(index2, location3.target) : findBlockByNodeIdOnly2(index2, location3.nodeId);
195503
197275
  if (!target) {
195504
- throw new DocumentApiAdapterError3("TARGET_NOT_FOUND", "Create paragraph target block was not found.", {
197276
+ throw new DocumentApiAdapterError3("TARGET_NOT_FOUND", `Create ${operationLabel} target block was not found.`, {
195505
197277
  target: hasTarget ? location3.target : location3.nodeId
195506
197278
  });
195507
197279
  }
195508
197280
  return location3.kind === "before" ? target.pos : target.end;
195509
197281
  }
195510
- function resolveCreatedParagraph2(editor, paragraphId) {
197282
+ function resolveCreatedBlock(editor, nodeType, blockId) {
195511
197283
  const index2 = getBlockIndex2(editor);
195512
- const resolved = index2.byId.get(`paragraph:${paragraphId}`);
197284
+ const resolved = index2.byId.get(`${nodeType}:${blockId}`);
195513
197285
  if (resolved)
195514
197286
  return resolved;
195515
197287
  const bySdBlockId = index2.candidates.find((candidate) => {
195516
- if (candidate.nodeType !== "paragraph")
197288
+ if (candidate.nodeType !== nodeType)
195517
197289
  return false;
195518
197290
  const attrs = candidate.node.attrs;
195519
- return typeof attrs?.sdBlockId === "string" && attrs.sdBlockId === paragraphId;
197291
+ return typeof attrs?.sdBlockId === "string" && attrs.sdBlockId === blockId;
195520
197292
  });
195521
197293
  if (bySdBlockId)
195522
197294
  return bySdBlockId;
195523
- const fallback = index2.candidates.find((candidate) => candidate.nodeType === "paragraph" && candidate.nodeId === paragraphId);
197295
+ const fallback = index2.candidates.find((candidate) => candidate.nodeType === nodeType && candidate.nodeId === blockId);
195524
197296
  if (fallback)
195525
197297
  return fallback;
195526
- throw new DocumentApiAdapterError3("TARGET_NOT_FOUND", "Created paragraph could not be resolved after insertion.", {
195527
- paragraphId
197298
+ throw new DocumentApiAdapterError3("TARGET_NOT_FOUND", `Created ${nodeType} could not be resolved after insertion.`, {
197299
+ [`${nodeType}Id`]: blockId
195528
197300
  });
195529
197301
  }
195530
197302
  function buildParagraphCreateSuccess2(paragraphNodeId, trackedChangeRefs) {
@@ -195543,13 +197315,29 @@ function buildParagraphCreateSuccess2(paragraphNodeId, trackedChangeRefs) {
195543
197315
  trackedChangeRefs
195544
197316
  };
195545
197317
  }
195546
- function createParagraphAdapter2(editor, input2, options) {
197318
+ function buildHeadingCreateSuccess2(headingNodeId, trackedChangeRefs) {
197319
+ return {
197320
+ success: true,
197321
+ heading: {
197322
+ kind: "block",
197323
+ nodeType: "heading",
197324
+ nodeId: headingNodeId
197325
+ },
197326
+ insertionPoint: {
197327
+ kind: "text",
197328
+ blockId: headingNodeId,
197329
+ range: { start: 0, end: 0 }
197330
+ },
197331
+ trackedChangeRefs
197332
+ };
197333
+ }
197334
+ function createParagraphWrapper(editor, input2, options) {
195547
197335
  const insertParagraphAt2 = requireEditorCommand2(editor.commands?.insertParagraphAt, "create.paragraph");
195548
197336
  const mode = options?.changeMode ?? "direct";
195549
197337
  if (mode === "tracked") {
195550
197338
  ensureTrackedCapability2(editor, { operation: "create.paragraph" });
195551
197339
  }
195552
- const insertAt = resolveParagraphInsertPosition2(editor, input2);
197340
+ const insertAt = resolveCreateInsertPosition(editor, input2.at, "paragraph");
195553
197341
  if (options?.dryRun) {
195554
197342
  const canInsert = editor.can().insertParagraphAt?.({
195555
197343
  pos: insertAt,
@@ -195580,13 +197368,26 @@ function createParagraphAdapter2(editor, input2, options) {
195580
197368
  };
195581
197369
  }
195582
197370
  const paragraphId = v42();
195583
- const didApply = insertParagraphAt2({
195584
- pos: insertAt,
195585
- text: input2.text,
195586
- sdBlockId: paragraphId,
195587
- tracked: mode === "tracked"
195588
- });
195589
- if (!didApply) {
197371
+ let trackedChangeRefs;
197372
+ const receipt2 = executeDomainCommand(editor, () => {
197373
+ const didApply = insertParagraphAt2({
197374
+ pos: insertAt,
197375
+ text: input2.text,
197376
+ sdBlockId: paragraphId,
197377
+ tracked: mode === "tracked"
197378
+ });
197379
+ if (didApply) {
197380
+ clearIndexCache2(editor);
197381
+ try {
197382
+ const paragraph2 = resolveCreatedBlock(editor, "paragraph", paragraphId);
197383
+ if (mode === "tracked") {
197384
+ trackedChangeRefs = collectTrackInsertRefsInRange2(editor, paragraph2.pos, paragraph2.end);
197385
+ }
197386
+ } catch {}
197387
+ }
197388
+ return didApply;
197389
+ }, { expectedRevision: options?.expectedRevision });
197390
+ if (receipt2.steps[0]?.effect !== "changed") {
195590
197391
  return {
195591
197392
  success: false,
195592
197393
  failure: {
@@ -195595,74 +197396,15 @@ function createParagraphAdapter2(editor, input2, options) {
195595
197396
  }
195596
197397
  };
195597
197398
  }
195598
- clearIndexCache2(editor);
195599
- try {
195600
- const paragraph2 = resolveCreatedParagraph2(editor, paragraphId);
195601
- const trackedChangeRefs = mode === "tracked" ? collectTrackInsertRefsInRange2(editor, paragraph2.pos, paragraph2.end) : undefined;
195602
- return buildParagraphCreateSuccess2(paragraphId, trackedChangeRefs);
195603
- } catch {
195604
- return buildParagraphCreateSuccess2(paragraphId);
195605
- }
195606
- }
195607
- function resolveHeadingInsertPosition2(editor, input2) {
195608
- const location3 = input2.at ?? { kind: "documentEnd" };
195609
- if (location3.kind === "documentStart")
195610
- return 0;
195611
- if (location3.kind === "documentEnd")
195612
- return editor.state.doc.content.size;
195613
- const index2 = getBlockIndex2(editor);
195614
- const hasTarget = "target" in location3 && location3.target != null;
195615
- const target = hasTarget ? findBlockById2(index2, location3.target) : findBlockByNodeIdOnly2(index2, location3.nodeId);
195616
- if (!target) {
195617
- throw new DocumentApiAdapterError3("TARGET_NOT_FOUND", "Create heading target block was not found.", {
195618
- target: hasTarget ? location3.target : location3.nodeId
195619
- });
195620
- }
195621
- return location3.kind === "before" ? target.pos : target.end;
195622
- }
195623
- function resolveCreatedHeading2(editor, headingId) {
195624
- const index2 = getBlockIndex2(editor);
195625
- const resolved = index2.byId.get(`heading:${headingId}`);
195626
- if (resolved)
195627
- return resolved;
195628
- const bySdBlockId = index2.candidates.find((candidate) => {
195629
- if (candidate.nodeType !== "heading")
195630
- return false;
195631
- const attrs = candidate.node.attrs;
195632
- return typeof attrs?.sdBlockId === "string" && attrs.sdBlockId === headingId;
195633
- });
195634
- if (bySdBlockId)
195635
- return bySdBlockId;
195636
- const fallback = index2.candidates.find((candidate) => candidate.nodeType === "heading" && candidate.nodeId === headingId);
195637
- if (fallback)
195638
- return fallback;
195639
- throw new DocumentApiAdapterError3("TARGET_NOT_FOUND", "Created heading could not be resolved after insertion.", {
195640
- headingId
195641
- });
197399
+ return buildParagraphCreateSuccess2(paragraphId, trackedChangeRefs);
195642
197400
  }
195643
- function buildHeadingCreateSuccess2(headingNodeId, trackedChangeRefs) {
195644
- return {
195645
- success: true,
195646
- heading: {
195647
- kind: "block",
195648
- nodeType: "heading",
195649
- nodeId: headingNodeId
195650
- },
195651
- insertionPoint: {
195652
- kind: "text",
195653
- blockId: headingNodeId,
195654
- range: { start: 0, end: 0 }
195655
- },
195656
- trackedChangeRefs
195657
- };
195658
- }
195659
- function createHeadingAdapter2(editor, input2, options) {
197401
+ function createHeadingWrapper(editor, input2, options) {
195660
197402
  const insertHeadingAt2 = requireEditorCommand2(editor.commands?.insertHeadingAt, "create.heading");
195661
197403
  const mode = options?.changeMode ?? "direct";
195662
197404
  if (mode === "tracked") {
195663
197405
  ensureTrackedCapability2(editor, { operation: "create.heading" });
195664
197406
  }
195665
- const insertAt = resolveHeadingInsertPosition2(editor, input2);
197407
+ const insertAt = resolveCreateInsertPosition(editor, input2.at, "heading");
195666
197408
  if (options?.dryRun) {
195667
197409
  const canInsert = editor.can().insertHeadingAt?.({
195668
197410
  pos: insertAt,
@@ -195694,14 +197436,27 @@ function createHeadingAdapter2(editor, input2, options) {
195694
197436
  };
195695
197437
  }
195696
197438
  const headingId = v42();
195697
- const didApply = insertHeadingAt2({
195698
- pos: insertAt,
195699
- level: input2.level,
195700
- text: input2.text,
195701
- sdBlockId: headingId,
195702
- tracked: mode === "tracked"
195703
- });
195704
- if (!didApply) {
197439
+ let trackedChangeRefs;
197440
+ const receipt2 = executeDomainCommand(editor, () => {
197441
+ const didApply = insertHeadingAt2({
197442
+ pos: insertAt,
197443
+ level: input2.level,
197444
+ text: input2.text,
197445
+ sdBlockId: headingId,
197446
+ tracked: mode === "tracked"
197447
+ });
197448
+ if (didApply) {
197449
+ clearIndexCache2(editor);
197450
+ try {
197451
+ const heading3 = resolveCreatedBlock(editor, "heading", headingId);
197452
+ if (mode === "tracked") {
197453
+ trackedChangeRefs = collectTrackInsertRefsInRange2(editor, heading3.pos, heading3.end);
197454
+ }
197455
+ } catch {}
197456
+ }
197457
+ return didApply;
197458
+ }, { expectedRevision: options?.expectedRevision });
197459
+ if (receipt2.steps[0]?.effect !== "changed") {
195705
197460
  return {
195706
197461
  success: false,
195707
197462
  failure: {
@@ -195710,22 +197465,16 @@ function createHeadingAdapter2(editor, input2, options) {
195710
197465
  }
195711
197466
  };
195712
197467
  }
195713
- clearIndexCache2(editor);
195714
- try {
195715
- const heading3 = resolveCreatedHeading2(editor, headingId);
195716
- const trackedChangeRefs = mode === "tracked" ? collectTrackInsertRefsInRange2(editor, heading3.pos, heading3.end) : undefined;
195717
- return buildHeadingCreateSuccess2(headingId, trackedChangeRefs);
195718
- } catch {
195719
- return buildHeadingCreateSuccess2(headingId);
195720
- }
197468
+ return buildHeadingCreateSuccess2(headingId, trackedChangeRefs);
195721
197469
  }
195722
- var init_create_adapter = __esm(() => {
197470
+ var init_create_wrappers = __esm(() => {
195723
197471
  init_wrapper();
195724
197472
  init_index_cache();
195725
197473
  init_node_address_resolver();
195726
197474
  init_tracked_change_refs();
195727
197475
  init_errors3();
195728
197476
  init_mutation_helpers();
197477
+ init_plan_wrappers();
195729
197478
  });
195730
197479
 
195731
197480
  // ../../packages/super-editor/src/document-api-adapters/helpers/node-info-mapper.ts
@@ -196181,174 +197930,6 @@ var init_node_info_resolver = __esm(() => {
196181
197930
  init_node_info_mapper();
196182
197931
  });
196183
197932
 
196184
- // ../../packages/super-editor/src/document-api-adapters/find/common.ts
196185
- function resolveUnknownBlockId2(attrs) {
196186
- if (!attrs)
196187
- return;
196188
- return toId2(attrs.sdBlockId) ?? toId2(attrs.paraId) ?? toId2(attrs.blockId) ?? toId2(attrs.id) ?? toId2(attrs.uuid);
196189
- }
196190
- function isDualKindType2(nodeType) {
196191
- return Boolean(nodeType && DUAL_KIND_TYPES2.has(nodeType));
196192
- }
196193
- function getAddressStartPos2(editor, index2, address2) {
196194
- if (address2.kind === "block") {
196195
- const block = findBlockById2(index2, address2);
196196
- return block?.pos ?? Number.MAX_SAFE_INTEGER;
196197
- }
196198
- const inlineIndex = getInlineIndex2(editor);
196199
- const inline = findInlineByAnchor2(inlineIndex, address2);
196200
- return inline?.pos ?? Number.MAX_SAFE_INTEGER;
196201
- }
196202
- function buildTextContext2(editor, address2, matchFrom, matchTo, textRanges) {
196203
- const docSize = editor.state.doc.content.size;
196204
- const snippetFrom = Math.max(0, matchFrom - SNIPPET_PADDING2);
196205
- const snippetTo = Math.min(docSize, matchTo + SNIPPET_PADDING2);
196206
- const rawSnippet = editor.state.doc.textBetween(snippetFrom, snippetTo, " ");
196207
- const snippet = rawSnippet.replace(/ {2,}/g, " ");
196208
- const rawPrefix = editor.state.doc.textBetween(snippetFrom, matchFrom, " ");
196209
- const rawMatch = editor.state.doc.textBetween(matchFrom, matchTo, " ");
196210
- const prefix3 = rawPrefix.replace(/ {2,}/g, " ");
196211
- const matchNormalized = rawMatch.replace(/ {2,}/g, " ");
196212
- return {
196213
- address: address2,
196214
- snippet,
196215
- highlightRange: {
196216
- start: prefix3.length,
196217
- end: prefix3.length + matchNormalized.length
196218
- },
196219
- textRanges: textRanges?.length ? textRanges : undefined
196220
- };
196221
- }
196222
- function toTextAddress3(editor, block, range) {
196223
- const blockStart = block.pos + 1;
196224
- const blockEnd = block.end - 1;
196225
- if (range.from < blockStart || range.to > blockEnd)
196226
- return;
196227
- const start2 = editor.state.doc.textBetween(blockStart, range.from, `
196228
- `, "").length;
196229
- const end = editor.state.doc.textBetween(blockStart, range.to, `
196230
- `, "").length;
196231
- return {
196232
- kind: "text",
196233
- blockId: block.nodeId,
196234
- range: { start: start2, end }
196235
- };
196236
- }
196237
- function shouldQueryBothKinds2(select2) {
196238
- if (select2.type === "node") {
196239
- return !select2.kind && isDualKindType2(select2.nodeType);
196240
- }
196241
- return false;
196242
- }
196243
- function sortAddressesByPosition2(editor, index2, addresses) {
196244
- return [...addresses].sort((a2, b3) => {
196245
- const aPos = getAddressStartPos2(editor, index2, a2);
196246
- const bPos = getAddressStartPos2(editor, index2, b3);
196247
- if (aPos !== bPos)
196248
- return aPos - bPos;
196249
- if (a2.kind === b3.kind)
196250
- return 0;
196251
- return a2.kind === "block" ? -1 : 1;
196252
- });
196253
- }
196254
- function collectUnknownNodeDiagnostics2(editor, index2, diagnostics) {
196255
- editor.state.doc.descendants((node3, pos) => {
196256
- if (node3.isBlock && !KNOWN_BLOCK_PM_NODE_TYPES2.has(node3.type.name)) {
196257
- const blockId = resolveUnknownBlockId2(node3.attrs ?? {});
196258
- diagnostics.push({
196259
- message: `Unknown block node type "${node3.type.name}" is not part of the stable Document API match set.`,
196260
- hint: blockId ? `Skipped unknown block with stable id "${blockId}".` : "Skipped unknown block with no stable id available."
196261
- });
196262
- return;
196263
- }
196264
- if (node3.isInline && !KNOWN_INLINE_PM_NODE_TYPES2.has(node3.type.name)) {
196265
- const container = findCandidateByPos2(index2.candidates, pos);
196266
- diagnostics.push({
196267
- message: `Unknown inline node type "${node3.type.name}" is not part of the stable Document API match set.`,
196268
- address: container ? toBlockAddress2(container) : undefined,
196269
- hint: container ? `Skipped unknown inline node inside block "${container.nodeType}" with id "${container.nodeId}".` : "Skipped unknown inline node outside resolvable block scope."
196270
- });
196271
- }
196272
- });
196273
- }
196274
- function isInlineQuery2(select2) {
196275
- if (select2.type === "node") {
196276
- if (select2.kind)
196277
- return select2.kind === "inline";
196278
- return Boolean(select2.nodeType && isInlineQueryType2(select2.nodeType));
196279
- }
196280
- return false;
196281
- }
196282
- var SNIPPET_PADDING2 = 30, DUAL_KIND_TYPES2, KNOWN_BLOCK_PM_NODE_TYPES2, KNOWN_INLINE_PM_NODE_TYPES2;
196283
- var init_common = __esm(() => {
196284
- init_index_cache();
196285
- init_node_address_resolver();
196286
- init_inline_address_resolver();
196287
- init_adapter_utils();
196288
- DUAL_KIND_TYPES2 = new Set(["sdt", "image"]);
196289
- KNOWN_BLOCK_PM_NODE_TYPES2 = new Set([
196290
- "paragraph",
196291
- "table",
196292
- "tableRow",
196293
- "tableCell",
196294
- "tableHeader",
196295
- "structuredContentBlock",
196296
- "sdt",
196297
- "image"
196298
- ]);
196299
- KNOWN_INLINE_PM_NODE_TYPES2 = new Set([
196300
- "text",
196301
- "run",
196302
- "structuredContent",
196303
- "image",
196304
- "tab",
196305
- "lineBreak",
196306
- "hardBreak",
196307
- "hard_break",
196308
- "footnoteReference",
196309
- "bookmarkStart",
196310
- "bookmarkEnd",
196311
- "commentRangeStart",
196312
- "commentRangeEnd"
196313
- ]);
196314
- });
196315
-
196316
- // ../../packages/super-editor/src/document-api-adapters/find/block-strategy.ts
196317
- function executeBlockSelector2(index2, query2, diagnostics) {
196318
- const scope = resolveWithinScope2(index2, query2, diagnostics);
196319
- if (!scope.ok)
196320
- return { matches: [], total: 0 };
196321
- const scoped = scopeByRange2(index2.candidates, scope.range);
196322
- const select2 = query2.select;
196323
- let filtered = [];
196324
- if (select2.type === "node") {
196325
- if (select2.kind && select2.kind !== "block") {
196326
- addDiagnostic2(diagnostics, "Only block nodes are supported by the current adapter.");
196327
- } else {
196328
- filtered = scoped.filter((candidate) => {
196329
- if (select2.nodeType) {
196330
- if (candidate.nodeType !== select2.nodeType)
196331
- return false;
196332
- }
196333
- return true;
196334
- });
196335
- }
196336
- }
196337
- const addresses = filtered.map((candidate) => ({
196338
- kind: "block",
196339
- nodeType: candidate.nodeType,
196340
- nodeId: candidate.nodeId
196341
- }));
196342
- const paged = paginate2(addresses, query2.offset, query2.limit);
196343
- return {
196344
- matches: paged.items,
196345
- total: paged.total
196346
- };
196347
- }
196348
- var init_block_strategy = __esm(() => {
196349
- init_adapter_utils();
196350
- });
196351
-
196352
197933
  // ../../packages/super-editor/src/document-api-adapters/find/inline-strategy.ts
196353
197934
  function toInlineAddress2(candidate, nodeTypeOverride) {
196354
197935
  return {
@@ -196420,93 +198001,6 @@ var init_dual_kind_strategy = __esm(() => {
196420
198001
  init_inline_strategy();
196421
198002
  });
196422
198003
 
196423
- // ../../packages/super-editor/src/document-api-adapters/find/text-strategy.ts
196424
- function compileRegex2(selector, diagnostics) {
196425
- const flags = selector.caseSensitive ? "g" : "gi";
196426
- try {
196427
- return new RegExp(selector.pattern, flags);
196428
- } catch (error) {
196429
- const reason = error instanceof Error ? error.message : String(error);
196430
- addDiagnostic2(diagnostics, `Invalid text query regex: ${reason}`);
196431
- return null;
196432
- }
196433
- }
196434
- function buildSearchPattern2(selector, diagnostics) {
196435
- const mode = selector.mode ?? "contains";
196436
- if (mode === "regex") {
196437
- return compileRegex2(selector, diagnostics);
196438
- }
196439
- const escaped = selector.pattern.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
196440
- const flags = selector.caseSensitive ? "g" : "gi";
196441
- return new RegExp(escaped, flags);
196442
- }
196443
- function executeTextSelector2(editor, index2, query2, diagnostics) {
196444
- if (query2.select.type !== "text") {
196445
- addDiagnostic2(diagnostics, `Text strategy received a non-text selector (type="${query2.select.type}").`);
196446
- return { matches: [], total: 0 };
196447
- }
196448
- const selector = query2.select;
196449
- if (!selector.pattern.length) {
196450
- addDiagnostic2(diagnostics, "Text query pattern must be non-empty.");
196451
- return { matches: [], total: 0 };
196452
- }
196453
- const scope = resolveWithinScope2(index2, query2, diagnostics);
196454
- if (!scope.ok)
196455
- return { matches: [], total: 0 };
196456
- const pattern = buildSearchPattern2(selector, diagnostics);
196457
- if (!pattern)
196458
- return { matches: [], total: 0 };
196459
- const search3 = requireEditorCommand2(editor.commands?.search, "find (search)");
196460
- const rawResult = search3(pattern, {
196461
- highlight: false,
196462
- caseSensitive: selector.caseSensitive ?? false,
196463
- maxMatches: Infinity
196464
- });
196465
- if (!Array.isArray(rawResult)) {
196466
- throw new DocumentApiAdapterError3("CAPABILITY_UNAVAILABLE", "Editor search command returned an unexpected result format.");
196467
- }
196468
- const allMatches = rawResult;
196469
- const scopeRange = scope.range;
196470
- const matches3 = scopeRange ? allMatches.filter((m3) => m3.from >= scopeRange.start && m3.to <= scopeRange.end) : allMatches;
196471
- const textBlocks = index2.candidates.filter(isTextBlockCandidate2);
196472
- const contexts = [];
196473
- const addresses = [];
196474
- for (const match2 of matches3) {
196475
- const ranges = match2.ranges?.length ? match2.ranges : [{ from: match2.from, to: match2.to }];
196476
- let source;
196477
- const textRanges = ranges.map((range) => {
196478
- const block = findCandidateByPos2(textBlocks, range.from);
196479
- if (!block)
196480
- return;
196481
- if (!source)
196482
- source = block;
196483
- return toTextAddress3(editor, block, range);
196484
- }).filter((range) => Boolean(range));
196485
- if (!source) {
196486
- source = findCandidateByPos2(textBlocks, match2.from) ?? findBlockByPos2(index2, match2.from);
196487
- }
196488
- if (!source)
196489
- continue;
196490
- const address2 = toBlockAddress2(source);
196491
- addresses.push(address2);
196492
- contexts.push(buildTextContext2(editor, address2, match2.from, match2.to, textRanges));
196493
- }
196494
- const paged = paginate2(addresses, query2.offset, query2.limit);
196495
- const pagedContexts = paginate2(contexts, query2.offset, query2.limit).items;
196496
- return {
196497
- matches: paged.items,
196498
- total: paged.total,
196499
- context: pagedContexts.length ? pagedContexts : undefined
196500
- };
196501
- }
196502
- var init_text_strategy = __esm(() => {
196503
- init_node_address_resolver();
196504
- init_adapter_utils();
196505
- init_common();
196506
- init_errors3();
196507
- init_mutation_helpers();
196508
- });
196509
-
196510
198004
  // ../../packages/super-editor/src/document-api-adapters/find-adapter.ts
196511
198005
  function findAdapter2(editor, query2) {
196512
198006
  const diagnostics = [];
@@ -196536,125 +198030,6 @@ var init_find_adapter = __esm(() => {
196536
198030
  init_text_strategy();
196537
198031
  });
196538
198032
 
196539
- // ../../packages/super-editor/src/document-api-adapters/helpers/transaction-meta.ts
196540
- function applyDirectMutationMeta2(tr) {
196541
- tr.setMeta("inputType", "programmatic");
196542
- tr.setMeta("skipTrackChanges", true);
196543
- return tr;
196544
- }
196545
- function applyTrackedMutationMeta2(tr) {
196546
- tr.setMeta("inputType", "programmatic");
196547
- tr.setMeta("forceTrackChanges", true);
196548
- return tr;
196549
- }
196550
-
196551
- // ../../packages/super-editor/src/document-api-adapters/helpers/text-mutation-resolution.ts
196552
- function readTextAtResolvedRange2(editor, range) {
196553
- return editor.state.doc.textBetween(range.from, range.to, `
196554
- `, OBJECT_REPLACEMENT_CHAR2);
196555
- }
196556
- function buildTextMutationResolution2(input2) {
196557
- return {
196558
- ...input2.requestedTarget ? { requestedTarget: input2.requestedTarget } : {},
196559
- target: input2.target,
196560
- range: { from: input2.range.from, to: input2.range.to },
196561
- text: input2.text
196562
- };
196563
- }
196564
- var OBJECT_REPLACEMENT_CHAR2 = "";
196565
-
196566
- // ../../packages/super-editor/src/document-api-adapters/format-adapter.ts
196567
- function normalizeFormatLocator2(input2) {
196568
- const hasBlockId = input2.blockId !== undefined;
196569
- const hasStart = input2.start !== undefined;
196570
- const hasEnd = input2.end !== undefined;
196571
- if (input2.target && (hasBlockId || hasStart || hasEnd)) {
196572
- throw new DocumentApiAdapterError3("INVALID_TARGET", "Cannot combine target with blockId/start/end on format request.", { fields: ["target", "blockId", "start", "end"] });
196573
- }
196574
- if (!hasBlockId && (hasStart || hasEnd)) {
196575
- throw new DocumentApiAdapterError3("INVALID_TARGET", "start/end require blockId on format request.", {
196576
- fields: ["blockId", "start", "end"]
196577
- });
196578
- }
196579
- if (!hasBlockId)
196580
- return input2;
196581
- if (!hasStart || !hasEnd) {
196582
- throw new DocumentApiAdapterError3("INVALID_TARGET", "blockId requires both start and end on format request.", {
196583
- fields: ["blockId", "start", "end"]
196584
- });
196585
- }
196586
- const target = {
196587
- kind: "text",
196588
- blockId: input2.blockId,
196589
- range: { start: input2.start, end: input2.end }
196590
- };
196591
- return { target };
196592
- }
196593
- function formatMarkAdapter2(editor, markName, operationId, input2, options) {
196594
- const normalizedInput = normalizeFormatLocator2(input2);
196595
- const range = resolveTextTarget2(editor, normalizedInput.target);
196596
- if (!range) {
196597
- throw new DocumentApiAdapterError3("TARGET_NOT_FOUND", "Format target could not be resolved.", {
196598
- target: normalizedInput.target
196599
- });
196600
- }
196601
- const resolution = buildTextMutationResolution2({
196602
- requestedTarget: input2.target,
196603
- target: normalizedInput.target,
196604
- range,
196605
- text: readTextAtResolvedRange2(editor, range)
196606
- });
196607
- if (range.from === range.to) {
196608
- const label = FORMAT_OPERATION_LABEL2[operationId];
196609
- return {
196610
- success: false,
196611
- resolution,
196612
- failure: {
196613
- code: "INVALID_TARGET",
196614
- message: `${label} formatting requires a non-collapsed target range.`
196615
- }
196616
- };
196617
- }
196618
- const mark2 = requireSchemaMark2(editor, markName, operationId);
196619
- const mode = options?.changeMode ?? "direct";
196620
- if (mode === "tracked")
196621
- ensureTrackedCapability2(editor, { operation: operationId, requireMarks: [TrackFormatMarkName2] });
196622
- if (options?.dryRun) {
196623
- return { success: true, resolution };
196624
- }
196625
- const tr = editor.state.tr.addMark(range.from, range.to, mark2.create());
196626
- if (mode === "tracked")
196627
- applyTrackedMutationMeta2(tr);
196628
- else
196629
- applyDirectMutationMeta2(tr);
196630
- editor.dispatch(tr);
196631
- return { success: true, resolution };
196632
- }
196633
- function formatBoldAdapter2(editor, input2, options) {
196634
- return formatMarkAdapter2(editor, "bold", "format.bold", input2, options);
196635
- }
196636
- function formatItalicAdapter2(editor, input2, options) {
196637
- return formatMarkAdapter2(editor, "italic", "format.italic", input2, options);
196638
- }
196639
- function formatUnderlineAdapter2(editor, input2, options) {
196640
- return formatMarkAdapter2(editor, "underline", "format.underline", input2, options);
196641
- }
196642
- function formatStrikethroughAdapter2(editor, input2, options) {
196643
- return formatMarkAdapter2(editor, "strike", "format.strikethrough", input2, options);
196644
- }
196645
- var FORMAT_OPERATION_LABEL2;
196646
- var init_format_adapter = __esm(() => {
196647
- init_errors3();
196648
- init_mutation_helpers();
196649
- init_adapter_utils();
196650
- FORMAT_OPERATION_LABEL2 = {
196651
- "format.bold": "Bold",
196652
- "format.italic": "Italic",
196653
- "format.underline": "Underline",
196654
- "format.strikethrough": "Strikethrough"
196655
- };
196656
- });
196657
-
196658
198033
  // ../../packages/super-editor/src/document-api-adapters/get-node-adapter.ts
196659
198034
  function findBlocksByTypeAndId2(blockIndex, nodeType, nodeId) {
196660
198035
  const byIdMatch = blockIndex.byId.get(`${nodeType}:${nodeId}`);
@@ -196814,11 +198189,13 @@ function infoAdapter2(editor, _input) {
196814
198189
  canGetNode: true,
196815
198190
  canComment: true,
196816
198191
  canReplace: true
196817
- }
198192
+ },
198193
+ revision: getRevision(editor)
196818
198194
  };
196819
198195
  }
196820
198196
  var init_info_adapter = __esm(() => {
196821
198197
  init_find_adapter();
198198
+ init_revision_tracker();
196822
198199
  });
196823
198200
 
196824
198201
  // ../../shared/common/list-numbering/index.ts
@@ -199407,16 +200784,12 @@ var init_isList = __esm(() => {
199407
200784
  function generateDocxRandomId2(length3 = 8) {
199408
200785
  const max3 = 2147483647;
199409
200786
  const value = Math.floor(Math.random() * (max3 + 1));
199410
- return value.toString(16).padStart(length3, "0").slice(0, length3);
200787
+ return value.toString(16).toUpperCase().padStart(length3, "0").slice(0, length3);
199411
200788
  }
199412
200789
  function generateRandomSigned32BitIntStrId2() {
199413
200790
  const val = Math.floor(Math.random() * 2147483647);
199414
200791
  return val.toString();
199415
200792
  }
199416
- function generateRandom32BitHex2() {
199417
- const val = Math.floor(Math.random() * 2147483647);
199418
- return val.toString(16).toUpperCase().padStart(8, "0");
199419
- }
199420
200793
 
199421
200794
  // ../../packages/super-editor/src/core/helpers/generateDocxListAttributes.js
199422
200795
  var init_generateDocxListAttributes = () => {};
@@ -215696,7 +217069,21 @@ function resolveParagraphProperties2(params3, inlineProps, tableInfo) {
215696
217069
  specialHandling: {
215697
217070
  tabStops: (target, source) => {
215698
217071
  if (target.tabStops != null && source.tabStops != null) {
215699
- return [...target.tabStops, ...source.tabStops];
217072
+ const sourceArr = source.tabStops;
217073
+ const clearPositions = new Set;
217074
+ for (const ts of sourceArr) {
217075
+ if (ts.tab?.tabType === "clear" && ts.tab.pos != null) {
217076
+ clearPositions.add(ts.tab.pos);
217077
+ }
217078
+ }
217079
+ const targetArr = target.tabStops;
217080
+ const merged = targetArr.filter((ts) => !(ts.tab?.pos != null && clearPositions.has(ts.tab.pos)));
217081
+ for (const ts of sourceArr) {
217082
+ if (ts.tab?.tabType !== "clear") {
217083
+ merged.push(ts);
217084
+ }
217085
+ }
217086
+ return merged;
215700
217087
  }
215701
217088
  return source.tabStops;
215702
217089
  }
@@ -226257,7 +227644,7 @@ var init_constants = __esm(() => {
226257
227644
  var prepareCommentParaIds2 = (comment2) => {
226258
227645
  const newComment = {
226259
227646
  ...comment2,
226260
- commentParaId: generateRandom32BitHex2()
227647
+ commentParaId: generateDocxRandomId2()
226261
227648
  };
226262
227649
  return newComment;
226263
227650
  }, getCommentDefinition2 = (comment2, commentId, allComments, editor) => {
@@ -226391,7 +227778,7 @@ var prepareCommentParaIds2 = (comment2) => {
226391
227778
  if (extensibleUpdated)
226392
227779
  extensibleUpdated.elements[0].elements = [];
226393
227780
  comments.forEach((comment2) => {
226394
- const newDurableId = generateRandom32BitHex2();
227781
+ const newDurableId = generateDocxRandomId2();
226395
227782
  if (documentIdsUpdated) {
226396
227783
  documentIdsUpdated.elements[0].elements.push({
226397
227784
  type: "element",
@@ -229953,7 +231340,7 @@ var init_list_item_resolver = __esm(() => {
229953
231340
  init_index_cache();
229954
231341
  });
229955
231342
 
229956
- // ../../packages/super-editor/src/document-api-adapters/lists-adapter.ts
231343
+ // ../../packages/super-editor/src/document-api-adapters/plan-engine/lists-wrappers.ts
229957
231344
  function toListsFailure2(code7, message, details) {
229958
231345
  return { success: false, failure: { code: code7, message, details } };
229959
231346
  }
@@ -230030,14 +231417,14 @@ function withListTarget2(editor, input2) {
230030
231417
  }
230031
231418
  throw new DocumentApiAdapterError3("TARGET_NOT_FOUND", "List item target was not found.", { nodeId });
230032
231419
  }
230033
- function listsListAdapter2(editor, query2) {
231420
+ function listsListWrapper(editor, query2) {
230034
231421
  return listListItems2(editor, query2);
230035
231422
  }
230036
- function listsGetAdapter2(editor, input2) {
231423
+ function listsGetWrapper(editor, input2) {
230037
231424
  const item = resolveListItem2(editor, input2.address);
230038
231425
  return listItemProjectionToInfo2(item);
230039
231426
  }
230040
- function listsInsertAdapter2(editor, input2, options) {
231427
+ function listsInsertWrapper(editor, input2, options) {
230041
231428
  const target = withListTarget2(editor, input2);
230042
231429
  const changeMode = options?.changeMode ?? "direct";
230043
231430
  const mode = changeMode === "tracked" ? "tracked" : "direct";
@@ -230056,24 +231443,30 @@ function listsInsertAdapter2(editor, input2, options) {
230056
231443
  };
230057
231444
  }
230058
231445
  const createdId = v42();
230059
- const didApply = insertListItemAt2({
230060
- pos: target.candidate.pos,
230061
- position: input2.position,
230062
- text: input2.text ?? "",
230063
- sdBlockId: createdId,
230064
- tracked: mode === "tracked"
230065
- });
230066
- if (!didApply) {
231446
+ let created = null;
231447
+ const receipt2 = executeDomainCommand(editor, () => {
231448
+ const didApply = insertListItemAt2({
231449
+ pos: target.candidate.pos,
231450
+ position: input2.position,
231451
+ text: input2.text ?? "",
231452
+ sdBlockId: createdId,
231453
+ tracked: mode === "tracked"
231454
+ });
231455
+ if (didApply) {
231456
+ clearIndexCache2(editor);
231457
+ try {
231458
+ created = resolveInsertedListItem2(editor, createdId);
231459
+ } catch {}
231460
+ }
231461
+ return didApply;
231462
+ }, { expectedRevision: options?.expectedRevision });
231463
+ if (receipt2.steps[0]?.effect !== "changed") {
230067
231464
  return toListsFailure2("INVALID_TARGET", "List item insertion could not be applied at the requested target.", {
230068
231465
  target: input2.target,
230069
231466
  position: input2.position
230070
231467
  });
230071
231468
  }
230072
- clearIndexCache2(editor);
230073
- let created;
230074
- try {
230075
- created = resolveInsertedListItem2(editor, createdId);
230076
- } catch {
231469
+ if (!created) {
230077
231470
  return {
230078
231471
  success: true,
230079
231472
  item: { kind: "block", nodeType: "listItem", nodeId: createdId },
@@ -230095,7 +231488,7 @@ function listsInsertAdapter2(editor, input2, options) {
230095
231488
  trackedChangeRefs: mode === "tracked" ? collectTrackInsertRefsInRange2(editor, created.candidate.pos, created.candidate.end) : undefined
230096
231489
  };
230097
231490
  }
230098
- function listsSetTypeAdapter2(editor, input2, options) {
231491
+ function listsSetTypeWrapper(editor, input2, options) {
230099
231492
  rejectTrackedMode2("lists.setType", options);
230100
231493
  const target = withListTarget2(editor, input2);
230101
231494
  if (target.kind === input2.kind) {
@@ -230108,22 +231501,18 @@ function listsSetTypeAdapter2(editor, input2, options) {
230108
231501
  if (options?.dryRun) {
230109
231502
  return { success: true, item: target.address };
230110
231503
  }
230111
- const didApply = setListTypeAt2({
230112
- pos: target.candidate.pos,
230113
- kind: input2.kind
231504
+ const receipt2 = executeDomainCommand(editor, () => setListTypeAt2({ pos: target.candidate.pos, kind: input2.kind }), {
231505
+ expectedRevision: options?.expectedRevision
230114
231506
  });
230115
- if (!didApply) {
231507
+ if (receipt2.steps[0]?.effect !== "changed") {
230116
231508
  return toListsFailure2("INVALID_TARGET", "List type conversion could not be applied.", {
230117
231509
  target: input2.target,
230118
231510
  kind: input2.kind
230119
231511
  });
230120
231512
  }
230121
- return {
230122
- success: true,
230123
- item: target.address
230124
- };
231513
+ return { success: true, item: target.address };
230125
231514
  }
230126
- function listsIndentAdapter2(editor, input2, options) {
231515
+ function listsIndentWrapper(editor, input2, options) {
230127
231516
  rejectTrackedMode2("lists.indent", options);
230128
231517
  const target = withListTarget2(editor, input2);
230129
231518
  if (isAtMaximumLevel2(editor, target)) {
@@ -230138,16 +231527,15 @@ function listsIndentAdapter2(editor, input2, options) {
230138
231527
  target: input2.target
230139
231528
  });
230140
231529
  }
230141
- const didApply = increaseListIndent2();
230142
- if (!didApply) {
231530
+ const receipt2 = executeDomainCommand(editor, () => increaseListIndent2(), {
231531
+ expectedRevision: options?.expectedRevision
231532
+ });
231533
+ if (receipt2.steps[0]?.effect !== "changed") {
230143
231534
  return toListsFailure2("INVALID_TARGET", "List indentation could not be applied.", { target: input2.target });
230144
231535
  }
230145
- return {
230146
- success: true,
230147
- item: target.address
230148
- };
231536
+ return { success: true, item: target.address };
230149
231537
  }
230150
- function listsOutdentAdapter2(editor, input2, options) {
231538
+ function listsOutdentWrapper(editor, input2, options) {
230151
231539
  rejectTrackedMode2("lists.outdent", options);
230152
231540
  const target = withListTarget2(editor, input2);
230153
231541
  if ((target.level ?? 0) <= 0) {
@@ -230162,16 +231550,15 @@ function listsOutdentAdapter2(editor, input2, options) {
230162
231550
  target: input2.target
230163
231551
  });
230164
231552
  }
230165
- const didApply = decreaseListIndent2();
230166
- if (!didApply) {
231553
+ const receipt2 = executeDomainCommand(editor, () => decreaseListIndent2(), {
231554
+ expectedRevision: options?.expectedRevision
231555
+ });
231556
+ if (receipt2.steps[0]?.effect !== "changed") {
230167
231557
  return toListsFailure2("INVALID_TARGET", "List outdent could not be applied.", { target: input2.target });
230168
231558
  }
230169
- return {
230170
- success: true,
230171
- item: target.address
230172
- };
231559
+ return { success: true, item: target.address };
230173
231560
  }
230174
- function listsRestartAdapter2(editor, input2, options) {
231561
+ function listsRestartWrapper(editor, input2, options) {
230175
231562
  rejectTrackedMode2("lists.restart", options);
230176
231563
  const target = withListTarget2(editor, input2);
230177
231564
  if (target.numId == null) {
@@ -230193,16 +231580,15 @@ function listsRestartAdapter2(editor, input2, options) {
230193
231580
  target: input2.target
230194
231581
  });
230195
231582
  }
230196
- const didApply = restartNumbering2();
230197
- if (!didApply) {
231583
+ const receipt2 = executeDomainCommand(editor, () => restartNumbering2(), {
231584
+ expectedRevision: options?.expectedRevision
231585
+ });
231586
+ if (receipt2.steps[0]?.effect !== "changed") {
230198
231587
  return toListsFailure2("INVALID_TARGET", "List restart could not be applied.", { target: input2.target });
230199
231588
  }
230200
- return {
230201
- success: true,
230202
- item: target.address
230203
- };
231589
+ return { success: true, item: target.address };
230204
231590
  }
230205
- function listsExitAdapter2(editor, input2, options) {
231591
+ function listsExitWrapper(editor, input2, options) {
230206
231592
  rejectTrackedMode2("lists.exit", options);
230207
231593
  const target = withListTarget2(editor, input2);
230208
231594
  const exitListItemAt2 = requireEditorCommand2(editor.commands?.exitListItemAt, "lists.exit (exitListItemAt)");
@@ -230216,8 +231602,10 @@ function listsExitAdapter2(editor, input2, options) {
230216
231602
  }
230217
231603
  };
230218
231604
  }
230219
- const didApply = exitListItemAt2({ pos: target.candidate.pos });
230220
- if (!didApply) {
231605
+ const receipt2 = executeDomainCommand(editor, () => exitListItemAt2({ pos: target.candidate.pos }), {
231606
+ expectedRevision: options?.expectedRevision
231607
+ });
231608
+ if (receipt2.steps[0]?.effect !== "changed") {
230221
231609
  return toListsFailure2("INVALID_TARGET", "List exit could not be applied.", { target: input2.target });
230222
231610
  }
230223
231611
  return {
@@ -230229,17 +231617,18 @@ function listsExitAdapter2(editor, input2, options) {
230229
231617
  }
230230
231618
  };
230231
231619
  }
230232
- var init_lists_adapter = __esm(() => {
231620
+ var init_lists_wrappers = __esm(() => {
230233
231621
  init_wrapper();
230234
231622
  init_errors3();
230235
231623
  init_mutation_helpers();
231624
+ init_plan_wrappers();
230236
231625
  init_index_cache();
230237
231626
  init_tracked_change_refs();
230238
231627
  init_list_item_resolver();
230239
231628
  init_list_numbering_helpers();
230240
231629
  });
230241
231630
 
230242
- // ../../packages/super-editor/src/document-api-adapters/track-changes-adapter.ts
231631
+ // ../../packages/super-editor/src/document-api-adapters/plan-engine/track-changes-wrappers.ts
230243
231632
  function buildTrackChangeInfo2(editor, change) {
230244
231633
  const excerpt = normalizeExcerpt2(editor.state.doc.textBetween(change.from, change.to, " ", ""));
230245
231634
  const type = resolveTrackedChangeType2(change);
@@ -230281,7 +231670,7 @@ function toNoOpReceipt2(message, details) {
230281
231670
  }
230282
231671
  };
230283
231672
  }
230284
- function trackChangesListAdapter2(editor, input2) {
231673
+ function trackChangesListWrapper(editor, input2) {
230285
231674
  const query2 = input2;
230286
231675
  const grouped = filterByType2(groupTrackedChanges2(editor), query2?.type);
230287
231676
  const paged = paginate2(grouped, query2?.offset, query2?.limit);
@@ -230293,277 +231682,341 @@ function trackChangesListAdapter2(editor, input2) {
230293
231682
  changes: changes.length ? changes : undefined
230294
231683
  };
230295
231684
  }
230296
- function trackChangesGetAdapter2(editor, input2) {
231685
+ function trackChangesGetWrapper(editor, input2) {
230297
231686
  const { id: id2 } = input2;
230298
231687
  return buildTrackChangeInfo2(editor, requireTrackChangeById2(editor, id2));
230299
231688
  }
230300
- function trackChangesAcceptAdapter2(editor, input2) {
231689
+ function trackChangesAcceptWrapper(editor, input2, options) {
230301
231690
  const { id: id2 } = input2;
230302
231691
  const change = requireTrackChangeById2(editor, id2);
230303
231692
  const acceptById = requireEditorCommand2(editor.commands?.acceptTrackedChangeById, "Accept tracked change");
230304
- const didAccept = Boolean(acceptById(change.rawId));
230305
- if (didAccept)
230306
- return { success: true };
230307
- return toNoOpReceipt2(`Accept tracked change "${id2}" produced no change.`, { id: id2 });
231693
+ const receipt2 = executeDomainCommand(editor, () => Boolean(acceptById(change.rawId)), {
231694
+ expectedRevision: options?.expectedRevision
231695
+ });
231696
+ if (receipt2.steps[0]?.effect !== "changed") {
231697
+ return toNoOpReceipt2(`Accept tracked change "${id2}" produced no change.`, { id: id2 });
231698
+ }
231699
+ return { success: true };
230308
231700
  }
230309
- function trackChangesRejectAdapter2(editor, input2) {
231701
+ function trackChangesRejectWrapper(editor, input2, options) {
230310
231702
  const { id: id2 } = input2;
230311
231703
  const change = requireTrackChangeById2(editor, id2);
230312
231704
  const rejectById = requireEditorCommand2(editor.commands?.rejectTrackedChangeById, "Reject tracked change");
230313
- const didReject = Boolean(rejectById(change.rawId));
230314
- if (didReject)
230315
- return { success: true };
230316
- return toNoOpReceipt2(`Reject tracked change "${id2}" produced no change.`, { id: id2 });
231705
+ const receipt2 = executeDomainCommand(editor, () => Boolean(rejectById(change.rawId)), {
231706
+ expectedRevision: options?.expectedRevision
231707
+ });
231708
+ if (receipt2.steps[0]?.effect !== "changed") {
231709
+ return toNoOpReceipt2(`Reject tracked change "${id2}" produced no change.`, { id: id2 });
231710
+ }
231711
+ return { success: true };
230317
231712
  }
230318
- function trackChangesAcceptAllAdapter2(editor, _input) {
231713
+ function trackChangesAcceptAllWrapper(editor, _input, options) {
230319
231714
  const acceptAll = requireEditorCommand2(editor.commands?.acceptAllTrackedChanges, "Accept all tracked changes");
230320
231715
  if (groupTrackedChanges2(editor).length === 0) {
230321
231716
  return toNoOpReceipt2("Accept all tracked changes produced no change.");
230322
231717
  }
230323
- const didAcceptAll = Boolean(acceptAll());
230324
- if (didAcceptAll)
230325
- return { success: true };
230326
- return toNoOpReceipt2("Accept all tracked changes produced no change.");
231718
+ const receipt2 = executeDomainCommand(editor, () => Boolean(acceptAll()), {
231719
+ expectedRevision: options?.expectedRevision
231720
+ });
231721
+ if (receipt2.steps[0]?.effect !== "changed") {
231722
+ return toNoOpReceipt2("Accept all tracked changes produced no change.");
231723
+ }
231724
+ return { success: true };
230327
231725
  }
230328
- function trackChangesRejectAllAdapter2(editor, _input) {
231726
+ function trackChangesRejectAllWrapper(editor, _input, options) {
230329
231727
  const rejectAll = requireEditorCommand2(editor.commands?.rejectAllTrackedChanges, "Reject all tracked changes");
230330
231728
  if (groupTrackedChanges2(editor).length === 0) {
230331
231729
  return toNoOpReceipt2("Reject all tracked changes produced no change.");
230332
231730
  }
230333
- const didRejectAll = Boolean(rejectAll());
230334
- if (didRejectAll)
230335
- return { success: true };
230336
- return toNoOpReceipt2("Reject all tracked changes produced no change.");
231731
+ const receipt2 = executeDomainCommand(editor, () => Boolean(rejectAll()), {
231732
+ expectedRevision: options?.expectedRevision
231733
+ });
231734
+ if (receipt2.steps[0]?.effect !== "changed") {
231735
+ return toNoOpReceipt2("Reject all tracked changes produced no change.");
231736
+ }
231737
+ return { success: true };
230337
231738
  }
230338
- var init_track_changes_adapter = __esm(() => {
231739
+ var init_track_changes_wrappers = __esm(() => {
230339
231740
  init_errors3();
230340
231741
  init_mutation_helpers();
231742
+ init_plan_wrappers();
230341
231743
  init_adapter_utils();
230342
231744
  init_tracked_change_resolver();
230343
231745
  });
230344
231746
 
230345
- // ../../packages/super-editor/src/document-api-adapters/write-adapter.ts
230346
- function validateWriteRequest2(request, resolvedTarget) {
230347
- if (request.kind === "insert") {
230348
- if (!request.text) {
230349
- return {
230350
- code: "INVALID_TARGET",
230351
- message: "Insert operations require non-empty text."
231747
+ // ../../packages/super-editor/src/document-api-adapters/plan-engine/preview.ts
231748
+ function previewPlan(editor, input2) {
231749
+ const evaluatedRevision = getRevision(editor);
231750
+ checkRevision(editor, input2.expectedRevision);
231751
+ if (!input2.steps?.length) {
231752
+ throw planError("INVALID_INPUT", "plan must contain at least one step");
231753
+ }
231754
+ const failures = [];
231755
+ const stepPreviews = [];
231756
+ let currentPhase = "compile";
231757
+ try {
231758
+ const compiled = compilePlan(editor, input2.steps);
231759
+ currentPhase = "execute";
231760
+ const tr = editor.state.tr;
231761
+ const { stepOutcomes, assertFailures } = runMutationsOnTransaction(editor, tr, compiled, {
231762
+ throwOnAssertFailure: false
231763
+ });
231764
+ for (const outcome of stepOutcomes) {
231765
+ const preview = {
231766
+ stepId: outcome.stepId,
231767
+ op: outcome.op
230352
231768
  };
231769
+ if (outcome.data && "resolutions" in outcome.data && outcome.data.domain === "text") {
231770
+ preview.resolutions = outcome.data.resolutions;
231771
+ }
231772
+ stepPreviews.push(preview);
230353
231773
  }
230354
- if (resolvedTarget.range.from !== resolvedTarget.range.to) {
230355
- return {
230356
- code: "INVALID_TARGET",
230357
- message: "Insert operations require a collapsed target range."
230358
- };
231774
+ for (const failure of assertFailures) {
231775
+ failures.push({
231776
+ code: "PRECONDITION_FAILED",
231777
+ stepId: failure.stepId,
231778
+ phase: "assert",
231779
+ message: `assert "${failure.stepId}" expected ${failure.expectedCount} matches but found ${failure.actualCount}`,
231780
+ details: { expectedCount: failure.expectedCount, actualCount: failure.actualCount }
231781
+ });
231782
+ }
231783
+ } catch (error) {
231784
+ if (error instanceof PlanError) {
231785
+ failures.push({
231786
+ code: error.code,
231787
+ stepId: error.stepId ?? "",
231788
+ phase: currentPhase,
231789
+ message: error.message,
231790
+ details: error.details
231791
+ });
231792
+ } else {
231793
+ throw error;
230359
231794
  }
230360
- return null;
230361
231795
  }
230362
- if (request.kind === "replace") {
230363
- if (request.text == null || request.text.length === 0) {
230364
- return {
230365
- code: "INVALID_TARGET",
230366
- message: "Replace operations require non-empty text. Use delete for removals."
230367
- };
231796
+ return {
231797
+ evaluatedRevision,
231798
+ steps: stepPreviews,
231799
+ valid: failures.length === 0,
231800
+ failures: failures.length > 0 ? failures : undefined
231801
+ };
231802
+ }
231803
+ var init_preview = __esm(() => {
231804
+ init_revision_tracker();
231805
+ init_compiler();
231806
+ init_executor();
231807
+ init_errors4();
231808
+ });
231809
+
231810
+ // ../../packages/super-editor/src/document-api-adapters/plan-engine/query-match-adapter.ts
231811
+ function buildStyleSummary(captured) {
231812
+ const totalChars = captured.runs.reduce((sum, r2) => sum + r2.charCount, 0);
231813
+ const marks = {};
231814
+ for (const markName of CORE_MARK_NAMES2) {
231815
+ let activeChars = 0;
231816
+ for (const run2 of captured.runs) {
231817
+ if (run2.marks.some((m4) => m4.type.name === markName)) {
231818
+ activeChars += run2.charCount;
231819
+ }
230368
231820
  }
230369
- if (resolvedTarget.resolution.text === request.text) {
230370
- return {
230371
- code: "NO_OP",
230372
- message: "Replace operation produced no change."
230373
- };
231821
+ if (activeChars > 0) {
231822
+ marks[markName] = totalChars > 0 && activeChars > totalChars / 2;
230374
231823
  }
230375
- return null;
230376
231824
  }
230377
- if (resolvedTarget.range.from === resolvedTarget.range.to) {
230378
- return {
230379
- code: "NO_OP",
230380
- message: "Delete operation produced no change for a collapsed range."
230381
- };
231825
+ return { marks, isUniform: captured.isUniform };
231826
+ }
231827
+ function captureMatchStyle(editor, textRanges) {
231828
+ if (!textRanges.length)
231829
+ return;
231830
+ const index2 = getBlockIndex2(editor);
231831
+ const allRuns = [];
231832
+ let allUniform = true;
231833
+ for (const range of textRanges) {
231834
+ const candidate = index2.candidates.find((c2) => c2.nodeId === range.blockId);
231835
+ if (!candidate)
231836
+ continue;
231837
+ const captured = captureRunsInRange(editor, candidate.pos, range.range.start, range.range.end);
231838
+ allRuns.push(...captured.runs);
231839
+ if (!captured.isUniform)
231840
+ allUniform = false;
230382
231841
  }
230383
- return null;
231842
+ if (allUniform && allRuns.length > 1) {
231843
+ const ref2 = allRuns[0].marks;
231844
+ for (let i4 = 1;i4 < allRuns.length; i4++) {
231845
+ const cur = allRuns[i4].marks;
231846
+ if (ref2.length !== cur.length || !ref2.every((m4, j3) => cur[j3] && m4.eq(cur[j3]))) {
231847
+ allUniform = false;
231848
+ break;
231849
+ }
231850
+ }
231851
+ }
231852
+ return buildStyleSummary({ runs: allRuns, isUniform: allUniform });
230384
231853
  }
230385
- function normalizeWriteLocator2(request) {
230386
- if (request.kind === "insert") {
230387
- const hasBlockId = request.blockId !== undefined;
230388
- const hasOffset = request.offset !== undefined;
230389
- if (hasOffset && request.target) {
230390
- throw new DocumentApiAdapterError3("INVALID_TARGET", "Cannot combine target with offset on insert request.", {
230391
- fields: ["target", "offset"]
230392
- });
231854
+ function queryMatchAdapter(editor, input2) {
231855
+ const evaluatedRevision = getRevision(editor);
231856
+ const require2 = input2.require ?? "any";
231857
+ if ((require2 === "first" || require2 === "exactlyOne") && (input2.limit !== undefined || input2.offset !== undefined)) {
231858
+ throw planError("INVALID_INPUT", `limit/offset are not valid when require is "${require2}"`);
231859
+ }
231860
+ const query2 = {
231861
+ select: input2.select,
231862
+ within: input2.within,
231863
+ includeNodes: input2.includeNodes,
231864
+ limit: input2.limit,
231865
+ offset: input2.offset
231866
+ };
231867
+ const result = findAdapter2(editor, query2);
231868
+ const totalMatches = result.total;
231869
+ if (require2 === "first") {
231870
+ if (totalMatches === 0) {
231871
+ throw planError("MATCH_NOT_FOUND", "selector matched zero ranges");
230393
231872
  }
230394
- if (hasOffset && !hasBlockId) {
230395
- throw new DocumentApiAdapterError3("INVALID_TARGET", "offset requires blockId on insert request.", {
230396
- fields: ["offset", "blockId"]
230397
- });
231873
+ } else if (require2 === "exactlyOne") {
231874
+ if (totalMatches === 0) {
231875
+ throw planError("MATCH_NOT_FOUND", "selector matched zero ranges");
230398
231876
  }
230399
- if (!hasBlockId)
230400
- return request;
230401
- if (request.target) {
230402
- throw new DocumentApiAdapterError3("INVALID_TARGET", "Cannot combine target with blockId on insert request.", {
230403
- fields: ["target", "blockId"]
231877
+ if (totalMatches > 1) {
231878
+ throw planError("AMBIGUOUS_MATCH", `selector matched ${totalMatches} ranges, expected exactly one`, undefined, {
231879
+ matchCount: totalMatches
230404
231880
  });
230405
231881
  }
230406
- const effectiveOffset = request.offset ?? 0;
230407
- const target = {
230408
- kind: "text",
230409
- blockId: request.blockId,
230410
- range: { start: effectiveOffset, end: effectiveOffset }
230411
- };
230412
- return { kind: "insert", target, text: request.text };
230413
- }
230414
- if (request.kind === "replace" || request.kind === "delete") {
230415
- const hasBlockId = request.blockId !== undefined;
230416
- const hasStart = request.start !== undefined;
230417
- const hasEnd = request.end !== undefined;
230418
- if (request.target && (hasBlockId || hasStart || hasEnd)) {
230419
- throw new DocumentApiAdapterError3("INVALID_TARGET", `Cannot combine target with blockId/start/end on ${request.kind} request.`, { fields: ["target", "blockId", "start", "end"] });
231882
+ } else if (require2 === "all") {
231883
+ if (totalMatches === 0) {
231884
+ throw planError("MATCH_NOT_FOUND", "selector matched zero ranges");
230420
231885
  }
230421
- if (!hasBlockId && (hasStart || hasEnd)) {
230422
- throw new DocumentApiAdapterError3("INVALID_TARGET", `start/end require blockId on ${request.kind} request.`, {
230423
- fields: ["blockId", "start", "end"]
230424
- });
231886
+ }
231887
+ const matchResults = result.matches.map((address2, idx) => {
231888
+ const matchResult = { address: address2 };
231889
+ const ctx2 = result.context?.[idx];
231890
+ if (ctx2?.textRanges?.length) {
231891
+ matchResult.textRanges = ctx2.textRanges;
230425
231892
  }
230426
- if (!hasBlockId)
230427
- return request;
230428
- if (!hasStart || !hasEnd) {
230429
- throw new DocumentApiAdapterError3("INVALID_TARGET", `blockId requires both start and end on ${request.kind} request.`, { fields: ["blockId", "start", "end"] });
231893
+ if (input2.includeStyle && matchResult.textRanges?.length) {
231894
+ matchResult.style = captureMatchStyle(editor, matchResult.textRanges);
230430
231895
  }
230431
- const target = {
230432
- kind: "text",
230433
- blockId: request.blockId,
230434
- range: { start: request.start, end: request.end }
230435
- };
230436
- if (request.kind === "replace") {
230437
- return { kind: "replace", target, text: request.text };
231896
+ if (input2.select.type === "text") {
231897
+ const refData = {
231898
+ rev: evaluatedRevision,
231899
+ addr: address2,
231900
+ ranges: ctx2?.textRanges
231901
+ };
231902
+ matchResult.ref = `text:${btoa(JSON.stringify(refData))}`;
231903
+ matchResult.refStability = "ephemeral";
231904
+ } else {
231905
+ if (address2.kind === "block") {
231906
+ matchResult.ref = address2.nodeId;
231907
+ matchResult.refStability = "stable";
231908
+ }
230438
231909
  }
230439
- return { kind: "delete", target, text: "" };
230440
- }
230441
- return request;
230442
- }
230443
- function resolveWriteTarget2(editor, request) {
230444
- const requestedTarget = request.target;
230445
- if (request.kind === "insert" && !request.target) {
230446
- const fallback = resolveDefaultInsertTarget2(editor);
230447
- if (!fallback)
230448
- return null;
230449
- const text5 = readTextAtResolvedRange2(editor, fallback.range);
230450
- return {
230451
- requestedTarget,
230452
- effectiveTarget: fallback.target,
230453
- range: fallback.range,
230454
- resolution: buildTextMutationResolution2({
230455
- requestedTarget,
230456
- target: fallback.target,
230457
- range: fallback.range,
230458
- text: text5
230459
- })
230460
- };
230461
- }
230462
- const target = request.target;
230463
- if (!target)
230464
- return null;
230465
- const range = resolveTextTarget2(editor, target);
230466
- if (!range)
230467
- return null;
230468
- const text4 = readTextAtResolvedRange2(editor, range);
231910
+ return matchResult;
231911
+ });
231912
+ const truncated = require2 === "first" ? matchResults.slice(0, 1) : matchResults;
230469
231913
  return {
230470
- requestedTarget,
230471
- effectiveTarget: target,
230472
- range,
230473
- resolution: buildTextMutationResolution2({
230474
- requestedTarget,
230475
- target,
230476
- range,
230477
- text: text4
230478
- })
231914
+ evaluatedRevision,
231915
+ matches: truncated,
231916
+ totalMatches
230479
231917
  };
230480
231918
  }
230481
- function applyDirectWrite2(editor, request, resolvedTarget) {
230482
- if (request.kind === "delete") {
230483
- const tr2 = applyDirectMutationMeta2(editor.state.tr.delete(resolvedTarget.range.from, resolvedTarget.range.to));
230484
- editor.dispatch(tr2);
230485
- return { success: true, resolution: resolvedTarget.resolution };
230486
- }
230487
- const tr = applyDirectMutationMeta2(editor.state.tr.insertText(request.text ?? "", resolvedTarget.range.from, resolvedTarget.range.to));
230488
- editor.dispatch(tr);
230489
- return { success: true, resolution: resolvedTarget.resolution };
230490
- }
230491
- function applyTrackedWrite2(editor, request, resolvedTarget) {
230492
- ensureTrackedCapability2(editor, { operation: "write" });
230493
- const insertTrackedChange = editor.commands.insertTrackedChange;
230494
- const text4 = request.kind === "delete" ? "" : request.text ?? "";
230495
- const changeId = v42();
230496
- const didApply = insertTrackedChange({
230497
- from: resolvedTarget.range.from,
230498
- to: request.kind === "insert" ? resolvedTarget.range.from : resolvedTarget.range.to,
230499
- text: text4,
230500
- id: changeId
231919
+ var CORE_MARK_NAMES2;
231920
+ var init_query_match_adapter = __esm(() => {
231921
+ init_find_adapter();
231922
+ init_index_cache();
231923
+ init_style_resolver();
231924
+ init_revision_tracker();
231925
+ init_errors4();
231926
+ CORE_MARK_NAMES2 = ["bold", "italic", "underline", "strike"];
231927
+ });
231928
+
231929
+ // ../../packages/super-editor/src/document-api-adapters/plan-engine/register-executors.ts
231930
+ function sortTargetsByPosition(targets) {
231931
+ return [...targets].sort((a2, b4) => {
231932
+ if (a2.blockId === b4.blockId)
231933
+ return a2.from - b4.from;
231934
+ return a2.blockId < b4.blockId ? -1 : 1;
230501
231935
  });
230502
- if (!didApply) {
230503
- return {
230504
- success: false,
230505
- resolution: resolvedTarget.resolution,
230506
- failure: {
230507
- code: "NO_OP",
230508
- message: "Tracked write command did not apply a change."
230509
- }
230510
- };
230511
- }
230512
- const publicChangeId = toCanonicalTrackedChangeId2(editor, changeId);
230513
- return {
230514
- success: true,
230515
- resolution: resolvedTarget.resolution,
230516
- ...publicChangeId ? {
230517
- inserted: [
230518
- {
230519
- kind: "entity",
230520
- entityType: "trackedChange",
230521
- entityId: publicChangeId
230522
- }
230523
- ]
230524
- } : {}
230525
- };
230526
231936
  }
230527
- function toFailureReceipt2(failure, resolvedTarget) {
231937
+ function buildTextResolution(target) {
230528
231938
  return {
230529
- success: false,
230530
- resolution: resolvedTarget.resolution,
230531
- failure
231939
+ target: {
231940
+ kind: "text",
231941
+ blockId: target.blockId,
231942
+ range: { start: target.from, end: target.to }
231943
+ },
231944
+ range: { from: target.from, to: target.to },
231945
+ text: target.text
230532
231946
  };
230533
231947
  }
230534
- function writeAdapter2(editor, request, options) {
230535
- const normalizedRequest = normalizeWriteLocator2(request);
230536
- const resolvedTarget = resolveWriteTarget2(editor, normalizedRequest);
230537
- if (!resolvedTarget) {
230538
- throw new DocumentApiAdapterError3("TARGET_NOT_FOUND", "Mutation target could not be resolved.", {
230539
- target: normalizedRequest.target
230540
- });
230541
- }
230542
- const validationFailure = validateWriteRequest2(normalizedRequest, resolvedTarget);
230543
- if (validationFailure) {
230544
- return toFailureReceipt2(validationFailure, resolvedTarget);
230545
- }
230546
- const mode = options?.changeMode ?? "direct";
230547
- if (options?.dryRun) {
230548
- if (mode === "tracked")
230549
- ensureTrackedCapability2(editor, { operation: "write" });
230550
- return { success: true, resolution: resolvedTarget.resolution };
230551
- }
230552
- if (mode === "tracked") {
230553
- return applyTrackedWrite2(editor, normalizedRequest, resolvedTarget);
231948
+ function executeWithTargetIteration(ctx2, targets, step, executeFn) {
231949
+ const sortedTargets = sortTargetsByPosition(targets);
231950
+ let overallChanged = false;
231951
+ const resolutions = [];
231952
+ for (const target of sortedTargets) {
231953
+ resolutions.push(buildTextResolution(target));
231954
+ const { changed } = executeFn(ctx2.editor, ctx2.tr, target, step, ctx2.mapping);
231955
+ if (changed)
231956
+ overallChanged = true;
230554
231957
  }
230555
- return applyDirectWrite2(editor, normalizedRequest, resolvedTarget);
231958
+ const effect2 = overallChanged ? "changed" : "noop";
231959
+ const data = { domain: "text", resolutions };
231960
+ return { stepId: step.id, op: step.op, effect: effect2, matchCount: targets.length, data };
230556
231961
  }
230557
- var init_write_adapter = __esm(() => {
230558
- init_wrapper();
230559
- init_errors3();
230560
- init_mutation_helpers();
230561
- init_adapter_utils();
230562
- init_tracked_change_resolver();
231962
+ function registerBuiltInExecutors() {
231963
+ if (registered)
231964
+ return;
231965
+ registered = true;
231966
+ registerStepExecutor("text.rewrite", {
231967
+ execute: (ctx2, targets, step) => executeWithTargetIteration(ctx2, targets, step, (e, tr, t, s2, m4) => executeTextRewrite(e, tr, t, s2, m4))
231968
+ });
231969
+ registerStepExecutor("text.insert", {
231970
+ execute: (ctx2, targets, step) => executeWithTargetIteration(ctx2, targets, step, (e, tr, t, s2, m4) => executeTextInsert(e, tr, t, s2, m4))
231971
+ });
231972
+ registerStepExecutor("text.delete", {
231973
+ execute: (ctx2, targets, step) => executeWithTargetIteration(ctx2, targets, step, (e, tr, t, s2, m4) => executeTextDelete(e, tr, t, s2, m4))
231974
+ });
231975
+ registerStepExecutor("style.apply", {
231976
+ execute: (ctx2, targets, step) => executeWithTargetIteration(ctx2, targets, step, (e, tr, t, s2, m4) => executeStyleApply(e, tr, t, s2, m4))
231977
+ });
231978
+ registerStepExecutor("create.paragraph", {
231979
+ execute: (ctx2, targets, step) => executeCreateStep(ctx2.editor, ctx2.tr, step, targets, ctx2.mapping)
231980
+ });
231981
+ registerStepExecutor("create.heading", {
231982
+ execute: (ctx2, targets, step) => executeCreateStep(ctx2.editor, ctx2.tr, step, targets, ctx2.mapping)
231983
+ });
231984
+ registerStepExecutor("domain.command", {
231985
+ execute(ctx2, _targets, step) {
231986
+ const handler3 = step._handler;
231987
+ if (!handler3) {
231988
+ return {
231989
+ stepId: step.id,
231990
+ op: step.op,
231991
+ effect: "noop",
231992
+ matchCount: 0,
231993
+ data: { domain: "command", commandDispatched: false }
231994
+ };
231995
+ }
231996
+ const success = handler3();
231997
+ if (success)
231998
+ ctx2.commandDispatched = true;
231999
+ return {
232000
+ stepId: step.id,
232001
+ op: step.op,
232002
+ effect: success ? "changed" : "noop",
232003
+ matchCount: success ? 1 : 0,
232004
+ data: { domain: "command", commandDispatched: success }
232005
+ };
232006
+ }
232007
+ });
232008
+ }
232009
+ var registered = false;
232010
+ var init_register_executors = __esm(() => {
232011
+ init_executor_registry();
232012
+ init_executor();
230563
232013
  });
230564
232014
 
230565
232015
  // ../../packages/super-editor/src/document-api-adapters/index.ts
230566
232016
  function getDocumentApiAdapters2(editor) {
232017
+ registerBuiltInExecutors();
232018
+ initRevision(editor);
232019
+ trackRevisions(editor);
230567
232020
  return {
230568
232021
  find: {
230569
232022
  find: (query2) => findAdapter2(editor, query2)
@@ -230581,51 +232034,62 @@ function getDocumentApiAdapters2(editor) {
230581
232034
  capabilities: {
230582
232035
  get: () => getDocumentApiCapabilities2(editor)
230583
232036
  },
230584
- comments: createCommentsAdapter2(editor),
232037
+ comments: createCommentsWrapper(editor),
230585
232038
  write: {
230586
- write: (request, options) => writeAdapter2(editor, request, options)
232039
+ write: (request, options) => writeWrapper(editor, request, options)
230587
232040
  },
230588
232041
  format: {
230589
- bold: (input2, options) => formatBoldAdapter2(editor, input2, options),
230590
- italic: (input2, options) => formatItalicAdapter2(editor, input2, options),
230591
- underline: (input2, options) => formatUnderlineAdapter2(editor, input2, options),
230592
- strikethrough: (input2, options) => formatStrikethroughAdapter2(editor, input2, options)
232042
+ bold: (input2, options) => formatBoldWrapper(editor, input2, options),
232043
+ italic: (input2, options) => formatItalicWrapper(editor, input2, options),
232044
+ underline: (input2, options) => formatUnderlineWrapper(editor, input2, options),
232045
+ strikethrough: (input2, options) => formatStrikethroughWrapper(editor, input2, options)
230593
232046
  },
230594
232047
  trackChanges: {
230595
- list: (query2) => trackChangesListAdapter2(editor, query2),
230596
- get: (input2) => trackChangesGetAdapter2(editor, input2),
230597
- accept: (input2) => trackChangesAcceptAdapter2(editor, input2),
230598
- reject: (input2) => trackChangesRejectAdapter2(editor, input2),
230599
- acceptAll: (input2) => trackChangesAcceptAllAdapter2(editor, input2),
230600
- rejectAll: (input2) => trackChangesRejectAllAdapter2(editor, input2)
232048
+ list: (query2) => trackChangesListWrapper(editor, query2),
232049
+ get: (input2) => trackChangesGetWrapper(editor, input2),
232050
+ accept: (input2, options) => trackChangesAcceptWrapper(editor, input2, options),
232051
+ reject: (input2, options) => trackChangesRejectWrapper(editor, input2, options),
232052
+ acceptAll: (input2, options) => trackChangesAcceptAllWrapper(editor, input2, options),
232053
+ rejectAll: (input2, options) => trackChangesRejectAllWrapper(editor, input2, options)
230601
232054
  },
230602
232055
  create: {
230603
- paragraph: (input2, options) => createParagraphAdapter2(editor, input2, options),
230604
- heading: (input2, options) => createHeadingAdapter2(editor, input2, options)
232056
+ paragraph: (input2, options) => createParagraphWrapper(editor, input2, options),
232057
+ heading: (input2, options) => createHeadingWrapper(editor, input2, options)
230605
232058
  },
230606
232059
  lists: {
230607
- list: (query2) => listsListAdapter2(editor, query2),
230608
- get: (input2) => listsGetAdapter2(editor, input2),
230609
- insert: (input2, options) => listsInsertAdapter2(editor, input2, options),
230610
- setType: (input2, options) => listsSetTypeAdapter2(editor, input2, options),
230611
- indent: (input2, options) => listsIndentAdapter2(editor, input2, options),
230612
- outdent: (input2, options) => listsOutdentAdapter2(editor, input2, options),
230613
- restart: (input2, options) => listsRestartAdapter2(editor, input2, options),
230614
- exit: (input2, options) => listsExitAdapter2(editor, input2, options)
232060
+ list: (query2) => listsListWrapper(editor, query2),
232061
+ get: (input2) => listsGetWrapper(editor, input2),
232062
+ insert: (input2, options) => listsInsertWrapper(editor, input2, options),
232063
+ setType: (input2, options) => listsSetTypeWrapper(editor, input2, options),
232064
+ indent: (input2, options) => listsIndentWrapper(editor, input2, options),
232065
+ outdent: (input2, options) => listsOutdentWrapper(editor, input2, options),
232066
+ restart: (input2, options) => listsRestartWrapper(editor, input2, options),
232067
+ exit: (input2, options) => listsExitWrapper(editor, input2, options)
232068
+ },
232069
+ query: {
232070
+ match: (input2) => queryMatchAdapter(editor, input2)
232071
+ },
232072
+ mutations: {
232073
+ preview: (input2) => previewPlan(editor, input2),
232074
+ apply: (input2) => executePlan(editor, input2)
230615
232075
  }
230616
232076
  };
230617
232077
  }
230618
232078
  var init_document_api_adapters = __esm(() => {
230619
232079
  init_capabilities_adapter();
230620
- init_comments_adapter();
230621
- init_create_adapter();
232080
+ init_comments_wrappers();
232081
+ init_create_wrappers();
230622
232082
  init_find_adapter();
230623
- init_format_adapter();
232083
+ init_plan_wrappers();
230624
232084
  init_get_node_adapter();
230625
232085
  init_info_adapter();
230626
- init_lists_adapter();
230627
- init_track_changes_adapter();
230628
- init_write_adapter();
232086
+ init_lists_wrappers();
232087
+ init_track_changes_wrappers();
232088
+ init_executor();
232089
+ init_preview();
232090
+ init_query_match_adapter();
232091
+ init_revision_tracker();
232092
+ init_register_executors();
230629
232093
  });
230630
232094
 
230631
232095
  // ../../node_modules/.pnpm/@hocuspocus+common@2.15.3/node_modules/@hocuspocus/common/dist/hocuspocus-common.esm.js
@@ -234568,7 +236032,8 @@ var init_invoke_input = __esm(() => {
234568
236032
  "lists.outdent": "input",
234569
236033
  "lists.restart": "input",
234570
236034
  "lists.exit": "input",
234571
- "create.paragraph": "input"
236035
+ "create.paragraph": "input",
236036
+ "create.heading": "input"
234572
236037
  };
234573
236038
  PARAM_RENAMES = {
234574
236039
  getNodeById: { id: "nodeId" },
@@ -235328,6 +236793,7 @@ function buildDocBackedMetadata() {
235328
236793
  mergedParams.push(param);
235329
236794
  }
235330
236795
  const overrides = PARAM_FLAG_OVERRIDES[cliOpId];
236796
+ const schemaOverrides = PARAM_SCHEMA_OVERRIDES[cliOpId];
235331
236797
  const exclusions = PARAM_EXCLUSIONS[cliOpId];
235332
236798
  for (const param of schemaParams) {
235333
236799
  if (exclusions?.has(param.name))
@@ -235339,6 +236805,9 @@ function buildDocBackedMetadata() {
235339
236805
  if (override.flag)
235340
236806
  param.flag = override.flag;
235341
236807
  }
236808
+ if (schemaOverrides?.[param.name]) {
236809
+ param.schema = schemaOverrides[param.name];
236810
+ }
235342
236811
  if (seenNames.has(param.name))
235343
236812
  continue;
235344
236813
  seenNames.add(param.name);
@@ -235399,7 +236868,7 @@ function deriveOptionSpecs(params4) {
235399
236868
  }
235400
236869
  return specs;
235401
236870
  }
235402
- var DOC_PARAM, SESSION_PARAM, OUT_PARAM, FORCE_PARAM, DRY_RUN_PARAM, CHANGE_MODE_PARAM, EXPECTED_REVISION_PARAM, OPERATION_CONSTRAINTS, PARAM_FLAG_OVERRIDES, PARAM_EXCLUSIONS, EXTRA_CLI_PARAMS, CLI_ONLY_METADATA, CLI_OPERATION_METADATA, CLI_OPERATION_OPTION_SPECS;
236871
+ var DOC_PARAM, SESSION_PARAM, OUT_PARAM, FORCE_PARAM, DRY_RUN_PARAM, CHANGE_MODE_PARAM, EXPECTED_REVISION_PARAM, OPERATION_CONSTRAINTS, PARAM_FLAG_OVERRIDES, PARAM_SCHEMA_OVERRIDES, PARAM_EXCLUSIONS, EXTRA_CLI_PARAMS, CLI_ONLY_METADATA, CLI_OPERATION_METADATA, CLI_OPERATION_OPTION_SPECS;
235403
236872
  var init_operation_params = __esm(() => {
235404
236873
  init_src();
235405
236874
  init_operation_set();
@@ -235485,6 +236954,14 @@ var init_operation_params = __esm(() => {
235485
236954
  address: { flag: "address-json" }
235486
236955
  }
235487
236956
  };
236957
+ PARAM_SCHEMA_OVERRIDES = {
236958
+ "doc.mutations.preview": {
236959
+ steps: { type: "json" }
236960
+ },
236961
+ "doc.mutations.apply": {
236962
+ steps: { type: "json" }
236963
+ }
236964
+ };
235488
236965
  PARAM_EXCLUSIONS = {
235489
236966
  "doc.find": new Set(["select"])
235490
236967
  };
@@ -235511,7 +236988,8 @@ var init_operation_params = __esm(() => {
235511
236988
  "doc.lists.outdent": [{ name: "input", kind: "jsonFlag", flag: "input-json", type: "json" }],
235512
236989
  "doc.lists.restart": [{ name: "input", kind: "jsonFlag", flag: "input-json", type: "json" }],
235513
236990
  "doc.lists.exit": [{ name: "input", kind: "jsonFlag", flag: "input-json", type: "json" }],
235514
- "doc.create.paragraph": [{ name: "input", kind: "jsonFlag", flag: "input-json", type: "json" }]
236991
+ "doc.create.paragraph": [{ name: "input", kind: "jsonFlag", flag: "input-json", type: "json" }],
236992
+ "doc.create.heading": [{ name: "input", kind: "jsonFlag", flag: "input-json", type: "json" }]
235515
236993
  };
235516
236994
  CLI_ONLY_METADATA = {
235517
236995
  "doc.open": {