@prosekit/core 0.5.5 → 0.6.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.
@@ -27,6 +27,7 @@ import { Options } from 'tsup';
27
27
  import { Plugin as Plugin_2 } from '@prosekit/pm/state';
28
28
  import { ProseMirrorFragment } from '@prosekit/pm/model';
29
29
  import { ProseMirrorNode } from '@prosekit/pm/model';
30
+ import type { ResolvedPos } from '@prosekit/pm/model';
30
31
  import { Schema } from '@prosekit/pm/model';
31
32
  import { SchemaSpec } from '@prosekit/pm/model';
32
33
  import { Selection as Selection_2 } from '@prosekit/pm/state';
@@ -257,47 +258,51 @@ declare function defineBaseCommands(): Extension<{
257
258
  Commands: {
258
259
  insertText: [{
259
260
  text: string;
260
- from?: number | undefined;
261
- to?: number | undefined;
261
+ from?: number;
262
+ to?: number;
262
263
  }];
263
264
  insertNode: [options: {
264
265
  node: Node_2;
265
- pos?: number | undefined;
266
+ pos?: number;
266
267
  type?: undefined;
267
268
  attrs?: undefined;
268
269
  } | {
269
270
  node?: undefined;
270
- pos?: number | undefined;
271
+ pos?: number;
271
272
  type: string;
272
- attrs?: Attrs_2 | undefined;
273
+ attrs?: Attrs_2;
274
+ }];
275
+ removeNode: [options: {
276
+ type: string | NodeType_2;
277
+ pos?: number;
273
278
  }];
274
279
  wrap: [{
275
280
  nodeType: NodeType_2;
276
- attrs?: Attrs_2 | null | undefined;
281
+ attrs?: Attrs_2 | null;
277
282
  }];
278
283
  setBlockType: [options: {
279
- type: string | NodeType_2;
280
- attrs?: Attrs_2 | null | undefined;
281
- from?: number | undefined;
282
- to?: number | undefined;
284
+ type: NodeType_2 | string;
285
+ attrs?: Attrs_2 | null;
286
+ from?: number;
287
+ to?: number;
283
288
  }];
284
289
  setNodeAttrs: [options: {
285
290
  type: string | NodeType_2 | string[] | NodeType_2[];
286
291
  attrs: Attrs_2;
287
- pos?: number | undefined;
292
+ pos?: number;
288
293
  }];
289
294
  selectAll: [];
290
295
  addMark: [options: {
291
296
  type: string | MarkType_2;
292
- attrs?: Attrs_2 | null | undefined;
293
- from?: number | undefined;
294
- to?: number | undefined;
297
+ attrs?: Attrs_2 | null;
298
+ from?: number;
299
+ to?: number;
295
300
  }];
296
301
  removeMark: [options: {
297
302
  type: string | MarkType_2;
298
- attrs?: Attrs_2 | null | undefined;
299
- from?: number | undefined;
300
- to?: number | undefined;
303
+ attrs?: Attrs_2 | null;
304
+ from?: number;
305
+ to?: number;
301
306
  }];
302
307
  };
303
308
  Nodes: never;
@@ -457,10 +462,11 @@ export { defineFocusChangeHandler as defineFocusChangeHandler_alias_1 }
457
462
  * Add undo/redo history to the editor.
458
463
  */
459
464
  declare function defineHistory(): Extension< {
460
- Nodes: any;
461
- Marks: any;
465
+ Nodes: never;
466
+ Marks: never;
462
467
  Commands: {
463
- [x: string]: any;
468
+ undo: [];
469
+ redo: [];
464
470
  };
465
471
  }>;
466
472
  export { defineHistory }
@@ -931,7 +937,7 @@ export { ExtractNodes as ExtractNodes_alias_1 }
931
937
  /**
932
938
  * @internal
933
939
  */
934
- export declare type ExtractTyping<E extends Extension> = E extends Extension<infer T> ? T : never;
940
+ export declare type ExtractTyping<E extends Extension> = E extends Extension<ExtensionTyping<infer N, infer M, infer C>> ? ExtensionTyping<PickStringLiteral<N>, PickStringLiteral<M>, PickKnownCommandTyping<C>> : never;
935
941
 
936
942
  /**
937
943
  * @internal
@@ -987,9 +993,9 @@ export declare class FacetNode<I = any, O = any> {
987
993
  readonly facet: Facet<I, O>;
988
994
  readonly inputs: Tuple5<I[] | null>;
989
995
  readonly children: Map<number, FacetNode>;
990
- reducers: Tuple5<FacetReducer<I, O> | null>;
996
+ readonly reducers: Tuple5<FacetReducer<I, O> | null>;
991
997
  output: Tuple5<O | null> | null;
992
- constructor(facet: Facet<I, O>, inputs?: Tuple5<I[] | null>, children?: Map<number, FacetNode>);
998
+ constructor(facet: Facet<I, O>, inputs?: Tuple5<I[] | null>, children?: Map<number, FacetNode>, reducers?: Tuple5<FacetReducer<I, O> | null>);
993
999
  private calcOutput;
994
1000
  getOutput(): Tuple5<O | null>;
995
1001
  getSingletonOutput(): O | null;
@@ -1010,6 +1016,11 @@ export declare function findBrowserWindow(options?: {
1010
1016
  document?: Document;
1011
1017
  }): (Window & typeof globalThis) | null | undefined;
1012
1018
 
1019
+ export declare function findParentNode(nodeType: NodeType, $pos: ResolvedPos): {
1020
+ from: number | null;
1021
+ to: number | null;
1022
+ };
1023
+
1013
1024
  /**
1014
1025
  * A function that is called when the editor gains or loses focus.
1015
1026
  *
@@ -1491,6 +1502,18 @@ export { PasteHandler as PasteHandler_alias_1 }
1491
1502
  */
1492
1503
  export declare type Payloads<T> = Tuple5<T[]>;
1493
1504
 
1505
+ /**
1506
+ * @internal
1507
+ */
1508
+ export declare type PickKnownCommandTyping<T extends CommandTyping> = [
1509
+ CommandTyping
1510
+ ] extends [T] ? never : T;
1511
+
1512
+ /**
1513
+ * @internal
1514
+ */
1515
+ export declare type PickStringLiteral<T extends string> = [string] extends [T] ? never : T;
1516
+
1494
1517
  /**
1495
1518
  * @internal
1496
1519
  */
@@ -1558,6 +1581,24 @@ declare function removeMark(options: {
1558
1581
  export { removeMark }
1559
1582
  export { removeMark as removeMark_alias_1 }
1560
1583
 
1584
+ /**
1585
+ * Returns a command to remove the nearest ancestor node of a specific type from the current position.
1586
+ *
1587
+ * @public
1588
+ */
1589
+ declare function removeNode(options: {
1590
+ /**
1591
+ * The type of the node to remove.
1592
+ */
1593
+ type: string | NodeType;
1594
+ /**
1595
+ * The document position to start searching node. By default it will be the anchor position of current selection.
1596
+ */
1597
+ pos?: number;
1598
+ }): Command;
1599
+ export { removeNode }
1600
+ export { removeNode as removeNode_alias_1 }
1601
+
1561
1602
  export declare const rootFacet: Facet<RootPayload, RootOutput>;
1562
1603
 
1563
1604
  export declare type RootOutput = {
@@ -1652,7 +1693,7 @@ export declare function setSelectionAround(tr: Transaction, pos: number): void;
1652
1693
  export declare type Setter<T> = (value: T) => void;
1653
1694
 
1654
1695
  /**
1655
- * @intneral
1696
+ * @internal
1656
1697
  */
1657
1698
  declare type SimplifyUnion<T> = Simplify<UnionToIntersection<T>>;
1658
1699
  export { SimplifyUnion }
@@ -1691,6 +1732,14 @@ export declare type StatePayload = (ctx: {
1691
1732
  schema: Schema;
1692
1733
  }) => EditorStateConfig;
1693
1734
 
1735
+ /**
1736
+ * Takes two facet nodes and returns a new facet node containing inputs and
1737
+ * children from the first node but not the second.
1738
+ *
1739
+ * The reducers of the first facet node will be reused.
1740
+ *
1741
+ * @internal
1742
+ */
1694
1743
  export declare function subtractFacetNode<I, O>(a: FacetNode<I, O>, b: FacetNode<I, O>): FacetNode<I, O>;
1695
1744
 
1696
1745
  declare type TextInputHandler = (view: EditorView, from: number, to: number, text: string) => boolean | void;
@@ -1748,16 +1797,18 @@ export declare type Tuple5<T> = [T, T, T, T, T];
1748
1797
  /**
1749
1798
  * Merge multiple extensions into one.
1750
1799
  *
1800
+ * @throws If no extensions are provided.
1801
+ *
1751
1802
  * @public
1752
1803
  */
1753
- declare function union<E extends Extension | Extension[]>(extension: E): UnionExtension<E>;
1804
+ declare function union<const E extends Extension | readonly Extension[]>(extension: E): UnionExtension<E>;
1754
1805
  export { union }
1755
1806
  export { union as union_alias_1 }
1756
1807
 
1757
1808
  /**
1758
1809
  * @internal
1759
1810
  */
1760
- declare type UnionExtension<E extends Extension | Extension[]> = E extends Extension[] ? Extension<{
1811
+ declare type UnionExtension<E extends Extension | readonly Extension[]> = E extends readonly Extension[] ? Extension<{
1761
1812
  Nodes: ExtractNodes<E[number]>;
1762
1813
  Marks: ExtractMarks<E[number]>;
1763
1814
  Commands: ExtractCommands<E[number]>;
@@ -1777,6 +1828,14 @@ export declare class UnionExtensionImpl<T extends ExtensionTyping = ExtensionTyp
1777
1828
  createTree(priority: Priority): FacetNode;
1778
1829
  }
1779
1830
 
1831
+ /**
1832
+ * Takes two facet nodes and returns a new facet node containing inputs and
1833
+ * children from both nodes.
1834
+ *
1835
+ * The reducers of the first facet node will be reused.
1836
+ *
1837
+ * @internal
1838
+ */
1780
1839
  export declare function unionFacetNode<I, O>(a: FacetNode<I, O>, b: FacetNode<I, O>): FacetNode<I, O>;
1781
1840
 
1782
1841
  export declare function uniqPush<T>(prev: readonly T[], next: readonly T[]): T[];
@@ -2,6 +2,7 @@ export { addMark } from './_tsup-dts-rollup';
2
2
  export { expandMark } from './_tsup-dts-rollup';
3
3
  export { insertNode } from './_tsup-dts-rollup';
4
4
  export { removeMark } from './_tsup-dts-rollup';
5
+ export { removeNode } from './_tsup-dts-rollup';
5
6
  export { setBlockType } from './_tsup-dts-rollup';
6
7
  export { setNodeAttrs } from './_tsup-dts-rollup';
7
8
  export { toggleMark } from './_tsup-dts-rollup';
@@ -128,6 +128,30 @@ function removeMark(options) {
128
128
  };
129
129
  }
130
130
 
131
+ // src/utils/find-parent-node.ts
132
+ function findParentNode(nodeType, $pos) {
133
+ for (let depth = $pos.depth; depth > 0; depth -= 1)
134
+ if ($pos.node(depth).type === nodeType) {
135
+ let from = $pos.before(depth), to = $pos.after(depth);
136
+ return {
137
+ from,
138
+ to
139
+ };
140
+ }
141
+ return {
142
+ from: null,
143
+ to: null
144
+ };
145
+ }
146
+
147
+ // src/commands/remove-node.ts
148
+ function removeNode(options) {
149
+ return (state, dispatch) => {
150
+ let nodeType = getNodeType(state.schema, options.type), $pos = typeof options.pos == "number" ? state.doc.resolve(options.pos) : state.selection.$anchor, { from, to } = findParentNode(nodeType, $pos);
151
+ return from == null || to == null || from > to ? !1 : (dispatch == null || dispatch(state.tr.delete(from, to)), !0);
152
+ };
153
+ }
154
+
131
155
  // src/commands/set-block-type.ts
132
156
  import "@prosekit/pm/state";
133
157
 
@@ -334,6 +358,11 @@ function toReversed(arr) {
334
358
  return (_b = (_a = arr.toReversed) == null ? void 0 : _a.call(arr)) != null ? _b : [...arr].reverse();
335
359
  }
336
360
 
361
+ // src/utils/is-not-null.ts
362
+ function isNotNull(value) {
363
+ return value != null;
364
+ }
365
+
337
366
  // src/facets/facet-node.ts
338
367
  function zip5(a, b, mapper) {
339
368
  return [
@@ -370,22 +399,30 @@ function unionFacetNode(a, b) {
370
399
  return assert(a.facet === b.facet), new FacetNode(
371
400
  a.facet,
372
401
  zip5(a.inputs, b.inputs, unionInput),
373
- unionChildren(a.children, b.children)
402
+ unionChildren(a.children, b.children),
403
+ a.reducers
374
404
  );
375
405
  }
376
406
  function subtractFacetNode(a, b) {
377
407
  return assert(a.facet === b.facet), new FacetNode(
378
408
  a.facet,
379
409
  zip5(a.inputs, b.inputs, subtractInput),
380
- subtractChildren(a.children, b.children)
410
+ subtractChildren(a.children, b.children),
411
+ a.reducers
381
412
  );
382
413
  }
383
414
  var FacetNode = class {
384
- constructor(facet, inputs = [null, null, null, null, null], children = /* @__PURE__ */ new Map()) {
415
+ constructor(facet, inputs = [null, null, null, null, null], children = /* @__PURE__ */ new Map(), reducers = [
416
+ null,
417
+ null,
418
+ null,
419
+ null,
420
+ null
421
+ ]) {
385
422
  this.facet = facet;
386
423
  this.inputs = inputs;
387
424
  this.children = children;
388
- this.reducers = [null, null, null, null, null];
425
+ this.reducers = reducers;
389
426
  this.output = null;
390
427
  }
391
428
  calcOutput() {
@@ -401,7 +438,7 @@ var FacetNode = class {
401
438
  childOutput[pri] && (inputs[pri] || (inputs[pri] = [])).push(childOutput[pri]);
402
439
  }
403
440
  if (this.facet.singleton) {
404
- let reducer = (_a = this.reducers)[_b = 2 /* default */] || (_a[_b] = this.facet.reducer), input = inputs.filter(Boolean).flat();
441
+ let reducer = (_a = this.reducers)[_b = 2 /* default */] || (_a[_b] = this.facet.reducer), input = inputs.filter(isNotNull).flat();
405
442
  output[2 /* default */] = reducer(input);
406
443
  } else
407
444
  for (let pri = 0; pri < 5; pri++) {
@@ -797,17 +834,23 @@ var UnionExtensionImpl = class extends BaseExtension {
797
834
  createTree(priority) {
798
835
  var _a;
799
836
  let pri = (_a = this.priority) != null ? _a : priority, extensions = [...this.extension];
800
- return extensions.sort((a, b) => {
837
+ extensions.sort((a, b) => {
801
838
  var _a2, _b;
802
839
  return ((_a2 = a.priority) != null ? _a2 : pri) - ((_b = b.priority) != null ? _b : pri);
803
- }), extensions.map((ext) => ext.getTree(pri)).reduce(unionFacetNode, new FacetNode(rootFacet));
840
+ });
841
+ let children = extensions.map((ext) => ext.getTree(pri));
842
+ assert(children.length > 0);
843
+ let node = children[0];
844
+ for (let i = 1; i < children.length; i++)
845
+ node = unionFacetNode(node, children[i]);
846
+ return node;
804
847
  }
805
848
  };
806
849
 
807
850
  // src/editor/union.ts
808
851
  function union(extension) {
809
852
  let array = Array.isArray(extension) ? extension : [extension];
810
- return new UnionExtensionImpl(
853
+ return assert(array.length > 0, "At least one extension is required"), new UnionExtensionImpl(
811
854
  array
812
855
  );
813
856
  }
@@ -908,7 +951,7 @@ var EditorInstance = class {
908
951
  defineCommand(name, commandCreator) {
909
952
  let applier = (...args) => {
910
953
  let view = this.view;
911
- return view ? commandCreator(...args)(view.state, view.dispatch.bind(view), view) : !1;
954
+ return assert(view, `Cannot call command "${name}" before the editor is mounted`), commandCreator(...args)(view.state, view.dispatch.bind(view), view);
912
955
  };
913
956
  applier.canApply = (...args) => {
914
957
  let view = this.view;
@@ -1062,6 +1105,7 @@ function defineBaseCommands() {
1062
1105
  return defineCommands({
1063
1106
  insertText,
1064
1107
  insertNode,
1108
+ removeNode,
1065
1109
  wrap,
1066
1110
  setBlockType,
1067
1111
  setNodeAttrs,
@@ -1095,11 +1139,6 @@ function isElement(value) {
1095
1139
  return hasElement && value instanceof Element;
1096
1140
  }
1097
1141
 
1098
- // src/utils/is-not-null.ts
1099
- function isNotNull(value) {
1100
- return value != null;
1101
- }
1102
-
1103
1142
  // src/extensions/node-spec.ts
1104
1143
  function defineNodeSpec(options) {
1105
1144
  return defineFacetPayload(nodeSpecFacet, [[options, void 0]]);
@@ -1758,6 +1797,7 @@ export {
1758
1797
  nodeFromJSON,
1759
1798
  pluginFacet,
1760
1799
  removeMark,
1800
+ removeNode,
1761
1801
  setBlockType,
1762
1802
  setNodeAttrs,
1763
1803
  stateFromJSON,
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@prosekit/core",
3
3
  "type": "module",
4
- "version": "0.5.5",
4
+ "version": "0.6.1",
5
5
  "private": false,
6
6
  "author": {
7
7
  "name": "ocavue",
@@ -38,12 +38,12 @@
38
38
  "clsx": "^2.1.1",
39
39
  "orderedmap": "^2.1.1",
40
40
  "prosemirror-splittable": "^0.1.1",
41
- "type-fest": "^4.19.0",
41
+ "type-fest": "^4.20.1",
42
42
  "@prosekit/pm": "^0.1.5"
43
43
  },
44
44
  "devDependencies": {
45
45
  "tsup": "^8.1.0",
46
- "typescript": "^5.4.5",
46
+ "typescript": "^5.5.2",
47
47
  "vitest": "^1.6.0",
48
48
  "@prosekit/dev": "0.0.0"
49
49
  },