@prosekit/core 0.0.5 → 0.0.7

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.
@@ -16,6 +16,20 @@ interface ToggleNodeOptions {
16
16
  }
17
17
  declare function toggleNode(options: ToggleNodeOptions): Command;
18
18
 
19
+ interface AddMarkOptions {
20
+ type: string | MarkType;
21
+ attrs?: Attrs | null;
22
+ /**
23
+ * The start position of the mark. By default it will be the start position of current selection.
24
+ */
25
+ from?: number;
26
+ /**
27
+ * The end position of the mark. By default it will be the end position of current selection.
28
+ */
29
+ to?: number;
30
+ }
31
+ declare function addMark(options: AddMarkOptions): Command;
32
+
19
33
  type CommandDispatcher<Args extends any[] = any[]> = (...arg: Args) => boolean;
20
34
  type CommandCreator<Args extends any[] = any[]> = (...arg: Args) => Command;
21
35
  /** @internal */
@@ -130,23 +144,32 @@ declare class Editor<E extends Extension = any> {
130
144
  isMarkActive(markType: string | MarkType, attrs?: Attrs): boolean;
131
145
  }
132
146
 
147
+ interface Slot<Input, Output> {
148
+ create: (inputs: Input[]) => Output;
149
+ update: (inputs: Input[]) => Output | null;
150
+ }
151
+
133
152
  /** @public */
134
153
  interface FacetOptions<Input, Output> {
135
- combine: (inputs: Input[]) => Output;
154
+ combine?: (inputs: Input[]) => Output;
155
+ slot?: () => Slot<Input, Output>;
136
156
  next: Facet<Output, any>;
157
+ single?: boolean;
137
158
  }
138
159
  /** @public */
139
160
  declare class Facet<Input, Output> {
140
161
  /** @internal */
141
162
  readonly index: number;
142
163
  /** @internal */
143
- readonly combine: (inputs: Input[]) => Output;
164
+ readonly slot: () => Slot<Input, Output>;
144
165
  /** @internal */
145
166
  readonly next: Facet<Output, any> | null;
167
+ /** @internal */
168
+ readonly single: boolean;
146
169
  private constructor();
147
- static define<Input, Output>({ combine, next }: FacetOptions<Input, Output>): Facet<Input, Output>;
170
+ static define<Input, Output>({ slot, combine, next, single, }: FacetOptions<Input, Output>): Facet<Input, Output>;
148
171
  /** @internal */
149
- static defineSlot<Input>({ combine, }: Omit<FacetOptions<Input, Input>, 'next'>): Facet<Input, Input>;
172
+ static defineSlot<Input>(options: Omit<FacetOptions<Input, Input>, 'next'>): Facet<Input, Input>;
150
173
  extension(inputs: Input[]): FacetExtension<Input, Output>;
151
174
  }
152
175
  /** @public */
@@ -208,7 +231,9 @@ declare function addDoc(): Extension<{
208
231
  NODES: "doc";
209
232
  }>;
210
233
 
211
- /** @public */
234
+ /**
235
+ * @public
236
+ */
212
237
  declare function addInputRule(rules: (context: {
213
238
  schema: Schema;
214
239
  }) => InputRule[]): Extension;
@@ -225,9 +250,8 @@ declare function addBaseKeymap(): Extension<ExtensionTyping<string, string, Comm
225
250
  /**
226
251
  * @public
227
252
  */
228
- interface MarkSpecOptions<M extends string = string> {
229
- name: M;
230
- spec: MarkSpec;
253
+ interface MarkSpecOptions<MarkName extends string = string> extends MarkSpec {
254
+ name: MarkName;
231
255
  }
232
256
  /**
233
257
  * @public
@@ -239,16 +263,15 @@ declare function addMarkSpec<Mark extends string>(options: MarkSpecOptions<Mark>
239
263
  /**
240
264
  * @public
241
265
  */
242
- interface NodeSpecOptions<N extends string = string> {
243
- name: N;
244
- spec: NodeSpec;
266
+ interface NodeSpecOptions<NodeName extends string = string> extends NodeSpec {
267
+ name: NodeName;
245
268
  topNode?: boolean;
246
269
  }
247
270
  /**
248
271
  * @public
249
272
  */
250
- declare function addNodeSpec<Node extends string>(options: NodeSpecOptions<Node>): Extension<{
251
- NODES: Node;
273
+ declare function addNodeSpec<NodeName extends string>(options: NodeSpecOptions<NodeName>): Extension<{
274
+ NODES: NodeName;
252
275
  }>;
253
276
 
254
277
  interface NodeViewOptions {
@@ -294,4 +317,4 @@ declare function getMarkType(schema: Schema, type: string | MarkType): MarkType;
294
317
  /** @internal */
295
318
  declare function getNodeType(schema: Schema, type: string | NodeType): NodeType;
296
319
 
297
- export { CommandArgs, Editor, EditorOptions, Extension, ExtensionTyping, ExtractCommandCreators, ExtractCommandDispatchers, ExtractMarks, ExtractNodes, Facet, FacetExtension, FacetOptions, Keymap, MarkSpecOptions, NodeSpecOptions, NodeViewOptions, PluginFacetInput, PluginOptions, Priority, ProseKitError, SimplifyUnion, StateConfigCallback, StateConfigContext, ToggleMarkOptions, ToggleNodeOptions, ViewProps, addBaseCommands, addBaseKeymap, addCommands, addDoc, addInputRule, addKeymap, addMarkSpec, addNodeSpec, addNodeView, addParagraph, addPlugin, addText, createEditor, defineExtension, getMarkType, getNodeType, pluginFacet, toggleMark, toggleNode, withPriority };
320
+ export { AddMarkOptions, CommandArgs, Editor, EditorOptions, Extension, ExtensionTyping, ExtractCommandCreators, ExtractCommandDispatchers, ExtractMarks, ExtractNodes, Facet, FacetExtension, FacetOptions, Keymap, MarkSpecOptions, NodeSpecOptions, NodeViewOptions, PluginFacetInput, PluginOptions, Priority, ProseKitError, SimplifyExtension, SimplifyUnion, StateConfigCallback, StateConfigContext, ToggleMarkOptions, ToggleNodeOptions, ViewProps, addBaseCommands, addBaseKeymap, addCommands, addDoc, addInputRule, addKeymap, addMark, addMarkSpec, addNodeSpec, addNodeView, addParagraph, addPlugin, addText, createEditor, defineExtension, getMarkType, getNodeType, pluginFacet, toggleMark, toggleNode, withPriority };
@@ -109,15 +109,28 @@ function toggleNode(options) {
109
109
  };
110
110
  }
111
111
 
112
+ // src/commands/add-mark.ts
113
+ import "@prosekit/pm/model";
114
+ import "@prosekit/pm/state";
115
+ function addMark(options) {
116
+ return (state, dispatch) => {
117
+ var _a, _b;
118
+ const mark = getMarkType(state.schema, options.type).create(options.attrs);
119
+ const from = (_a = options.from) != null ? _a : state.selection.from;
120
+ const to = (_b = options.to) != null ? _b : state.selection.to;
121
+ if (from > to) {
122
+ return false;
123
+ }
124
+ dispatch == null ? void 0 : dispatch(state.tr.addMark(from, to, mark));
125
+ return true;
126
+ };
127
+ }
128
+
112
129
  // src/editor/editor.ts
113
130
  import { Schema as Schema3 } from "@prosekit/pm/model";
114
131
  import { EditorState } from "@prosekit/pm/state";
115
132
  import { EditorView } from "@prosekit/pm/view";
116
133
 
117
- // src/types/void-function.ts
118
- function voidFunction() {
119
- }
120
-
121
134
  // src/utils/is-mark-active.ts
122
135
  function isMarkActive(state, type, attrs) {
123
136
  const markType = getMarkType(state.schema, type);
@@ -136,23 +149,57 @@ var Priority = /* @__PURE__ */ ((Priority2) => {
136
149
  return Priority2;
137
150
  })(Priority || {});
138
151
 
152
+ // src/utils/uniq-array.ts
153
+ function uniqPush(prev, next) {
154
+ const result = [...prev];
155
+ for (const item of next) {
156
+ if (!result.includes(item)) {
157
+ result.push(item);
158
+ }
159
+ }
160
+ return result;
161
+ }
162
+ function uniqRemove(prev, next) {
163
+ const result = [...prev];
164
+ for (const item of next) {
165
+ const index = result.indexOf(item);
166
+ if (index !== -1) {
167
+ result.splice(index, 1);
168
+ }
169
+ }
170
+ return result;
171
+ }
172
+
139
173
  // src/editor/facet.ts
140
174
  var nextIndex = 0;
141
175
  var Facet = class _Facet {
142
- constructor(combine, next) {
176
+ constructor(slot, next, single) {
143
177
  /** @internal */
144
178
  this.index = nextIndex++;
145
- this.combine = combine;
179
+ this.slot = slot;
146
180
  this.next = next;
181
+ this.single = single;
147
182
  }
148
- static define({ combine, next }) {
149
- return new _Facet(combine, next);
183
+ static define({
184
+ slot,
185
+ combine,
186
+ next,
187
+ single
188
+ }) {
189
+ const slotFn = slot ? slot : combine ? () => ({
190
+ create: combine,
191
+ update: combine
192
+ }) : null;
193
+ if (!slotFn) {
194
+ throw new ProseKitError(
195
+ "Facet must have either 'slot' or 'combine' option"
196
+ );
197
+ }
198
+ return new _Facet(slotFn, next, single != null ? single : false);
150
199
  }
151
200
  /** @internal */
152
- static defineSlot({
153
- combine
154
- }) {
155
- return new _Facet(combine, null);
201
+ static defineSlot(options) {
202
+ return _Facet.define(options);
156
203
  }
157
204
  extension(inputs) {
158
205
  return new FacetExtension(this, inputs);
@@ -215,7 +262,7 @@ function sortFacets(unsorted) {
215
262
  return sortedFacets;
216
263
  }
217
264
 
218
- // src/editor/slot.ts
265
+ // src/editor/slots.ts
219
266
  import OrderedMap from "orderedmap";
220
267
  var schemaSlot = Facet.defineSlot({
221
268
  combine: (specs) => {
@@ -234,7 +281,7 @@ var schemaSlot = Facet.defineSlot({
234
281
  var stateSlot = Facet.defineSlot({
235
282
  combine: (callbacks) => {
236
283
  return (ctx) => {
237
- var _a, _b, _c, _d, _e;
284
+ var _a, _b, _c, _d, _e, _f;
238
285
  const configs = callbacks.map((cb) => cb(ctx));
239
286
  const config = {
240
287
  schema: ctx.schema,
@@ -246,7 +293,7 @@ var stateSlot = Facet.defineSlot({
246
293
  config.doc = (_b = config.doc) != null ? _b : c.doc;
247
294
  config.selection = (_c = config.selection) != null ? _c : c.selection;
248
295
  config.storedMarks = [...config.storedMarks, ...(_d = c.storedMarks) != null ? _d : []];
249
- config.plugins = [...config.plugins, ...(_e = c.plugins) != null ? _e : []];
296
+ config.plugins = uniqPush((_e = config.plugins) != null ? _e : [], (_f = c.plugins) != null ? _f : []);
250
297
  }
251
298
  if (!config.doc && !config.schema) {
252
299
  throw new Error("Can't create state without a schema nor a document");
@@ -270,7 +317,46 @@ var commandSlot = Facet.defineSlot({
270
317
  });
271
318
 
272
319
  // src/editor/flatten.ts
273
- function flatten(root) {
320
+ function flattenInputTuple(inputTuple) {
321
+ return [
322
+ ...inputTuple[0],
323
+ ...inputTuple[1],
324
+ ...inputTuple[2],
325
+ ...inputTuple[3],
326
+ ...inputTuple[4]
327
+ ];
328
+ }
329
+ function mergeInputTuple(tupleA, tupleB) {
330
+ if (!tupleA)
331
+ return tupleB;
332
+ if (!tupleB)
333
+ return tupleA;
334
+ const [a0, a1, a2, a3, a4] = tupleA;
335
+ const [b0, b1, b2, b3, b4] = tupleB;
336
+ return [
337
+ uniqPush(a0, b0),
338
+ uniqPush(a1, b1),
339
+ uniqPush(a2, b2),
340
+ uniqPush(a3, b3),
341
+ uniqPush(a4, b4)
342
+ ];
343
+ }
344
+ function removeInputTuple(tupleA, tupleB) {
345
+ if (!tupleA)
346
+ return [[], [], [], [], []];
347
+ if (!tupleB)
348
+ return tupleA;
349
+ const [a0, a1, a2, a3, a4] = tupleA;
350
+ const [b0, b1, b2, b3, b4] = tupleB;
351
+ return [
352
+ uniqRemove(a0, b0),
353
+ uniqRemove(a1, b1),
354
+ uniqRemove(a2, b2),
355
+ uniqRemove(a3, b3),
356
+ uniqRemove(a4, b4)
357
+ ];
358
+ }
359
+ function extractFacets(root) {
274
360
  var _a;
275
361
  const extensions = [root];
276
362
  const priorities = [2 /* default */];
@@ -302,43 +388,97 @@ function flatten(root) {
302
388
  throw new Error("Invalid extension");
303
389
  }
304
390
  }
391
+ return [facets, inputs];
392
+ }
393
+ function updateExtension(prevInputs, prevSlots, extension, mode) {
394
+ const modifyInputTuple = mode === "add" ? mergeInputTuple : removeInputTuple;
395
+ const [facets, inputs] = extractFacets(extension);
305
396
  let schemaInput = null;
306
397
  let stateInput = null;
307
398
  let viewInput = null;
308
399
  let commandInput = null;
309
- const sortedFacets = sortFacets(facets);
310
- for (const facet of sortedFacets) {
311
- const nextFacet = facet.next;
312
- if (nextFacet) {
400
+ for (const facet of sortFacets(facets)) {
401
+ if (!inputs[facet.index]) {
402
+ continue;
403
+ }
404
+ const inputTuple = modifyInputTuple(
405
+ prevInputs[facet.index],
406
+ inputs[facet.index]
407
+ );
408
+ prevInputs[facet.index] = inputTuple;
409
+ if (facet.next && !facet.single) {
410
+ let hasOutput = false;
411
+ const outputTuple = [[], [], [], [], []];
313
412
  for (let pri = 0; pri < 5; pri++) {
314
- const input = inputs[facet.index][pri];
315
- if (input.length > 0) {
316
- const output = facet.combine(input);
317
- if (!inputs[nextFacet.index]) {
318
- inputs[nextFacet.index] = [[], [], [], [], []];
319
- }
320
- inputs[nextFacet.index][pri].push(output);
413
+ const inputArray = inputTuple[pri];
414
+ if (inputArray.length === 0) {
415
+ continue;
416
+ }
417
+ const slotTuple = prevSlots[facet.index] || (prevSlots[facet.index] = [
418
+ void 0,
419
+ void 0,
420
+ void 0,
421
+ void 0,
422
+ void 0
423
+ ]);
424
+ const prevSlot = slotTuple[pri];
425
+ const slot = prevSlot || facet.slot();
426
+ prevSlots[facet.index][pri] = slot;
427
+ const output = prevSlot ? slot.update(inputArray) : slot.create(inputArray);
428
+ if (!output) {
429
+ continue;
321
430
  }
431
+ hasOutput = true;
432
+ outputTuple[pri].push(output);
322
433
  }
323
- } else if (inputs[facet.index]) {
324
- const [i1, i2, i3, i4, i5] = inputs[facet.index];
325
- const jointInputs = [...i1, ...i2, ...i3, ...i4, ...i5];
326
- const output = facet.combine(jointInputs);
327
- switch (facet) {
328
- case schemaSlot:
329
- schemaInput = output;
330
- break;
331
- case stateSlot:
332
- stateInput = output;
333
- break;
334
- case viewSlot:
335
- viewInput = output;
336
- break;
337
- case commandSlot:
338
- commandInput = output;
339
- break;
340
- default:
341
- throw new Error("Invalid facet");
434
+ if (!hasOutput) {
435
+ continue;
436
+ }
437
+ inputs[facet.next.index] = modifyInputTuple(
438
+ inputs[facet.next.index],
439
+ outputTuple
440
+ );
441
+ continue;
442
+ } else {
443
+ const inputArray = flattenInputTuple(inputTuple);
444
+ const slotTuple = prevSlots[facet.index] || (prevSlots[facet.index] = [
445
+ void 0,
446
+ void 0,
447
+ void 0,
448
+ void 0,
449
+ void 0
450
+ ]);
451
+ const prevSlot = slotTuple[2 /* default */];
452
+ const slot = prevSlot || facet.slot();
453
+ prevSlots[facet.index][2 /* default */] = slot;
454
+ const output = prevSlot ? slot.update(inputArray) : slot.create(inputArray);
455
+ if (!output) {
456
+ continue;
457
+ }
458
+ const outputTuple = [[], [], [output], [], []];
459
+ if (facet.next) {
460
+ inputs[facet.next.index] = modifyInputTuple(
461
+ inputs[facet.next.index],
462
+ outputTuple
463
+ );
464
+ continue;
465
+ } else {
466
+ switch (facet) {
467
+ case schemaSlot:
468
+ schemaInput = output;
469
+ break;
470
+ case stateSlot:
471
+ stateInput = output;
472
+ break;
473
+ case viewSlot:
474
+ viewInput = output;
475
+ break;
476
+ case commandSlot:
477
+ commandInput = output;
478
+ break;
479
+ default:
480
+ throw new Error("Invalid facet");
481
+ }
342
482
  }
343
483
  }
344
484
  }
@@ -349,30 +489,58 @@ function flatten(root) {
349
489
  function createEditor({
350
490
  extension
351
491
  }) {
352
- const { schemaInput, stateInput, viewInput, commandInput } = flatten(extension);
353
- if (!schemaInput) {
354
- throw new Error("Schema must be defined");
355
- }
356
- const schema = new Schema3(schemaInput);
357
- const stateConfig = stateInput ? stateInput({ schema }) : { schema };
358
- const state = EditorState.create(stateConfig);
359
- const directEditorProps = { state, ...viewInput };
360
- const instance = new EditorInstance(directEditorProps);
361
- if (commandInput) {
362
- for (const [name, commandCreator] of Object.entries(commandInput)) {
363
- instance.addCommand(name, commandCreator);
364
- }
365
- }
366
- return Editor.create(instance);
492
+ const instance = new EditorInstance(extension);
493
+ const editor = Editor.create(instance);
494
+ return editor;
367
495
  }
368
496
  var EditorInstance = class {
369
- constructor(directEditorProps) {
370
- this.directEditorProps = directEditorProps;
497
+ constructor(extension) {
371
498
  this.view = null;
372
499
  this.commandDispatchers = {};
500
+ this.inputs = [];
501
+ this.slots = [];
373
502
  this.mount = this.mount.bind(this);
374
503
  this.unmount = this.unmount.bind(this);
375
- this.schema = directEditorProps.state.schema;
504
+ const { schemaInput, stateInput, viewInput, commandInput } = updateExtension(this.inputs, this.slots, extension, "add");
505
+ if (!schemaInput) {
506
+ throw new Error("Schema must be defined");
507
+ }
508
+ const schema = new Schema3(schemaInput);
509
+ const stateConfig = stateInput ? stateInput({ schema }) : { schema };
510
+ const state = EditorState.create(stateConfig);
511
+ if (commandInput) {
512
+ for (const [name, commandCreator] of Object.entries(commandInput)) {
513
+ this.addCommand(name, commandCreator);
514
+ }
515
+ }
516
+ this.directEditorProps = { state, ...viewInput };
517
+ this.schema = this.directEditorProps.state.schema;
518
+ }
519
+ updateExtension(extension, mode) {
520
+ var _a;
521
+ const { schemaInput, stateInput, viewInput, commandInput } = updateExtension(this.inputs, this.slots, extension, mode);
522
+ if (schemaInput) {
523
+ throw new ProseKitError("Schema cannot be changed");
524
+ }
525
+ if (viewInput) {
526
+ throw new ProseKitError("View cannot be changed");
527
+ }
528
+ const plugins = (_a = stateInput == null ? void 0 : stateInput({ schema: this.schema })) == null ? void 0 : _a.plugins;
529
+ if (plugins && plugins.length > 0) {
530
+ if (!this.view) {
531
+ throw new ProseKitError(
532
+ "Unexpected inner state: EditorInstance.view is not defined"
533
+ );
534
+ }
535
+ const state = this.view.state.reconfigure({ plugins });
536
+ this.view.updateState(state);
537
+ }
538
+ if (commandInput) {
539
+ const names = Object.keys(commandInput);
540
+ for (const name of names) {
541
+ this.addCommand(name, commandInput[name]);
542
+ }
543
+ }
376
544
  }
377
545
  mount(place) {
378
546
  if (this.view) {
@@ -434,7 +602,7 @@ var Editor = class _Editor {
434
602
  /** @internal */
435
603
  static create(instance) {
436
604
  if (!(instance instanceof EditorInstance)) {
437
- throw new TypeError("Editor's instance is not EditorInstance");
605
+ throw new TypeError("Invalid EditorInstance");
438
606
  }
439
607
  return new _Editor(instance);
440
608
  }
@@ -473,33 +641,8 @@ var Editor = class _Editor {
473
641
  lazyRemove == null ? void 0 : lazyRemove();
474
642
  };
475
643
  }
476
- const { schemaInput, stateInput, viewInput, commandInput } = flatten(extension);
477
- if (schemaInput) {
478
- throw new ProseKitError("Schema cannot be changed");
479
- }
480
- if (viewInput) {
481
- throw new ProseKitError("View cannot be changed");
482
- }
483
- if (stateInput) {
484
- const stateConfig = stateInput({ schema: this.schema });
485
- const plugins = stateConfig.plugins;
486
- if (plugins && plugins.length > 0) {
487
- this.instance.addPlugins(plugins);
488
- return () => this.instance.removePlugins(plugins);
489
- }
490
- }
491
- if (commandInput) {
492
- const names = Object.keys(commandInput);
493
- for (const name of names) {
494
- this.instance.addCommand(name, commandInput[name]);
495
- }
496
- return () => {
497
- for (const name of names) {
498
- this.instance.removeCommand(name);
499
- }
500
- };
501
- }
502
- return voidFunction;
644
+ this.instance.updateExtension(extension, "add");
645
+ return () => this.instance.updateExtension(extension, "remove");
503
646
  }
504
647
  isNodeActive(nodeType, attrs) {
505
648
  return isNodeActive(this.view.state, nodeType, attrs);
@@ -524,7 +667,7 @@ function withPriority(extension, priority) {
524
667
 
525
668
  // src/extensions/command.ts
526
669
  import "@prosekit/pm/model";
527
- import { AllSelection, Selection } from "@prosekit/pm/state";
670
+ import { AllSelection } from "@prosekit/pm/state";
528
671
  import { findWrapping, insertPoint } from "@prosekit/pm/transform";
529
672
  function addCommands(commands) {
530
673
  return commandSlot.extension([commands]);
@@ -554,8 +697,6 @@ function addBaseCommands() {
554
697
  return false;
555
698
  if (dispatch) {
556
699
  const tr = state.tr.insert(insertPos, node);
557
- const $pos = tr.doc.resolve(insertPos);
558
- tr.setSelection(Selection.near($pos));
559
700
  dispatch(tr);
560
701
  }
561
702
  return true;
@@ -606,17 +747,17 @@ function addNodeSpec(options) {
606
747
  var nodeSpecFacet = Facet.define({
607
748
  combine: (options) => {
608
749
  const nodes = {};
609
- let topNode = void 0;
610
- for (const { name, spec, topNode: isTopNode } of options) {
750
+ let topNodeName = void 0;
751
+ for (const { name, topNode, ...spec } of options) {
611
752
  if (nodes[name]) {
612
753
  throw new Error(`Node type ${name} has already been defined`);
613
754
  }
614
- nodes[name] = spec;
615
- if (isTopNode && !topNode) {
616
- topNode = name;
755
+ if (topNodeName && !topNode) {
756
+ topNodeName = name;
617
757
  }
758
+ nodes[name] = spec;
618
759
  }
619
- return { nodes, topNode };
760
+ return { nodes, topNode: topNodeName };
620
761
  },
621
762
  next: schemaSlot
622
763
  });
@@ -625,9 +766,7 @@ var nodeSpecFacet = Facet.define({
625
766
  function addDoc() {
626
767
  return addNodeSpec({
627
768
  name: "doc",
628
- spec: {
629
- content: "block+"
630
- }
769
+ content: "block+"
631
770
  });
632
771
  }
633
772
 
@@ -674,8 +813,8 @@ var inputRuleFacet = Facet.define({
674
813
 
675
814
  // src/extensions/keymap.ts
676
815
  import { baseKeymap, chainCommands } from "@prosekit/pm/commands";
677
- import { keymap as createKeymapPlugin } from "@prosekit/pm/keymap";
678
- import "@prosekit/pm/state";
816
+ import { keydownHandler } from "@prosekit/pm/keymap";
817
+ import { Plugin as Plugin3, PluginKey } from "@prosekit/pm/state";
679
818
  function addKeymap(keymap) {
680
819
  return keymapFacet.extension([keymap]);
681
820
  }
@@ -683,20 +822,38 @@ function addBaseKeymap() {
683
822
  return addKeymap(baseKeymap);
684
823
  }
685
824
  var keymapFacet = Facet.define({
686
- combine: (keymaps) => {
687
- const keymap = mergeKeymaps(keymaps);
688
- const plugin = createKeymapPlugin(keymap);
689
- return () => [plugin];
825
+ slot: () => {
826
+ let handler = null;
827
+ const handlerWrapper = (view, event) => {
828
+ if (handler)
829
+ return handler(view, event);
830
+ return false;
831
+ };
832
+ const plugin = new Plugin3({
833
+ key: keymapPluginKey,
834
+ props: { handleKeyDown: handlerWrapper }
835
+ });
836
+ const pluginFunc = () => [plugin];
837
+ return {
838
+ create: (keymaps) => {
839
+ handler = keydownHandler(mergeKeymaps(keymaps));
840
+ return pluginFunc;
841
+ },
842
+ update: (keymaps) => {
843
+ handler = keydownHandler(mergeKeymaps(keymaps));
844
+ return null;
845
+ }
846
+ };
690
847
  },
691
- next: pluginFacet
848
+ next: pluginFacet,
849
+ single: true
692
850
  });
693
851
  function mergeKeymaps(keymaps) {
694
852
  const bindings = {};
695
853
  for (const keymap of keymaps) {
696
854
  for (const [key, command] of Object.entries(keymap)) {
697
- if (!bindings[key])
698
- bindings[key] = [];
699
- bindings[key].push(command);
855
+ const commands = bindings[key] || (bindings[key] = []);
856
+ commands.push(command);
700
857
  }
701
858
  }
702
859
  return Object.fromEntries(
@@ -706,6 +863,7 @@ function mergeKeymaps(keymaps) {
706
863
  ])
707
864
  );
708
865
  }
866
+ var keymapPluginKey = new PluginKey("prosekit-keymap");
709
867
 
710
868
  // src/extensions/mark-spec.ts
711
869
  function addMarkSpec(options) {
@@ -714,7 +872,7 @@ function addMarkSpec(options) {
714
872
  var markSpecFacet = Facet.define({
715
873
  combine: (options) => {
716
874
  const marks = {};
717
- for (const { name, spec } of options) {
875
+ for (const { name, ...spec } of options) {
718
876
  if (marks[name]) {
719
877
  throw new Error(`Mark type ${name} has already been defined`);
720
878
  }
@@ -748,13 +906,11 @@ var nodeViewFacet = Facet.define({
748
906
  function addParagraph() {
749
907
  return addNodeSpec({
750
908
  name: "paragraph",
751
- spec: {
752
- content: "inline*",
753
- group: "block",
754
- parseDOM: [{ tag: "p" }],
755
- toDOM() {
756
- return ["p", 0];
757
- }
909
+ content: "inline*",
910
+ group: "block",
911
+ parseDOM: [{ tag: "p" }],
912
+ toDOM() {
913
+ return ["p", 0];
758
914
  }
759
915
  });
760
916
  }
@@ -763,9 +919,7 @@ function addParagraph() {
763
919
  function addText() {
764
920
  return addNodeSpec({
765
921
  name: "text",
766
- spec: {
767
- group: "inline"
768
- }
922
+ group: "inline"
769
923
  });
770
924
  }
771
925
  export {
@@ -780,6 +934,7 @@ export {
780
934
  addDoc,
781
935
  addInputRule,
782
936
  addKeymap,
937
+ addMark,
783
938
  addMarkSpec,
784
939
  addNodeSpec,
785
940
  addNodeView,
package/dist/style.css CHANGED
@@ -1,4 +1,4 @@
1
- /* ../../node_modules/.pnpm/prosemirror-view@1.31.6/node_modules/prosemirror-view/style/prosemirror.css */
1
+ /* ../../node_modules/.pnpm/prosemirror-view@1.31.7/node_modules/prosemirror-view/style/prosemirror.css */
2
2
  .ProseMirror {
3
3
  position: relative;
4
4
  }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@prosekit/core",
3
3
  "type": "module",
4
- "version": "0.0.5",
4
+ "version": "0.0.7",
5
5
  "private": false,
6
6
  "author": {
7
7
  "name": "ocavue",
@@ -40,13 +40,13 @@
40
40
  "dependencies": {
41
41
  "@prosekit/pm": "^0.0.3",
42
42
  "orderedmap": "^2.1.1",
43
- "type-fest": "^4.0.0"
43
+ "type-fest": "^4.2.0"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@prosekit/dev": "*",
47
- "tsup": "^7.1.0",
47
+ "tsup": "^7.2.0",
48
48
  "typescript": "^5.1.6",
49
- "vitest": "^0.33.0"
49
+ "vitest": "^0.34.1"
50
50
  },
51
51
  "scripts": {
52
52
  "build:tsup": "tsup",
package/src/index.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  export { toggleMark, type ToggleMarkOptions } from './commands/toggle-mark'
2
2
  export { toggleNode, type ToggleNodeOptions } from './commands/toggle-node'
3
+ export { addMark, type AddMarkOptions } from './commands/add-mark'
3
4
  export { Editor, createEditor, type EditorOptions } from './editor/editor'
4
5
  export { Facet, FacetExtension, type FacetOptions } from './editor/facet'
5
6
  export { defineExtension } from './editor/type-utils'
@@ -28,6 +29,7 @@ export {
28
29
  type ExtractCommandDispatchers,
29
30
  type ExtractMarks,
30
31
  type ExtractNodes,
32
+ type SimplifyExtension,
31
33
  } from './types/extension'
32
34
  export { type ExtensionTyping } from './types/extension-typing'
33
35
  export { Priority } from './types/priority'