@prosekit/core 0.0.0-next-20240715071354 → 0.0.0-next-20240724155246

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.
@@ -512,15 +512,36 @@ function defineDefaultState({
512
512
  ]);
513
513
  }
514
514
 
515
+ // src/utils/is-subset.ts
516
+ function isSubset(subset, superset) {
517
+ return Object.keys(subset).every((key) => subset[key] === superset[key]);
518
+ }
519
+
520
+ // src/utils/includes-mark.ts
521
+ function includesMark(marks, markType, attrs) {
522
+ attrs = attrs || {};
523
+ return marks.some((mark) => {
524
+ return mark.type === markType && isSubset(attrs, mark.attrs);
525
+ });
526
+ }
527
+
515
528
  // src/utils/is-mark-absent.ts
516
529
  function isMarkAbsent(node, from, to, markType, attrs) {
517
- const mark = attrs ? markType.create(attrs) : markType;
518
530
  let missing = false;
531
+ let available = false;
519
532
  node.nodesBetween(from, to, (node2, pos, parent) => {
520
- if (missing) return false;
521
- missing = !mark.isInSet(node2.marks) && !!parent && parent.type.allowsMarkType(markType);
533
+ if (missing) {
534
+ return false;
535
+ }
536
+ const allowed = (parent == null ? void 0 : parent.type.allowsMarkType(markType)) && !node2.marks.some((m) => m.type !== markType && m.type.excludes(markType));
537
+ if (allowed) {
538
+ available = true;
539
+ if (!includesMark(node2.marks, markType, attrs)) {
540
+ missing = true;
541
+ }
542
+ }
522
543
  });
523
- return missing;
544
+ return available ? missing : true;
524
545
  }
525
546
 
526
547
  // src/utils/is-mark-active.ts
@@ -528,8 +549,8 @@ function isMarkActive(state, type, attrs) {
528
549
  const { from, $from, to, empty } = state.selection;
529
550
  const markType = getMarkType(state.schema, type);
530
551
  if (empty) {
531
- const mark = attrs ? markType.create(attrs) : markType;
532
- return !!mark.isInSet(state.storedMarks || $from.marks());
552
+ const marks = state.storedMarks || $from.marks();
553
+ return includesMark(marks, markType, attrs);
533
554
  } else {
534
555
  return !isMarkAbsent(state.doc, from, to, markType, attrs);
535
556
  }
@@ -589,12 +610,10 @@ var UnionExtensionImpl = class extends BaseExtension {
589
610
  };
590
611
 
591
612
  // src/editor/union.ts
592
- function union(extension) {
593
- const array = Array.isArray(extension) ? extension : [extension];
594
- assert(array.length > 0, "At least one extension is required");
595
- return new UnionExtensionImpl(
596
- array
597
- );
613
+ function union(...exts) {
614
+ const extensions = exts.flat();
615
+ assert(extensions.length > 0, "At least one extension is required");
616
+ return new UnionExtensionImpl(extensions);
598
617
  }
599
618
 
600
619
  // src/editor/editor.ts
@@ -625,7 +644,7 @@ function deepEquals(a, b) {
625
644
  return false;
626
645
  }
627
646
 
628
- // src/editor/builder.ts
647
+ // src/editor/action.ts
629
648
  import "@prosekit/pm/model";
630
649
 
631
650
  // src/utils/attrs-match.ts
@@ -652,8 +671,8 @@ function isNodeActive(state, type, attrs) {
652
671
  return false;
653
672
  }
654
673
 
655
- // src/editor/builder.ts
656
- function createNodeBuilders(schema, getState, createNode = defaultCreateNode) {
674
+ // src/editor/action.ts
675
+ function createNodeActions(schema, getState, createNode = defaultCreateNode) {
657
676
  const builders = {};
658
677
  for (const type of Object.values(schema.nodes)) {
659
678
  const builder = (...args) => buildNode(type, args, createNode);
@@ -665,7 +684,7 @@ function createNodeBuilders(schema, getState, createNode = defaultCreateNode) {
665
684
  }
666
685
  return builders;
667
686
  }
668
- function createMarkBuilders(schema, getState, applyMark = defaultApplyMark) {
687
+ function createMarkActions(schema, getState, applyMark = defaultApplyMark) {
669
688
  const builders = {};
670
689
  for (const type of Object.values(schema.marks)) {
671
690
  const builder = (...args) => buildMark(type, args, applyMark);
@@ -751,7 +770,7 @@ function createEditor(options) {
751
770
  var EditorInstance = class {
752
771
  constructor(extension) {
753
772
  this.view = null;
754
- this.commandAppliers = {};
773
+ this.commands = {};
755
774
  this.getState = () => {
756
775
  var _a;
757
776
  return ((_a = this.view) == null ? void 0 : _a.state) || this.directEditorProps.state;
@@ -767,8 +786,8 @@ var EditorInstance = class {
767
786
  this.defineCommand(name, commandCreator);
768
787
  }
769
788
  }
770
- this.nodeBuilders = createNodeBuilders(state.schema, this.getState);
771
- this.markBuilders = createMarkBuilders(state.schema, this.getState);
789
+ this.nodes = createNodeActions(state.schema, this.getState);
790
+ this.marks = createMarkActions(state.schema, this.getState);
772
791
  this.schema = state.schema;
773
792
  this.directEditorProps = { state, ...payload.view };
774
793
  }
@@ -852,13 +871,13 @@ var EditorInstance = class {
852
871
  view.setProps({ state: newState });
853
872
  }
854
873
  defineCommand(name, commandCreator) {
855
- const applier = (...args) => {
874
+ const action = (...args) => {
856
875
  const view = this.view;
857
876
  assert(view, `Cannot call command "${name}" before the editor is mounted`);
858
877
  const command = commandCreator(...args);
859
878
  return command(view.state, view.dispatch.bind(view), view);
860
879
  };
861
- applier.canApply = (...args) => {
880
+ action.canApply = (...args) => {
862
881
  const view = this.view;
863
882
  if (!view) {
864
883
  return false;
@@ -866,10 +885,10 @@ var EditorInstance = class {
866
885
  const command = commandCreator(...args);
867
886
  return command(view.state, void 0, view);
868
887
  };
869
- this.commandAppliers[name] = applier;
888
+ this.commands[name] = action;
870
889
  }
871
890
  removeCommand(name) {
872
- delete this.commandAppliers[name];
891
+ delete this.commands[name];
873
892
  }
874
893
  };
875
894
  var Editor = class _Editor {
@@ -910,12 +929,6 @@ var Editor = class _Editor {
910
929
  get schema() {
911
930
  return this.instance.schema;
912
931
  }
913
- /**
914
- * All commands defined by the editor.
915
- */
916
- get commands() {
917
- return this.instance.commandAppliers;
918
- }
919
932
  /**
920
933
  * Whether the editor is focused.
921
934
  */
@@ -995,11 +1008,23 @@ var Editor = class _Editor {
995
1008
  updateState(state) {
996
1009
  this.instance.updateState(state);
997
1010
  }
1011
+ /**
1012
+ * All {@link CommandAction}s defined by the editor.
1013
+ */
1014
+ get commands() {
1015
+ return this.instance.commands;
1016
+ }
1017
+ /**
1018
+ * All {@link NodeAction}s defined by the editor.
1019
+ */
998
1020
  get nodes() {
999
- return this.instance.nodeBuilders;
1021
+ return this.instance.nodes;
1000
1022
  }
1023
+ /**
1024
+ * All {@link MarkAction}s defined by the editor.
1025
+ */
1001
1026
  get marks() {
1002
- return this.instance.markBuilders;
1027
+ return this.instance.marks;
1003
1028
  }
1004
1029
  };
1005
1030
 
@@ -1037,8 +1062,8 @@ export {
1037
1062
  isTextSelection,
1038
1063
  isNodeSelection,
1039
1064
  isAllSelection,
1040
- createNodeBuilders,
1041
- createMarkBuilders,
1065
+ createNodeActions,
1066
+ createMarkActions,
1042
1067
  union,
1043
1068
  setupEditorExtension,
1044
1069
  createEditor,
@@ -2,10 +2,10 @@ import {
2
2
  Editor,
3
3
  EditorInstance,
4
4
  assert,
5
- createMarkBuilders,
6
- createNodeBuilders,
5
+ createMarkActions,
6
+ createNodeActions,
7
7
  setupEditorExtension
8
- } from "./chunk-UDQXAK7F.js";
8
+ } from "./chunk-MOSGJZHV.js";
9
9
 
10
10
  // src/test/test-editor.ts
11
11
  import { EditorState, NodeSelection, TextSelection } from "@prosekit/pm/state";
@@ -82,16 +82,8 @@ function getSelection(doc) {
82
82
  var TestEditorInstance = class extends EditorInstance {
83
83
  constructor(extension) {
84
84
  super(extension);
85
- this.nodeBuilders = createNodeBuilders(
86
- this.schema,
87
- this.getState,
88
- createNodeForTest
89
- );
90
- this.markBuilders = createMarkBuilders(
91
- this.schema,
92
- this.getState,
93
- applyMarkForTest
94
- );
85
+ this.nodes = createNodeActions(this.schema, this.getState, createNodeForTest);
86
+ this.marks = createMarkActions(this.schema, this.getState, applyMarkForTest);
95
87
  }
96
88
  };
97
89
  var TestEditor = class extends Editor {
@@ -22,8 +22,11 @@ export { unsetMark } from './_tsup-dts-rollup';
22
22
  export { UnsetMarkOptions } from './_tsup-dts-rollup';
23
23
  export { wrap } from './_tsup-dts-rollup';
24
24
  export { WrapOptions } from './_tsup-dts-rollup';
25
+ export { MarkAction } from './_tsup-dts-rollup';
25
26
  export { MarkBuilder } from './_tsup-dts-rollup';
27
+ export { NodeAction } from './_tsup-dts-rollup';
26
28
  export { NodeBuilder } from './_tsup-dts-rollup';
29
+ export { NodeChild } from './_tsup-dts-rollup';
27
30
  export { Editor } from './_tsup-dts-rollup';
28
31
  export { createEditor } from './_tsup-dts-rollup';
29
32
  export { EditorOptions } from './_tsup-dts-rollup';
@@ -101,26 +104,39 @@ export { defineText } from './_tsup-dts-rollup';
101
104
  export { defineFacet } from './_tsup-dts-rollup';
102
105
  export { Facet } from './_tsup-dts-rollup';
103
106
  export { defineFacetPayload } from './_tsup-dts-rollup';
107
+ export { AnyAttrs } from './_tsup-dts-rollup';
108
+ export { AttrSpec } from './_tsup-dts-rollup';
104
109
  export { BaseNodeViewOptions } from './_tsup-dts-rollup';
105
- export { CommandTyping } from './_tsup-dts-rollup';
106
110
  export { Extension } from './_tsup-dts-rollup';
107
111
  export { ExtensionTyping } from './_tsup-dts-rollup';
112
+ export { ExtractCommandActions } from './_tsup-dts-rollup';
108
113
  export { ExtractCommandAppliers } from './_tsup-dts-rollup';
109
114
  export { ExtractCommandCreators } from './_tsup-dts-rollup';
115
+ export { ExtractMarkActions } from './_tsup-dts-rollup';
110
116
  export { ExtractMarks } from './_tsup-dts-rollup';
117
+ export { ExtractNodeActions } from './_tsup-dts-rollup';
111
118
  export { ExtractNodes } from './_tsup-dts-rollup';
112
119
  export { UnionExtension } from './_tsup-dts-rollup';
120
+ export { CommandAction } from './_tsup-dts-rollup';
121
+ export { CommandTyping } from './_tsup-dts-rollup';
122
+ export { MarkTyping } from './_tsup-dts-rollup';
123
+ export { ToMarkAction } from './_tsup-dts-rollup';
124
+ export { NodeTyping } from './_tsup-dts-rollup';
125
+ export { ToNodeAction } from './_tsup-dts-rollup';
113
126
  export { NodeJSON } from './_tsup-dts-rollup';
114
127
  export { SelectionJSON } from './_tsup-dts-rollup';
115
128
  export { StateJSON } from './_tsup-dts-rollup';
116
129
  export { StepJSON } from './_tsup-dts-rollup';
130
+ export { PickSubType } from './_tsup-dts-rollup';
117
131
  export { Priority } from './_tsup-dts-rollup';
132
+ export { SimplifyDeeper } from './_tsup-dts-rollup';
118
133
  export { SimplifyUnion } from './_tsup-dts-rollup';
119
134
  export { assert } from './_tsup-dts-rollup';
120
135
  export { canUseRegexLookbehind } from './_tsup-dts-rollup';
121
136
  export { clsx } from './_tsup-dts-rollup';
122
137
  export { collectNodes } from './_tsup-dts-rollup';
123
138
  export { NodeContent } from './_tsup-dts-rollup';
139
+ export { containsInlineNode } from './_tsup-dts-rollup';
124
140
  export { defaultBlockAt } from './_tsup-dts-rollup';
125
141
  export { isApple } from './_tsup-dts-rollup';
126
142
  export { _getId } from './_tsup-dts-rollup';
@@ -35,11 +35,10 @@ import {
35
35
  stateFromJSON,
36
36
  toReversed,
37
37
  union
38
- } from "./chunk-UDQXAK7F.js";
38
+ } from "./chunk-MOSGJZHV.js";
39
39
 
40
40
  // src/commands/add-mark.ts
41
41
  import "@prosekit/pm/model";
42
- import "@prosekit/pm/state";
43
42
  function addMark(options) {
44
43
  return (state, dispatch) => {
45
44
  var _a, _b;
@@ -108,7 +107,6 @@ function expandMarkAfter($pos, predicate) {
108
107
  }
109
108
 
110
109
  // src/commands/insert-node.ts
111
- import "@prosekit/pm/state";
112
110
  import { insertPoint } from "@prosekit/pm/transform";
113
111
 
114
112
  // src/utils/set-selection-around.ts
@@ -143,7 +141,6 @@ function insertNode(options) {
143
141
 
144
142
  // src/commands/remove-mark.ts
145
143
  import "@prosekit/pm/model";
146
- import "@prosekit/pm/state";
147
144
  function removeMark(options) {
148
145
  return (state, dispatch) => {
149
146
  var _a, _b;
@@ -192,9 +189,6 @@ function removeNode(options) {
192
189
  };
193
190
  }
194
191
 
195
- // src/commands/set-block-type.ts
196
- import "@prosekit/pm/state";
197
-
198
192
  // src/utils/get-custom-selection.ts
199
193
  import { TextSelection as TextSelection3 } from "@prosekit/pm/state";
200
194
  function getCustomSelection(state, from, to) {
@@ -366,7 +360,6 @@ function toggleMark({ type, attrs }) {
366
360
  // src/commands/toggle-node.ts
367
361
  import { setBlockType as setBlockType2 } from "@prosekit/pm/commands";
368
362
  import "@prosekit/pm/model";
369
- import "@prosekit/pm/state";
370
363
  function toggleNode({ type, attrs }) {
371
364
  return (state, dispatch, view) => {
372
365
  if (isNodeActive(state, type, attrs)) {
@@ -426,7 +419,6 @@ function unsetTextBlockType(tr, from, to) {
426
419
  }
427
420
 
428
421
  // src/commands/unset-mark.ts
429
- import "@prosekit/pm/state";
430
422
  function unsetMark(options) {
431
423
  return (state, dispatch) => {
432
424
  var _a, _b;
@@ -440,7 +432,6 @@ function unsetMark(options) {
440
432
 
441
433
  // src/commands/wrap.ts
442
434
  import "@prosekit/pm/model";
443
- import "@prosekit/pm/state";
444
435
  import { findWrapping } from "@prosekit/pm/transform";
445
436
  function wrap({ nodeType, attrs }) {
446
437
  return (state, dispatch) => {
@@ -554,16 +545,16 @@ function defineNodeAttr(options) {
554
545
  }
555
546
  var nodeSpecFacet = defineFacet({
556
547
  reducer: (payloads) => {
557
- let nodes = OrderedMap2.from({});
548
+ let specs = OrderedMap2.from({});
558
549
  let topNodeName = void 0;
559
550
  const specPayloads = payloads.map((input) => input[0]).filter(isNotNull);
560
551
  const attrPayloads = payloads.map((input) => input[1]).filter(isNotNull);
561
552
  for (const { name, topNode, ...spec } of specPayloads) {
562
- assert(!nodes.get(name), `Node type ${name} can only be defined once`);
553
+ assert(!specs.get(name), `Node type ${name} can only be defined once`);
563
554
  if (topNode) {
564
555
  topNodeName = name;
565
556
  }
566
- nodes = nodes.addToStart(name, spec);
557
+ specs = specs.addToStart(name, spec);
567
558
  }
568
559
  for (const {
569
560
  type,
@@ -573,7 +564,7 @@ var nodeSpecFacet = defineFacet({
573
564
  toDOM,
574
565
  parseDOM
575
566
  } of attrPayloads) {
576
- const spec = nodes.get(type);
567
+ const spec = specs.get(type);
577
568
  assert(spec, `Node type ${type} must be defined`);
578
569
  if (!spec.attrs) {
579
570
  spec.attrs = {};
@@ -638,7 +629,7 @@ var nodeSpecFacet = defineFacet({
638
629
  }
639
630
  }
640
631
  }
641
- return { nodes, topNode: topNodeName };
632
+ return { nodes: specs, topNode: topNodeName };
642
633
  },
643
634
  parent: schemaSpecFacet,
644
635
  singleton: true
@@ -1071,6 +1062,7 @@ function defineBaseKeymap(options) {
1071
1062
  }
1072
1063
 
1073
1064
  // src/extensions/mark-spec.ts
1065
+ import OrderedMap3 from "orderedmap";
1074
1066
  function defineMarkSpec(options) {
1075
1067
  const payload = [options, void 0];
1076
1068
  return defineFacetPayload(markSpecFacet, [payload]);
@@ -1081,14 +1073,12 @@ function defineMarkAttr(options) {
1081
1073
  }
1082
1074
  var markSpecFacet = defineFacet({
1083
1075
  reducer: (payloads) => {
1084
- const marks = {};
1076
+ let specs = OrderedMap3.from({});
1085
1077
  const specPayloads = payloads.map((input) => input[0]).filter(isNotNull);
1086
1078
  const attrPayloads = payloads.map((input) => input[1]).filter(isNotNull);
1087
1079
  for (const { name, ...spec } of specPayloads) {
1088
- if (marks[name]) {
1089
- throw new ProseKitError(`Mark type ${name} has already been defined`);
1090
- }
1091
- marks[name] = spec;
1080
+ assert(!specs.get(name), `Mark type ${name} can only be defined once`);
1081
+ specs = specs.addToStart(name, spec);
1092
1082
  }
1093
1083
  for (const {
1094
1084
  type,
@@ -1097,12 +1087,8 @@ var markSpecFacet = defineFacet({
1097
1087
  toDOM,
1098
1088
  parseDOM
1099
1089
  } of attrPayloads) {
1100
- const spec = marks[type];
1101
- if (!spec) {
1102
- throw new ProseKitError(
1103
- `Mark type ${type} must be defined before defining attributes`
1104
- );
1105
- }
1090
+ const spec = specs.get(type);
1091
+ assert(spec, `Mark type ${type} must be defined`);
1106
1092
  if (!spec.attrs) {
1107
1093
  spec.attrs = {};
1108
1094
  }
@@ -1155,7 +1141,7 @@ var markSpecFacet = defineFacet({
1155
1141
  }
1156
1142
  }
1157
1143
  }
1158
- return { marks, nodes: {} };
1144
+ return { marks: specs, nodes: {} };
1159
1145
  },
1160
1146
  parent: schemaSpecFacet,
1161
1147
  singleton: true
@@ -1163,7 +1149,6 @@ var markSpecFacet = defineFacet({
1163
1149
 
1164
1150
  // src/extensions/node-view.ts
1165
1151
  import { PluginKey as PluginKey5, ProseMirrorPlugin as ProseMirrorPlugin5 } from "@prosekit/pm/state";
1166
- import "@prosekit/pm/view";
1167
1152
  function defineNodeView(options) {
1168
1153
  return defineFacetPayload(nodeViewFacet, [options]);
1169
1154
  }
@@ -1187,7 +1172,6 @@ var nodeViewFacet = defineFacet({
1187
1172
 
1188
1173
  // src/extensions/node-view-effect.ts
1189
1174
  import { PluginKey as PluginKey6, ProseMirrorPlugin as ProseMirrorPlugin6 } from "@prosekit/pm/state";
1190
- import "@prosekit/pm/view";
1191
1175
  function defineNodeViewFactory(options) {
1192
1176
  const input = [options, null];
1193
1177
  return defineFacetPayload(nodeViewFactoryFacet, [input]);
@@ -1285,6 +1269,16 @@ function collectNodes(content) {
1285
1269
  throw new ProseKitError(`Invalid node content: ${typeof content}`);
1286
1270
  }
1287
1271
 
1272
+ // src/utils/contains-inline-node.ts
1273
+ function containsInlineNode(doc, from, to) {
1274
+ let found = false;
1275
+ doc.nodesBetween(from, to, (node) => {
1276
+ if (found) return false;
1277
+ if (node.isInline) found = true;
1278
+ });
1279
+ return found;
1280
+ }
1281
+
1288
1282
  // src/utils/default-block-at.ts
1289
1283
  function defaultBlockAt(match) {
1290
1284
  for (let i = 0; i < match.edgeCount; i++) {
@@ -1346,6 +1340,7 @@ export {
1346
1340
  canUseRegexLookbehind,
1347
1341
  clsx,
1348
1342
  collectNodes,
1343
+ containsInlineNode,
1349
1344
  createEditor,
1350
1345
  defaultBlockAt,
1351
1346
  defineBaseCommands,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@prosekit/core",
3
3
  "type": "module",
4
- "version": "0.0.0-next-20240715071354",
4
+ "version": "0.0.0-next-20240724155246",
5
5
  "private": false,
6
6
  "author": {
7
7
  "name": "ocavue",
@@ -43,13 +43,13 @@
43
43
  "clsx": "^2.1.1",
44
44
  "orderedmap": "^2.1.1",
45
45
  "prosemirror-splittable": "^0.1.1",
46
- "type-fest": "^4.21.0",
47
- "@prosekit/pm": "^0.0.0-next-20240715071354"
46
+ "type-fest": "^4.23.0",
47
+ "@prosekit/pm": "^0.0.0-next-20240724155246"
48
48
  },
49
49
  "devDependencies": {
50
- "tsup": "^8.1.0",
50
+ "tsup": "^8.2.2",
51
51
  "typescript": "^5.5.3",
52
- "vitest": "^2.0.2",
52
+ "vitest": "^2.0.4",
53
53
  "@prosekit/dev": "0.0.0"
54
54
  },
55
55
  "scripts": {