@markput/react 0.10.1 → 0.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.js CHANGED
@@ -58,10 +58,10 @@ var MarkputHandler = class {
58
58
  this.store = store;
59
59
  }
60
60
  get container() {
61
- return this.store.refs.container;
61
+ return this.store.state.container();
62
62
  }
63
63
  get overlay() {
64
- return this.store.refs.overlay;
64
+ return this.store.state.overlay();
65
65
  }
66
66
  focus() {
67
67
  this.store.nodes.focus.head?.focus();
@@ -392,11 +392,11 @@ var NodeProxy = class NodeProxy {
392
392
  return this.target?.isContentEditable ?? false;
393
393
  }
394
394
  get isCaretAtBeginning() {
395
- if (!this.target) return;
395
+ if (!this.target) return false;
396
396
  return Caret.getCaretIndex(this.target) === 0;
397
397
  }
398
398
  get isCaretAtEnd() {
399
- if (!this.target) return;
399
+ if (!this.target) return false;
400
400
  return Caret.getCaretIndex(this.target) === this.target.textContent.length;
401
401
  }
402
402
  get index() {
@@ -420,10 +420,10 @@ var NodeProxy = class NodeProxy {
420
420
  if (this.target) this.target.textContent = value ?? "";
421
421
  }
422
422
  get head() {
423
- return firstHtmlChild(this.#store.refs.container ?? void 0);
423
+ return firstHtmlChild(this.#store.state.container() ?? void 0);
424
424
  }
425
425
  get tail() {
426
- return lastHtmlChild(this.#store.refs.container ?? void 0);
426
+ return lastHtmlChild(this.#store.state.container() ?? void 0);
427
427
  }
428
428
  get isFocused() {
429
429
  return this.target === document.activeElement;
@@ -443,16 +443,6 @@ var NodeProxy = class NodeProxy {
443
443
  }
444
444
  };
445
445
  //#endregion
446
- //#region ../../core/src/shared/signals/registry.ts
447
- let _factory;
448
- function setUseHookFactory(f) {
449
- _factory = f;
450
- }
451
- function getUseHookFactory() {
452
- if (!_factory) throw new Error("[markput] setUseHookFactory() must be called before using signal.use()");
453
- return _factory;
454
- }
455
- //#endregion
456
446
  //#region ../../core/src/shared/signals/alien-signals/system.ts
457
447
  let ReactiveFlags = /* @__PURE__ */ function(ReactiveFlags) {
458
448
  ReactiveFlags[ReactiveFlags["None"] = 0] = "None";
@@ -633,17 +623,19 @@ function createReactiveSystem({ update, notify, unwatched }) {
633
623
  }
634
624
  }
635
625
  //#endregion
636
- //#region ../../core/src/shared/signals/alien-signals/index.ts
626
+ //#region ../../core/src/shared/signals/signal.ts
637
627
  let cycle = 0;
638
628
  let batchDepth = 0;
639
629
  let notifyIndex = 0;
640
630
  let queuedLength = 0;
641
631
  let activeSub;
632
+ let mutableScope = false;
642
633
  const queued = [];
643
634
  const { link, unlink, propagate, checkDirty, shallowPropagate } = createReactiveSystem({
644
635
  update(node) {
645
- if (node.depsTail !== void 0) return updateComputed(node);
646
- else return updateSignal(node);
636
+ if ("getter" in node) return updateComputed(node);
637
+ if ("seq" in node) return updateEvent(node);
638
+ return updateSignal(node);
647
639
  },
648
640
  notify(effect) {
649
641
  let insertIndex = queuedLength;
@@ -662,8 +654,16 @@ const { link, unlink, propagate, checkDirty, shallowPropagate } = createReactive
662
654
  }
663
655
  },
664
656
  unwatched(node) {
665
- if (!(node.flags & ReactiveFlags.Mutable)) effectScopeOper.call(node);
666
- else if (node.depsTail !== void 0) {
657
+ if (!(node.flags & ReactiveFlags.Mutable)) {
658
+ if ("fn" in node) {
659
+ const e = node;
660
+ if (e.cleanup !== void 0) {
661
+ e.cleanup();
662
+ e.cleanup = void 0;
663
+ }
664
+ }
665
+ effectScopeOper.call(node);
666
+ } else if (node.depsTail !== void 0) {
667
667
  node.depsTail = void 0;
668
668
  node.flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty;
669
669
  purgeDeps(node);
@@ -675,67 +675,9 @@ function setActiveSub(sub) {
675
675
  activeSub = sub;
676
676
  return prevSub;
677
677
  }
678
- function startBatch() {
679
- ++batchDepth;
680
- }
681
- function endBatch() {
682
- if (!--batchDepth) flush();
683
- }
684
- function signal$1(initialValue) {
685
- return signalOper.bind({
686
- currentValue: initialValue,
687
- pendingValue: initialValue,
688
- subs: void 0,
689
- subsTail: void 0,
690
- flags: ReactiveFlags.Mutable
691
- });
692
- }
693
- function computed$1(getter) {
694
- return computedOper.bind({
695
- value: void 0,
696
- subs: void 0,
697
- subsTail: void 0,
698
- deps: void 0,
699
- depsTail: void 0,
700
- flags: ReactiveFlags.None,
701
- getter
702
- });
703
- }
704
- function effect(fn) {
705
- const e = {
706
- fn,
707
- subs: void 0,
708
- subsTail: void 0,
709
- deps: void 0,
710
- depsTail: void 0,
711
- flags: ReactiveFlags.Watching | ReactiveFlags.RecursedCheck
712
- };
713
- const prevSub = setActiveSub(e);
714
- if (prevSub !== void 0) link(e, prevSub, 0);
715
- try {
716
- e.fn();
717
- } finally {
718
- activeSub = prevSub;
719
- e.flags &= ~ReactiveFlags.RecursedCheck;
720
- }
721
- return effectOper.bind(e);
722
- }
723
- function effectScope(fn) {
724
- const e = {
725
- deps: void 0,
726
- depsTail: void 0,
727
- subs: void 0,
728
- subsTail: void 0,
729
- flags: ReactiveFlags.None
730
- };
731
- const prevSub = setActiveSub(e);
732
- if (prevSub !== void 0) link(e, prevSub, 0);
733
- try {
734
- fn();
735
- } finally {
736
- activeSub = prevSub;
737
- }
738
- return effectScopeOper.bind(e);
678
+ function updateSignal(s) {
679
+ s.flags = ReactiveFlags.Mutable;
680
+ return s.currentValue !== (s.currentValue = s.pendingValue);
739
681
  }
740
682
  function updateComputed(c) {
741
683
  ++cycle;
@@ -744,26 +686,33 @@ function updateComputed(c) {
744
686
  const prevSub = setActiveSub(c);
745
687
  try {
746
688
  const oldValue = c.value;
747
- return oldValue !== (c.value = c.getter(oldValue));
689
+ const newValue = c.getter(oldValue);
690
+ if (c.equalsFn !== void 0 && oldValue !== void 0 && c.equalsFn(oldValue, newValue)) return false;
691
+ return oldValue !== (c.value = newValue);
748
692
  } finally {
749
693
  activeSub = prevSub;
750
694
  c.flags &= ~ReactiveFlags.RecursedCheck;
751
695
  purgeDeps(c);
752
696
  }
753
697
  }
754
- function updateSignal(s) {
755
- s.flags = ReactiveFlags.Mutable;
756
- return s.currentValue !== (s.currentValue = s.pendingValue);
698
+ function updateEvent(e) {
699
+ e.flags = ReactiveFlags.Mutable;
700
+ return true;
757
701
  }
758
702
  function run(e) {
759
703
  const flags = e.flags;
760
704
  if (flags & ReactiveFlags.Dirty || flags & ReactiveFlags.Pending && checkDirty(e.deps, e)) {
705
+ if (e.cleanup !== void 0) {
706
+ e.cleanup();
707
+ e.cleanup = void 0;
708
+ }
761
709
  ++cycle;
762
710
  e.depsTail = void 0;
763
711
  e.flags = ReactiveFlags.Watching | ReactiveFlags.RecursedCheck;
764
712
  const prevSub = setActiveSub(e);
765
713
  try {
766
- e.fn();
714
+ const result = e.fn();
715
+ if (typeof result === "function") e.cleanup = result;
767
716
  } finally {
768
717
  activeSub = prevSub;
769
718
  e.flags &= ~ReactiveFlags.RecursedCheck;
@@ -788,36 +737,31 @@ function flush() {
788
737
  queuedLength = 0;
789
738
  }
790
739
  }
791
- function computedOper() {
792
- const flags = this.flags;
793
- if (flags & ReactiveFlags.Dirty || flags & ReactiveFlags.Pending && (checkDirty(this.deps, this) || (this.flags = flags & ~ReactiveFlags.Pending, false))) {
794
- if (updateComputed(this)) {
795
- const subs = this.subs;
796
- if (subs !== void 0) shallowPropagate(subs);
797
- }
798
- } else if (!flags) {
799
- this.flags = ReactiveFlags.Mutable | ReactiveFlags.RecursedCheck;
800
- const prevSub = setActiveSub(this);
801
- try {
802
- this.value = this.getter();
803
- } finally {
804
- activeSub = prevSub;
805
- this.flags &= ~ReactiveFlags.RecursedCheck;
806
- }
807
- }
808
- const sub = activeSub;
809
- if (sub !== void 0) link(this, sub, cycle);
810
- return this.value;
740
+ function purgeDeps(sub) {
741
+ const depsTail = sub.depsTail;
742
+ let dep = depsTail !== void 0 ? depsTail.nextDep : sub.deps;
743
+ while (dep !== void 0) dep = unlink(dep, sub);
811
744
  }
812
745
  function signalOper(...value) {
813
746
  if (value.length) {
814
- if (this.pendingValue !== (this.pendingValue = value[0])) {
815
- this.flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty;
816
- const subs = this.subs;
817
- if (subs !== void 0) {
818
- propagate(subs);
819
- if (!batchDepth) flush();
820
- }
747
+ if (this.isReadonly && !mutableScope) return;
748
+ const v = value[0];
749
+ if (v === void 0) {
750
+ if (this.hasDefault ? this.pendingValue === void 0 || this.pendingValue === this.defaultValue : this.pendingValue === void 0) return;
751
+ this.pendingValue = void 0;
752
+ } else {
753
+ const current = this.pendingValue;
754
+ const effectiveCurrent = current === void 0 && this.hasDefault ? this.defaultValue : current;
755
+ if (this.equalsFn !== void 0) {
756
+ if (this.equalsFn(effectiveCurrent, v)) return;
757
+ } else if (effectiveCurrent === v) return;
758
+ this.pendingValue = v;
759
+ }
760
+ this.flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty;
761
+ const subs = this.subs;
762
+ if (subs !== void 0) {
763
+ propagate(subs);
764
+ if (!batchDepth) flush();
821
765
  }
822
766
  } else {
823
767
  if (this.flags & ReactiveFlags.Dirty) {
@@ -834,10 +778,44 @@ function signalOper(...value) {
834
778
  }
835
779
  sub = sub.subs?.sub;
836
780
  }
837
- return this.currentValue;
781
+ const v = this.currentValue;
782
+ if (v === void 0 && this.hasDefault) return this.defaultValue;
783
+ return v;
784
+ }
785
+ }
786
+ function computedOper() {
787
+ const flags = this.flags;
788
+ const deps = this.deps;
789
+ if (flags & ReactiveFlags.Dirty || flags & ReactiveFlags.Pending && (checkDirty(deps, this) || (this.flags = flags & ~ReactiveFlags.Pending, false))) {
790
+ if (updateComputed(this)) {
791
+ const subs = this.subs;
792
+ if (subs !== void 0) shallowPropagate(subs);
793
+ }
794
+ } else if (!flags) {
795
+ this.flags = ReactiveFlags.Mutable | ReactiveFlags.RecursedCheck;
796
+ const prevSub = setActiveSub(this);
797
+ try {
798
+ this.value = this.getter();
799
+ } finally {
800
+ activeSub = prevSub;
801
+ this.flags &= ~ReactiveFlags.RecursedCheck;
802
+ }
838
803
  }
804
+ const sub = activeSub;
805
+ if (sub !== void 0) link(this, sub, cycle);
806
+ return this.value;
807
+ }
808
+ function eventReadOper() {
809
+ if (this.flags & ReactiveFlags.Dirty) updateEvent(this);
810
+ const sub = activeSub;
811
+ if (sub !== void 0) link(this, sub, cycle);
812
+ return this.payload;
839
813
  }
840
814
  function effectOper() {
815
+ if (this.cleanup !== void 0) {
816
+ this.cleanup();
817
+ this.cleanup = void 0;
818
+ }
841
819
  effectScopeOper.call(this);
842
820
  }
843
821
  function effectScopeOper() {
@@ -847,111 +825,101 @@ function effectScopeOper() {
847
825
  const sub = this.subs;
848
826
  if (sub !== void 0) unlink(sub);
849
827
  }
850
- function purgeDeps(sub) {
851
- const depsTail = sub.depsTail;
852
- let dep = depsTail !== void 0 ? depsTail.nextDep : sub.deps;
853
- while (dep !== void 0) dep = unlink(dep, sub);
828
+ function isReactive(fn) {
829
+ if (typeof fn !== "function") return false;
830
+ const name = fn.name;
831
+ return name === "bound " + signalOper.name || name === "bound " + computedOper.name;
854
832
  }
855
- //#endregion
856
- //#region ../../core/src/shared/signals/signal.ts
857
833
  function signal(initial, opts) {
858
- const hasCustomEquals = opts?.equals !== void 0;
859
- const equalsOpt = hasCustomEquals ? opts.equals : void 0;
860
- if (hasCustomEquals && equalsOpt === false) {
861
- const _default = initial;
862
- const hasDefault = initial !== void 0;
863
- let seq = 0;
864
- const inner = signal$1(void 0);
865
- const read = () => {
866
- const box = inner();
867
- if (box === void 0) return hasDefault ? _default : void 0;
868
- return box.v;
869
- };
870
- const callable = function signalCallable(...args) {
871
- if (args.length) if (args[0] === void 0) {
872
- if (hasDefault && inner() === void 0) return;
873
- inner(void 0);
874
- } else inner({
875
- v: args[0],
876
- seq: seq++
877
- });
878
- else return read();
879
- };
880
- callable.use = (() => getUseHookFactory()(callable)());
881
- return callable;
882
- }
883
- if (hasCustomEquals && typeof equalsOpt === "function") {
884
- const equalsFn = equalsOpt;
885
- const _default = initial;
886
- const hasDefault = initial !== void 0;
887
- const inner = signal$1(void 0);
888
- const read = () => {
889
- const v = inner();
890
- if (v === void 0 && hasDefault) return _default;
891
- return v;
892
- };
893
- const callable = function signalCallable(...args) {
894
- if (args.length) {
895
- if (args[0] === void 0) {
896
- if (hasDefault && inner() === void 0) return;
897
- inner(void 0);
898
- } else if (!equalsFn(read(), args[0])) inner(args[0]);
899
- } else return read();
900
- };
901
- callable.use = (() => getUseHookFactory()(callable)());
902
- return callable;
903
- }
904
- const _default = initial;
905
- const hasDefault = initial !== void 0;
906
- const inner = signal$1(void 0);
907
- const read = () => {
908
- const v = inner();
909
- if (v === void 0 && hasDefault) return _default;
910
- return v;
911
- };
912
- const callable = function signalCallable(...args) {
913
- if (args.length) {
914
- const v = args[0];
915
- if (v === void 0 && hasDefault) {
916
- if (inner() === void 0) return;
917
- inner(void 0);
918
- } else {
919
- const current = inner();
920
- if ((current === void 0 && hasDefault ? _default : current) !== v) inner(v);
921
- }
922
- } else return read();
834
+ const node = {
835
+ currentValue: initial,
836
+ pendingValue: initial,
837
+ defaultValue: initial,
838
+ hasDefault: initial !== void 0,
839
+ equalsFn: opts?.equals ?? void 0,
840
+ isReadonly: !!opts?.readonly,
841
+ subs: void 0,
842
+ subsTail: void 0,
843
+ flags: ReactiveFlags.Mutable
923
844
  };
924
- callable.use = (() => getUseHookFactory()(callable)());
925
- return callable;
845
+ return signalOper.bind(node);
926
846
  }
927
- function computed(getter) {
928
- const inner = computed$1(getter);
929
- const callable = function computedCallable() {
930
- return inner();
847
+ function computed(getter, opts) {
848
+ const node = {
849
+ value: void 0,
850
+ subs: void 0,
851
+ subsTail: void 0,
852
+ deps: void 0,
853
+ depsTail: void 0,
854
+ flags: ReactiveFlags.None,
855
+ getter,
856
+ equalsFn: opts?.equals ?? void 0
931
857
  };
932
- callable.use = (() => getUseHookFactory()(callable)());
933
- return callable;
858
+ return computedOper.bind(node);
934
859
  }
935
860
  function event() {
936
- let seq = 0;
937
- const inner = signal$1(void 0);
938
- const callable = function eventCallable(payload) {
939
- inner({
940
- v: payload,
941
- id: ++seq
942
- });
861
+ const node = {
862
+ payload: void 0,
863
+ seq: 0,
864
+ subs: void 0,
865
+ subsTail: void 0,
866
+ flags: ReactiveFlags.Mutable
943
867
  };
944
- callable.read = () => {
945
- const box = inner();
946
- return box !== void 0 ? box.v : void 0;
868
+ const callable = function eventCallable(payload) {
869
+ node.payload = payload;
870
+ node.seq++;
871
+ node.flags = ReactiveFlags.Mutable | ReactiveFlags.Dirty;
872
+ const subs = node.subs;
873
+ if (subs !== void 0) {
874
+ propagate(subs);
875
+ if (!batchDepth) flush();
876
+ }
947
877
  };
948
- callable.use = () => getUseHookFactory()(callable.read)();
878
+ callable.read = eventReadOper.bind(node);
949
879
  return callable;
950
880
  }
881
+ function alienEffect(fn) {
882
+ const e = {
883
+ fn,
884
+ cleanup: void 0,
885
+ subs: void 0,
886
+ subsTail: void 0,
887
+ deps: void 0,
888
+ depsTail: void 0,
889
+ flags: ReactiveFlags.Watching | ReactiveFlags.RecursedCheck
890
+ };
891
+ const prevSub = setActiveSub(e);
892
+ if (prevSub !== void 0) link(e, prevSub, 0);
893
+ try {
894
+ const result = e.fn();
895
+ if (typeof result === "function") e.cleanup = result;
896
+ } finally {
897
+ activeSub = prevSub;
898
+ e.flags &= ~ReactiveFlags.RecursedCheck;
899
+ }
900
+ return effectOper.bind(e);
901
+ }
902
+ function effectScope(fn) {
903
+ const e = {
904
+ deps: void 0,
905
+ depsTail: void 0,
906
+ subs: void 0,
907
+ subsTail: void 0,
908
+ flags: ReactiveFlags.None
909
+ };
910
+ const prevSub = setActiveSub(e);
911
+ if (prevSub !== void 0) link(e, prevSub, 0);
912
+ try {
913
+ fn();
914
+ } finally {
915
+ activeSub = prevSub;
916
+ }
917
+ return effectScopeOper.bind(e);
918
+ }
951
919
  function watch(dep, fn) {
952
920
  let initialized = false;
953
921
  let oldValue;
954
- return effect(() => {
922
+ return alienEffect(() => {
955
923
  const newValue = "read" in dep ? dep.read() : dep();
956
924
  if (!initialized) {
957
925
  initialized = true;
@@ -960,22 +928,58 @@ function watch(dep, fn) {
960
928
  }
961
929
  const prev = oldValue;
962
930
  oldValue = newValue;
963
- const prevSub = setActiveSub(void 0);
964
- try {
965
- fn(newValue, prev);
966
- } finally {
967
- setActiveSub(prevSub);
968
- }
931
+ untracked(() => fn(newValue, prev));
969
932
  });
970
933
  }
971
- function batch(fn) {
972
- startBatch();
934
+ function batch(fn, opts) {
935
+ const prevMutable = mutableScope;
936
+ if (opts?.mutable) mutableScope = true;
937
+ ++batchDepth;
938
+ try {
939
+ fn();
940
+ } finally {
941
+ if (!--batchDepth) flush();
942
+ mutableScope = prevMutable;
943
+ }
944
+ }
945
+ function trigger(fn) {
946
+ const sub = {
947
+ deps: void 0,
948
+ depsTail: void 0,
949
+ flags: ReactiveFlags.Watching
950
+ };
951
+ const prevSub = setActiveSub(sub);
973
952
  try {
974
953
  fn();
975
954
  } finally {
976
- endBatch();
955
+ activeSub = prevSub;
956
+ let dep = sub.deps;
957
+ while (dep !== void 0) {
958
+ const subs = dep.dep.subs;
959
+ dep = unlink(dep, sub);
960
+ if (subs !== void 0) {
961
+ sub.flags = ReactiveFlags.None;
962
+ propagate(subs);
963
+ shallowPropagate(subs);
964
+ }
965
+ }
966
+ if (!batchDepth) flush();
967
+ }
968
+ }
969
+ function untracked(fn) {
970
+ const prev = setActiveSub(void 0);
971
+ try {
972
+ return fn();
973
+ } finally {
974
+ setActiveSub(prev);
977
975
  }
978
976
  }
977
+ function listen(target, event, handler, options) {
978
+ return alienEffect(() => {
979
+ target.addEventListener(event, handler, options);
980
+ return () => target.removeEventListener(event, handler, options);
981
+ });
982
+ }
979
983
  //#endregion
980
984
  //#region ../../core/src/features/parsing/parser/constants.ts
981
985
  /**
@@ -2170,23 +2174,30 @@ function getTokensByUI(store) {
2170
2174
  const tokens = store.state.tokens();
2171
2175
  if (!parser) return tokens;
2172
2176
  const parsed = parser.parse(focus.content);
2173
- if (parsed.length === 1) return tokens;
2177
+ if (parsed.length <= 1) return tokens;
2174
2178
  return tokens.toSpliced(focus.index, 1, ...parsed);
2175
2179
  }
2176
- function getTokensByValue(store) {
2177
- const value = store.state.value();
2178
- const ranges = getRangeMap(store);
2179
- const gap = findGap(store.state.previousValue(), value);
2180
+ function computeTokensFromValue(store) {
2181
+ const value = store.props.value();
2182
+ const previousValue = store.state.previousValue();
2183
+ const gap = findGap(previousValue, value);
2180
2184
  if (!gap.left && !gap.right) {
2181
2185
  store.state.previousValue(value);
2182
2186
  return store.state.tokens();
2183
2187
  }
2188
+ if (gap.left === 0 && previousValue !== void 0 && gap.right !== void 0 && gap.right >= previousValue.length) {
2189
+ store.state.previousValue(value);
2190
+ return parseWithParser(store, value ?? "");
2191
+ }
2184
2192
  store.state.previousValue(value);
2193
+ const ranges = getRangeMap(store);
2185
2194
  const tokens = store.state.tokens();
2186
2195
  if (gap.left !== void 0 && ranges.includes(gap.left) && gap.right !== void 0 && Math.abs(gap.left - gap.right) > 1) {
2187
2196
  const updatedIndex = ranges.indexOf(gap.left);
2188
- const parsed = parseUnionLabels(store, updatedIndex - 1, updatedIndex);
2189
- return tokens.toSpliced(updatedIndex - 1, 2, ...parsed);
2197
+ if (updatedIndex > 0) {
2198
+ const parsed = parseUnionLabels(store, updatedIndex - 1, updatedIndex);
2199
+ return tokens.toSpliced(updatedIndex - 1, 2, ...parsed);
2200
+ }
2190
2201
  }
2191
2202
  if (gap.left !== void 0) {
2192
2203
  const [updatedIndex] = getClosestIndexes(ranges, gap.left);
@@ -2235,9 +2246,6 @@ function parseWithParser(store, value) {
2235
2246
  //#region ../../core/src/features/parsing/ParseFeature.ts
2236
2247
  var ParseFeature = class {
2237
2248
  #scope;
2238
- #initialized = false;
2239
- #lastValue;
2240
- #lastParser;
2241
2249
  constructor(store) {
2242
2250
  this.store = store;
2243
2251
  }
@@ -2246,48 +2254,35 @@ var ParseFeature = class {
2246
2254
  this.sync();
2247
2255
  this.#scope = effectScope(() => {
2248
2256
  this.#subscribeParse();
2249
- this.#subscribeUpdated();
2257
+ this.#subscribeReactiveParse();
2250
2258
  });
2251
2259
  }
2252
2260
  disable() {
2253
2261
  this.#scope?.();
2254
2262
  this.#scope = void 0;
2255
- this.#initialized = false;
2256
2263
  }
2257
2264
  sync() {
2258
2265
  const { store } = this;
2259
- const inputValue = store.state.value() ?? store.state.defaultValue() ?? "";
2266
+ const inputValue = store.props.value() ?? store.props.defaultValue() ?? "";
2260
2267
  store.state.tokens(parseWithParser(store, inputValue));
2261
2268
  store.state.previousValue(inputValue);
2262
- this.#lastValue = store.state.value();
2263
- this.#lastParser = store.computed.parser();
2264
- this.#initialized = true;
2265
- }
2266
- hasChanged() {
2267
- const value = this.store.state.value();
2268
- const parser = this.store.computed.parser();
2269
- if (this.#initialized && value === this.#lastValue && parser === this.#lastParser) return false;
2270
- this.#lastValue = value;
2271
- this.#lastParser = parser;
2272
- return true;
2273
2269
  }
2274
2270
  #subscribeParse() {
2275
2271
  const { store } = this;
2276
- watch(store.event.parse, () => {
2272
+ watch(store.emit.reparse, () => {
2277
2273
  if (store.state.recovery()) {
2278
2274
  const text = toString(store.state.tokens());
2279
2275
  store.state.tokens(parseWithParser(store, text));
2280
2276
  store.state.previousValue(text);
2281
2277
  return;
2282
2278
  }
2283
- store.state.tokens(store.nodes.focus.target ? getTokensByUI(store) : getTokensByValue(store));
2279
+ store.state.tokens(store.nodes.focus.target ? getTokensByUI(store) : computeTokensFromValue(store));
2284
2280
  });
2285
2281
  }
2286
- #subscribeUpdated() {
2282
+ #subscribeReactiveParse() {
2287
2283
  const { store } = this;
2288
- watch(store.event.updated, () => {
2289
- if (!this.hasChanged()) return;
2290
- if (!store.state.recovery()) store.event.parse();
2284
+ watch(computed(() => [store.props.value(), store.computed.parser()]), () => {
2285
+ if (!store.state.recovery()) store.emit.reparse();
2291
2286
  });
2292
2287
  }
2293
2288
  };
@@ -2323,7 +2318,7 @@ function shiftFocusNext(store, event) {
2323
2318
  //#region ../../core/src/features/selection/selectionHelpers.ts
2324
2319
  function isFullSelection(store) {
2325
2320
  const sel = window.getSelection();
2326
- const container = store.refs.container;
2321
+ const container = store.state.container();
2327
2322
  if (!sel?.rangeCount || !container?.firstChild || !container.lastChild) return false;
2328
2323
  try {
2329
2324
  const range = sel.getRangeAt(0);
@@ -2334,11 +2329,11 @@ function isFullSelection(store) {
2334
2329
  }
2335
2330
  function selectAllText(store, event) {
2336
2331
  if ((event.ctrlKey || event.metaKey) && event.code === "KeyA") {
2337
- if (store.state.drag()) return;
2332
+ if (store.computed.isBlock()) return;
2338
2333
  event.preventDefault();
2339
2334
  const selection = window.getSelection();
2340
- const anchorNode = store.refs.container?.firstChild;
2341
- const focusNode = store.refs.container?.lastChild;
2335
+ const anchorNode = store.state.container()?.firstChild;
2336
+ const focusNode = store.state.container()?.lastChild;
2342
2337
  if (!selection || !anchorNode || !focusNode) return;
2343
2338
  selection.setBaseAndExtent(anchorNode, 0, focusNode, 1);
2344
2339
  store.state.selecting("all");
@@ -2347,10 +2342,6 @@ function selectAllText(store, event) {
2347
2342
  //#endregion
2348
2343
  //#region ../../core/src/features/selection/TextSelectionFeature.ts
2349
2344
  var TextSelectionFeature = class {
2350
- #mousedownHandler;
2351
- #mousemoveHandler;
2352
- #mouseupHandler;
2353
- #selectionchangeHandler;
2354
2345
  #scope;
2355
2346
  #pressedNode = null;
2356
2347
  #isPressed = false;
@@ -2358,61 +2349,47 @@ var TextSelectionFeature = class {
2358
2349
  this.store = store;
2359
2350
  }
2360
2351
  enable() {
2361
- if (this.#mousedownHandler) return;
2362
- this.#mousedownHandler = (e) => {
2363
- this.#pressedNode = nodeTarget(e);
2364
- this.#isPressed = true;
2365
- };
2366
- this.#mousemoveHandler = (e) => {
2367
- const container = this.store.refs.container;
2368
- if (!container) return;
2369
- const isPressed = this.#isPressed;
2370
- const isNotInnerSome = !container.contains(this.#pressedNode) || this.#pressedNode !== e.target;
2371
- const isInside = window.getSelection()?.containsNode(container, true);
2372
- if (isPressed && isNotInnerSome && isInside) {
2373
- if (this.store.state.selecting() !== "drag") this.store.state.selecting("drag");
2374
- }
2375
- };
2376
- this.#mouseupHandler = () => {
2377
- this.#isPressed = false;
2378
- this.#pressedNode = null;
2379
- if (this.store.state.selecting() === "drag") {
2352
+ if (this.#scope) return;
2353
+ this.#scope = effectScope(() => {
2354
+ listen(document, "mousedown", (e) => {
2355
+ this.#pressedNode = nodeTarget(e);
2356
+ this.#isPressed = true;
2357
+ });
2358
+ listen(document, "mousemove", (e) => {
2359
+ const container = this.store.state.container();
2360
+ if (!container) return;
2361
+ const isPressed = this.#isPressed;
2362
+ const isNotInnerSome = !container.contains(this.#pressedNode) || this.#pressedNode !== e.target;
2363
+ const isInside = window.getSelection()?.containsNode(container, true);
2364
+ if (isPressed && isNotInnerSome && isInside) {
2365
+ if (this.store.state.selecting() !== "drag") this.store.state.selecting("drag");
2366
+ }
2367
+ });
2368
+ listen(document, "mouseup", () => {
2369
+ this.#isPressed = false;
2370
+ this.#pressedNode = null;
2371
+ if (this.store.state.selecting() === "drag") {
2372
+ const sel = window.getSelection();
2373
+ if (!sel || sel.isCollapsed) this.store.state.selecting(void 0);
2374
+ }
2375
+ });
2376
+ listen(document, "selectionchange", () => {
2377
+ if (this.store.state.selecting() !== "drag") return;
2380
2378
  const sel = window.getSelection();
2381
2379
  if (!sel || sel.isCollapsed) this.store.state.selecting(void 0);
2382
- }
2383
- };
2384
- this.#selectionchangeHandler = () => {
2385
- if (this.store.state.selecting() !== "drag") return;
2386
- const sel = window.getSelection();
2387
- if (!sel || sel.isCollapsed) this.store.state.selecting(void 0);
2388
- };
2389
- this.#scope = effectScope(() => {
2390
- effect(() => {
2380
+ });
2381
+ alienEffect(() => {
2391
2382
  if (this.store.state.selecting() !== "drag") return;
2392
- const container = this.store.refs.container;
2383
+ const container = this.store.state.container();
2393
2384
  if (!container) return;
2394
2385
  container.querySelectorAll("[contenteditable=\"true\"]").forEach((el) => el.contentEditable = "false");
2395
2386
  });
2396
2387
  });
2397
- document.addEventListener("mousedown", this.#mousedownHandler);
2398
- document.addEventListener("mousemove", this.#mousemoveHandler);
2399
- document.addEventListener("mouseup", this.#mouseupHandler);
2400
- document.addEventListener("selectionchange", this.#selectionchangeHandler);
2401
2388
  }
2402
2389
  disable() {
2403
2390
  if (this.store.state.selecting() === "drag") this.store.state.selecting(void 0);
2404
2391
  this.#scope?.();
2405
2392
  this.#scope = void 0;
2406
- if (this.#mousedownHandler) {
2407
- document.removeEventListener("mousedown", this.#mousedownHandler);
2408
- if (this.#mousemoveHandler) document.removeEventListener("mousemove", this.#mousemoveHandler);
2409
- if (this.#mouseupHandler) document.removeEventListener("mouseup", this.#mouseupHandler);
2410
- if (this.#selectionchangeHandler) document.removeEventListener("selectionchange", this.#selectionchangeHandler);
2411
- this.#mousedownHandler = void 0;
2412
- this.#mousemoveHandler = void 0;
2413
- this.#mouseupHandler = void 0;
2414
- this.#selectionchangeHandler = void 0;
2415
- }
2416
2393
  this.#pressedNode = null;
2417
2394
  this.#isPressed = false;
2418
2395
  }
@@ -2420,28 +2397,27 @@ var TextSelectionFeature = class {
2420
2397
  //#endregion
2421
2398
  //#region ../../core/src/features/arrownav/ArrowNavFeature.ts
2422
2399
  var ArrowNavFeature = class {
2423
- #keydownHandler;
2400
+ #scope;
2424
2401
  constructor(store) {
2425
2402
  this.store = store;
2426
2403
  }
2427
2404
  enable() {
2428
- if (this.#keydownHandler) return;
2429
- const container = this.store.refs.container;
2405
+ if (this.#scope) return;
2406
+ const container = this.store.state.container();
2430
2407
  if (!container) return;
2431
- this.#keydownHandler = (e) => {
2432
- if (this.store.state.drag()) return;
2433
- if (!this.store.nodes.focus.target) return;
2434
- if (e.key === KEYBOARD.LEFT) shiftFocusPrev(this.store, e);
2435
- else if (e.key === KEYBOARD.RIGHT) shiftFocusNext(this.store, e);
2436
- selectAllText(this.store, e);
2437
- };
2438
- container.addEventListener("keydown", this.#keydownHandler);
2408
+ this.#scope = effectScope(() => {
2409
+ listen(container, "keydown", (e) => {
2410
+ if (this.store.computed.isBlock()) return;
2411
+ if (!this.store.nodes.focus.target) return;
2412
+ if (e.key === KEYBOARD.LEFT) shiftFocusPrev(this.store, e);
2413
+ else if (e.key === KEYBOARD.RIGHT) shiftFocusNext(this.store, e);
2414
+ selectAllText(this.store, e);
2415
+ });
2416
+ });
2439
2417
  }
2440
2418
  disable() {
2441
- const container = this.store.refs.container;
2442
- if (!container || !this.#keydownHandler) return;
2443
- container.removeEventListener("keydown", this.#keydownHandler);
2444
- this.#keydownHandler = void 0;
2419
+ this.#scope?.();
2420
+ this.#scope = void 0;
2445
2421
  }
2446
2422
  };
2447
2423
  //#endregion
@@ -2515,7 +2491,7 @@ function getBoundaryOffset(range, child, isStart) {
2515
2491
  * Returns null if selection is collapsed, empty, or outside the container.
2516
2492
  */
2517
2493
  function selectionToTokens(store) {
2518
- const container = store.refs.container;
2494
+ const container = store.state.container();
2519
2495
  if (!container) return null;
2520
2496
  const sel = window.getSelection();
2521
2497
  if (!sel || sel.isCollapsed || !sel.rangeCount) return null;
@@ -2567,56 +2543,49 @@ function trimBoundaryTokens({ tokens, startOffset, endOffset }) {
2567
2543
  });
2568
2544
  }
2569
2545
  var CopyFeature = class {
2570
- #copyHandler;
2571
- #cutHandler;
2546
+ #scope;
2572
2547
  constructor(store) {
2573
2548
  this.store = store;
2574
2549
  }
2575
2550
  enable() {
2576
- if (this.#copyHandler) return;
2577
- this.#copyHandler = (e) => {
2578
- this.#handleCopy(e);
2579
- };
2580
- this.#cutHandler = (e) => {
2581
- if (!this.#handleCopy(e)) return;
2582
- const result = selectionToTokens(this.store);
2583
- if (!result || result.tokens.length === 0) return;
2584
- const first = result.tokens[0];
2585
- const last = result.tokens[result.tokens.length - 1];
2586
- const rawStart = first.type === "text" ? first.position.start + result.startOffset : first.position.start;
2587
- const rawEnd = last.type === "text" ? last.position.start + result.endOffset : last.position.end;
2588
- const value = this.store.state.previousValue() ?? this.store.state.value() ?? "";
2589
- if (rawStart === rawEnd) return;
2590
- const newValue = value.slice(0, rawStart) + value.slice(rawEnd);
2591
- this.store.state.innerValue(newValue);
2592
- const newTokens = this.store.state.tokens();
2593
- let targetIdx = newTokens.findIndex((t) => t.type === "text" && rawStart >= t.position.start && rawStart <= t.position.end);
2594
- if (targetIdx === -1) targetIdx = newTokens.length - 1;
2595
- const caretWithinToken = rawStart - newTokens[targetIdx].position.start;
2596
- this.store.state.recovery({
2597
- anchor: this.store.nodes.focus,
2598
- caret: caretWithinToken,
2599
- isNext: true,
2600
- childIndex: targetIdx - 2
2551
+ if (this.#scope) return;
2552
+ const container = this.store.state.container();
2553
+ if (!container) return;
2554
+ this.#scope = effectScope(() => {
2555
+ listen(container, "copy", (e) => {
2556
+ this.#handleCopy(e);
2601
2557
  });
2602
- };
2603
- const container = this.store.refs.container;
2604
- container?.addEventListener("copy", this.#copyHandler);
2605
- container?.addEventListener("cut", this.#cutHandler);
2558
+ listen(container, "cut", (e) => {
2559
+ if (!this.#handleCopy(e)) return;
2560
+ const result = selectionToTokens(this.store);
2561
+ if (!result || result.tokens.length === 0) return;
2562
+ const first = result.tokens[0];
2563
+ const last = result.tokens[result.tokens.length - 1];
2564
+ const rawStart = first.type === "text" ? first.position.start + result.startOffset : first.position.start;
2565
+ const rawEnd = last.type === "text" ? last.position.start + result.endOffset : last.position.end;
2566
+ const value = this.store.computed.currentValue();
2567
+ if (rawStart === rawEnd) return;
2568
+ const newValue = value.slice(0, rawStart) + value.slice(rawEnd);
2569
+ this.store.state.innerValue(newValue);
2570
+ const newTokens = this.store.state.tokens();
2571
+ let targetIdx = newTokens.findIndex((t) => t.type === "text" && rawStart >= t.position.start && rawStart <= t.position.end);
2572
+ if (targetIdx === -1) targetIdx = newTokens.length - 1;
2573
+ const caretWithinToken = rawStart - newTokens[targetIdx].position.start;
2574
+ this.store.state.recovery({
2575
+ anchor: this.store.nodes.focus,
2576
+ caret: caretWithinToken,
2577
+ isNext: true,
2578
+ childIndex: targetIdx - 2
2579
+ });
2580
+ });
2581
+ });
2606
2582
  }
2607
2583
  disable() {
2608
- const container = this.store.refs.container;
2609
- if (this.#copyHandler) {
2610
- container?.removeEventListener("copy", this.#copyHandler);
2611
- this.#copyHandler = void 0;
2612
- }
2613
- if (this.#cutHandler) {
2614
- container?.removeEventListener("cut", this.#cutHandler);
2615
- this.#cutHandler = void 0;
2616
- }
2584
+ this.#scope?.();
2585
+ this.#scope = void 0;
2617
2586
  }
2618
2587
  #handleCopy(e) {
2619
- const container = this.store.refs.container;
2588
+ const container = this.store.state.container();
2620
2589
  if (!container) return false;
2621
2590
  const sel = window.getSelection();
2622
2591
  if (!sel || sel.isCollapsed || !sel.rangeCount) return false;
@@ -2771,9 +2740,10 @@ function deleteMark(place, store) {
2771
2740
  anchor: caretAnchor.prev,
2772
2741
  caret
2773
2742
  });
2774
- store.state.onChange()?.(toString(store.state.tokens()));
2743
+ store.emit.change();
2775
2744
  queueMicrotask(() => {
2776
- const target = childAt(store.refs.container, targetIndex);
2745
+ const container = store.state.container();
2746
+ const target = container ? childAt(container, targetIndex) : null;
2777
2747
  if (!target) return;
2778
2748
  store.nodes.focus.target = target;
2779
2749
  target.focus();
@@ -2795,14 +2765,14 @@ var ContentEditableFeature = class {
2795
2765
  enable() {
2796
2766
  if (this.#scope) return;
2797
2767
  this.#scope = effectScope(() => {
2798
- effect(() => {
2799
- this.store.state.readOnly();
2768
+ alienEffect(() => {
2769
+ this.store.props.readOnly();
2800
2770
  this.sync();
2801
2771
  });
2802
- effect(() => {
2772
+ alienEffect(() => {
2803
2773
  if (this.store.state.selecting() === void 0) this.sync();
2804
2774
  });
2805
- watch(this.store.event.sync, () => {
2775
+ watch(this.store.emit.sync, () => {
2806
2776
  this.sync();
2807
2777
  });
2808
2778
  });
@@ -2812,13 +2782,13 @@ var ContentEditableFeature = class {
2812
2782
  this.#scope = void 0;
2813
2783
  }
2814
2784
  sync() {
2815
- const container = this.store.refs.container;
2785
+ const container = this.store.state.container();
2816
2786
  if (!container) return;
2817
- const readOnly = this.store.state.readOnly();
2787
+ const readOnly = this.store.props.readOnly();
2818
2788
  const value = readOnly ? "false" : "true";
2819
2789
  const children = container.children;
2820
- const isDrag = !!this.store.state.drag();
2821
- if (isDrag) {
2790
+ const isBlock = this.store.computed.isBlock();
2791
+ if (isBlock) {
2822
2792
  const tokens = this.store.state.tokens();
2823
2793
  for (let i = 0; i < tokens.length && i < children.length; i++) {
2824
2794
  const el = childAt(container, i);
@@ -2832,7 +2802,7 @@ var ContentEditableFeature = class {
2832
2802
  if (el) el.contentEditable = value;
2833
2803
  }
2834
2804
  const tokens = this.store.state.tokens();
2835
- if (isDrag) this.#syncDragTextContent(tokens, container, readOnly);
2805
+ if (isBlock) this.#syncDragTextContent(tokens, container, readOnly);
2836
2806
  else this.#syncTextContent(tokens, container);
2837
2807
  }
2838
2808
  #syncTextContent(tokens, parent) {
@@ -3025,40 +2995,35 @@ function isTextLikeRow(token) {
3025
2995
  return token.descriptor.hasSlot && token.descriptor.segments.length === 1;
3026
2996
  }
3027
2997
  var BlockEditFeature = class {
3028
- #keydownHandler;
3029
- #beforeInputHandler;
2998
+ #scope;
3030
2999
  constructor(store) {
3031
3000
  this.store = store;
3032
3001
  }
3033
3002
  enable() {
3034
- if (this.#keydownHandler) return;
3035
- const container = this.store.refs.container;
3003
+ if (this.#scope) return;
3004
+ const container = this.store.state.container();
3036
3005
  if (!container) return;
3037
- this.#keydownHandler = (e) => {
3038
- if (!this.store.state.drag()) return;
3039
- if (e.key === KEYBOARD.LEFT || e.key === KEYBOARD.RIGHT) this.#handleBlockArrowLeftRight(e, e.key === KEYBOARD.LEFT ? "left" : "right");
3040
- else if (e.key === KEYBOARD.UP || e.key === KEYBOARD.DOWN) this.#handleArrowUpDown(e);
3041
- this.#handleDelete(e);
3042
- this.#handleEnter(e);
3043
- };
3044
- this.#beforeInputHandler = (e) => {
3045
- if (!this.store.state.drag()) return;
3046
- if (e.defaultPrevented) return;
3047
- this.#handleBlockBeforeInput(e);
3048
- };
3049
- container.addEventListener("keydown", this.#keydownHandler);
3050
- container.addEventListener("beforeinput", this.#beforeInputHandler, true);
3006
+ this.#scope = effectScope(() => {
3007
+ listen(container, "keydown", (e) => {
3008
+ if (!this.store.computed.isBlock()) return;
3009
+ if (e.key === KEYBOARD.LEFT || e.key === KEYBOARD.RIGHT) this.#handleBlockArrowLeftRight(e, e.key === KEYBOARD.LEFT ? "left" : "right");
3010
+ else if (e.key === KEYBOARD.UP || e.key === KEYBOARD.DOWN) this.#handleArrowUpDown(e);
3011
+ this.#handleDelete(e);
3012
+ this.#handleEnter(e);
3013
+ });
3014
+ listen(container, "beforeinput", (e) => {
3015
+ if (!this.store.computed.isBlock()) return;
3016
+ if (e.defaultPrevented) return;
3017
+ this.#handleBlockBeforeInput(e);
3018
+ }, true);
3019
+ });
3051
3020
  }
3052
3021
  disable() {
3053
- const container = this.store.refs.container;
3054
- if (!container || !this.#keydownHandler) return;
3055
- container.removeEventListener("keydown", this.#keydownHandler);
3056
- if (this.#beforeInputHandler) container.removeEventListener("beforeinput", this.#beforeInputHandler, true);
3057
- this.#keydownHandler = void 0;
3058
- this.#beforeInputHandler = void 0;
3022
+ this.#scope?.();
3023
+ this.#scope = void 0;
3059
3024
  }
3060
3025
  #handleDelete(event) {
3061
- const container = this.store.refs.container;
3026
+ const container = this.store.state.container();
3062
3027
  if (!container) return;
3063
3028
  const blockDivs = htmlChildren(container);
3064
3029
  const blockIndex = blockDivs.findIndex((div) => div === document.activeElement || div.contains(document.activeElement));
@@ -3066,8 +3031,8 @@ var BlockEditFeature = class {
3066
3031
  const rows = this.store.state.tokens();
3067
3032
  if (blockIndex >= rows.length) return;
3068
3033
  const token = rows[blockIndex];
3069
- const value = this.store.state.previousValue() ?? this.store.state.value() ?? "";
3070
- if (!this.store.state.onChange()) return;
3034
+ const value = this.store.computed.currentValue();
3035
+ if (!this.store.props.onChange()) return;
3071
3036
  if (event.key === KEYBOARD.BACKSPACE) {
3072
3037
  const blockDiv = blockDivs[blockIndex];
3073
3038
  const caretAtStart = Caret.getCaretIndex(blockDiv) === 0;
@@ -3175,7 +3140,7 @@ var BlockEditFeature = class {
3175
3140
  #handleEnter(event) {
3176
3141
  if (event.key !== KEYBOARD.ENTER) return;
3177
3142
  if (event.shiftKey) return;
3178
- const container = this.store.refs.container;
3143
+ const container = this.store.state.container();
3179
3144
  if (!container) return;
3180
3145
  const activeElement = document.activeElement;
3181
3146
  if (!isHtmlElement(activeElement) || !container.contains(activeElement)) return;
@@ -3190,9 +3155,9 @@ var BlockEditFeature = class {
3190
3155
  const rows = this.store.state.tokens();
3191
3156
  const token = rows[blockIndex];
3192
3157
  const blockDiv = blockDivs[blockIndex];
3193
- const value = this.store.state.previousValue() ?? this.store.state.value() ?? "";
3194
- if (!this.store.state.onChange()) return;
3195
- const newRowContent = createRowContent(this.store.state.options());
3158
+ const value = this.store.computed.currentValue();
3159
+ if (!this.store.props.onChange()) return;
3160
+ const newRowContent = createRowContent(this.store.props.options());
3196
3161
  if (!isTextLikeRow(token)) {
3197
3162
  const newValue = addDragRow(value, rows, blockIndex, newRowContent);
3198
3163
  this.store.state.innerValue(newValue);
@@ -3223,7 +3188,7 @@ var BlockEditFeature = class {
3223
3188
  });
3224
3189
  }
3225
3190
  #handleBlockArrowLeftRight(event, direction) {
3226
- const container = this.store.refs.container;
3191
+ const container = this.store.state.container();
3227
3192
  if (!container) return false;
3228
3193
  const activeElement = document.activeElement;
3229
3194
  if (!isHtmlElement(activeElement) || !container.contains(activeElement)) return false;
@@ -3249,7 +3214,7 @@ var BlockEditFeature = class {
3249
3214
  return true;
3250
3215
  }
3251
3216
  #handleArrowUpDown(event) {
3252
- const container = this.store.refs.container;
3217
+ const container = this.store.state.container();
3253
3218
  if (!container) return;
3254
3219
  const activeElement = document.activeElement;
3255
3220
  if (!isHtmlElement(activeElement) || !container.contains(activeElement)) return;
@@ -3278,7 +3243,7 @@ var BlockEditFeature = class {
3278
3243
  }
3279
3244
  }
3280
3245
  #handleBlockBeforeInput(event) {
3281
- const container = this.store.refs.container;
3246
+ const container = this.store.state.container();
3282
3247
  if (!container) return;
3283
3248
  const activeElement = document.activeElement;
3284
3249
  if (!isHtmlElement(activeElement) || !container.contains(activeElement)) return;
@@ -3289,7 +3254,7 @@ var BlockEditFeature = class {
3289
3254
  const rows = this.store.state.tokens();
3290
3255
  if (blockIndex >= rows.length) return;
3291
3256
  const token = rows[blockIndex];
3292
- const value = this.store.state.previousValue() ?? this.store.state.value() ?? "";
3257
+ const value = this.store.computed.currentValue();
3293
3258
  const focusAndSetCaret = (newRawPos) => {
3294
3259
  queueMicrotask(() => {
3295
3260
  const target = childAt(container, blockIndex);
@@ -3318,7 +3283,8 @@ var BlockEditFeature = class {
3318
3283
  case "insertFromPaste":
3319
3284
  case "insertReplacementText": {
3320
3285
  event.preventDefault();
3321
- const pasteData = (this.store.refs.container ? consumeMarkupPaste(this.store.refs.container) : void 0) ?? event.dataTransfer?.getData("text/plain") ?? "";
3286
+ const c = this.store.state.container();
3287
+ const pasteData = (c ? consumeMarkupPaste(c) : void 0) ?? event.dataTransfer?.getData("text/plain") ?? "";
3322
3288
  const ranges = event.getTargetRanges();
3323
3289
  let rawFrom;
3324
3290
  let rawTo;
@@ -3369,7 +3335,8 @@ var DragFeature = class {
3369
3335
  }
3370
3336
  #unsub;
3371
3337
  enable() {
3372
- this.#unsub = watch(this.store.event.dragAction, (action) => {
3338
+ if (this.#unsub) return;
3339
+ this.#unsub = watch(this.store.emit.drag, (action) => {
3373
3340
  switch (action.type) {
3374
3341
  case "reorder":
3375
3342
  this.#reorder(action.source, action.target);
@@ -3391,33 +3358,33 @@ var DragFeature = class {
3391
3358
  this.#unsub = void 0;
3392
3359
  }
3393
3360
  #reorder(sourceIndex, targetIndex) {
3394
- const value = this.store.state.value();
3395
- if (value == null || !this.store.state.onChange()) return;
3361
+ const value = this.store.props.value();
3362
+ if (value == null || !this.store.props.onChange()) return;
3396
3363
  const newValue = reorderDragRows(value, this.store.state.tokens(), sourceIndex, targetIndex);
3397
3364
  if (newValue !== value) this.store.state.innerValue(newValue);
3398
3365
  }
3399
3366
  #add(afterIndex) {
3400
- const value = this.store.state.value();
3401
- if (value == null || !this.store.state.onChange()) return;
3367
+ const value = this.store.props.value();
3368
+ if (value == null || !this.store.props.onChange()) return;
3402
3369
  const rawRows = this.store.state.tokens();
3403
3370
  const rows = rawRows.length > 0 ? rawRows : [EMPTY_TEXT_TOKEN];
3404
- const newRowContent = createRowContent(this.store.state.options());
3371
+ const newRowContent = createRowContent(this.store.props.options());
3405
3372
  this.store.state.innerValue(addDragRow(value, rows, afterIndex, newRowContent));
3406
3373
  queueMicrotask(() => {
3407
- const container = this.store.refs.container;
3374
+ const container = this.store.state.container();
3408
3375
  if (!container) return;
3409
3376
  childAt(container, afterIndex + 1)?.focus();
3410
3377
  });
3411
3378
  }
3412
3379
  #delete(index) {
3413
- const value = this.store.state.value();
3414
- if (value == null || !this.store.state.onChange()) return;
3380
+ const value = this.store.props.value();
3381
+ if (value == null || !this.store.props.onChange()) return;
3415
3382
  const rows = this.store.state.tokens();
3416
3383
  this.store.state.innerValue(deleteDragRow(value, rows, index));
3417
3384
  }
3418
3385
  #duplicate(index) {
3419
- const value = this.store.state.value();
3420
- if (value == null || !this.store.state.onChange()) return;
3386
+ const value = this.store.props.value();
3387
+ if (value == null || !this.store.props.onChange()) return;
3421
3388
  const rows = this.store.state.tokens();
3422
3389
  this.store.state.innerValue(duplicateDragRow(value, rows, index));
3423
3390
  }
@@ -3436,8 +3403,8 @@ function getDragTargetIndex(blockIndex, position) {
3436
3403
  }
3437
3404
  //#endregion
3438
3405
  //#region ../../core/src/features/drag/config.ts
3439
- function getAlwaysShowHandleDrag(drag) {
3440
- return typeof drag === "object" && !!drag.alwaysShowHandle;
3406
+ function getAlwaysShowHandle(draggable) {
3407
+ return typeof draggable === "object" && !!draggable.alwaysShowHandle;
3441
3408
  }
3442
3409
  //#endregion
3443
3410
  //#region ../../core/src/features/events/SystemListenerFeature.ts
@@ -3449,25 +3416,25 @@ var SystemListenerFeature = class {
3449
3416
  enable() {
3450
3417
  if (this.#scope) return;
3451
3418
  this.#scope = effectScope(() => {
3452
- watch(this.store.event.change, () => {
3453
- const onChange = this.store.state.onChange();
3419
+ watch(this.store.emit.change, () => {
3420
+ const onChange = this.store.props.onChange();
3454
3421
  const { focus } = this.store.nodes;
3455
3422
  if (!focus.target || !focus.target.isContentEditable) {
3456
- const tokens = this.store.state.tokens();
3457
- const serialized = toString(tokens);
3423
+ const serialized = toString(this.store.state.tokens());
3458
3424
  onChange?.(serialized);
3459
3425
  this.store.state.previousValue(serialized);
3460
- this.store.state.tokens([...tokens]);
3426
+ trigger(this.store.state.tokens);
3461
3427
  return;
3462
3428
  }
3463
3429
  const tokens = this.store.state.tokens();
3430
+ if (focus.index >= tokens.length) return;
3464
3431
  const token = tokens[focus.index];
3465
3432
  if (token.type === "text") token.content = focus.content;
3466
3433
  else token.value = focus.content;
3467
3434
  onChange?.(toString(tokens));
3468
- this.store.event.parse();
3435
+ this.store.emit.reparse();
3469
3436
  });
3470
- watch(this.store.event.delete, (payload) => {
3437
+ watch(this.store.emit.markRemove, (payload) => {
3471
3438
  const { token } = payload;
3472
3439
  const tokens = this.store.state.tokens();
3473
3440
  if (!findToken(tokens, token)) return;
@@ -3482,11 +3449,11 @@ var SystemListenerFeature = class {
3482
3449
  this.store.state.tokens(newTokens);
3483
3450
  this.store.state.previousValue(newValue);
3484
3451
  });
3485
- this.store.state.onChange()?.(newValue);
3452
+ this.store.props.onChange()?.(newValue);
3486
3453
  });
3487
- watch(this.store.event.select, (event) => {
3488
- const Mark = this.store.state.Mark();
3489
- const onChange = this.store.state.onChange();
3454
+ watch(this.store.emit.overlaySelect, (event) => {
3455
+ const Mark = this.store.props.Mark();
3456
+ const onChange = this.store.props.onChange();
3490
3457
  const { mark, match: { option, span, index, source } } = event;
3491
3458
  const markup = option.markup;
3492
3459
  if (!markup) return;
@@ -3512,7 +3479,7 @@ var SystemListenerFeature = class {
3512
3479
  this.store.nodes.focus.target = this.store.nodes.input.target;
3513
3480
  this.store.nodes.input.clear();
3514
3481
  onChange?.(toString(tokens));
3515
- this.store.event.parse();
3482
+ this.store.emit.reparse();
3516
3483
  }
3517
3484
  });
3518
3485
  });
@@ -3525,51 +3492,40 @@ var SystemListenerFeature = class {
3525
3492
  //#endregion
3526
3493
  //#region ../../core/src/features/focus/FocusFeature.ts
3527
3494
  var FocusFeature = class {
3528
- #focusinHandler;
3529
- #focusoutHandler;
3530
- #clickHandler;
3495
+ #scope;
3531
3496
  constructor(store) {
3532
3497
  this.store = store;
3533
3498
  }
3534
3499
  enable() {
3535
- if (this.#focusinHandler) return;
3536
- const container = this.store.refs.container;
3500
+ if (this.#scope) return;
3501
+ const container = this.store.state.container();
3537
3502
  if (!container) return;
3538
- this.#focusinHandler = (e) => {
3539
- const target = isHtmlElement(e.target) ? e.target : void 0;
3540
- this.store.nodes.focus.target = target;
3541
- };
3542
- this.#focusoutHandler = () => {
3543
- this.store.nodes.focus.target = void 0;
3544
- };
3545
- this.#clickHandler = () => {
3546
- const tokens = this.store.state.tokens();
3547
- if (tokens.length === 1 && tokens[0].type === "text" && tokens[0].content === "") {
3548
- const container = this.store.refs.container;
3549
- (container ? firstHtmlChild(container) : null)?.focus();
3550
- }
3551
- };
3552
- container.addEventListener("focusin", this.#focusinHandler);
3553
- container.addEventListener("focusout", this.#focusoutHandler);
3554
- container.addEventListener("click", this.#clickHandler);
3555
- watch(this.store.event.recoverFocus, () => {
3556
- this.#recover();
3557
- });
3558
- watch(this.store.event.afterTokensRendered, () => {
3559
- this.store.event.sync();
3560
- if (!this.store.state.Mark()) return;
3561
- this.store.event.recoverFocus();
3503
+ this.#scope = effectScope(() => {
3504
+ listen(container, "focusin", (e) => {
3505
+ const target = isHtmlElement(e.target) ? e.target : void 0;
3506
+ this.store.nodes.focus.target = target;
3507
+ });
3508
+ listen(container, "focusout", () => {
3509
+ this.store.nodes.focus.target = void 0;
3510
+ });
3511
+ listen(container, "click", () => {
3512
+ const tokens = this.store.state.tokens();
3513
+ if (tokens.length === 1 && tokens[0].type === "text" && tokens[0].content === "") {
3514
+ const container = this.store.state.container();
3515
+ (container ? firstHtmlChild(container) : null)?.focus();
3516
+ }
3517
+ });
3518
+ watch(this.store.emit.rendered, () => {
3519
+ this.store.emit.sync();
3520
+ if (!this.store.props.Mark()) return;
3521
+ this.#recover();
3522
+ });
3562
3523
  });
3563
3524
  }
3564
3525
  disable() {
3565
- const container = this.store.refs.container;
3566
- if (!container || !this.#focusinHandler) return;
3567
- container.removeEventListener("focusin", this.#focusinHandler);
3568
- if (this.#focusoutHandler) container.removeEventListener("focusout", this.#focusoutHandler);
3569
- if (this.#clickHandler) container.removeEventListener("click", this.#clickHandler);
3570
- this.#focusinHandler = void 0;
3571
- this.#focusoutHandler = void 0;
3572
- this.#clickHandler = void 0;
3526
+ this.#scope?.();
3527
+ this.#scope = void 0;
3528
+ this.store.nodes.focus.clear();
3573
3529
  }
3574
3530
  #recover() {
3575
3531
  const recovery = this.store.state.recovery();
@@ -3579,7 +3535,7 @@ var FocusFeature = class {
3579
3535
  let target;
3580
3536
  switch (true) {
3581
3537
  case isNext && isStale: {
3582
- const container = this.store.refs.container;
3538
+ const container = this.store.state.container();
3583
3539
  target = (recovery.childIndex != null ? childAt(container, recovery.childIndex + 2) : void 0) ?? this.store.nodes.focus.tail ?? void 0;
3584
3540
  break;
3585
3541
  }
@@ -3604,40 +3560,31 @@ var FocusFeature = class {
3604
3560
  //#endregion
3605
3561
  //#region ../../core/src/features/input/InputFeature.ts
3606
3562
  var InputFeature = class {
3607
- #keydownHandler;
3608
- #pasteHandler;
3609
- #beforeInputHandler;
3563
+ #scope;
3610
3564
  constructor(store) {
3611
3565
  this.store = store;
3612
3566
  }
3613
3567
  enable() {
3614
- if (this.#keydownHandler) return;
3615
- const container = this.store.refs.container;
3568
+ if (this.#scope) return;
3569
+ const container = this.store.state.container();
3616
3570
  if (!container) return;
3617
- this.#keydownHandler = (e) => {
3618
- if (!this.store.state.drag()) this.#handleDelete(e);
3619
- };
3620
- this.#pasteHandler = (e) => {
3621
- const c = this.store.refs.container;
3622
- if (c) captureMarkupPaste(e, c);
3623
- handlePaste(this.store, e);
3624
- };
3625
- this.#beforeInputHandler = (e) => {
3626
- handleBeforeInput(this.store, e);
3627
- };
3628
- container.addEventListener("keydown", this.#keydownHandler);
3629
- container.addEventListener("paste", this.#pasteHandler);
3630
- container.addEventListener("beforeinput", this.#beforeInputHandler, true);
3571
+ this.#scope = effectScope(() => {
3572
+ listen(container, "keydown", (e) => {
3573
+ if (!this.store.computed.isBlock()) this.#handleDelete(e);
3574
+ });
3575
+ listen(container, "paste", (e) => {
3576
+ const c = this.store.state.container();
3577
+ if (c) captureMarkupPaste(e, c);
3578
+ handlePaste(this.store, e);
3579
+ });
3580
+ listen(container, "beforeinput", (e) => {
3581
+ handleBeforeInput(this.store, e);
3582
+ }, true);
3583
+ });
3631
3584
  }
3632
3585
  disable() {
3633
- const container = this.store.refs.container;
3634
- if (!container || !this.#keydownHandler) return;
3635
- container.removeEventListener("keydown", this.#keydownHandler);
3636
- if (this.#pasteHandler) container.removeEventListener("paste", this.#pasteHandler);
3637
- if (this.#beforeInputHandler) container.removeEventListener("beforeinput", this.#beforeInputHandler, true);
3638
- this.#keydownHandler = void 0;
3639
- this.#pasteHandler = void 0;
3640
- this.#beforeInputHandler = void 0;
3586
+ this.#scope?.();
3587
+ this.#scope = void 0;
3641
3588
  }
3642
3589
  #handleDelete(event) {
3643
3590
  const { focus } = this.store.nodes;
@@ -3672,14 +3619,14 @@ var InputFeature = class {
3672
3619
  event.preventDefault();
3673
3620
  focus.content = content.slice(0, caret - 1) + content.slice(caret);
3674
3621
  focus.caret = caret - 1;
3675
- this.store.event.change();
3622
+ this.store.emit.change();
3676
3623
  return;
3677
3624
  }
3678
3625
  if (event.key === KEYBOARD.DELETE && caret >= 0 && caret < content.length) {
3679
3626
  event.preventDefault();
3680
3627
  focus.content = content.slice(0, caret) + content.slice(caret + 1);
3681
3628
  focus.caret = caret;
3682
- this.store.event.change();
3629
+ this.store.emit.change();
3683
3630
  return;
3684
3631
  }
3685
3632
  }
@@ -3697,21 +3644,21 @@ function handleBeforeInput(store, event) {
3697
3644
  return;
3698
3645
  }
3699
3646
  if (selecting === "all") store.state.selecting(void 0);
3700
- if (store.state.drag()) return;
3647
+ if (store.computed.isBlock()) return;
3701
3648
  const { focus } = store.nodes;
3702
3649
  if (!focus.target || !focus.isEditable) return;
3703
3650
  if ((event.inputType === "insertFromPaste" || event.inputType === "insertReplacementText") && handleMarkputSpanPaste(store, focus, event)) return;
3704
- if (applySpanInput(focus, event)) store.event.change();
3651
+ if (applySpanInput(focus, event)) store.emit.change();
3705
3652
  }
3706
3653
  function handleMarkputSpanPaste(store, focus, event) {
3707
- const container = store.refs.container;
3654
+ const container = store.state.container();
3708
3655
  if (!container) return false;
3709
3656
  const markup = consumeMarkupPaste(container);
3710
3657
  if (!markup) return false;
3711
3658
  event.preventDefault();
3712
3659
  const token = store.state.tokens()[focus.index];
3713
3660
  const offset = focus.caret;
3714
- const currentValue = store.state.previousValue() ?? store.state.value() ?? "";
3661
+ const currentValue = store.computed.currentValue();
3715
3662
  const ranges = event.getTargetRanges();
3716
3663
  const childElement = container.children[focus.index];
3717
3664
  let rawInsertPos;
@@ -3801,13 +3748,15 @@ function handlePaste(store, event) {
3801
3748
  return;
3802
3749
  }
3803
3750
  event.preventDefault();
3804
- replaceAllContentWith(store, (store.refs.container ? consumeMarkupPaste(store.refs.container) : void 0) ?? event.clipboardData?.getData("text/plain") ?? "");
3751
+ const c = store.state.container();
3752
+ replaceAllContentWith(store, (c ? consumeMarkupPaste(c) : void 0) ?? event.clipboardData?.getData("text/plain") ?? "");
3805
3753
  }
3806
3754
  function replaceAllContentWith(store, newContent) {
3807
3755
  store.nodes.focus.target = null;
3808
3756
  store.state.selecting(void 0);
3809
- store.state.onChange()?.(newContent);
3810
- if (store.state.value() === void 0) store.state.tokens(store.computed.parser()?.parse(newContent) ?? [{
3757
+ store.state.previousValue(newContent);
3758
+ store.props.onChange()?.(newContent);
3759
+ if (store.props.value() === void 0) store.state.tokens(store.computed.parser()?.parse(newContent) ?? [{
3811
3760
  type: "text",
3812
3761
  content: newContent,
3813
3762
  position: {
@@ -3816,7 +3765,7 @@ function replaceAllContentWith(store, newContent) {
3816
3765
  }
3817
3766
  }]);
3818
3767
  queueMicrotask(() => {
3819
- const rawFirstChild = store.refs.container?.firstChild;
3768
+ const rawFirstChild = store.state.container()?.firstChild;
3820
3769
  const firstChild = isHtmlElement(rawFirstChild) ? rawFirstChild : null;
3821
3770
  if (firstChild) {
3822
3771
  store.state.recovery({
@@ -3864,93 +3813,50 @@ function createMarkFromOverlay(match, value, meta) {
3864
3813
  //#region ../../core/src/features/overlay/OverlayFeature.ts
3865
3814
  var OverlayFeature = class {
3866
3815
  #scope;
3867
- #selectionChangeHandler;
3868
- #focusinHandler;
3869
- #focusoutHandler;
3870
- #escHandler;
3871
- #clickHandler;
3872
3816
  constructor(store) {
3873
3817
  this.store = store;
3874
3818
  }
3819
+ #probeTrigger() {
3820
+ const match = TriggerFinder.find(this.store.props.options(), (option) => option.overlay?.trigger);
3821
+ this.store.state.overlayMatch(match);
3822
+ }
3875
3823
  enable() {
3876
3824
  if (this.#scope) return;
3877
- this.store.state.overlayTrigger((option) => option.overlay?.trigger);
3878
3825
  this.#scope = effectScope(() => {
3879
- watch(this.store.event.clearOverlay, () => {
3826
+ watch(this.store.emit.overlayClose, () => {
3880
3827
  this.store.state.overlayMatch(void 0);
3881
3828
  });
3882
- watch(this.store.event.checkOverlay, () => {
3883
- const getTrigger = this.store.state.overlayTrigger();
3884
- if (!getTrigger) return;
3885
- const match = TriggerFinder.find(this.store.state.options(), getTrigger);
3886
- this.store.state.overlayMatch(match);
3887
- });
3888
- watch(this.store.event.change, () => {
3889
- const showOverlayOn = this.store.state.showOverlayOn();
3829
+ watch(this.store.emit.change, () => {
3830
+ const showOverlayOn = this.store.props.showOverlayOn();
3890
3831
  const type = "change";
3891
- if (showOverlayOn === type || Array.isArray(showOverlayOn) && showOverlayOn.includes(type)) this.store.event.checkOverlay();
3832
+ if (showOverlayOn === type || Array.isArray(showOverlayOn) && showOverlayOn.includes(type)) this.#probeTrigger();
3892
3833
  });
3893
- watch(this.store.state.overlayMatch, (match) => {
3894
- if (match) {
3834
+ alienEffect(() => {
3835
+ if (this.store.state.overlayMatch()) {
3895
3836
  this.store.nodes.input.target = this.store.nodes.focus.target;
3896
- this.#enableClose();
3897
- } else this.#disableClose();
3837
+ listen(window, "keydown", (e) => {
3838
+ if (e.key === KEYBOARD.ESC) this.store.emit.overlayClose();
3839
+ });
3840
+ listen(document, "click", (e) => {
3841
+ const target = e.target instanceof HTMLElement ? e.target : null;
3842
+ if (this.store.state.overlay()?.contains(target)) return;
3843
+ if (this.store.state.container()?.contains(target)) return;
3844
+ this.store.emit.overlayClose();
3845
+ }, true);
3846
+ }
3898
3847
  });
3848
+ const selectionChangeHandler = () => {
3849
+ if (!this.store.state.container()?.contains(document.activeElement)) return;
3850
+ const showOverlayOn = this.store.props.showOverlayOn();
3851
+ const type = "selectionChange";
3852
+ if (showOverlayOn === type || Array.isArray(showOverlayOn) && showOverlayOn.includes(type)) this.#probeTrigger();
3853
+ };
3854
+ listen(document, "selectionchange", selectionChangeHandler);
3899
3855
  });
3900
- const selectionChangeHandler = () => {
3901
- const showOverlayOn = this.store.state.showOverlayOn();
3902
- const type = "selectionChange";
3903
- if (showOverlayOn === type || Array.isArray(showOverlayOn) && showOverlayOn.includes(type)) this.store.event.checkOverlay();
3904
- };
3905
- this.#selectionChangeHandler = selectionChangeHandler;
3906
- this.#focusinHandler = () => {
3907
- document.addEventListener("selectionchange", selectionChangeHandler);
3908
- };
3909
- this.#focusoutHandler = () => {
3910
- document.removeEventListener("selectionchange", selectionChangeHandler);
3911
- };
3912
- const container = this.store.refs.container;
3913
- if (container) {
3914
- container.addEventListener("focusin", this.#focusinHandler);
3915
- container.addEventListener("focusout", this.#focusoutHandler);
3916
- }
3917
3856
  }
3918
3857
  disable() {
3919
- const container = this.store.refs.container;
3920
- if (container && this.#focusinHandler) {
3921
- container.removeEventListener("focusin", this.#focusinHandler);
3922
- if (this.#focusoutHandler) container.removeEventListener("focusout", this.#focusoutHandler);
3923
- }
3924
- if (this.#selectionChangeHandler) document.removeEventListener("selectionchange", this.#selectionChangeHandler);
3925
- this.#disableClose();
3926
- this.store.state.overlayTrigger(void 0);
3927
3858
  this.#scope?.();
3928
3859
  this.#scope = void 0;
3929
- this.#selectionChangeHandler = void 0;
3930
- this.#focusinHandler = void 0;
3931
- this.#focusoutHandler = void 0;
3932
- }
3933
- #enableClose() {
3934
- if (this.#escHandler) return;
3935
- this.#escHandler = (e) => {
3936
- if (e.key === KEYBOARD.ESC) this.store.event.clearOverlay();
3937
- };
3938
- this.#clickHandler = (e) => {
3939
- const target = e.target instanceof HTMLElement ? e.target : null;
3940
- if (this.store.refs.overlay?.contains(target)) return;
3941
- if (this.store.refs.container?.contains(target)) return;
3942
- this.store.event.clearOverlay();
3943
- };
3944
- window.addEventListener("keydown", this.#escHandler);
3945
- document.addEventListener("click", this.#clickHandler, true);
3946
- }
3947
- #disableClose() {
3948
- if (this.#escHandler) {
3949
- window.removeEventListener("keydown", this.#escHandler);
3950
- if (this.#clickHandler) document.removeEventListener("click", this.#clickHandler, true);
3951
- this.#escHandler = void 0;
3952
- this.#clickHandler = void 0;
3953
- }
3954
3860
  }
3955
3861
  };
3956
3862
  //#endregion
@@ -4046,35 +3952,6 @@ function resolveMarkSlot(token, tokenOptions, GlobalMark, GlobalSpan) {
4046
3952
  return [Component, props];
4047
3953
  }
4048
3954
  //#endregion
4049
- //#region ../../core/src/features/slots/createSlots.ts
4050
- function createNamedSlot(slots, slotProps, name) {
4051
- return {
4052
- use: () => [resolveSlot(name, slots.use()), resolveSlotProps(name, slotProps.use())],
4053
- get: () => [resolveSlot(name, slots()), resolveSlotProps(name, slotProps())]
4054
- };
4055
- }
4056
- function createOverlaySlot(overlay) {
4057
- return {
4058
- use: (option, defaultComponent) => resolveOverlaySlot(overlay.use(), option, defaultComponent),
4059
- get: (option, defaultComponent) => resolveOverlaySlot(overlay(), option, defaultComponent)
4060
- };
4061
- }
4062
- function createMarkSlot(options, mark, span) {
4063
- return {
4064
- use: (token) => resolveMarkSlot(token, options(), mark.use(), span.use()),
4065
- get: (token) => resolveMarkSlot(token, options(), mark(), span())
4066
- };
4067
- }
4068
- function createSlots(signals) {
4069
- return {
4070
- container: createNamedSlot(signals.slots, signals.slotProps, "container"),
4071
- block: createNamedSlot(signals.slots, signals.slotProps, "block"),
4072
- span: createNamedSlot(signals.slots, signals.slotProps, "span"),
4073
- overlay: createOverlaySlot(signals.Overlay),
4074
- mark: createMarkSlot(signals.options, signals.Mark, signals.Span)
4075
- };
4076
- }
4077
- //#endregion
4078
3955
  //#region ../../core/src/shared/utils/menuUtils.ts
4079
3956
  /**
4080
3957
  * Returns true when `target` is outside `element` (i.e. not contained by it).
@@ -4110,7 +3987,7 @@ var BlockStore = class {
4110
3987
  #cleanupMenu;
4111
3988
  attachContainer(el, blockIndex, actions) {
4112
3989
  this.#blockIndex = blockIndex;
4113
- this.#dragAction = actions.dragAction;
3990
+ this.#dragAction = actions.drag;
4114
3991
  if (el === this.refs.container) return;
4115
3992
  this.#cleanupContainer?.();
4116
3993
  this.refs.container = el;
@@ -4156,7 +4033,7 @@ var BlockStore = class {
4156
4033
  }
4157
4034
  attachGrip(el, blockIndex, actions) {
4158
4035
  this.#blockIndex = blockIndex;
4159
- this.#dragAction = actions.dragAction;
4036
+ this.#dragAction = actions.drag;
4160
4037
  this.#cleanupGrip?.();
4161
4038
  if (!el) return;
4162
4039
  const onDragStart = (e) => {
@@ -4245,6 +4122,21 @@ var BlockRegistry = class {
4245
4122
  };
4246
4123
  //#endregion
4247
4124
  //#region ../../core/src/store/Store.ts
4125
+ const DRAG_HANDLE_WIDTH = 24;
4126
+ function buildContainerProps(isDraggableBlock, readOnly, className, style, slotProps) {
4127
+ const containerSlotProps = slotProps?.container;
4128
+ const baseStyle = merge(style, containerSlotProps?.style);
4129
+ const mergedStyle = isDraggableBlock && !readOnly ? {
4130
+ paddingLeft: DRAG_HANDLE_WIDTH,
4131
+ ...baseStyle
4132
+ } : baseStyle;
4133
+ const { className: _, style: __, ...otherSlotProps } = resolveSlotProps("container", slotProps) ?? {};
4134
+ return {
4135
+ className: cx(styles.Container, className, containerSlotProps?.className),
4136
+ style: mergedStyle,
4137
+ ...otherSlotProps
4138
+ };
4139
+ }
4248
4140
  var Store = class {
4249
4141
  key = new KeyGenerator();
4250
4142
  blocks = new BlockRegistry();
@@ -4252,75 +4144,81 @@ var Store = class {
4252
4144
  focus: new NodeProxy(void 0, this),
4253
4145
  input: new NodeProxy(void 0, this)
4254
4146
  };
4147
+ props = {
4148
+ value: signal(void 0, { readonly: true }),
4149
+ defaultValue: signal(void 0, { readonly: true }),
4150
+ onChange: signal(void 0, { readonly: true }),
4151
+ options: signal(DEFAULT_OPTIONS, { readonly: true }),
4152
+ readOnly: signal(false, { readonly: true }),
4153
+ layout: signal("inline", { readonly: true }),
4154
+ draggable: signal(false, { readonly: true }),
4155
+ showOverlayOn: signal("change", { readonly: true }),
4156
+ Span: signal(void 0, { readonly: true }),
4157
+ Mark: signal(void 0, { readonly: true }),
4158
+ Overlay: signal(void 0, { readonly: true }),
4159
+ className: signal(void 0, { readonly: true }),
4160
+ style: signal(void 0, {
4161
+ equals: shallow,
4162
+ readonly: true
4163
+ }),
4164
+ slots: signal(void 0, { readonly: true }),
4165
+ slotProps: signal(void 0, { readonly: true })
4166
+ };
4255
4167
  state = {
4256
4168
  tokens: signal([]),
4257
- value: signal(void 0),
4258
- defaultValue: signal(void 0),
4259
4169
  previousValue: signal(void 0),
4260
4170
  innerValue: signal(void 0),
4261
4171
  recovery: signal(void 0),
4172
+ container: signal(null),
4173
+ overlay: signal(null),
4262
4174
  selecting: signal(void 0),
4263
- drag: signal(false),
4264
- overlayMatch: signal(void 0),
4265
- overlayTrigger: signal(void 0),
4266
- showOverlayOn: signal("change"),
4267
- onChange: signal(void 0),
4268
- options: signal(DEFAULT_OPTIONS),
4269
- readOnly: signal(false),
4270
- Span: signal(void 0),
4271
- Mark: signal(void 0),
4272
- Overlay: signal(void 0),
4273
- className: signal(void 0),
4274
- style: signal(void 0, { equals: shallow }),
4275
- slots: signal(void 0),
4276
- slotProps: signal(void 0)
4175
+ overlayMatch: signal(void 0)
4277
4176
  };
4278
4177
  computed = {
4279
4178
  hasMark: computed(() => {
4280
- if (this.state.Mark()) return true;
4281
- return this.state.options().some((opt) => "Mark" in opt && opt.Mark != null);
4179
+ if (this.props.Mark()) return true;
4180
+ return this.props.options().some((opt) => "Mark" in opt && opt.Mark != null);
4282
4181
  }),
4182
+ isBlock: computed(() => this.props.layout() === "block"),
4183
+ isDraggable: computed(() => !!this.props.draggable()),
4283
4184
  parser: computed(() => {
4284
4185
  if (!this.computed.hasMark()) return;
4285
- const markups = this.state.options().map((opt) => opt.markup);
4186
+ const markups = this.props.options().map((opt) => opt.markup);
4286
4187
  if (!markups.some(Boolean)) return;
4287
- return new Parser(markups, !!this.state.drag() ? { skipEmptyText: true } : void 0);
4188
+ return new Parser(markups, this.computed.isBlock() ? { skipEmptyText: true } : void 0);
4288
4189
  }),
4289
- containerClass: computed(() => cx(styles.Container, this.state.className(), this.state.slotProps()?.container?.className)),
4290
- containerStyle: computed((prev) => {
4291
- const next = merge(this.state.style(), this.state.slotProps()?.container?.style);
4292
- return prev && shallow(prev, next) ? prev : next;
4190
+ currentValue: computed(() => this.state.previousValue() ?? this.props.value() ?? ""),
4191
+ containerComponent: computed(() => resolveSlot("container", this.props.slots())),
4192
+ containerProps: computed(() => buildContainerProps(this.computed.isDraggable() && this.computed.isBlock(), this.props.readOnly(), this.props.className(), this.props.style(), this.props.slotProps()), { equals: shallow }),
4193
+ blockComponent: computed(() => resolveSlot("block", this.props.slots())),
4194
+ blockProps: computed(() => resolveSlotProps("block", this.props.slotProps())),
4195
+ spanComponent: computed(() => resolveSlot("span", this.props.slots())),
4196
+ spanProps: computed(() => resolveSlotProps("span", this.props.slotProps())),
4197
+ overlay: computed(() => {
4198
+ const Overlay = this.props.Overlay();
4199
+ return (option, defaultComponent) => resolveOverlaySlot(Overlay, option, defaultComponent);
4200
+ }),
4201
+ mark: computed(() => {
4202
+ const options = this.props.options();
4203
+ const Mark = this.props.Mark();
4204
+ const Span = this.props.Span();
4205
+ return (token) => resolveMarkSlot(token, options, Mark, Span);
4293
4206
  })
4294
4207
  };
4295
- slot = createSlots({
4296
- slots: this.state.slots,
4297
- slotProps: this.state.slotProps,
4298
- Overlay: this.state.Overlay,
4299
- options: this.state.options,
4300
- Mark: this.state.Mark,
4301
- Span: this.state.Span
4302
- });
4303
- event = {
4208
+ emit = {
4304
4209
  change: event(),
4305
- parse: event(),
4306
- delete: event(),
4307
- select: event(),
4308
- clearOverlay: event(),
4309
- checkOverlay: event(),
4210
+ reparse: event(),
4211
+ markRemove: event(),
4212
+ overlaySelect: event(),
4213
+ overlayClose: event(),
4310
4214
  sync: event(),
4311
- recoverFocus: event(),
4312
- dragAction: event(),
4313
- updated: event(),
4314
- afterTokensRendered: event(),
4215
+ drag: event(),
4216
+ rendered: event(),
4315
4217
  mounted: event(),
4316
4218
  unmounted: event()
4317
4219
  };
4318
- refs = {
4319
- container: null,
4320
- overlay: null
4321
- };
4322
4220
  handler = new MarkputHandler(this);
4323
- features = {
4221
+ feature = {
4324
4222
  overlay: new OverlayFeature(this),
4325
4223
  focus: new FocusFeature(this),
4326
4224
  input: new InputFeature(this),
@@ -4334,17 +4232,17 @@ var Store = class {
4334
4232
  parse: new ParseFeature(this)
4335
4233
  };
4336
4234
  constructor() {
4337
- watch(this.event.mounted, () => Object.values(this.features).forEach((f) => f.enable()));
4338
- watch(this.event.unmounted, () => Object.values(this.features).forEach((f) => f.disable()));
4235
+ watch(this.emit.mounted, () => Object.values(this.feature).forEach((f) => f.enable()));
4236
+ watch(this.emit.unmounted, () => Object.values(this.feature).forEach((f) => f.disable()));
4339
4237
  }
4340
- setState(values) {
4238
+ setProps(values) {
4341
4239
  batch(() => {
4342
- const state = this.state;
4240
+ const props = this.props;
4343
4241
  for (const key of Object.keys(values)) {
4344
- if (!(key in state)) continue;
4345
- state[key](values[key]);
4242
+ if (!(key in props)) continue;
4243
+ props[key](values[key]);
4346
4244
  }
4347
- });
4245
+ }, { mutable: true });
4348
4246
  }
4349
4247
  };
4350
4248
  //#endregion
@@ -4389,14 +4287,17 @@ var MarkHandler = class {
4389
4287
  get slot() {
4390
4288
  return this.#token.slot?.content;
4391
4289
  }
4290
+ get #tokenInfo() {
4291
+ return findToken(this.#store.state.tokens(), this.#token);
4292
+ }
4392
4293
  get depth() {
4393
- return findToken(this.#store.state.tokens(), this.#token)?.depth ?? 0;
4294
+ return this.#tokenInfo?.depth ?? 0;
4394
4295
  }
4395
4296
  get hasChildren() {
4396
4297
  return this.#token.children.some((child) => child.type === "mark");
4397
4298
  }
4398
4299
  get parent() {
4399
- return findToken(this.#store.state.tokens(), this.#token)?.parent;
4300
+ return this.#tokenInfo?.parent;
4400
4301
  }
4401
4302
  get tokens() {
4402
4303
  return this.#token.children;
@@ -4407,27 +4308,40 @@ var MarkHandler = class {
4407
4308
  if (props.meta !== void 0) this.#token.meta = props.meta;
4408
4309
  this.#emitChange();
4409
4310
  };
4410
- remove = () => this.#store.event.delete({ token: this.#token });
4311
+ remove = () => this.#store.emit.markRemove({ token: this.#token });
4411
4312
  #emitChange() {
4412
- this.#store.event.change();
4313
+ this.#store.emit.change();
4413
4314
  }
4414
4315
  };
4415
4316
  //#endregion
4416
- //#region src/lib/hooks/createUseHook.ts
4417
- setUseHookFactory((sig) => {
4418
- const s = sig;
4419
- const subscribe = (cb) => watch(s, cb);
4420
- const getSnapshot = () => s();
4421
- return () => useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
4422
- });
4423
- //#endregion
4424
4317
  //#region src/lib/providers/StoreContext.ts
4425
4318
  const StoreContext = createContext(void 0);
4426
4319
  StoreContext.displayName = "StoreContext";
4427
- function useStore() {
4320
+ //#endregion
4321
+ //#region src/lib/hooks/useMarkput.ts
4322
+ function useMarkput(selector) {
4428
4323
  const store = useContext(StoreContext);
4429
4324
  if (store === void 0) throw new Error("Store not found. Make sure to wrap component in StoreContext.");
4430
- return store;
4325
+ const stableRef = useRef(null);
4326
+ if (stableRef.current === null) {
4327
+ const target = selector(store);
4328
+ const derived = computed(() => {
4329
+ if (typeof target === "function") return target();
4330
+ const out = {};
4331
+ for (const k in target) {
4332
+ const val = target[k];
4333
+ out[k] = isReactive(val) ? val() : val;
4334
+ }
4335
+ return out;
4336
+ });
4337
+ stableRef.current = {
4338
+ derived,
4339
+ subscribe: (cb) => watch(derived, cb),
4340
+ getSnapshot: () => derived()
4341
+ };
4342
+ }
4343
+ const { subscribe, getSnapshot } = stableRef.current;
4344
+ return useSyncExternalStore(subscribe, getSnapshot, getSnapshot);
4431
4345
  }
4432
4346
  //#endregion
4433
4347
  //#region src/components/Popup/List.tsx
@@ -4463,9 +4377,11 @@ const Popup = ({ ref, style, children }) => {
4463
4377
  //#endregion
4464
4378
  //#region src/components/BlockMenu.tsx
4465
4379
  const BlockMenu = memo(({ token }) => {
4466
- const blockStore = useStore().blocks.get(token);
4467
- const menuOpen = blockStore.state.menuOpen.use();
4468
- const menuPosition = blockStore.state.menuPosition.use();
4380
+ const { blockStore, menuOpen, menuPosition } = useMarkput((s) => ({
4381
+ blockStore: s.blocks.get(token),
4382
+ menuOpen: s.blocks.get(token).state.menuOpen,
4383
+ menuPosition: s.blocks.get(token).state.menuPosition
4384
+ }));
4469
4385
  if (!menuOpen) return null;
4470
4386
  return /* @__PURE__ */ jsx(Popup, {
4471
4387
  ref: (el) => blockStore.attachMenu(el),
@@ -4494,18 +4410,20 @@ BlockMenu.displayName = "BlockMenu";
4494
4410
  //#region src/components/DragHandle.tsx
4495
4411
  const iconGrip = `${styles$1.Icon} ${styles$1.IconGrip}`;
4496
4412
  const DragHandle = memo(({ token, blockIndex }) => {
4497
- const store = useStore();
4498
- const readOnly = store.state.readOnly.use();
4499
- const drag = store.state.drag.use();
4500
- const blockStore = store.blocks.get(token);
4501
- const isDragging = blockStore.state.isDragging.use();
4502
- const isHovered = blockStore.state.isHovered.use();
4503
- const alwaysShowHandle = useMemo(() => getAlwaysShowHandleDrag(drag), [drag]);
4413
+ const { blockStore, emit, readOnly, draggable, isDragging, isHovered } = useMarkput((s) => ({
4414
+ blockStore: s.blocks.get(token),
4415
+ emit: s.emit,
4416
+ readOnly: s.props.readOnly,
4417
+ draggable: s.props.draggable,
4418
+ isDragging: s.blocks.get(token).state.isDragging,
4419
+ isHovered: s.blocks.get(token).state.isHovered
4420
+ }));
4421
+ const alwaysShowHandle = useMemo(() => getAlwaysShowHandle(draggable), [draggable]);
4504
4422
  if (readOnly) return null;
4505
4423
  return /* @__PURE__ */ jsx("div", {
4506
4424
  className: cx(styles$1.SidePanel, alwaysShowHandle ? styles$1.SidePanelAlways : isHovered && !isDragging && styles$1.SidePanelVisible),
4507
4425
  children: /* @__PURE__ */ jsx("button", {
4508
- ref: (el) => blockStore.attachGrip(el, blockIndex, store.event),
4426
+ ref: (el) => blockStore.attachGrip(el, blockIndex, emit),
4509
4427
  type: "button",
4510
4428
  draggable: true,
4511
4429
  className: cx(styles$1.GripButton, isDragging && styles$1.GripButtonDragging),
@@ -4518,7 +4436,7 @@ DragHandle.displayName = "DragHandle";
4518
4436
  //#endregion
4519
4437
  //#region src/components/DropIndicator.tsx
4520
4438
  const DropIndicator = memo(({ token, position }) => {
4521
- if (useStore().blocks.get(token).state.dropPosition.use() !== position) return null;
4439
+ if (useMarkput((s) => s.blocks.get(token).state.dropPosition) !== position) return null;
4522
4440
  return /* @__PURE__ */ jsx("div", {
4523
4441
  className: styles$1.DropIndicator,
4524
4442
  style: position === "before" ? { top: -1 } : { bottom: -1 }
@@ -4537,12 +4455,15 @@ function useToken() {
4537
4455
  //#endregion
4538
4456
  //#region src/components/Token.tsx
4539
4457
  const Token = memo(({ mark }) => {
4540
- const store = useStore();
4541
- const [Component, props] = store.slot.mark.use(mark);
4458
+ const { resolveMarkSlot, key } = useMarkput((s) => ({
4459
+ resolveMarkSlot: s.computed.mark,
4460
+ key: s.key
4461
+ }));
4462
+ const [Component, props] = resolveMarkSlot(mark);
4542
4463
  return /* @__PURE__ */ jsx(TokenContext, {
4543
4464
  value: mark,
4544
4465
  children: /* @__PURE__ */ jsx(Component, {
4545
- children: mark.type === "mark" && mark.children.length > 0 ? mark.children.map((child) => /* @__PURE__ */ jsx(Token, { mark: child }, store.key.get(child))) : void 0,
4466
+ children: mark.type === "mark" && mark.children.length > 0 ? mark.children.map((child) => /* @__PURE__ */ jsx(Token, { mark: child }, key.get(child))) : void 0,
4546
4467
  ...props
4547
4468
  })
4548
4469
  });
@@ -4550,17 +4471,25 @@ const Token = memo(({ mark }) => {
4550
4471
  Token.displayName = "Token";
4551
4472
  //#endregion
4552
4473
  //#region src/components/Block.tsx
4553
- const Block = memo(({ token, blockIndex }) => {
4554
- const store = useStore();
4555
- const [ContainerComponent, containerProps] = store.slot.block.use();
4556
- const blockStore = store.blocks.get(token);
4557
- const isDragging = blockStore.state.isDragging.use();
4558
- return /* @__PURE__ */ jsxs(ContainerComponent, {
4559
- ref: (el) => blockStore.attachContainer(el, blockIndex, store.event),
4474
+ const Block = memo(({ token }) => {
4475
+ const { blockStore, emit, Component, slotProps, isDragging, tokens } = useMarkput((s) => ({
4476
+ blockStore: s.blocks.get(token),
4477
+ emit: s.emit,
4478
+ Component: s.computed.blockComponent,
4479
+ slotProps: s.computed.blockProps,
4480
+ isDragging: s.blocks.get(token).state.isDragging,
4481
+ tokens: s.state.tokens
4482
+ }));
4483
+ const blockIndex = tokens.indexOf(token);
4484
+ return /* @__PURE__ */ jsxs(Component, {
4485
+ ref: (el) => blockStore.attachContainer(el, blockIndex, emit),
4560
4486
  "data-testid": "block",
4561
- ...containerProps,
4562
- className: styles$1.Block,
4563
- style: { opacity: isDragging ? .4 : 1 },
4487
+ ...slotProps,
4488
+ className: cx(styles$1.Block, slotProps?.className),
4489
+ style: {
4490
+ opacity: isDragging ? .4 : 1,
4491
+ ...slotProps?.style
4492
+ },
4564
4493
  children: [
4565
4494
  /* @__PURE__ */ jsx(DropIndicator, {
4566
4495
  token,
@@ -4583,60 +4512,60 @@ Block.displayName = "Block";
4583
4512
  //#endregion
4584
4513
  //#region src/components/Container.tsx
4585
4514
  const Container = memo(() => {
4586
- const store = useStore();
4587
- const drag = store.state.drag.use();
4588
- const tokens = store.state.tokens.use();
4515
+ const { isBlock, tokens, key, state, emit, Component, props } = useMarkput((s) => ({
4516
+ isBlock: s.computed.isBlock,
4517
+ tokens: s.state.tokens,
4518
+ key: s.key,
4519
+ state: s.state,
4520
+ emit: s.emit,
4521
+ Component: s.computed.containerComponent,
4522
+ props: s.computed.containerProps
4523
+ }));
4589
4524
  useLayoutEffect(() => {
4590
- store.event.afterTokensRendered();
4591
- }, [tokens]);
4592
- const className = store.computed.containerClass.use();
4593
- const style = store.computed.containerStyle.use();
4594
- const readOnly = store.state.readOnly.use();
4595
- const key = store.key;
4596
- const refs = store.refs;
4597
- const [ContainerComponent, containerProps] = store.slot.container.use();
4598
- const containerStyle = drag && !readOnly ? style ? {
4599
- paddingLeft: 24,
4600
- ...style
4601
- } : { paddingLeft: 24 } : style;
4602
- return /* @__PURE__ */ jsx(ContainerComponent, {
4603
- ref: (el) => refs.container = el,
4604
- ...containerProps,
4605
- className,
4606
- style: containerStyle,
4607
- children: drag ? tokens.map((t, i) => /* @__PURE__ */ jsx(Block, {
4608
- token: t,
4609
- blockIndex: i
4610
- }, key.get(t))) : tokens.map((t) => /* @__PURE__ */ jsx(Token, { mark: t }, key.get(t)))
4525
+ emit.rendered();
4526
+ }, [tokens, emit]);
4527
+ return /* @__PURE__ */ jsx(Component, {
4528
+ ref: state.container,
4529
+ ...props,
4530
+ children: isBlock ? tokens.map((t) => /* @__PURE__ */ jsx(Block, { token: t }, key.get(t))) : tokens.map((t) => /* @__PURE__ */ jsx(Token, { mark: t }, key.get(t)))
4611
4531
  });
4612
4532
  });
4613
4533
  Container.displayName = "Container";
4614
4534
  //#endregion
4615
4535
  //#region src/lib/hooks/useOverlay.tsx
4616
4536
  function useOverlay() {
4617
- const store = useStore();
4618
- const match = store.state.overlayMatch.use();
4619
- if (!match) throw new Error("useOverlay requires an active overlay match");
4620
- const style = useMemo(() => Caret.getAbsolutePosition(), [match]);
4621
- const close = useCallback(() => store.event.clearOverlay(), []);
4537
+ const { match, emit, state } = useMarkput((s) => ({
4538
+ match: s.state.overlayMatch,
4539
+ emit: s.emit,
4540
+ state: s.state
4541
+ }));
4542
+ const style = useMemo(() => {
4543
+ if (!match) return {
4544
+ left: 0,
4545
+ top: 0
4546
+ };
4547
+ return Caret.getAbsolutePosition();
4548
+ }, [match]);
4549
+ const close = useCallback(() => emit.overlayClose(), []);
4622
4550
  return {
4623
4551
  match,
4624
4552
  style,
4625
4553
  select: useCallback((value) => {
4554
+ if (!match) return;
4626
4555
  const mark = createMarkFromOverlay(match, value.value, value.meta);
4627
- store.event.select({
4556
+ emit.overlaySelect({
4628
4557
  mark,
4629
4558
  match
4630
4559
  });
4631
- store.event.clearOverlay();
4560
+ emit.overlayClose();
4632
4561
  }, [match]),
4633
4562
  close,
4634
4563
  ref: useMemo(() => ({
4635
4564
  get current() {
4636
- return store.refs.overlay;
4565
+ return state.overlay();
4637
4566
  },
4638
4567
  set current(v) {
4639
- store.refs.overlay = v;
4568
+ state.overlay(v);
4640
4569
  }
4641
4570
  }), [])
4642
4571
  };
@@ -4644,18 +4573,18 @@ function useOverlay() {
4644
4573
  //#endregion
4645
4574
  //#region src/components/Suggestions/Suggestions.tsx
4646
4575
  const Suggestions = () => {
4647
- const store = useStore();
4576
+ const { state } = useMarkput((s) => ({ state: s.state }));
4648
4577
  const { match, select, style, ref } = useOverlay();
4649
4578
  const [active, setActive] = useState(NaN);
4650
- const data = match.option.overlay?.data ?? [];
4651
- const filtered = useMemo(() => filterSuggestions(data, match.value), [match.value, data]);
4579
+ const data = match?.option.overlay?.data ?? [];
4580
+ const filtered = useMemo(() => match ? filterSuggestions(data, match.value) : [], [match, data]);
4652
4581
  const length = filtered.length;
4653
4582
  const activeRef = useRef(active);
4654
4583
  activeRef.current = active;
4655
4584
  const filteredRef = useRef(filtered);
4656
4585
  filteredRef.current = filtered;
4657
4586
  useEffect(() => {
4658
- const container = store.refs.container;
4587
+ const container = state.container();
4659
4588
  if (!container) return;
4660
4589
  const handler = (event) => {
4661
4590
  const result = navigateSuggestions(event.key, activeRef.current, length);
@@ -4697,10 +4626,13 @@ const Suggestions = () => {
4697
4626
  //#endregion
4698
4627
  //#region src/components/OverlayRenderer.tsx
4699
4628
  const OverlayRenderer = memo(() => {
4700
- const store = useStore();
4701
- const overlayMatch = store.state.overlayMatch.use();
4702
- const key = useMemo(() => overlayMatch ? store.key.get(overlayMatch.option) : void 0, [overlayMatch]);
4703
- const [Overlay, props] = store.slot.overlay.use(overlayMatch?.option, Suggestions);
4629
+ const { overlayMatch, key: keyGen, resolveOverlay } = useMarkput((s) => ({
4630
+ overlayMatch: s.state.overlayMatch,
4631
+ key: s.key,
4632
+ resolveOverlay: s.computed.overlay
4633
+ }));
4634
+ const key = useMemo(() => overlayMatch ? keyGen.get(overlayMatch.option) : void 0, [overlayMatch]);
4635
+ const [Overlay, props] = resolveOverlay(overlayMatch?.option, Suggestions);
4704
4636
  if (!key) return;
4705
4637
  return /* @__PURE__ */ jsx(Overlay, { ...props }, key);
4706
4638
  });
@@ -4709,10 +4641,11 @@ OverlayRenderer.displayName = "OverlayRenderer";
4709
4641
  //#region src/components/MarkedInput.tsx
4710
4642
  function MarkedInput(props) {
4711
4643
  const [store] = useState(() => new Store());
4712
- store.setState(props);
4713
- useLayoutEffect(() => store.event.mounted());
4714
- useLayoutEffect(() => store.event.updated());
4715
- useEffect(() => () => store.event.unmounted(), [store]);
4644
+ store.setProps(props);
4645
+ useLayoutEffect(() => {
4646
+ store.emit.mounted();
4647
+ return () => store.emit.unmounted();
4648
+ }, []);
4716
4649
  useImperativeHandle(props.ref, () => store.handler, [store]);
4717
4650
  return /* @__PURE__ */ jsxs(StoreContext, {
4718
4651
  value: store,
@@ -4722,7 +4655,10 @@ function MarkedInput(props) {
4722
4655
  //#endregion
4723
4656
  //#region src/lib/hooks/useMark.tsx
4724
4657
  const useMark = (options = {}) => {
4725
- const store = useStore();
4658
+ const { store, readOnly } = useMarkput((s) => ({
4659
+ store: s,
4660
+ readOnly: s.props.readOnly
4661
+ }));
4726
4662
  const token = useToken();
4727
4663
  if (token.type !== "mark") throw new Error("useMark must be called within a mark token context");
4728
4664
  const ref = useRef(null);
@@ -4732,7 +4668,6 @@ const useMark = (options = {}) => {
4732
4668
  token
4733
4669
  }), [store, token]);
4734
4670
  useUncontrolledInit(ref, options, token);
4735
- const readOnly = store.state.readOnly.use();
4736
4671
  useEffect(() => {
4737
4672
  mark.readOnly = readOnly;
4738
4673
  }, [mark, readOnly]);
@@ -4744,6 +4679,6 @@ function useUncontrolledInit(ref, options, token) {
4744
4679
  }, []);
4745
4680
  }
4746
4681
  //#endregion
4747
- export { MarkHandler, MarkedInput, MarkputHandler, annotate, denote, useMark, useOverlay };
4682
+ export { MarkHandler, MarkedInput, MarkputHandler, annotate, denote, useMark, useMarkput, useOverlay };
4748
4683
 
4749
4684
  //# sourceMappingURL=index.js.map