@prosekit/core 0.4.2 → 0.5.1

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];
639
+ }
640
+ /**
641
+ * @internal
642
+ */
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));
455
647
  }
456
648
  /**
457
649
  * @internal
458
650
  */
459
- static defineRootFacet(options) {
460
- return _Facet.define(options);
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());
854
881
  }
855
- return { schemaInput, stateInput, viewInput, commandInput };
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]));
886
+ }
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,34 @@ 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;
1095
+ const view = this.view;
1096
+ if (!view || view.isDestroyed) {
1097
+ return;
1098
+ }
1099
+ const tree = extension.getTree();
1100
+ const payload = tree.getRootOutput();
1101
+ if (payload == null ? void 0 : payload.schema) {
1084
1102
  throw new ProseKitError("Schema cannot be changed");
1085
1103
  }
1086
- if (viewInput) {
1104
+ if (payload == null ? void 0 : payload.view) {
1087
1105
  throw new ProseKitError("View cannot be changed");
1088
1106
  }
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 });
1097
- this.view.updateState(state);
1098
- }
1099
- if (commandInput) {
1100
- const names = Object.keys(commandInput);
1107
+ const oldPayload = this.tree.getRootOutput();
1108
+ const oldPlugins = [...(_b = (_a = view.state) == null ? void 0 : _a.plugins) != null ? _b : []];
1109
+ this.tree = add ? unionFacetNode(this.tree, tree) : subtractFacetNode(this.tree, tree);
1110
+ const newPayload = this.tree.getRootOutput();
1111
+ const newPlugins = [...(_d = (_c = newPayload == null ? void 0 : newPayload.state) == null ? void 0 : _c.plugins) != null ? _d : []];
1112
+ if (!deepEquals(oldPlugins, newPlugins)) {
1113
+ const state = view.state.reconfigure({ plugins: newPlugins });
1114
+ view.updateState(state);
1115
+ }
1116
+ if ((newPayload == null ? void 0 : newPayload.commands) && !deepEquals(oldPayload == null ? void 0 : oldPayload.commands, newPayload == null ? void 0 : newPayload.commands)) {
1117
+ const commands = newPayload.commands;
1118
+ const names = Object.keys(commands);
1101
1119
  for (const name of names) {
1102
- this.defineCommand(name, commandInput[name]);
1120
+ this.defineCommand(name, commands[name]);
1103
1121
  }
1104
1122
  }
1105
1123
  }
@@ -1119,6 +1137,9 @@ var EditorInstance = class {
1119
1137
  this.view.destroy();
1120
1138
  this.view = null;
1121
1139
  }
1140
+ get mounted() {
1141
+ return !!this.view && !this.view.isDestroyed;
1142
+ }
1122
1143
  get assertView() {
1123
1144
  if (!this.view) {
1124
1145
  throw new ProseKitError("Editor is not mounted");
@@ -1185,7 +1206,7 @@ var Editor = class _Editor {
1185
1206
  * Whether the editor is mounted.
1186
1207
  */
1187
1208
  get mounted() {
1188
- return !!this.instance.view;
1209
+ return this.instance.mounted;
1189
1210
  }
1190
1211
  /**
1191
1212
  * The editor view.
@@ -1253,8 +1274,8 @@ var Editor = class _Editor {
1253
1274
  lazyRemove == null ? void 0 : lazyRemove();
1254
1275
  };
1255
1276
  }
1256
- this.instance.updateExtension(extension, "add");
1257
- return () => this.instance.updateExtension(extension, "remove");
1277
+ this.instance.updateExtension(extension, true);
1278
+ return () => this.instance.updateExtension(extension, false);
1258
1279
  }
1259
1280
  get state() {
1260
1281
  return this.instance.getState();
@@ -1318,9 +1339,19 @@ function wrap({
1318
1339
  };
1319
1340
  }
1320
1341
 
1342
+ // src/facets/command.ts
1343
+ var commandFacet = defineFacet({
1344
+ reducer: (inputs) => {
1345
+ const commands = Object.assign({}, ...inputs);
1346
+ return { commands };
1347
+ },
1348
+ parent: rootFacet,
1349
+ singleton: true
1350
+ });
1351
+
1321
1352
  // src/extensions/command.ts
1322
1353
  function defineCommands(commands) {
1323
- return commandFacet.extension([commands]);
1354
+ return defineFacetPayload(commandFacet, [commands]);
1324
1355
  }
1325
1356
  function defineBaseCommands() {
1326
1357
  return defineCommands({
@@ -1335,6 +1366,29 @@ function defineBaseCommands() {
1335
1366
  });
1336
1367
  }
1337
1368
 
1369
+ // src/extensions/node-spec.ts
1370
+ import OrderedMap3 from "orderedmap";
1371
+
1372
+ // src/facets/schema-spec.ts
1373
+ import "@prosekit/pm/model";
1374
+ import OrderedMap2 from "orderedmap";
1375
+ var schemaSpecFacet = defineFacet({
1376
+ reducer: (specs) => {
1377
+ var _a;
1378
+ let nodes = OrderedMap2.from({});
1379
+ let marks = OrderedMap2.from({});
1380
+ let topNode = void 0;
1381
+ for (const spec of specs) {
1382
+ nodes = nodes.append(spec.nodes);
1383
+ marks = marks.append((_a = spec.marks) != null ? _a : {});
1384
+ topNode = topNode != null ? topNode : spec.topNode;
1385
+ }
1386
+ return { nodes, marks, topNode };
1387
+ },
1388
+ parent: schemaFacet,
1389
+ singleton: true
1390
+ });
1391
+
1338
1392
  // src/utils/is-element.ts
1339
1393
  var hasElement = typeof Element !== "undefined";
1340
1394
  function isElement(value) {
@@ -1349,44 +1403,39 @@ function isNotNull(value) {
1349
1403
  // src/extensions/node-spec.ts
1350
1404
  function defineNodeSpec(options) {
1351
1405
  const payload = [options, void 0];
1352
- return nodeSpecFacet.extension([payload]);
1406
+ return defineFacetPayload(nodeSpecFacet, [payload]);
1353
1407
  }
1354
1408
  function defineNodeAttr(options) {
1355
1409
  const payload = [void 0, options];
1356
- return nodeSpecFacet.extension([payload]);
1410
+ return defineFacetPayload(nodeSpecFacet, [payload]);
1357
1411
  }
1358
- var nodeSpecFacet = Facet.define({
1359
- convert: (payloads) => {
1360
- const nodes = {};
1412
+ var nodeSpecFacet = defineFacet({
1413
+ reducer: (payloads) => {
1414
+ let nodes = OrderedMap3.from({});
1361
1415
  let topNodeName = void 0;
1362
1416
  const specPayloads = payloads.map((input) => input[0]).filter(isNotNull);
1363
1417
  const attrPayloads = payloads.map((input) => input[1]).filter(isNotNull);
1364
1418
  for (const { name, topNode, ...spec } of specPayloads) {
1365
- if (nodes[name]) {
1366
- throw new ProseKitError(`Node type ${name} has already been defined`);
1367
- }
1419
+ assert(!nodes.get(name), `Node type ${name} can only be defined once`);
1368
1420
  if (topNode) {
1369
1421
  topNodeName = name;
1370
1422
  }
1371
- nodes[name] = spec;
1423
+ nodes = nodes.addToStart(name, spec);
1372
1424
  }
1373
1425
  for (const {
1374
1426
  type,
1375
1427
  attr,
1376
1428
  default: defaultValue,
1429
+ splittable,
1377
1430
  toDOM,
1378
1431
  parseDOM
1379
1432
  } 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
- }
1433
+ const spec = nodes.get(type);
1434
+ assert(spec, `Node type ${type} must be defined`);
1386
1435
  if (!spec.attrs) {
1387
1436
  spec.attrs = {};
1388
1437
  }
1389
- spec.attrs[attr] = { default: defaultValue };
1438
+ spec.attrs[attr] = { default: defaultValue, splittable };
1390
1439
  if (toDOM && spec.toDOM) {
1391
1440
  const existingToDom = spec.toDOM;
1392
1441
  spec.toDOM = (node) => {
@@ -1404,14 +1453,22 @@ var nodeSpecFacet = Facet.define({
1404
1453
  }
1405
1454
  if (Array.isArray(dom)) {
1406
1455
  if (typeof dom[1] === "object") {
1407
- return [dom[0], { ...dom[1], [key]: value }, ...dom.slice(2)];
1456
+ return [
1457
+ dom[0],
1458
+ setObjectAttribute(
1459
+ dom[1],
1460
+ key,
1461
+ value
1462
+ ),
1463
+ ...dom.slice(2)
1464
+ ];
1408
1465
  } else {
1409
1466
  return [dom[0], { [key]: value }, ...dom.slice(1)];
1410
1467
  }
1411
1468
  } else if (isElement(dom)) {
1412
- dom.setAttribute(key, value);
1469
+ setElementAttribute(dom, key, value);
1413
1470
  } else if (typeof dom === "object" && "dom" in dom && isElement(dom.dom)) {
1414
- dom.dom.setAttribute(key, value);
1471
+ setElementAttribute(dom.dom, key, value);
1415
1472
  }
1416
1473
  return dom;
1417
1474
  };
@@ -1437,9 +1494,21 @@ var nodeSpecFacet = Facet.define({
1437
1494
  }
1438
1495
  return { nodes, topNode: topNodeName };
1439
1496
  },
1440
- next: schemaFacet,
1497
+ parent: schemaSpecFacet,
1441
1498
  singleton: true
1442
1499
  });
1500
+ function setObjectAttribute(obj, key, value) {
1501
+ if (key === "style") {
1502
+ value = `${value}${obj.style || ""}`;
1503
+ }
1504
+ return { ...obj, [key]: value };
1505
+ }
1506
+ function setElementAttribute(element, key, value) {
1507
+ if (key === "style") {
1508
+ value = `${value}${element.getAttribute("style") || ""}`;
1509
+ }
1510
+ element.setAttribute(key, value);
1511
+ }
1443
1512
 
1444
1513
  // src/extensions/doc.ts
1445
1514
  function defineDoc() {
@@ -1451,60 +1520,61 @@ function defineDoc() {
1451
1520
  }
1452
1521
 
1453
1522
  // src/extensions/events/plugin-view.ts
1454
- import { PluginKey, ProseMirrorPlugin } from "@prosekit/pm/state";
1523
+ import { PluginKey, ProseMirrorPlugin as ProseMirrorPlugin2 } from "@prosekit/pm/state";
1455
1524
 
1456
1525
  // src/extensions/plugin.ts
1457
1526
  import "@prosekit/pm/model";
1458
1527
  import { Plugin as Plugin2 } from "@prosekit/pm/state";
1459
1528
  function definePlugin(plugin) {
1460
1529
  if (plugin instanceof Plugin2) {
1461
- return pluginFacet.extension([() => [plugin]]);
1530
+ return defineFacetPayload(pluginFacet, [() => [plugin]]);
1462
1531
  }
1463
1532
  if (Array.isArray(plugin) && plugin.every((p) => p instanceof Plugin2)) {
1464
- return pluginFacet.extension([() => plugin]);
1533
+ return defineFacetPayload(pluginFacet, [() => plugin]);
1465
1534
  }
1466
1535
  if (typeof plugin === "function") {
1467
- return pluginFacet.extension([plugin]);
1536
+ return defineFacetPayload(pluginFacet, [plugin]);
1468
1537
  }
1469
1538
  throw new TypeError("Invalid plugin");
1470
1539
  }
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;
1540
+ var pluginFacet = defineFacet({
1541
+ reducer: (payloads) => {
1542
+ return ({ schema }) => {
1543
+ const plugins = [];
1544
+ for (const payload of payloads) {
1545
+ if (payload instanceof Plugin2) {
1546
+ plugins.push(payload);
1547
+ } else if (Array.isArray(payload) && payload.every((p) => p instanceof Plugin2)) {
1548
+ plugins.push(...payload);
1549
+ } else if (typeof payload === "function") {
1550
+ plugins.push(...[payload({ schema })].flat());
1551
+ } else {
1552
+ throw new ProseKitError("Invalid plugin");
1553
+ }
1486
1554
  }
1555
+ plugins.reverse();
1556
+ return { plugins };
1487
1557
  };
1488
1558
  },
1489
- next: stateFacet
1559
+ parent: stateFacet
1490
1560
  });
1491
1561
 
1492
1562
  // src/extensions/events/plugin-view.ts
1493
1563
  function defineMountHandler(handler) {
1494
- return pluginViewFacet.extension([["mount", handler]]);
1564
+ return defineFacetPayload(pluginViewFacet, [["mount", handler]]);
1495
1565
  }
1496
1566
  function defineUpdateHandler(handler) {
1497
- return pluginViewFacet.extension([["update", handler]]);
1567
+ return defineFacetPayload(pluginViewFacet, [["update", handler]]);
1498
1568
  }
1499
1569
  function defineUnmountHandler(handler) {
1500
- return pluginViewFacet.extension([["unmount", handler]]);
1570
+ return defineFacetPayload(pluginViewFacet, [["unmount", handler]]);
1501
1571
  }
1502
- var pluginViewFacet = Facet.define({
1503
- converter: () => {
1572
+ var pluginViewFacet = defineFacet({
1573
+ reduce: () => {
1504
1574
  let mountHandlers = [];
1505
1575
  let updateHandlers = [];
1506
1576
  let unmountHandlers = [];
1507
- const plugin = new ProseMirrorPlugin({
1577
+ const plugin = new ProseMirrorPlugin2({
1508
1578
  key: pluginKey,
1509
1579
  view: (view) => {
1510
1580
  mountHandlers.forEach((fn) => fn(view));
@@ -1518,7 +1588,6 @@ var pluginViewFacet = Facet.define({
1518
1588
  };
1519
1589
  }
1520
1590
  });
1521
- const pluginFunc = () => [plugin];
1522
1591
  const register = (input) => {
1523
1592
  mountHandlers = [];
1524
1593
  updateHandlers = [];
@@ -1537,18 +1606,12 @@ var pluginViewFacet = Facet.define({
1537
1606
  }
1538
1607
  }
1539
1608
  };
1540
- return {
1541
- create: (input) => {
1542
- register(input);
1543
- return pluginFunc;
1544
- },
1545
- update: (input) => {
1546
- register(input);
1547
- return null;
1548
- }
1609
+ return function reducer(input) {
1610
+ register(input);
1611
+ return plugin;
1549
1612
  };
1550
1613
  },
1551
- next: pluginFacet,
1614
+ parent: pluginFacet,
1552
1615
  singleton: true
1553
1616
  });
1554
1617
  var pluginKey = new PluginKey("prosekit-plugin-view-handler");
@@ -1563,13 +1626,13 @@ function defineDocChangeHandler(handler) {
1563
1626
  }
1564
1627
 
1565
1628
  // src/extensions/events/dom-event.ts
1566
- import { PluginKey as PluginKey2, ProseMirrorPlugin as ProseMirrorPlugin2 } from "@prosekit/pm/state";
1629
+ import { PluginKey as PluginKey2, ProseMirrorPlugin as ProseMirrorPlugin3 } from "@prosekit/pm/state";
1567
1630
 
1568
1631
  // src/utils/combine-event-handlers.ts
1569
1632
  function combineEventHandlers() {
1570
1633
  let _handlers = [];
1571
1634
  function setHandlers(handlers) {
1572
- _handlers = handlers;
1635
+ _handlers = toReversed(handlers);
1573
1636
  }
1574
1637
  function combinedEventHandler(...args) {
1575
1638
  for (const handler of _handlers) {
@@ -1598,106 +1661,97 @@ function groupEntries(entries) {
1598
1661
 
1599
1662
  // src/extensions/events/dom-event.ts
1600
1663
  function defineDOMEventHandler(event, handler) {
1601
- return domEventFacet.extension([
1664
+ return defineFacetPayload(domEventFacet, [
1602
1665
  [event, handler]
1603
1666
  ]);
1604
1667
  }
1605
- var domEventFacet = Facet.define({
1606
- converter: () => {
1668
+ var domEventFacet = defineFacet({
1669
+ reduce: () => {
1607
1670
  const setHandlersMap = {};
1608
1671
  const combinedHandlerMap = {};
1672
+ let plugin = null;
1609
1673
  const update = (payloads) => {
1674
+ var _a;
1610
1675
  let hasNewEvent = false;
1611
1676
  for (const [event] of payloads) {
1612
1677
  if (!setHandlersMap[event]) {
1613
1678
  hasNewEvent = true;
1614
1679
  const [setHandlers, combinedHandler] = combineEventHandlers();
1615
1680
  setHandlersMap[event] = setHandlers;
1616
- combinedHandlerMap[event] = combinedHandler;
1681
+ const e = (view, eventObject) => {
1682
+ return combinedHandler(view, eventObject);
1683
+ };
1684
+ combinedHandlerMap[event] = e;
1617
1685
  }
1618
1686
  }
1619
1687
  const map = groupEntries(payloads);
1620
- for (const [event, handlers] of Object.entries(map)) {
1621
- const setHandlers = setHandlersMap[event];
1622
- setHandlers(handlers != null ? handlers : []);
1688
+ for (const [event, setHandlers] of Object.entries(setHandlersMap)) {
1689
+ const handlers = (_a = map[event]) != null ? _a : [];
1690
+ setHandlers(handlers);
1623
1691
  }
1624
1692
  if (hasNewEvent) {
1625
- return new ProseMirrorPlugin2({
1693
+ plugin = new ProseMirrorPlugin3({
1626
1694
  key: new PluginKey2("prosekit-dom-event-handler"),
1627
1695
  props: { handleDOMEvents: combinedHandlerMap }
1628
1696
  });
1629
- } else {
1630
- return null;
1631
1697
  }
1632
1698
  };
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
- }
1699
+ return function reducer(inputs) {
1700
+ update(inputs);
1701
+ return plugin != null ? plugin : [];
1642
1702
  };
1643
1703
  },
1644
- next: pluginFacet,
1704
+ parent: pluginFacet,
1645
1705
  singleton: true
1646
1706
  });
1647
1707
 
1648
1708
  // src/extensions/events/editor-event.ts
1649
- import { PluginKey as PluginKey3, ProseMirrorPlugin as ProseMirrorPlugin3 } from "@prosekit/pm/state";
1709
+ import { PluginKey as PluginKey3, ProseMirrorPlugin as ProseMirrorPlugin4 } from "@prosekit/pm/state";
1650
1710
  function defineKeyDownHandler(handler) {
1651
- return editorEventFacet.extension([["keyDown", handler]]);
1711
+ return defineFacetPayload(editorEventFacet, [["keyDown", handler]]);
1652
1712
  }
1653
1713
  function defineKeyPressHandler(handler) {
1654
- return editorEventFacet.extension([["keyPress", handler]]);
1714
+ return defineFacetPayload(editorEventFacet, [["keyPress", handler]]);
1655
1715
  }
1656
1716
  function defineTextInputHandler(handler) {
1657
- return editorEventFacet.extension([["textInput", handler]]);
1717
+ return defineFacetPayload(editorEventFacet, [["textInput", handler]]);
1658
1718
  }
1659
1719
  function defineClickOnHandler(handler) {
1660
- return editorEventFacet.extension([["clickOn", handler]]);
1720
+ return defineFacetPayload(editorEventFacet, [["clickOn", handler]]);
1661
1721
  }
1662
1722
  function defineClickHandler(handler) {
1663
- return editorEventFacet.extension([["click", handler]]);
1723
+ return defineFacetPayload(editorEventFacet, [["click", handler]]);
1664
1724
  }
1665
1725
  function defineDoubleClickOnHandler(handler) {
1666
- return editorEventFacet.extension([["doubleClickOn", handler]]);
1726
+ return defineFacetPayload(editorEventFacet, [["doubleClickOn", handler]]);
1667
1727
  }
1668
1728
  function defineDoubleClickHandler(handler) {
1669
- return editorEventFacet.extension([["doubleClick", handler]]);
1729
+ return defineFacetPayload(editorEventFacet, [["doubleClick", handler]]);
1670
1730
  }
1671
1731
  function defineTripleClickOnHandler(handler) {
1672
- return editorEventFacet.extension([["tripleClickOn", handler]]);
1732
+ return defineFacetPayload(editorEventFacet, [["tripleClickOn", handler]]);
1673
1733
  }
1674
1734
  function defineTripleClickHandler(handler) {
1675
- return editorEventFacet.extension([["tripleClick", handler]]);
1735
+ return defineFacetPayload(editorEventFacet, [["tripleClick", handler]]);
1676
1736
  }
1677
1737
  function definePasteHandler(handler) {
1678
- return editorEventFacet.extension([["paste", handler]]);
1738
+ return defineFacetPayload(editorEventFacet, [["paste", handler]]);
1679
1739
  }
1680
1740
  function defineDropHandler(handler) {
1681
- return editorEventFacet.extension([["drop", handler]]);
1741
+ return defineFacetPayload(editorEventFacet, [["drop", handler]]);
1682
1742
  }
1683
1743
  function defineScrollToSelectionHandler(handler) {
1684
- return editorEventFacet.extension([["scrollToSelection", handler]]);
1744
+ return defineFacetPayload(editorEventFacet, [["scrollToSelection", handler]]);
1685
1745
  }
1686
- var editorEventFacet = Facet.define({
1687
- converter: () => {
1746
+ var editorEventFacet = defineFacet({
1747
+ reduce: () => {
1688
1748
  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
- }
1749
+ return (entries) => {
1750
+ update(entries);
1751
+ return plugin;
1698
1752
  };
1699
1753
  },
1700
- next: pluginFacet,
1754
+ parent: pluginFacet,
1701
1755
  singleton: true
1702
1756
  });
1703
1757
  function setupEditorEventPlugin() {
@@ -1729,8 +1783,8 @@ function setupEditorEventPlugin() {
1729
1783
  setDropHandlers((_k = map.drop) != null ? _k : []);
1730
1784
  setScrollToSelectionHandlers((_l = map.scrollToSelection) != null ? _l : []);
1731
1785
  };
1732
- const plugin = new ProseMirrorPlugin3({
1733
- key: new PluginKey3("prosekit-editor-handler"),
1786
+ const plugin = new ProseMirrorPlugin4({
1787
+ key: new PluginKey3("prosekit-editor-event"),
1734
1788
  props: {
1735
1789
  handleKeyDown,
1736
1790
  handleKeyPress,
@@ -1753,7 +1807,7 @@ function setupEditorEventPlugin() {
1753
1807
  function defineFocusChangeHandler(handler) {
1754
1808
  const handleFocus = () => handler(true);
1755
1809
  const handleBlur = () => handler(false);
1756
- return domEventFacet.extension([
1810
+ return defineFacetPayload(domEventFacet, [
1757
1811
  ["focus", handleFocus],
1758
1812
  ["blur", handleBlur]
1759
1813
  ]);
@@ -1763,22 +1817,127 @@ function defineFocusChangeHandler(handler) {
1763
1817
  import { history, redo, undo } from "@prosekit/pm/history";
1764
1818
 
1765
1819
  // src/utils/env.ts
1766
- var isMac = typeof navigator !== "undefined" ? /Mac|iP(hone|[ao]d)/.test(navigator.platform) : false;
1820
+ var isApple = typeof navigator !== "undefined" ? /Mac|iP(hone|[ao]d)/.test(navigator.platform) : false;
1767
1821
 
1768
1822
  // src/extensions/keymap.ts
1769
- import { baseKeymap, chainCommands } from "@prosekit/pm/commands";
1823
+ import {
1824
+ baseKeymap,
1825
+ chainCommands,
1826
+ createParagraphNear,
1827
+ liftEmptyBlock,
1828
+ newlineInCode
1829
+ } from "@prosekit/pm/commands";
1770
1830
  import { keydownHandler } from "@prosekit/pm/keymap";
1771
1831
  import { Plugin as Plugin3, PluginKey as PluginKey4 } from "@prosekit/pm/state";
1832
+
1833
+ // src/commands/split-block-as.ts
1834
+ import {
1835
+ AllSelection as AllSelection3,
1836
+ NodeSelection as NodeSelection2,
1837
+ TextSelection as TextSelection6
1838
+ } from "@prosekit/pm/state";
1839
+ import { canSplit } from "@prosekit/pm/transform";
1840
+
1841
+ // src/utils/default-block-at.ts
1842
+ function defaultBlockAt(match) {
1843
+ for (let i = 0; i < match.edgeCount; i++) {
1844
+ const { type } = match.edge(i);
1845
+ if (type.isTextblock && !type.hasRequiredAttrs())
1846
+ return type;
1847
+ }
1848
+ return null;
1849
+ }
1850
+
1851
+ // src/commands/split-block-as.ts
1852
+ function splitBlockAs(splitNode) {
1853
+ return (state, dispatch) => {
1854
+ const { $from, $to } = state.selection;
1855
+ if (state.selection instanceof NodeSelection2 && state.selection.node.isBlock) {
1856
+ if (!$from.parentOffset || !canSplit(state.doc, $from.pos))
1857
+ return false;
1858
+ if (dispatch)
1859
+ dispatch(state.tr.split($from.pos).scrollIntoView());
1860
+ return true;
1861
+ }
1862
+ if (!$from.parent.isBlock)
1863
+ return false;
1864
+ if (dispatch) {
1865
+ const atEnd = $to.parentOffset == $to.parent.content.size;
1866
+ const tr = state.tr;
1867
+ if (state.selection instanceof TextSelection6 || state.selection instanceof AllSelection3)
1868
+ tr.deleteSelection();
1869
+ const deflt = $from.depth == 0 ? null : defaultBlockAt($from.node(-1).contentMatchAt($from.indexAfter(-1)));
1870
+ const splitType = splitNode && splitNode($from.parent, deflt, atEnd);
1871
+ let types = splitType ? [splitType] : atEnd && deflt ? [{ type: deflt }] : void 0;
1872
+ let can = canSplit(tr.doc, tr.mapping.map($from.pos), 1, types);
1873
+ if (!types && !can && canSplit(
1874
+ tr.doc,
1875
+ tr.mapping.map($from.pos),
1876
+ 1,
1877
+ deflt ? [{ type: deflt }] : void 0
1878
+ )) {
1879
+ if (deflt)
1880
+ types = [{ type: deflt }];
1881
+ can = true;
1882
+ }
1883
+ if (can) {
1884
+ tr.split(tr.mapping.map($from.pos), 1, types);
1885
+ if (!atEnd && !$from.parentOffset && $from.parent.type != deflt) {
1886
+ const first = tr.mapping.map($from.before()), $first = tr.doc.resolve(first);
1887
+ if (deflt && $from.node(-1).canReplaceWith($first.index(), $first.index() + 1, deflt))
1888
+ tr.setNodeMarkup(tr.mapping.map($from.before()), deflt);
1889
+ }
1890
+ }
1891
+ dispatch(tr.scrollIntoView());
1892
+ }
1893
+ return true;
1894
+ };
1895
+ }
1896
+
1897
+ // src/commands/split-block-enter.ts
1898
+ var splitBlockEnter = splitBlockAs((node, deflt, atEnd) => {
1899
+ if (atEnd && deflt) {
1900
+ const attrs = pickSplittableAttrs(node, deflt);
1901
+ if (attrs) {
1902
+ return { type: deflt, attrs };
1903
+ }
1904
+ }
1905
+ return null;
1906
+ });
1907
+ function pickSplittableAttrs(node, type) {
1908
+ var _a;
1909
+ const attrs = {};
1910
+ let found = false;
1911
+ for (const [attr, value] of Object.entries(node.attrs)) {
1912
+ const spec = (_a = type.spec.attrs) == null ? void 0 : _a[attr];
1913
+ if (spec && spec.default !== value && spec.splittable === true) {
1914
+ attrs[attr] = value;
1915
+ found = true;
1916
+ }
1917
+ }
1918
+ return found ? attrs : null;
1919
+ }
1920
+
1921
+ // src/extensions/keymap.ts
1922
+ var customBaseKeymap = {
1923
+ ...baseKeymap,
1924
+ Enter: chainCommands(
1925
+ newlineInCode,
1926
+ createParagraphNear,
1927
+ liftEmptyBlock,
1928
+ splitBlockEnter
1929
+ )
1930
+ };
1772
1931
  function defineKeymap(keymap) {
1773
- return keymapFacet.extension([keymap]);
1932
+ return defineFacetPayload(keymapFacet, [keymap]);
1774
1933
  }
1775
1934
  function defineBaseKeymap(options) {
1776
1935
  var _a;
1777
- const priority = (_a = options == null ? void 0 : options.priority) != null ? _a : 3 /* low */;
1778
- return withPriority(defineKeymap(baseKeymap), priority);
1936
+ const priority = (_a = options == null ? void 0 : options.priority) != null ? _a : 1 /* low */;
1937
+ return withPriority(defineKeymap(customBaseKeymap), priority);
1779
1938
  }
1780
- var keymapFacet = Facet.define({
1781
- converter: () => {
1939
+ var keymapFacet = defineFacet({
1940
+ reduce: () => {
1782
1941
  let handler = null;
1783
1942
  const handlerWrapper = (view, event) => {
1784
1943
  if (handler)
@@ -1789,19 +1948,17 @@ var keymapFacet = Facet.define({
1789
1948
  key: keymapPluginKey,
1790
1949
  props: { handleKeyDown: handlerWrapper }
1791
1950
  });
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
- }
1951
+ return (keymaps) => {
1952
+ handler = keydownHandler(
1953
+ mergeKeymaps(
1954
+ // The keymap at the end have a higher priority.
1955
+ toReversed(keymaps)
1956
+ )
1957
+ );
1958
+ return plugin;
1802
1959
  };
1803
1960
  },
1804
- next: pluginFacet,
1961
+ parent: pluginFacet,
1805
1962
  singleton: true
1806
1963
  });
1807
1964
  function mergeKeymaps(keymaps) {
@@ -1827,7 +1984,7 @@ function defineHistory() {
1827
1984
  "Mod-z": undo,
1828
1985
  "Shift-Mod-z": redo
1829
1986
  };
1830
- if (!isMac) {
1987
+ if (!isApple) {
1831
1988
  keymap["Mod-y"] = redo;
1832
1989
  }
1833
1990
  return union([
@@ -1843,14 +2000,14 @@ function defineHistory() {
1843
2000
  // src/extensions/mark-spec.ts
1844
2001
  function defineMarkSpec(options) {
1845
2002
  const payload = [options, void 0];
1846
- return markSpecFacet.extension([payload]);
2003
+ return defineFacetPayload(markSpecFacet, [payload]);
1847
2004
  }
1848
2005
  function defineMarkAttr(options) {
1849
2006
  const payload = [void 0, options];
1850
- return markSpecFacet.extension([payload]);
2007
+ return defineFacetPayload(markSpecFacet, [payload]);
1851
2008
  }
1852
- var markSpecFacet = Facet.define({
1853
- convert: (payloads) => {
2009
+ var markSpecFacet = defineFacet({
2010
+ reducer: (payloads) => {
1854
2011
  const marks = {};
1855
2012
  const specPayloads = payloads.map((input) => input[0]).filter(isNotNull);
1856
2013
  const attrPayloads = payloads.map((input) => input[1]).filter(isNotNull);
@@ -1927,37 +2084,42 @@ var markSpecFacet = Facet.define({
1927
2084
  }
1928
2085
  return { marks, nodes: {} };
1929
2086
  },
1930
- next: schemaFacet,
2087
+ parent: schemaSpecFacet,
1931
2088
  singleton: true
1932
2089
  });
1933
2090
 
1934
2091
  // src/extensions/node-view.ts
1935
- import { ProseMirrorPlugin as ProseMirrorPlugin4 } from "@prosekit/pm/state";
2092
+ import { PluginKey as PluginKey5, ProseMirrorPlugin as ProseMirrorPlugin5 } from "@prosekit/pm/state";
1936
2093
  import "@prosekit/pm/view";
1937
2094
  function defineNodeView(options) {
1938
- return nodeViewFacet.extension([options]);
2095
+ return defineFacetPayload(nodeViewFacet, [options]);
1939
2096
  }
1940
- var nodeViewFacet = Facet.define({
1941
- convert: (inputs) => {
2097
+ var nodeViewFacet = defineFacet({
2098
+ reducer: (inputs) => {
1942
2099
  const nodeViews = {};
1943
2100
  for (const input of inputs) {
1944
2101
  if (!nodeViews[input.name]) {
1945
2102
  nodeViews[input.name] = input.constructor;
1946
2103
  }
1947
2104
  }
1948
- return () => [new ProseMirrorPlugin4({ props: { nodeViews } })];
2105
+ return () => [
2106
+ new ProseMirrorPlugin5({
2107
+ key: new PluginKey5("prosekit-node-view"),
2108
+ props: { nodeViews }
2109
+ })
2110
+ ];
1949
2111
  },
1950
- next: pluginFacet
2112
+ parent: pluginFacet
1951
2113
  });
1952
2114
 
1953
2115
  // src/extensions/node-view-effect.ts
1954
- import { ProseMirrorPlugin as ProseMirrorPlugin5 } from "@prosekit/pm/state";
2116
+ import { PluginKey as PluginKey6, ProseMirrorPlugin as ProseMirrorPlugin6 } from "@prosekit/pm/state";
1955
2117
  import "@prosekit/pm/view";
1956
2118
  function defineNodeViewFactory(options) {
1957
- return nodeViewFactoryFacet.extension([options]);
2119
+ return defineFacetPayload(nodeViewFactoryFacet, [options]);
1958
2120
  }
1959
- var nodeViewFactoryFacet = Facet.define({
1960
- convert: (inputs) => {
2121
+ var nodeViewFactoryFacet = defineFacet({
2122
+ reducer: (inputs) => {
1961
2123
  const nodeViews = {};
1962
2124
  const options = {};
1963
2125
  const factories = {};
@@ -1979,9 +2141,14 @@ var nodeViewFactoryFacet = Facet.define({
1979
2141
  nodeViews[name] = factory(args);
1980
2142
  }
1981
2143
  }
1982
- return () => [new ProseMirrorPlugin5({ props: { nodeViews } })];
2144
+ return () => [
2145
+ new ProseMirrorPlugin6({
2146
+ key: new PluginKey6("prosekit-node-view-effect"),
2147
+ props: { nodeViews }
2148
+ })
2149
+ ];
1983
2150
  },
1984
- next: pluginFacet
2151
+ parent: pluginFacet
1985
2152
  });
1986
2153
 
1987
2154
  // src/extensions/paragraph.ts
@@ -1997,7 +2164,7 @@ function defineParagraphSpec() {
1997
2164
  });
1998
2165
  }
1999
2166
  function defineParagraph() {
2000
- return withPriority(defineParagraphSpec(), 0 /* highest */);
2167
+ return withPriority(defineParagraphSpec(), 4 /* highest */);
2001
2168
  }
2002
2169
 
2003
2170
  // src/extensions/text.ts
@@ -2032,16 +2199,6 @@ var canUseRegexLookbehind = cache(() => {
2032
2199
  import clsxLite from "clsx/lite";
2033
2200
  var clsx = clsxLite;
2034
2201
 
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
2202
  // src/utils/get-id.ts
2046
2203
  var id = 0;
2047
2204
  function getId() {
@@ -2077,12 +2234,12 @@ function withSkipCodeBlock(command) {
2077
2234
  export {
2078
2235
  Editor,
2079
2236
  EditorNotFoundError,
2080
- Facet,
2081
2237
  OBJECT_REPLACEMENT_CHARACTER,
2082
2238
  Priority,
2083
2239
  ProseKitError,
2084
2240
  getId as _getId,
2085
2241
  addMark,
2242
+ assert,
2086
2243
  canUseRegexLookbehind,
2087
2244
  clsx,
2088
2245
  createEditor,
@@ -2099,6 +2256,8 @@ export {
2099
2256
  defineDoubleClickHandler,
2100
2257
  defineDoubleClickOnHandler,
2101
2258
  defineDropHandler,
2259
+ defineFacet,
2260
+ defineFacetPayload,
2102
2261
  defineFocusChangeHandler,
2103
2262
  defineHistory,
2104
2263
  defineKeyDownHandler,
@@ -2130,6 +2289,7 @@ export {
2130
2289
  htmlFromNode,
2131
2290
  insertNode,
2132
2291
  isAllSelection,
2292
+ isApple,
2133
2293
  isInCodeBlock,
2134
2294
  isMark,
2135
2295
  isMarkAbsent,