@prosekit/core 0.4.2 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -107,6 +107,13 @@ function expandMarkAfter($pos, predicate) {
107
107
  import "@prosekit/pm/state";
108
108
  import { insertPoint } from "@prosekit/pm/transform";
109
109
 
110
+ // src/utils/assert.ts
111
+ function assert(condition, message = "Assertion failed") {
112
+ if (!condition) {
113
+ throw new ProseKitError(message);
114
+ }
115
+ }
116
+
110
117
  // src/utils/get-node-type.ts
111
118
  import "@prosekit/pm/model";
112
119
  function getNodeType(schema, type) {
@@ -133,10 +140,8 @@ function setSelectionAround(tr, pos) {
133
140
  function insertNode(options) {
134
141
  return (state, dispatch) => {
135
142
  var _a;
136
- const node = options.node ? options.node : options.type ? getNodeType(state.schema, options.type).createChecked(options.attrs) : null;
137
- if (!node) {
138
- throw new ProseKitError("You must provide either a node or a type");
139
- }
143
+ const node = options.node ? options.node : options.type ? getNodeType(state.schema, options.type).createAndFill(options.attrs) : null;
144
+ assert(node, "You must provide either a node or a type");
140
145
  const insertPos = insertPoint(
141
146
  state.doc,
142
147
  (_a = options.pos) != null ? _a : state.selection.to,
@@ -228,20 +233,38 @@ function setBlockType(options) {
228
233
  };
229
234
  }
230
235
 
236
+ // src/utils/get-node-types.ts
237
+ import "@prosekit/pm/model";
238
+ function getNodeTypes(schema, types) {
239
+ if (Array.isArray(types)) {
240
+ return types.map((type) => getNodeType(schema, type));
241
+ }
242
+ return [getNodeType(schema, types)];
243
+ }
244
+
231
245
  // src/commands/set-node-attrs.ts
232
246
  function setNodeAttrs(options) {
233
247
  return (state, dispatch) => {
234
- var _a;
235
- const nodeType = getNodeType(state.schema, options.type);
236
- const pos = (_a = options.pos) != null ? _a : state.selection.$from.before();
237
- const node = state.doc.nodeAt(pos);
238
- if (!node || node.type !== nodeType) {
248
+ var _a, _b;
249
+ const nodeTypes = getNodeTypes(state.schema, options.type);
250
+ const from = (_a = options.pos) != null ? _a : state.selection.from;
251
+ const to = (_b = options.pos) != null ? _b : state.selection.to;
252
+ const positions = [];
253
+ state.doc.nodesBetween(from, to, (node, pos) => {
254
+ if (nodeTypes.includes(node.type)) {
255
+ positions.push(pos);
256
+ }
257
+ if (!dispatch && positions.length > 0) {
258
+ return false;
259
+ }
260
+ });
261
+ if (positions.length === 0) {
239
262
  return false;
240
263
  }
241
264
  if (dispatch) {
242
265
  const { tr } = state;
243
- for (const [key, value] of Object.entries(options.attrs)) {
244
- if (value !== void 0) {
266
+ for (const pos of positions) {
267
+ for (const [key, value] of Object.entries(options.attrs)) {
245
268
  tr.setNodeAttribute(pos, key, value);
246
269
  }
247
270
  }
@@ -383,14 +406,27 @@ function toggleNode({
383
406
  }
384
407
 
385
408
  // src/editor/editor.ts
386
- import { Schema as Schema6 } from "@prosekit/pm/model";
409
+ import "@prosekit/pm/model";
387
410
  import { EditorState as EditorState2 } from "@prosekit/pm/state";
388
411
  import { EditorView } from "@prosekit/pm/view";
389
412
 
390
413
  // src/extensions/default-state.ts
391
414
  import { Selection } from "@prosekit/pm/state";
392
415
 
393
- // src/utils/uniq-array.ts
416
+ // src/types/priority.ts
417
+ var Priority = /* @__PURE__ */ ((Priority2) => {
418
+ Priority2[Priority2["lowest"] = 0] = "lowest";
419
+ Priority2[Priority2["low"] = 1] = "low";
420
+ Priority2[Priority2["default"] = 2] = "default";
421
+ Priority2[Priority2["high"] = 3] = "high";
422
+ Priority2[Priority2["highest"] = 4] = "highest";
423
+ return Priority2;
424
+ })(Priority || {});
425
+
426
+ // src/facets/base-extension.ts
427
+ import "@prosekit/pm/model";
428
+
429
+ // src/utils/array.ts
394
430
  function uniqPush(prev, next) {
395
431
  const result = [...prev];
396
432
  for (const item of next) {
@@ -400,84 +436,268 @@ function uniqPush(prev, next) {
400
436
  }
401
437
  return result;
402
438
  }
403
- function uniqRemove(prev, next) {
404
- const result = [...prev];
405
- for (const item of next) {
406
- const index = result.indexOf(item);
407
- if (index !== -1) {
408
- result.splice(index, 1);
409
- }
410
- }
411
- return result;
439
+ function arraySubstract(a, b) {
440
+ return a.filter((x) => !b.includes(x));
441
+ }
442
+ function toReversed(arr) {
443
+ var _a, _b;
444
+ return (_b = (_a = arr.toReversed) == null ? void 0 : _a.call(arr)) != null ? _b : [...arr].reverse();
412
445
  }
413
446
 
414
- // src/facets/base-extension.ts
415
- import "@prosekit/pm/model";
416
- var BaseExtension = class {
417
- constructor() {
418
- this.extension = [];
447
+ // src/facets/facet-node.ts
448
+ function zip5(a, b, mapper) {
449
+ return [
450
+ mapper(a[0], b[0]),
451
+ mapper(a[1], b[1]),
452
+ mapper(a[2], b[2]),
453
+ mapper(a[3], b[3]),
454
+ mapper(a[4], b[4])
455
+ ];
456
+ }
457
+ function unionInput(a, b) {
458
+ if (!a && !b)
459
+ return null;
460
+ return uniqPush(a != null ? a : [], b != null ? b : []);
461
+ }
462
+ function subtractInput(a, b) {
463
+ if (!a)
464
+ return null;
465
+ if (!b)
466
+ return [];
467
+ return arraySubstract(a, b);
468
+ }
469
+ function unionChildren(a, b) {
470
+ const merged = new Map(a);
471
+ for (const [key, valueB] of b.entries()) {
472
+ const valueA = a.get(key);
473
+ merged.set(key, valueA ? unionFacetNode(valueA, valueB) : valueB);
474
+ }
475
+ return merged;
476
+ }
477
+ function subtractChildren(a, b) {
478
+ const merged = new Map(a);
479
+ for (const [key, valueB] of b.entries()) {
480
+ const valueA = a.get(key);
481
+ merged.set(key, valueA ? subtractFacetNode(valueA, valueB) : valueB);
482
+ }
483
+ return merged;
484
+ }
485
+ function unionFacetNode(a, b) {
486
+ assert(a.facet === b.facet);
487
+ return new FacetNode(
488
+ a.facet,
489
+ zip5(a.inputs, b.inputs, unionInput),
490
+ unionChildren(a.children, b.children)
491
+ );
492
+ }
493
+ function subtractFacetNode(a, b) {
494
+ assert(a.facet === b.facet);
495
+ return new FacetNode(
496
+ a.facet,
497
+ zip5(a.inputs, b.inputs, subtractInput),
498
+ subtractChildren(a.children, b.children)
499
+ );
500
+ }
501
+ var FacetNode = class {
502
+ constructor(facet, inputs = [null, null, null, null, null], children = /* @__PURE__ */ new Map()) {
503
+ this.facet = facet;
504
+ this.inputs = inputs;
505
+ this.children = children;
506
+ this.reducers = [null, null, null, null, null];
507
+ this.output = null;
508
+ }
509
+ calcOutput() {
510
+ var _a, _b, _c;
511
+ const inputs = [null, null, null, null, null];
512
+ const output = [null, null, null, null, null];
513
+ for (let pri = 0; pri < 5; pri++) {
514
+ const input = this.inputs[pri];
515
+ if (input) {
516
+ inputs[pri] = [...input];
517
+ }
518
+ }
519
+ for (const child of this.children.values()) {
520
+ const childOutput = child.getOutput();
521
+ for (let pri = 0; pri < 5; pri++) {
522
+ if (childOutput[pri]) {
523
+ const input = inputs[pri] || (inputs[pri] = []);
524
+ input.push(childOutput[pri]);
525
+ }
526
+ }
527
+ }
528
+ if (this.facet.singleton) {
529
+ const reducer = (_a = this.reducers)[_b = 2 /* default */] || (_a[_b] = this.facet.reducer);
530
+ const input = inputs.filter(Boolean).flat();
531
+ output[2 /* default */] = reducer(input);
532
+ } else {
533
+ for (let pri = 0; pri < 5; pri++) {
534
+ const input = inputs[pri];
535
+ if (input) {
536
+ const reducer = (_c = this.reducers)[pri] || (_c[pri] = this.facet.reducer);
537
+ output[pri] = reducer(input);
538
+ }
539
+ }
540
+ }
541
+ return output;
542
+ }
543
+ getOutput() {
544
+ if (!this.output) {
545
+ this.output = this.calcOutput();
546
+ }
547
+ return this.output;
548
+ }
549
+ getSingletonOutput() {
550
+ assert(this.facet.singleton);
551
+ return this.getOutput()[2 /* default */];
552
+ }
553
+ getRootOutput() {
554
+ assert(this.isRoot());
555
+ const output = this.getSingletonOutput();
556
+ assert(output);
557
+ return output;
558
+ }
559
+ isRoot() {
560
+ return !this.facet.parent;
419
561
  }
420
562
  };
421
563
 
564
+ // src/facets/schema.ts
565
+ import { Schema as Schema4 } from "@prosekit/pm/model";
566
+
422
567
  // src/facets/facet.ts
423
568
  var facetCount = 0;
424
- function getFacetCount() {
425
- return facetCount;
426
- }
427
- var Facet = class _Facet {
428
- constructor(converter, next, singleton) {
569
+ var Facet = class {
570
+ /**
571
+ * @internal
572
+ */
573
+ constructor(parent, singleton, _reducer, _reduce) {
574
+ this._reducer = _reducer;
575
+ this._reduce = _reduce;
429
576
  /**
430
577
  * @internal
431
578
  */
432
579
  this.index = facetCount++;
433
- /**
434
- * @internal
435
- */
436
- this.isSchema = false;
437
- this.converter = converter;
438
- this.next = next;
580
+ assert((_reduce || _reducer) && !(_reduce && _reducer));
581
+ this.parent = parent;
439
582
  this.singleton = singleton;
583
+ this.path = parent ? [...parent.path, this.index] : [];
440
584
  }
441
- static define({
442
- converter,
443
- convert,
444
- next,
445
- singleton
446
- }) {
447
- const converterFunction = converter ? converter : convert ? () => ({
448
- create: convert,
449
- update: convert
450
- }) : null;
451
- if (!converterFunction) {
452
- throw new ProseKitError("Facet must have either 'convert' or 'converter'");
453
- }
454
- return new _Facet(converterFunction, next, singleton != null ? singleton : false);
585
+ get reducer() {
586
+ var _a, _b;
587
+ return (_b = this._reducer) != null ? _b : (_a = this._reduce) == null ? void 0 : _a.call(this);
588
+ }
589
+ };
590
+ function defineFacet(options) {
591
+ var _a;
592
+ return new Facet(
593
+ options.parent,
594
+ (_a = options.singleton) != null ? _a : false,
595
+ options.reducer,
596
+ options.reduce
597
+ );
598
+ }
599
+
600
+ // src/facets/root.ts
601
+ function rootReducer(inputs) {
602
+ var _a;
603
+ let schema;
604
+ let commands;
605
+ let stateFunc;
606
+ let view;
607
+ for (const input of inputs) {
608
+ schema = input.schema || schema;
609
+ commands = input.commands || commands;
610
+ stateFunc = input.state || stateFunc;
611
+ view = input.view || view;
612
+ }
613
+ const state = schema && ((_a = stateFunc == null ? void 0 : stateFunc({ schema })) != null ? _a : { schema });
614
+ return { schema, state, commands, view };
615
+ }
616
+ var rootFacet = new Facet(
617
+ null,
618
+ true,
619
+ rootReducer
620
+ );
621
+
622
+ // src/facets/schema.ts
623
+ var schemaFacet = defineFacet({
624
+ reducer: (specs) => {
625
+ assert(specs.length <= 1);
626
+ const spec = specs[0];
627
+ const schema = spec ? new Schema4(spec) : null;
628
+ return { schema };
629
+ },
630
+ parent: rootFacet,
631
+ singleton: true
632
+ });
633
+
634
+ // src/facets/base-extension.ts
635
+ var BaseExtension = class {
636
+ constructor() {
637
+ this.extension = [];
638
+ this.trees = [null, null, null, null, null];
455
639
  }
456
640
  /**
457
641
  * @internal
458
642
  */
459
- static defineRootFacet(options) {
460
- return _Facet.define(options);
643
+ getTree(priority) {
644
+ var _a, _b;
645
+ const pri = (_a = priority != null ? priority : this.priority) != null ? _a : 2 /* default */;
646
+ return (_b = this.trees)[pri] || (_b[pri] = this.createTree(pri));
647
+ }
648
+ /**
649
+ * @internal
650
+ */
651
+ findFacetOutput(facet) {
652
+ var _a;
653
+ let node = this.getTree();
654
+ for (const index of facet.path) {
655
+ node = node == null ? void 0 : node.children.get(index);
656
+ }
657
+ return (_a = node == null ? void 0 : node.getOutput()) != null ? _a : null;
461
658
  }
462
- extension(payloads) {
463
- return new FacetExtensionImpl(this, payloads);
659
+ get schema() {
660
+ var _a, _b;
661
+ const output = this.findFacetOutput(schemaFacet);
662
+ return (_b = (_a = output == null ? void 0 : output.find(Boolean)) == null ? void 0 : _a.schema) != null ? _b : null;
464
663
  }
465
664
  };
665
+
666
+ // src/facets/facet-extension.ts
466
667
  var FacetExtensionImpl = class extends BaseExtension {
668
+ /**
669
+ * @internal
670
+ */
467
671
  constructor(facet, payloads) {
468
- var _a;
469
672
  super();
470
673
  this.facet = facet;
471
674
  this.payloads = payloads;
472
- this.schema = null;
473
- this.hasSchema = !!(facet.isSchema || ((_a = facet.next) == null ? void 0 : _a.isSchema));
675
+ }
676
+ /**
677
+ * @internal
678
+ */
679
+ createTree(priority) {
680
+ var _a;
681
+ const pri = (_a = this.priority) != null ? _a : priority;
682
+ const inputs = [null, null, null, null, null];
683
+ inputs[pri] = [...this.payloads];
684
+ let node = new FacetNode(this.facet, inputs);
685
+ while (node.facet.parent) {
686
+ const children = /* @__PURE__ */ new Map([[node.facet.index, node]]);
687
+ node = new FacetNode(node.facet.parent, void 0, children);
688
+ }
689
+ return node;
474
690
  }
475
691
  };
692
+ function defineFacetPayload(facet, payloads) {
693
+ return new FacetExtensionImpl(facet, payloads);
694
+ }
476
695
 
477
696
  // src/facets/state.ts
478
- var stateFacet = Facet.defineRootFacet({
479
- convert: (callbacks) => {
480
- return (ctx) => {
697
+ var stateFacet = defineFacet({
698
+ reduce: () => {
699
+ let callbacks = [];
700
+ const state = (ctx) => {
481
701
  var _a, _b, _c, _d, _e, _f;
482
702
  const configs = callbacks.map((cb) => cb(ctx));
483
703
  const config = {
@@ -492,17 +712,22 @@ var stateFacet = Facet.defineRootFacet({
492
712
  config.storedMarks = [...config.storedMarks, ...(_d = c.storedMarks) != null ? _d : []];
493
713
  config.plugins = uniqPush((_e = config.plugins) != null ? _e : [], (_f = c.plugins) != null ? _f : []);
494
714
  }
495
- if (!config.doc && !config.schema) {
496
- throw new ProseKitError(
497
- "Can't create state without a schema nor a document"
498
- );
499
- }
715
+ assert(
716
+ config.doc || config.schema,
717
+ "Can't create state without a schema nor a document"
718
+ );
500
719
  if (config.doc) {
501
720
  config.schema = void 0;
502
721
  }
503
722
  return config;
504
723
  };
505
- }
724
+ return function reducer(inputs) {
725
+ callbacks = inputs;
726
+ return { state };
727
+ };
728
+ },
729
+ singleton: true,
730
+ parent: rootFacet
506
731
  });
507
732
 
508
733
  // src/utils/parse.ts
@@ -618,7 +843,7 @@ function defineDefaultState({
618
843
  "Only one of defaultHTML and defaultDoc can be provided"
619
844
  );
620
845
  }
621
- return stateFacet.extension([
846
+ return defineFacetPayload(stateFacet, [
622
847
  ({ schema }) => {
623
848
  const config = {};
624
849
  if (defaultHTML) {
@@ -639,220 +864,27 @@ function defineDefaultState({
639
864
  ]);
640
865
  }
641
866
 
642
- // src/types/priority.ts
643
- var Priority = /* @__PURE__ */ ((Priority2) => {
644
- Priority2[Priority2["lowest"] = 4] = "lowest";
645
- Priority2[Priority2["low"] = 3] = "low";
646
- Priority2[Priority2["default"] = 2] = "default";
647
- Priority2[Priority2["high"] = 1] = "high";
648
- Priority2[Priority2["highest"] = 0] = "highest";
649
- return Priority2;
650
- })(Priority || {});
651
-
652
- // src/facets/command.ts
653
- var commandFacet = Facet.defineRootFacet({
654
- convert: (inputs) => {
655
- return Object.assign({}, ...inputs);
656
- }
657
- });
658
-
659
- // src/facets/schema.ts
867
+ // src/utils/deep-equals.ts
660
868
  import OrderedMap from "orderedmap";
661
- var schemaFacet = Facet.defineRootFacet({
662
- convert: (specs) => {
663
- var _a;
664
- let nodes = OrderedMap.from({});
665
- let marks = OrderedMap.from({});
666
- let topNode = void 0;
667
- for (const spec of specs) {
668
- nodes = nodes.append(spec.nodes);
669
- marks = marks.append((_a = spec.marks) != null ? _a : {});
670
- topNode = topNode != null ? topNode : spec.topNode;
671
- }
672
- return { nodes, marks, topNode };
869
+ function deepEquals(a, b) {
870
+ if (a === b) {
871
+ return true;
673
872
  }
674
- });
675
- schemaFacet.isSchema = true;
676
-
677
- // src/facets/view.ts
678
- var viewFacet = Facet.defineRootFacet({
679
- convert: (props) => {
680
- return Object.assign({}, ...props);
873
+ if (!a || !b) {
874
+ return false;
681
875
  }
682
- });
683
-
684
- // src/facets/flatten.ts
685
- function flattenInputTuple(inputTuple) {
686
- return [
687
- ...inputTuple[0],
688
- ...inputTuple[1],
689
- ...inputTuple[2],
690
- ...inputTuple[3],
691
- ...inputTuple[4]
692
- ];
693
- }
694
- function mergeInputTuple(tupleA, tupleB) {
695
- if (!tupleA)
696
- return tupleB;
697
- if (!tupleB)
698
- return tupleA;
699
- const [a0, a1, a2, a3, a4] = tupleA;
700
- const [b0, b1, b2, b3, b4] = tupleB;
701
- return [
702
- uniqPush(a0, b0),
703
- uniqPush(a1, b1),
704
- uniqPush(a2, b2),
705
- uniqPush(a3, b3),
706
- uniqPush(a4, b4)
707
- ];
708
- }
709
- function removeInputTuple(tupleA, tupleB) {
710
- if (!tupleA)
711
- return [[], [], [], [], []];
712
- if (!tupleB)
713
- return tupleA;
714
- const [a0, a1, a2, a3, a4] = tupleA;
715
- const [b0, b1, b2, b3, b4] = tupleB;
716
- return [
717
- uniqRemove(a0, b0),
718
- uniqRemove(a1, b1),
719
- uniqRemove(a2, b2),
720
- uniqRemove(a3, b3),
721
- uniqRemove(a4, b4)
722
- ];
723
- }
724
- function extractFacets(root) {
725
- var _a;
726
- const extensions = [root];
727
- const priorities = [2 /* default */];
728
- const facets = [];
729
- const payloads = [];
730
- while (extensions.length > 0) {
731
- const ext = extensions.pop();
732
- const pri = priorities.pop();
733
- if (ext instanceof FacetExtensionImpl) {
734
- const facet = ext.facet;
735
- if (!facets[facet.index]) {
736
- facets[facet.index] = facet;
737
- payloads[facet.index] = [[], [], [], [], []];
738
- }
739
- const facetPayloads = ext.payloads;
740
- payloads[facet.index][pri].push(...facetPayloads);
741
- } else if (ext.extension) {
742
- const p = (_a = ext.priority) != null ? _a : pri;
743
- if (Array.isArray(ext.extension)) {
744
- for (const e of ext.extension) {
745
- extensions.push(e);
746
- priorities.push(p);
747
- }
748
- } else {
749
- extensions.push(ext.extension);
750
- priorities.push(p);
751
- }
752
- } else {
753
- throw new ProseKitError("Invalid extension");
754
- }
876
+ if (Array.isArray(a) && Array.isArray(b)) {
877
+ return a.length === b.length && a.every((x, i) => deepEquals(x, b[i]));
755
878
  }
756
- return [facets, payloads];
757
- }
758
- function updateExtension(prevInputs, prevConverters, extension, mode) {
759
- var _a;
760
- const modifyInputTuple = mode === "add" ? mergeInputTuple : removeInputTuple;
761
- const [facets, inputs] = extractFacets(extension);
762
- let schemaInput = null;
763
- let stateInput = null;
764
- let viewInput = null;
765
- let commandInput = null;
766
- for (let index = getFacetCount(); index >= 0; index--) {
767
- const facet = facets[index];
768
- if (!facet) {
769
- continue;
770
- }
771
- const nextFacet = facet.next;
772
- if (nextFacet) {
773
- facets[_a = nextFacet.index] || (facets[_a] = nextFacet);
774
- }
775
- if (!inputs[facet.index]) {
776
- continue;
777
- }
778
- const inputTuple = modifyInputTuple(prevInputs[index], inputs[index]);
779
- prevInputs[index] = inputTuple;
780
- if (facet.next && !facet.singleton) {
781
- let hasOutput = false;
782
- const outputTuple = [[], [], [], [], []];
783
- for (let pri = 0; pri < 5; pri++) {
784
- const inputArray = inputTuple[pri];
785
- if (inputArray.length === 0) {
786
- continue;
787
- }
788
- const converterTuple = prevConverters[index] || (prevConverters[index] = [
789
- void 0,
790
- void 0,
791
- void 0,
792
- void 0,
793
- void 0
794
- ]);
795
- const prevConverter = converterTuple[pri];
796
- const converter = prevConverter || facet.converter();
797
- prevConverters[index][pri] = converter;
798
- const output = prevConverter ? converter.update(inputArray) : converter.create(inputArray);
799
- if (!output) {
800
- continue;
801
- }
802
- hasOutput = true;
803
- outputTuple[pri].push(output);
804
- }
805
- if (!hasOutput) {
806
- continue;
807
- }
808
- inputs[facet.next.index] = modifyInputTuple(
809
- inputs[facet.next.index],
810
- outputTuple
811
- );
812
- continue;
813
- } else {
814
- const inputArray = flattenInputTuple(inputTuple);
815
- prevConverters[index] || (prevConverters[index] = [
816
- void 0,
817
- void 0,
818
- void 0,
819
- void 0,
820
- void 0
821
- ]);
822
- const prevConverter = prevConverters[index][2 /* default */];
823
- const converter = prevConverter || facet.converter();
824
- prevConverters[index][2 /* default */] = converter;
825
- const output = prevConverter ? converter.update(inputArray) : converter.create(inputArray);
826
- if (!output) {
827
- continue;
828
- }
829
- if (facet.next) {
830
- const outputTuple = [[], [], [output], [], []];
831
- inputs[facet.next.index] = modifyInputTuple(
832
- inputs[facet.next.index],
833
- outputTuple
834
- );
835
- } else {
836
- switch (facet) {
837
- case schemaFacet:
838
- schemaInput = output;
839
- break;
840
- case stateFacet:
841
- stateInput = output;
842
- break;
843
- case viewFacet:
844
- viewInput = output;
845
- break;
846
- case commandFacet:
847
- commandInput = output;
848
- break;
849
- default:
850
- throw new ProseKitError("Invalid root facet");
851
- }
852
- }
853
- }
879
+ if (a instanceof OrderedMap && b instanceof OrderedMap) {
880
+ return a.size === b.size && deepEquals(a.toObject(), b.toObject());
881
+ }
882
+ if (typeof a === "object" && typeof b === "object") {
883
+ const aKeys = Object.keys(a);
884
+ const bKeys = Object.keys(b);
885
+ return aKeys.length === bKeys.length && aKeys.every((key) => deepEquals(a[key], b[key]));
854
886
  }
855
- return { schemaInput, stateInput, viewInput, commandInput };
887
+ return false;
856
888
  }
857
889
 
858
890
  // src/editor/builder.ts
@@ -970,43 +1002,27 @@ function isNodeChild(value) {
970
1002
  }
971
1003
 
972
1004
  // src/facets/union-extension.ts
973
- import { Schema as Schema5 } from "@prosekit/pm/model";
974
1005
  var UnionExtensionImpl = class extends BaseExtension {
1006
+ /**
1007
+ * @internal
1008
+ */
975
1009
  constructor(extension = []) {
976
1010
  super();
977
1011
  this.extension = extension;
978
- this._schema = void 0;
979
- this.hasSchemaCount = 0;
980
- for (const e of extension) {
981
- if (e instanceof BaseExtension) {
982
- this.hasSchemaCount += e.hasSchema ? 1 : 0;
983
- } else {
984
- throw new ProseKitError("Invalid extension");
985
- }
986
- }
987
1012
  }
988
- get hasSchema() {
989
- return this.hasSchemaCount > 0;
990
- }
991
- get schema() {
1013
+ /**
1014
+ * @internal
1015
+ */
1016
+ createTree(priority) {
992
1017
  var _a;
993
- if (this._schema !== void 0) {
994
- return this._schema;
995
- }
996
- if (this.hasSchemaCount === 0) {
997
- this._schema = null;
998
- return this._schema;
999
- }
1000
- if (this.hasSchemaCount === 1) {
1001
- const schema = (_a = this.extension.find((e) => e.hasSchema)) == null ? void 0 : _a.schema;
1002
- if (schema) {
1003
- this._schema = schema;
1004
- return this._schema;
1005
- }
1006
- }
1007
- const { schemaInput } = updateExtension([], [], this, "add");
1008
- this._schema = schemaInput ? new Schema5(schemaInput) : null;
1009
- return this._schema;
1018
+ const pri = (_a = this.priority) != null ? _a : priority;
1019
+ const extensions = [...this.extension];
1020
+ extensions.sort((a, b) => {
1021
+ var _a2, _b;
1022
+ return ((_a2 = a.priority) != null ? _a2 : pri) - ((_b = b.priority) != null ? _b : pri);
1023
+ });
1024
+ const children = extensions.map((ext) => ext.getTree(pri));
1025
+ return children.reduce(unionFacetNode, new FacetNode(rootFacet));
1010
1026
  }
1011
1027
  };
1012
1028
 
@@ -1038,24 +1054,21 @@ var EditorInstance = class {
1038
1054
  constructor(extension) {
1039
1055
  this.view = null;
1040
1056
  this.commandAppliers = {};
1041
- this.payloads = [];
1042
- this.converters = [];
1043
1057
  this.mount = this.mount.bind(this);
1044
1058
  this.unmount = this.unmount.bind(this);
1045
- const { schemaInput, stateInput, viewInput, commandInput } = updateExtension(this.payloads, this.converters, extension, "add");
1046
- if (!schemaInput) {
1047
- throw new ProseKitError("Schema must be defined");
1048
- }
1049
- const schema = new Schema6(schemaInput);
1050
- const stateConfig = stateInput ? stateInput({ schema }) : { schema };
1059
+ this.tree = extension.getTree();
1060
+ const payload = this.tree.getRootOutput();
1061
+ const schema = payload.schema;
1062
+ const stateConfig = payload.state;
1063
+ assert(schema && stateConfig, "Schema must be defined");
1051
1064
  const state = EditorState2.create(stateConfig);
1052
1065
  this.cachedState = state;
1053
- if (commandInput) {
1054
- for (const [name, commandCreator] of Object.entries(commandInput)) {
1066
+ if (payload.commands) {
1067
+ for (const [name, commandCreator] of Object.entries(payload.commands)) {
1055
1068
  this.defineCommand(name, commandCreator);
1056
1069
  }
1057
1070
  }
1058
- this.directEditorProps = { state, ...viewInput };
1071
+ this.directEditorProps = { state, ...payload.view };
1059
1072
  this.schema = this.directEditorProps.state.schema;
1060
1073
  const getState = () => this.getState();
1061
1074
  this.nodeBuilders = Object.fromEntries(
@@ -1077,29 +1090,31 @@ var EditorInstance = class {
1077
1090
  }
1078
1091
  return this.cachedState;
1079
1092
  }
1080
- updateExtension(extension, mode) {
1081
- var _a;
1082
- const { schemaInput, stateInput, viewInput, commandInput } = updateExtension(this.payloads, this.converters, extension, mode);
1083
- if (schemaInput) {
1093
+ updateExtension(extension, add) {
1094
+ var _a, _b, _c, _d, _e;
1095
+ const tree = extension.getTree();
1096
+ const payload = tree.getRootOutput();
1097
+ if (payload == null ? void 0 : payload.schema) {
1084
1098
  throw new ProseKitError("Schema cannot be changed");
1085
1099
  }
1086
- if (viewInput) {
1100
+ if (payload == null ? void 0 : payload.view) {
1087
1101
  throw new ProseKitError("View cannot be changed");
1088
1102
  }
1089
- const plugins = (_a = stateInput == null ? void 0 : stateInput({ schema: this.schema })) == null ? void 0 : _a.plugins;
1090
- if (plugins && plugins.length > 0) {
1091
- if (!this.view) {
1092
- throw new ProseKitError(
1093
- "Unexpected inner state: EditorInstance.view is not defined"
1094
- );
1095
- }
1096
- const state = this.view.state.reconfigure({ plugins });
1103
+ const oldPayload = this.tree.getRootOutput();
1104
+ const oldPlugins = [...(_c = (_b = (_a = this.view) == null ? void 0 : _a.state) == null ? void 0 : _b.plugins) != null ? _c : []];
1105
+ this.tree = add ? unionFacetNode(this.tree, tree) : subtractFacetNode(this.tree, tree);
1106
+ const newPayload = this.tree.getRootOutput();
1107
+ const newPlugins = [...(_e = (_d = newPayload == null ? void 0 : newPayload.state) == null ? void 0 : _d.plugins) != null ? _e : []];
1108
+ if (!deepEquals(oldPlugins, newPlugins)) {
1109
+ assert(this.view, "EditorInstance.view is not defined");
1110
+ const state = this.view.state.reconfigure({ plugins: newPlugins });
1097
1111
  this.view.updateState(state);
1098
1112
  }
1099
- if (commandInput) {
1100
- const names = Object.keys(commandInput);
1113
+ if ((newPayload == null ? void 0 : newPayload.commands) && !deepEquals(oldPayload == null ? void 0 : oldPayload.commands, newPayload == null ? void 0 : newPayload.commands)) {
1114
+ const commands = newPayload.commands;
1115
+ const names = Object.keys(commands);
1101
1116
  for (const name of names) {
1102
- this.defineCommand(name, commandInput[name]);
1117
+ this.defineCommand(name, commands[name]);
1103
1118
  }
1104
1119
  }
1105
1120
  }
@@ -1253,8 +1268,8 @@ var Editor = class _Editor {
1253
1268
  lazyRemove == null ? void 0 : lazyRemove();
1254
1269
  };
1255
1270
  }
1256
- this.instance.updateExtension(extension, "add");
1257
- return () => this.instance.updateExtension(extension, "remove");
1271
+ this.instance.updateExtension(extension, true);
1272
+ return () => this.instance.updateExtension(extension, false);
1258
1273
  }
1259
1274
  get state() {
1260
1275
  return this.instance.getState();
@@ -1318,9 +1333,19 @@ function wrap({
1318
1333
  };
1319
1334
  }
1320
1335
 
1336
+ // src/facets/command.ts
1337
+ var commandFacet = defineFacet({
1338
+ reducer: (inputs) => {
1339
+ const commands = Object.assign({}, ...inputs);
1340
+ return { commands };
1341
+ },
1342
+ parent: rootFacet,
1343
+ singleton: true
1344
+ });
1345
+
1321
1346
  // src/extensions/command.ts
1322
1347
  function defineCommands(commands) {
1323
- return commandFacet.extension([commands]);
1348
+ return defineFacetPayload(commandFacet, [commands]);
1324
1349
  }
1325
1350
  function defineBaseCommands() {
1326
1351
  return defineCommands({
@@ -1335,6 +1360,29 @@ function defineBaseCommands() {
1335
1360
  });
1336
1361
  }
1337
1362
 
1363
+ // src/extensions/node-spec.ts
1364
+ import OrderedMap3 from "orderedmap";
1365
+
1366
+ // src/facets/schema-spec.ts
1367
+ import "@prosekit/pm/model";
1368
+ import OrderedMap2 from "orderedmap";
1369
+ var schemaSpecFacet = defineFacet({
1370
+ reducer: (specs) => {
1371
+ var _a;
1372
+ let nodes = OrderedMap2.from({});
1373
+ let marks = OrderedMap2.from({});
1374
+ let topNode = void 0;
1375
+ for (const spec of specs) {
1376
+ nodes = nodes.append(spec.nodes);
1377
+ marks = marks.append((_a = spec.marks) != null ? _a : {});
1378
+ topNode = topNode != null ? topNode : spec.topNode;
1379
+ }
1380
+ return { nodes, marks, topNode };
1381
+ },
1382
+ parent: schemaFacet,
1383
+ singleton: true
1384
+ });
1385
+
1338
1386
  // src/utils/is-element.ts
1339
1387
  var hasElement = typeof Element !== "undefined";
1340
1388
  function isElement(value) {
@@ -1349,44 +1397,39 @@ function isNotNull(value) {
1349
1397
  // src/extensions/node-spec.ts
1350
1398
  function defineNodeSpec(options) {
1351
1399
  const payload = [options, void 0];
1352
- return nodeSpecFacet.extension([payload]);
1400
+ return defineFacetPayload(nodeSpecFacet, [payload]);
1353
1401
  }
1354
1402
  function defineNodeAttr(options) {
1355
1403
  const payload = [void 0, options];
1356
- return nodeSpecFacet.extension([payload]);
1404
+ return defineFacetPayload(nodeSpecFacet, [payload]);
1357
1405
  }
1358
- var nodeSpecFacet = Facet.define({
1359
- convert: (payloads) => {
1360
- const nodes = {};
1406
+ var nodeSpecFacet = defineFacet({
1407
+ reducer: (payloads) => {
1408
+ let nodes = OrderedMap3.from({});
1361
1409
  let topNodeName = void 0;
1362
1410
  const specPayloads = payloads.map((input) => input[0]).filter(isNotNull);
1363
1411
  const attrPayloads = payloads.map((input) => input[1]).filter(isNotNull);
1364
1412
  for (const { name, topNode, ...spec } of specPayloads) {
1365
- if (nodes[name]) {
1366
- throw new ProseKitError(`Node type ${name} has already been defined`);
1367
- }
1413
+ assert(!nodes.get(name), `Node type ${name} can only be defined once`);
1368
1414
  if (topNode) {
1369
1415
  topNodeName = name;
1370
1416
  }
1371
- nodes[name] = spec;
1417
+ nodes = nodes.addToStart(name, spec);
1372
1418
  }
1373
1419
  for (const {
1374
1420
  type,
1375
1421
  attr,
1376
1422
  default: defaultValue,
1423
+ splittable,
1377
1424
  toDOM,
1378
1425
  parseDOM
1379
1426
  } of attrPayloads) {
1380
- const spec = nodes[type];
1381
- if (!spec) {
1382
- throw new ProseKitError(
1383
- `Node type ${type} must be defined before defining attributes`
1384
- );
1385
- }
1427
+ const spec = nodes.get(type);
1428
+ assert(spec, `Node type ${type} must be defined`);
1386
1429
  if (!spec.attrs) {
1387
1430
  spec.attrs = {};
1388
1431
  }
1389
- spec.attrs[attr] = { default: defaultValue };
1432
+ spec.attrs[attr] = { default: defaultValue, splittable };
1390
1433
  if (toDOM && spec.toDOM) {
1391
1434
  const existingToDom = spec.toDOM;
1392
1435
  spec.toDOM = (node) => {
@@ -1404,14 +1447,22 @@ var nodeSpecFacet = Facet.define({
1404
1447
  }
1405
1448
  if (Array.isArray(dom)) {
1406
1449
  if (typeof dom[1] === "object") {
1407
- return [dom[0], { ...dom[1], [key]: value }, ...dom.slice(2)];
1450
+ return [
1451
+ dom[0],
1452
+ setObjectAttribute(
1453
+ dom[1],
1454
+ key,
1455
+ value
1456
+ ),
1457
+ ...dom.slice(2)
1458
+ ];
1408
1459
  } else {
1409
1460
  return [dom[0], { [key]: value }, ...dom.slice(1)];
1410
1461
  }
1411
1462
  } else if (isElement(dom)) {
1412
- dom.setAttribute(key, value);
1463
+ setElementAttribute(dom, key, value);
1413
1464
  } else if (typeof dom === "object" && "dom" in dom && isElement(dom.dom)) {
1414
- dom.dom.setAttribute(key, value);
1465
+ setElementAttribute(dom.dom, key, value);
1415
1466
  }
1416
1467
  return dom;
1417
1468
  };
@@ -1437,9 +1488,21 @@ var nodeSpecFacet = Facet.define({
1437
1488
  }
1438
1489
  return { nodes, topNode: topNodeName };
1439
1490
  },
1440
- next: schemaFacet,
1491
+ parent: schemaSpecFacet,
1441
1492
  singleton: true
1442
1493
  });
1494
+ function setObjectAttribute(obj, key, value) {
1495
+ if (key === "style") {
1496
+ value = `${value}${obj.style || ""}`;
1497
+ }
1498
+ return { ...obj, [key]: value };
1499
+ }
1500
+ function setElementAttribute(element, key, value) {
1501
+ if (key === "style") {
1502
+ value = `${value}${element.getAttribute("style") || ""}`;
1503
+ }
1504
+ element.setAttribute(key, value);
1505
+ }
1443
1506
 
1444
1507
  // src/extensions/doc.ts
1445
1508
  function defineDoc() {
@@ -1451,60 +1514,61 @@ function defineDoc() {
1451
1514
  }
1452
1515
 
1453
1516
  // src/extensions/events/plugin-view.ts
1454
- import { PluginKey, ProseMirrorPlugin } from "@prosekit/pm/state";
1517
+ import { PluginKey, ProseMirrorPlugin as ProseMirrorPlugin2 } from "@prosekit/pm/state";
1455
1518
 
1456
1519
  // src/extensions/plugin.ts
1457
1520
  import "@prosekit/pm/model";
1458
1521
  import { Plugin as Plugin2 } from "@prosekit/pm/state";
1459
1522
  function definePlugin(plugin) {
1460
1523
  if (plugin instanceof Plugin2) {
1461
- return pluginFacet.extension([() => [plugin]]);
1524
+ return defineFacetPayload(pluginFacet, [() => [plugin]]);
1462
1525
  }
1463
1526
  if (Array.isArray(plugin) && plugin.every((p) => p instanceof Plugin2)) {
1464
- return pluginFacet.extension([() => plugin]);
1527
+ return defineFacetPayload(pluginFacet, [() => plugin]);
1465
1528
  }
1466
1529
  if (typeof plugin === "function") {
1467
- return pluginFacet.extension([plugin]);
1530
+ return defineFacetPayload(pluginFacet, [plugin]);
1468
1531
  }
1469
1532
  throw new TypeError("Invalid plugin");
1470
1533
  }
1471
- var pluginFacet = Facet.define({
1472
- converter: () => {
1473
- let inputs = [];
1474
- const output = ({ schema }) => {
1475
- const plugins = inputs.flatMap((func) => func({ schema }));
1476
- return { plugins };
1477
- };
1478
- return {
1479
- create: (payloads) => {
1480
- inputs = payloads;
1481
- return output;
1482
- },
1483
- update: (payloads) => {
1484
- inputs = payloads;
1485
- return output;
1534
+ var pluginFacet = defineFacet({
1535
+ reducer: (payloads) => {
1536
+ return ({ schema }) => {
1537
+ const plugins = [];
1538
+ for (const payload of payloads) {
1539
+ if (payload instanceof Plugin2) {
1540
+ plugins.push(payload);
1541
+ } else if (Array.isArray(payload) && payload.every((p) => p instanceof Plugin2)) {
1542
+ plugins.push(...payload);
1543
+ } else if (typeof payload === "function") {
1544
+ plugins.push(...[payload({ schema })].flat());
1545
+ } else {
1546
+ throw new ProseKitError("Invalid plugin");
1547
+ }
1486
1548
  }
1549
+ plugins.reverse();
1550
+ return { plugins };
1487
1551
  };
1488
1552
  },
1489
- next: stateFacet
1553
+ parent: stateFacet
1490
1554
  });
1491
1555
 
1492
1556
  // src/extensions/events/plugin-view.ts
1493
1557
  function defineMountHandler(handler) {
1494
- return pluginViewFacet.extension([["mount", handler]]);
1558
+ return defineFacetPayload(pluginViewFacet, [["mount", handler]]);
1495
1559
  }
1496
1560
  function defineUpdateHandler(handler) {
1497
- return pluginViewFacet.extension([["update", handler]]);
1561
+ return defineFacetPayload(pluginViewFacet, [["update", handler]]);
1498
1562
  }
1499
1563
  function defineUnmountHandler(handler) {
1500
- return pluginViewFacet.extension([["unmount", handler]]);
1564
+ return defineFacetPayload(pluginViewFacet, [["unmount", handler]]);
1501
1565
  }
1502
- var pluginViewFacet = Facet.define({
1503
- converter: () => {
1566
+ var pluginViewFacet = defineFacet({
1567
+ reduce: () => {
1504
1568
  let mountHandlers = [];
1505
1569
  let updateHandlers = [];
1506
1570
  let unmountHandlers = [];
1507
- const plugin = new ProseMirrorPlugin({
1571
+ const plugin = new ProseMirrorPlugin2({
1508
1572
  key: pluginKey,
1509
1573
  view: (view) => {
1510
1574
  mountHandlers.forEach((fn) => fn(view));
@@ -1518,7 +1582,6 @@ var pluginViewFacet = Facet.define({
1518
1582
  };
1519
1583
  }
1520
1584
  });
1521
- const pluginFunc = () => [plugin];
1522
1585
  const register = (input) => {
1523
1586
  mountHandlers = [];
1524
1587
  updateHandlers = [];
@@ -1537,18 +1600,12 @@ var pluginViewFacet = Facet.define({
1537
1600
  }
1538
1601
  }
1539
1602
  };
1540
- return {
1541
- create: (input) => {
1542
- register(input);
1543
- return pluginFunc;
1544
- },
1545
- update: (input) => {
1546
- register(input);
1547
- return null;
1548
- }
1603
+ return function reducer(input) {
1604
+ register(input);
1605
+ return plugin;
1549
1606
  };
1550
1607
  },
1551
- next: pluginFacet,
1608
+ parent: pluginFacet,
1552
1609
  singleton: true
1553
1610
  });
1554
1611
  var pluginKey = new PluginKey("prosekit-plugin-view-handler");
@@ -1563,13 +1620,13 @@ function defineDocChangeHandler(handler) {
1563
1620
  }
1564
1621
 
1565
1622
  // src/extensions/events/dom-event.ts
1566
- import { PluginKey as PluginKey2, ProseMirrorPlugin as ProseMirrorPlugin2 } from "@prosekit/pm/state";
1623
+ import { PluginKey as PluginKey2, ProseMirrorPlugin as ProseMirrorPlugin3 } from "@prosekit/pm/state";
1567
1624
 
1568
1625
  // src/utils/combine-event-handlers.ts
1569
1626
  function combineEventHandlers() {
1570
1627
  let _handlers = [];
1571
1628
  function setHandlers(handlers) {
1572
- _handlers = handlers;
1629
+ _handlers = toReversed(handlers);
1573
1630
  }
1574
1631
  function combinedEventHandler(...args) {
1575
1632
  for (const handler of _handlers) {
@@ -1598,106 +1655,97 @@ function groupEntries(entries) {
1598
1655
 
1599
1656
  // src/extensions/events/dom-event.ts
1600
1657
  function defineDOMEventHandler(event, handler) {
1601
- return domEventFacet.extension([
1658
+ return defineFacetPayload(domEventFacet, [
1602
1659
  [event, handler]
1603
1660
  ]);
1604
1661
  }
1605
- var domEventFacet = Facet.define({
1606
- converter: () => {
1662
+ var domEventFacet = defineFacet({
1663
+ reduce: () => {
1607
1664
  const setHandlersMap = {};
1608
1665
  const combinedHandlerMap = {};
1666
+ let plugin = null;
1609
1667
  const update = (payloads) => {
1668
+ var _a;
1610
1669
  let hasNewEvent = false;
1611
1670
  for (const [event] of payloads) {
1612
1671
  if (!setHandlersMap[event]) {
1613
1672
  hasNewEvent = true;
1614
1673
  const [setHandlers, combinedHandler] = combineEventHandlers();
1615
1674
  setHandlersMap[event] = setHandlers;
1616
- combinedHandlerMap[event] = combinedHandler;
1675
+ const e = (view, eventObject) => {
1676
+ return combinedHandler(view, eventObject);
1677
+ };
1678
+ combinedHandlerMap[event] = e;
1617
1679
  }
1618
1680
  }
1619
1681
  const map = groupEntries(payloads);
1620
- for (const [event, handlers] of Object.entries(map)) {
1621
- const setHandlers = setHandlersMap[event];
1622
- setHandlers(handlers != null ? handlers : []);
1682
+ for (const [event, setHandlers] of Object.entries(setHandlersMap)) {
1683
+ const handlers = (_a = map[event]) != null ? _a : [];
1684
+ setHandlers(handlers);
1623
1685
  }
1624
1686
  if (hasNewEvent) {
1625
- return new ProseMirrorPlugin2({
1687
+ plugin = new ProseMirrorPlugin3({
1626
1688
  key: new PluginKey2("prosekit-dom-event-handler"),
1627
1689
  props: { handleDOMEvents: combinedHandlerMap }
1628
1690
  });
1629
- } else {
1630
- return null;
1631
1691
  }
1632
1692
  };
1633
- return {
1634
- create: (payloads) => {
1635
- const plugin = update(payloads);
1636
- return plugin ? () => plugin : () => [];
1637
- },
1638
- update: (payloads) => {
1639
- const plugin = update(payloads);
1640
- return plugin ? () => plugin : null;
1641
- }
1693
+ return function reducer(inputs) {
1694
+ update(inputs);
1695
+ return plugin != null ? plugin : [];
1642
1696
  };
1643
1697
  },
1644
- next: pluginFacet,
1698
+ parent: pluginFacet,
1645
1699
  singleton: true
1646
1700
  });
1647
1701
 
1648
1702
  // src/extensions/events/editor-event.ts
1649
- import { PluginKey as PluginKey3, ProseMirrorPlugin as ProseMirrorPlugin3 } from "@prosekit/pm/state";
1703
+ import { PluginKey as PluginKey3, ProseMirrorPlugin as ProseMirrorPlugin4 } from "@prosekit/pm/state";
1650
1704
  function defineKeyDownHandler(handler) {
1651
- return editorEventFacet.extension([["keyDown", handler]]);
1705
+ return defineFacetPayload(editorEventFacet, [["keyDown", handler]]);
1652
1706
  }
1653
1707
  function defineKeyPressHandler(handler) {
1654
- return editorEventFacet.extension([["keyPress", handler]]);
1708
+ return defineFacetPayload(editorEventFacet, [["keyPress", handler]]);
1655
1709
  }
1656
1710
  function defineTextInputHandler(handler) {
1657
- return editorEventFacet.extension([["textInput", handler]]);
1711
+ return defineFacetPayload(editorEventFacet, [["textInput", handler]]);
1658
1712
  }
1659
1713
  function defineClickOnHandler(handler) {
1660
- return editorEventFacet.extension([["clickOn", handler]]);
1714
+ return defineFacetPayload(editorEventFacet, [["clickOn", handler]]);
1661
1715
  }
1662
1716
  function defineClickHandler(handler) {
1663
- return editorEventFacet.extension([["click", handler]]);
1717
+ return defineFacetPayload(editorEventFacet, [["click", handler]]);
1664
1718
  }
1665
1719
  function defineDoubleClickOnHandler(handler) {
1666
- return editorEventFacet.extension([["doubleClickOn", handler]]);
1720
+ return defineFacetPayload(editorEventFacet, [["doubleClickOn", handler]]);
1667
1721
  }
1668
1722
  function defineDoubleClickHandler(handler) {
1669
- return editorEventFacet.extension([["doubleClick", handler]]);
1723
+ return defineFacetPayload(editorEventFacet, [["doubleClick", handler]]);
1670
1724
  }
1671
1725
  function defineTripleClickOnHandler(handler) {
1672
- return editorEventFacet.extension([["tripleClickOn", handler]]);
1726
+ return defineFacetPayload(editorEventFacet, [["tripleClickOn", handler]]);
1673
1727
  }
1674
1728
  function defineTripleClickHandler(handler) {
1675
- return editorEventFacet.extension([["tripleClick", handler]]);
1729
+ return defineFacetPayload(editorEventFacet, [["tripleClick", handler]]);
1676
1730
  }
1677
1731
  function definePasteHandler(handler) {
1678
- return editorEventFacet.extension([["paste", handler]]);
1732
+ return defineFacetPayload(editorEventFacet, [["paste", handler]]);
1679
1733
  }
1680
1734
  function defineDropHandler(handler) {
1681
- return editorEventFacet.extension([["drop", handler]]);
1735
+ return defineFacetPayload(editorEventFacet, [["drop", handler]]);
1682
1736
  }
1683
1737
  function defineScrollToSelectionHandler(handler) {
1684
- return editorEventFacet.extension([["scrollToSelection", handler]]);
1738
+ return defineFacetPayload(editorEventFacet, [["scrollToSelection", handler]]);
1685
1739
  }
1686
- var editorEventFacet = Facet.define({
1687
- converter: () => {
1740
+ var editorEventFacet = defineFacet({
1741
+ reduce: () => {
1688
1742
  const [update, plugin] = setupEditorEventPlugin();
1689
- return {
1690
- create: (entries) => {
1691
- update(entries);
1692
- return () => plugin;
1693
- },
1694
- update: (entries) => {
1695
- update(entries);
1696
- return null;
1697
- }
1743
+ return (entries) => {
1744
+ update(entries);
1745
+ return plugin;
1698
1746
  };
1699
1747
  },
1700
- next: pluginFacet,
1748
+ parent: pluginFacet,
1701
1749
  singleton: true
1702
1750
  });
1703
1751
  function setupEditorEventPlugin() {
@@ -1729,8 +1777,8 @@ function setupEditorEventPlugin() {
1729
1777
  setDropHandlers((_k = map.drop) != null ? _k : []);
1730
1778
  setScrollToSelectionHandlers((_l = map.scrollToSelection) != null ? _l : []);
1731
1779
  };
1732
- const plugin = new ProseMirrorPlugin3({
1733
- key: new PluginKey3("prosekit-editor-handler"),
1780
+ const plugin = new ProseMirrorPlugin4({
1781
+ key: new PluginKey3("prosekit-editor-event"),
1734
1782
  props: {
1735
1783
  handleKeyDown,
1736
1784
  handleKeyPress,
@@ -1753,7 +1801,7 @@ function setupEditorEventPlugin() {
1753
1801
  function defineFocusChangeHandler(handler) {
1754
1802
  const handleFocus = () => handler(true);
1755
1803
  const handleBlur = () => handler(false);
1756
- return domEventFacet.extension([
1804
+ return defineFacetPayload(domEventFacet, [
1757
1805
  ["focus", handleFocus],
1758
1806
  ["blur", handleBlur]
1759
1807
  ]);
@@ -1763,22 +1811,127 @@ function defineFocusChangeHandler(handler) {
1763
1811
  import { history, redo, undo } from "@prosekit/pm/history";
1764
1812
 
1765
1813
  // src/utils/env.ts
1766
- var isMac = typeof navigator !== "undefined" ? /Mac|iP(hone|[ao]d)/.test(navigator.platform) : false;
1814
+ var isApple = typeof navigator !== "undefined" ? /Mac|iP(hone|[ao]d)/.test(navigator.platform) : false;
1767
1815
 
1768
1816
  // src/extensions/keymap.ts
1769
- import { baseKeymap, chainCommands } from "@prosekit/pm/commands";
1817
+ import {
1818
+ baseKeymap,
1819
+ chainCommands,
1820
+ createParagraphNear,
1821
+ liftEmptyBlock,
1822
+ newlineInCode
1823
+ } from "@prosekit/pm/commands";
1770
1824
  import { keydownHandler } from "@prosekit/pm/keymap";
1771
1825
  import { Plugin as Plugin3, PluginKey as PluginKey4 } from "@prosekit/pm/state";
1826
+
1827
+ // src/commands/split-block-as.ts
1828
+ import {
1829
+ AllSelection as AllSelection3,
1830
+ NodeSelection as NodeSelection2,
1831
+ TextSelection as TextSelection6
1832
+ } from "@prosekit/pm/state";
1833
+ import { canSplit } from "@prosekit/pm/transform";
1834
+
1835
+ // src/utils/default-block-at.ts
1836
+ function defaultBlockAt(match) {
1837
+ for (let i = 0; i < match.edgeCount; i++) {
1838
+ const { type } = match.edge(i);
1839
+ if (type.isTextblock && !type.hasRequiredAttrs())
1840
+ return type;
1841
+ }
1842
+ return null;
1843
+ }
1844
+
1845
+ // src/commands/split-block-as.ts
1846
+ function splitBlockAs(splitNode) {
1847
+ return (state, dispatch) => {
1848
+ const { $from, $to } = state.selection;
1849
+ if (state.selection instanceof NodeSelection2 && state.selection.node.isBlock) {
1850
+ if (!$from.parentOffset || !canSplit(state.doc, $from.pos))
1851
+ return false;
1852
+ if (dispatch)
1853
+ dispatch(state.tr.split($from.pos).scrollIntoView());
1854
+ return true;
1855
+ }
1856
+ if (!$from.parent.isBlock)
1857
+ return false;
1858
+ if (dispatch) {
1859
+ const atEnd = $to.parentOffset == $to.parent.content.size;
1860
+ const tr = state.tr;
1861
+ if (state.selection instanceof TextSelection6 || state.selection instanceof AllSelection3)
1862
+ tr.deleteSelection();
1863
+ const deflt = $from.depth == 0 ? null : defaultBlockAt($from.node(-1).contentMatchAt($from.indexAfter(-1)));
1864
+ const splitType = splitNode && splitNode($from.parent, deflt, atEnd);
1865
+ let types = splitType ? [splitType] : atEnd && deflt ? [{ type: deflt }] : void 0;
1866
+ let can = canSplit(tr.doc, tr.mapping.map($from.pos), 1, types);
1867
+ if (!types && !can && canSplit(
1868
+ tr.doc,
1869
+ tr.mapping.map($from.pos),
1870
+ 1,
1871
+ deflt ? [{ type: deflt }] : void 0
1872
+ )) {
1873
+ if (deflt)
1874
+ types = [{ type: deflt }];
1875
+ can = true;
1876
+ }
1877
+ if (can) {
1878
+ tr.split(tr.mapping.map($from.pos), 1, types);
1879
+ if (!atEnd && !$from.parentOffset && $from.parent.type != deflt) {
1880
+ const first = tr.mapping.map($from.before()), $first = tr.doc.resolve(first);
1881
+ if (deflt && $from.node(-1).canReplaceWith($first.index(), $first.index() + 1, deflt))
1882
+ tr.setNodeMarkup(tr.mapping.map($from.before()), deflt);
1883
+ }
1884
+ }
1885
+ dispatch(tr.scrollIntoView());
1886
+ }
1887
+ return true;
1888
+ };
1889
+ }
1890
+
1891
+ // src/commands/split-block-enter.ts
1892
+ var splitBlockEnter = splitBlockAs((node, deflt, atEnd) => {
1893
+ if (atEnd && deflt) {
1894
+ const attrs = pickSplittableAttrs(node, deflt);
1895
+ if (attrs) {
1896
+ return { type: deflt, attrs };
1897
+ }
1898
+ }
1899
+ return null;
1900
+ });
1901
+ function pickSplittableAttrs(node, type) {
1902
+ var _a;
1903
+ const attrs = {};
1904
+ let found = false;
1905
+ for (const [attr, value] of Object.entries(node.attrs)) {
1906
+ const spec = (_a = type.spec.attrs) == null ? void 0 : _a[attr];
1907
+ if (spec && spec.default !== value && spec.splittable === true) {
1908
+ attrs[attr] = value;
1909
+ found = true;
1910
+ }
1911
+ }
1912
+ return found ? attrs : null;
1913
+ }
1914
+
1915
+ // src/extensions/keymap.ts
1916
+ var customBaseKeymap = {
1917
+ ...baseKeymap,
1918
+ Enter: chainCommands(
1919
+ newlineInCode,
1920
+ createParagraphNear,
1921
+ liftEmptyBlock,
1922
+ splitBlockEnter
1923
+ )
1924
+ };
1772
1925
  function defineKeymap(keymap) {
1773
- return keymapFacet.extension([keymap]);
1926
+ return defineFacetPayload(keymapFacet, [keymap]);
1774
1927
  }
1775
1928
  function defineBaseKeymap(options) {
1776
1929
  var _a;
1777
- const priority = (_a = options == null ? void 0 : options.priority) != null ? _a : 3 /* low */;
1778
- return withPriority(defineKeymap(baseKeymap), priority);
1930
+ const priority = (_a = options == null ? void 0 : options.priority) != null ? _a : 1 /* low */;
1931
+ return withPriority(defineKeymap(customBaseKeymap), priority);
1779
1932
  }
1780
- var keymapFacet = Facet.define({
1781
- converter: () => {
1933
+ var keymapFacet = defineFacet({
1934
+ reduce: () => {
1782
1935
  let handler = null;
1783
1936
  const handlerWrapper = (view, event) => {
1784
1937
  if (handler)
@@ -1789,19 +1942,17 @@ var keymapFacet = Facet.define({
1789
1942
  key: keymapPluginKey,
1790
1943
  props: { handleKeyDown: handlerWrapper }
1791
1944
  });
1792
- const pluginFunc = () => [plugin];
1793
- return {
1794
- create: (keymaps) => {
1795
- handler = keydownHandler(mergeKeymaps(keymaps));
1796
- return pluginFunc;
1797
- },
1798
- update: (keymaps) => {
1799
- handler = keydownHandler(mergeKeymaps(keymaps));
1800
- return null;
1801
- }
1945
+ return (keymaps) => {
1946
+ handler = keydownHandler(
1947
+ mergeKeymaps(
1948
+ // The keymap at the end have a higher priority.
1949
+ toReversed(keymaps)
1950
+ )
1951
+ );
1952
+ return plugin;
1802
1953
  };
1803
1954
  },
1804
- next: pluginFacet,
1955
+ parent: pluginFacet,
1805
1956
  singleton: true
1806
1957
  });
1807
1958
  function mergeKeymaps(keymaps) {
@@ -1827,7 +1978,7 @@ function defineHistory() {
1827
1978
  "Mod-z": undo,
1828
1979
  "Shift-Mod-z": redo
1829
1980
  };
1830
- if (!isMac) {
1981
+ if (!isApple) {
1831
1982
  keymap["Mod-y"] = redo;
1832
1983
  }
1833
1984
  return union([
@@ -1843,14 +1994,14 @@ function defineHistory() {
1843
1994
  // src/extensions/mark-spec.ts
1844
1995
  function defineMarkSpec(options) {
1845
1996
  const payload = [options, void 0];
1846
- return markSpecFacet.extension([payload]);
1997
+ return defineFacetPayload(markSpecFacet, [payload]);
1847
1998
  }
1848
1999
  function defineMarkAttr(options) {
1849
2000
  const payload = [void 0, options];
1850
- return markSpecFacet.extension([payload]);
2001
+ return defineFacetPayload(markSpecFacet, [payload]);
1851
2002
  }
1852
- var markSpecFacet = Facet.define({
1853
- convert: (payloads) => {
2003
+ var markSpecFacet = defineFacet({
2004
+ reducer: (payloads) => {
1854
2005
  const marks = {};
1855
2006
  const specPayloads = payloads.map((input) => input[0]).filter(isNotNull);
1856
2007
  const attrPayloads = payloads.map((input) => input[1]).filter(isNotNull);
@@ -1927,37 +2078,42 @@ var markSpecFacet = Facet.define({
1927
2078
  }
1928
2079
  return { marks, nodes: {} };
1929
2080
  },
1930
- next: schemaFacet,
2081
+ parent: schemaSpecFacet,
1931
2082
  singleton: true
1932
2083
  });
1933
2084
 
1934
2085
  // src/extensions/node-view.ts
1935
- import { ProseMirrorPlugin as ProseMirrorPlugin4 } from "@prosekit/pm/state";
2086
+ import { PluginKey as PluginKey5, ProseMirrorPlugin as ProseMirrorPlugin5 } from "@prosekit/pm/state";
1936
2087
  import "@prosekit/pm/view";
1937
2088
  function defineNodeView(options) {
1938
- return nodeViewFacet.extension([options]);
2089
+ return defineFacetPayload(nodeViewFacet, [options]);
1939
2090
  }
1940
- var nodeViewFacet = Facet.define({
1941
- convert: (inputs) => {
2091
+ var nodeViewFacet = defineFacet({
2092
+ reducer: (inputs) => {
1942
2093
  const nodeViews = {};
1943
2094
  for (const input of inputs) {
1944
2095
  if (!nodeViews[input.name]) {
1945
2096
  nodeViews[input.name] = input.constructor;
1946
2097
  }
1947
2098
  }
1948
- return () => [new ProseMirrorPlugin4({ props: { nodeViews } })];
2099
+ return () => [
2100
+ new ProseMirrorPlugin5({
2101
+ key: new PluginKey5("prosekit-node-view"),
2102
+ props: { nodeViews }
2103
+ })
2104
+ ];
1949
2105
  },
1950
- next: pluginFacet
2106
+ parent: pluginFacet
1951
2107
  });
1952
2108
 
1953
2109
  // src/extensions/node-view-effect.ts
1954
- import { ProseMirrorPlugin as ProseMirrorPlugin5 } from "@prosekit/pm/state";
2110
+ import { PluginKey as PluginKey6, ProseMirrorPlugin as ProseMirrorPlugin6 } from "@prosekit/pm/state";
1955
2111
  import "@prosekit/pm/view";
1956
2112
  function defineNodeViewFactory(options) {
1957
- return nodeViewFactoryFacet.extension([options]);
2113
+ return defineFacetPayload(nodeViewFactoryFacet, [options]);
1958
2114
  }
1959
- var nodeViewFactoryFacet = Facet.define({
1960
- convert: (inputs) => {
2115
+ var nodeViewFactoryFacet = defineFacet({
2116
+ reducer: (inputs) => {
1961
2117
  const nodeViews = {};
1962
2118
  const options = {};
1963
2119
  const factories = {};
@@ -1979,9 +2135,14 @@ var nodeViewFactoryFacet = Facet.define({
1979
2135
  nodeViews[name] = factory(args);
1980
2136
  }
1981
2137
  }
1982
- return () => [new ProseMirrorPlugin5({ props: { nodeViews } })];
2138
+ return () => [
2139
+ new ProseMirrorPlugin6({
2140
+ key: new PluginKey6("prosekit-node-view-effect"),
2141
+ props: { nodeViews }
2142
+ })
2143
+ ];
1983
2144
  },
1984
- next: pluginFacet
2145
+ parent: pluginFacet
1985
2146
  });
1986
2147
 
1987
2148
  // src/extensions/paragraph.ts
@@ -1997,7 +2158,7 @@ function defineParagraphSpec() {
1997
2158
  });
1998
2159
  }
1999
2160
  function defineParagraph() {
2000
- return withPriority(defineParagraphSpec(), 0 /* highest */);
2161
+ return withPriority(defineParagraphSpec(), 4 /* highest */);
2001
2162
  }
2002
2163
 
2003
2164
  // src/extensions/text.ts
@@ -2032,16 +2193,6 @@ var canUseRegexLookbehind = cache(() => {
2032
2193
  import clsxLite from "clsx/lite";
2033
2194
  var clsx = clsxLite;
2034
2195
 
2035
- // src/utils/default-block-at.ts
2036
- function defaultBlockAt(match) {
2037
- for (let i = 0; i < match.edgeCount; i++) {
2038
- const { type } = match.edge(i);
2039
- if (type.isTextblock && !type.hasRequiredAttrs())
2040
- return type;
2041
- }
2042
- return null;
2043
- }
2044
-
2045
2196
  // src/utils/get-id.ts
2046
2197
  var id = 0;
2047
2198
  function getId() {
@@ -2077,12 +2228,12 @@ function withSkipCodeBlock(command) {
2077
2228
  export {
2078
2229
  Editor,
2079
2230
  EditorNotFoundError,
2080
- Facet,
2081
2231
  OBJECT_REPLACEMENT_CHARACTER,
2082
2232
  Priority,
2083
2233
  ProseKitError,
2084
2234
  getId as _getId,
2085
2235
  addMark,
2236
+ assert,
2086
2237
  canUseRegexLookbehind,
2087
2238
  clsx,
2088
2239
  createEditor,
@@ -2099,6 +2250,8 @@ export {
2099
2250
  defineDoubleClickHandler,
2100
2251
  defineDoubleClickOnHandler,
2101
2252
  defineDropHandler,
2253
+ defineFacet,
2254
+ defineFacetPayload,
2102
2255
  defineFocusChangeHandler,
2103
2256
  defineHistory,
2104
2257
  defineKeyDownHandler,
@@ -2130,6 +2283,7 @@ export {
2130
2283
  htmlFromNode,
2131
2284
  insertNode,
2132
2285
  isAllSelection,
2286
+ isApple,
2133
2287
  isInCodeBlock,
2134
2288
  isMark,
2135
2289
  isMarkAbsent,