@bitcobblers/wod-wiki-ui 0.35.2116 → 0.35.2119

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/dist/index.cjs CHANGED
@@ -2055,14 +2055,25 @@ function RowsResultsChrome({
2055
2055
  }
2056
2056
  )
2057
2057
  ] }),
2058
- /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntime.jsx(
2059
- RpeChip,
2060
- {
2061
- resultId,
2062
- events: sessionRun?.events,
2063
- onCapture: handleCapture
2064
- }
2065
- ) })
2058
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-3", children: [
2059
+ /* @__PURE__ */ jsxRuntime.jsx(
2060
+ "a",
2061
+ {
2062
+ href: `/results/${encodeURIComponent(resultId)}`,
2063
+ className: "text-[11px] font-medium text-primary hover:underline inline-flex items-center gap-0.5",
2064
+ "data-testid": "view-in-results-link",
2065
+ children: "View in Results \u2192"
2066
+ }
2067
+ ),
2068
+ /* @__PURE__ */ jsxRuntime.jsx(
2069
+ RpeChip,
2070
+ {
2071
+ resultId,
2072
+ events: sessionRun?.events,
2073
+ onCapture: handleCapture
2074
+ }
2075
+ )
2076
+ ] })
2066
2077
  ] }),
2067
2078
  /* @__PURE__ */ jsxRuntime.jsx(
2068
2079
  RowsTable,
@@ -2757,7 +2768,7 @@ function mergeTagSuggestions(userLabels, corpusLabels) {
2757
2768
  []
2758
2769
  ).map((item) => item.value);
2759
2770
  }
2760
- var CANONICAL_BLOCK_TYPES = ["wod", "movement", "workout"];
2771
+ var CANONICAL_BLOCK_TYPES = ["wod", "query", "widget", "embed"];
2761
2772
  function canonicalSuggestionItems(values2) {
2762
2773
  return values2.map((value) => ({ value, label: value.charAt(0).toUpperCase() + value.slice(1) }));
2763
2774
  }
@@ -4815,255 +4826,202 @@ var linkOpen = [
4815
4826
  ctrlClickPlugin,
4816
4827
  linkCursorTheme
4817
4828
  ];
4818
- var VALID_DIALECTS = ["time", "log"];
4829
+ var sectionIdentity = state.Facet.define({ combine: (values2) => values2[0] });
4830
+ var registeredSectionWidgets = state.Facet.define({ combine: (values2) => values2.length ? values2.flat() : void 0 });
4819
4831
  var forceSectionParse = state.StateEffect.define();
4820
- function generateSectionId(type, cmStartLine, content) {
4821
- return wodWikiCore.generateSectionId(type, cmStartLine - 1, content);
4822
- }
4823
- function mapIdentities(oldSections, newSections) {
4824
- return newSections.map((nSec) => {
4825
- const match = oldSections.find(
4826
- (oSec) => oSec.type === nSec.type && Math.abs(oSec.startLine - nSec.startLine) <= 2
4827
- );
4828
- return match ? { ...nSec, id: match.id } : nSec;
4829
- });
4830
- }
4831
- function matchDialectFence(trimmed) {
4832
- const match = wodWikiCore.matchDialectFence(trimmed);
4833
- if (!match) return null;
4834
- return { dialect: match.dialect, sport: match.sport };
4835
- }
4836
- function matchWidgetFence(trimmed) {
4837
- const match = trimmed.match(/^```\s*widget:([\w-]+)\s*$/);
4838
- return match ? match[1] : null;
4839
- }
4840
- function matchContentFence(trimmed) {
4841
- const match = trimmed.match(/^```\s*query(?:[:\s](.*))?$/i);
4842
- if (!match) return null;
4843
- const rawSuffix = (match[1] ?? "").trim();
4844
- if (rawSuffix === "") return { kind: "query" };
4845
- const parsed = wodWikiWql.parseQueryWidgetSuffix(rawSuffix.replace(/^:/, ""));
4846
- return {
4847
- kind: "query",
4848
- widgetType: parsed.type,
4849
- widgetError: parsed.error
4850
- };
4851
- }
4852
- function matchGenericFence(trimmed) {
4853
- const match = trimmed.match(/^```\s*(\S+)\s*$/);
4854
- if (!match) return null;
4855
- const tag = match[1].toLowerCase();
4856
- if (VALID_DIALECTS.includes(tag)) return null;
4857
- if (tag.startsWith("widget:")) return null;
4858
- if (tag.startsWith("query")) return null;
4859
- return match[1];
4860
- }
4861
- function matchMarkdownEmbed(trimmed) {
4862
- const imgMatch = trimmed.match(/^!\[([^\]]*)\]\(([^)]+)\)$/);
4863
- if (imgMatch) {
4864
- const label = imgMatch[1];
4865
- const url = imgMatch[2];
4866
- return { type: "image", url, label };
4867
- }
4868
- const linkMatch = trimmed.match(/^\[([^\]]+)\]\(([^)]+)\)$/);
4869
- if (linkMatch) {
4870
- const label = linkMatch[1];
4871
- const url = linkMatch[2];
4872
- return { type: "link", url, label };
4832
+ var sectionSaved = state.StateEffect.define();
4833
+ var sectionRestore = state.StateEffect.define();
4834
+ var sectionMove = state.StateEffect.define();
4835
+ var restoreHistoryIdentity = state.StateEffect.define({
4836
+ map(value, changes) {
4837
+ const blocks = {};
4838
+ for (const block of Object.values(value.blocks)) {
4839
+ const from = changes.mapPos(block.from, 1);
4840
+ const to = changes.mapPos(block.to, -1);
4841
+ if (from < to) blocks[block.id] = { ...block, from, to };
4842
+ }
4843
+ return { rawContent: value.rawContent, blocks };
4873
4844
  }
4874
- return null;
4845
+ });
4846
+ function sourceCoordinates(rawContent) {
4847
+ const rawStarts = [0];
4848
+ const editorStarts = [0];
4849
+ let removed = 0;
4850
+ for (const match of rawContent.matchAll(/\r\n|\r|\n/g)) {
4851
+ removed += match[0].length - 1;
4852
+ rawStarts.push(match.index + match[0].length);
4853
+ editorStarts.push(match.index + match[0].length - removed);
4854
+ }
4855
+ return { rawStarts, editorStarts };
4856
+ }
4857
+ function toSourcePosition(state, rawStarts, position) {
4858
+ const line = state.doc.lineAt(position);
4859
+ return rawStarts[line.number - 1] + position - line.from;
4860
+ }
4861
+ function toEditorBlocks(state) {
4862
+ const blocks = {};
4863
+ for (const block of Object.values(state.noteBlocks)) {
4864
+ const section = state.sections.find((section2) => section2.id === block.id);
4865
+ if (section) blocks[block.id] = { ...block, from: section.from, to: section.to };
4866
+ }
4867
+ return blocks;
4868
+ }
4869
+ function deriveState(state, rawContent, sourceRevision, lineage, savedVersions, previousSections = []) {
4870
+ const registeredWidgets = state.facet(registeredSectionWidgets);
4871
+ const noteBlocks = wodWikiCore.reconcileNoteBlocks(rawContent, { sourceRevision, blocks: lineage, registeredWidgets });
4872
+ const coordinates = sourceCoordinates(rawContent);
4873
+ const sections = wodWikiCore.parseDocumentSections(rawContent, { registeredWidgets }).map((section) => {
4874
+ const start = coordinates.editorStarts[section.startLine];
4875
+ const end = coordinates.editorStarts[section.endLine] + section.to - coordinates.rawStarts[section.endLine];
4876
+ const block = wodWikiCore.actionableSectionKind(section) ? Object.values(noteBlocks).find((block2) => block2.from === section.from && block2.to === section.to) : void 0;
4877
+ const prior = previousSections.find((prior2) => prior2.from === start && prior2.to === end && prior2.type === (section.type === "title" ? "markdown" : section.type));
4878
+ const query = section.querySuffix ? wodWikiWql.parseQueryWidgetSuffix(section.querySuffix) : void 0;
4879
+ const subtype = section.subtype;
4880
+ return {
4881
+ id: block?.id ?? prior?.id ?? section.id,
4882
+ type: section.type === "title" ? "markdown" : section.type,
4883
+ ...subtype === "heading" || subtype === "paragraph" || subtype === "list" || subtype === "blockquote" || subtype === "table" ? { subtype } : {},
4884
+ from: start,
4885
+ to: end,
4886
+ startLine: section.startLine + 1,
4887
+ endLine: section.endLine + 1,
4888
+ ...section.contentFrom !== void 0 ? { contentFrom: coordinates.editorStarts[section.startLine + 1] ?? end } : {},
4889
+ ...section.contentTo !== void 0 ? { contentTo: coordinates.editorStarts[section.endLine] - (section.type === "frontmatter" ? 1 : 0) } : {},
4890
+ sport: section.sport,
4891
+ widgetName: section.widgetName,
4892
+ contentId: section.contentId,
4893
+ queryType: query?.type,
4894
+ queryError: query?.error,
4895
+ embed: section.embed
4896
+ };
4897
+ });
4898
+ for (const block of Object.values(noteBlocks)) block.version = savedVersions[block.id] ?? block.version;
4899
+ return { sections, rawContent, sourceRevision, noteBlocks, savedVersions };
4875
4900
  }
4876
- function detectMarkdownSubtype(lines) {
4877
- const first = lines.find((l) => l.trim().length > 0)?.trim() ?? "";
4878
- if (/^#{1,6}\s/.test(first)) return "heading";
4879
- if (/^[-*+]\s|^\d+\.\s/.test(first)) return "list";
4880
- if (/^>\s?/.test(first)) return "blockquote";
4881
- if (first.startsWith("|") && lines.some((l) => /^\|[\s:]*-+/.test(l.trim()))) return "table";
4882
- return "paragraph";
4883
- }
4884
- function scanFenced(state, openLineNum) {
4885
- const openLine = state.doc.line(openLineNum);
4886
- const contentFrom = openLine.to + 1;
4887
- for (let i = openLineNum + 1; i <= state.doc.lines; i++) {
4888
- const l = state.doc.line(i);
4889
- if (l.text.trim().startsWith("```")) {
4890
- return { closeLine: i, contentFrom, contentTo: l.from };
4891
- }
4892
- }
4893
- const last = state.doc.line(state.doc.lines);
4894
- return { closeLine: state.doc.lines, contentFrom, contentTo: last.to };
4895
- }
4896
- function parseSections(state) {
4897
- const sections = [];
4898
- let currentMdLines = [];
4899
- let mdStartLine = 1;
4900
- let mdStartPos = 0;
4901
- function flushMarkdown(endLine, endPos) {
4902
- if (currentMdLines.length === 0) return;
4903
- const content = currentMdLines.join("\n");
4904
- if (content.trim().length > 0) {
4905
- const embed = currentMdLines.length === 1 ? matchMarkdownEmbed(content.trim()) : null;
4906
- if (embed) {
4907
- sections.push({
4908
- id: generateSectionId("embed", mdStartLine, content),
4909
- type: "embed",
4910
- from: mdStartPos,
4911
- to: endPos,
4912
- startLine: mdStartLine,
4913
- endLine,
4914
- embed
4915
- });
4916
- } else {
4917
- sections.push({
4918
- id: generateSectionId("markdown", mdStartLine, content),
4919
- type: "markdown",
4920
- subtype: detectMarkdownSubtype(currentMdLines),
4921
- from: mdStartPos,
4922
- to: endPos,
4923
- startLine: mdStartLine,
4924
- endLine
4925
- });
4926
- }
4927
- }
4928
- currentMdLines = [];
4929
- }
4930
- let lineNum = 1;
4931
- while (lineNum <= state.doc.lines) {
4932
- const line = state.doc.line(lineNum);
4933
- const trimmed = line.text.trim();
4934
- const dialectMatch = matchDialectFence(trimmed);
4935
- const widgetMatch = matchWidgetFence(trimmed);
4936
- const contentMatch = matchContentFence(trimmed);
4937
- const genericFence = matchGenericFence(trimmed);
4938
- if (dialectMatch || widgetMatch || contentMatch || genericFence) {
4939
- flushMarkdown(lineNum - 1, line.from);
4940
- const { closeLine, contentFrom, contentTo } = scanFenced(state, lineNum);
4941
- const closeLineObj = state.doc.line(closeLine);
4942
- const innerContent = state.doc.sliceString(contentFrom, contentTo);
4943
- if (dialectMatch) {
4944
- sections.push({
4945
- id: generateSectionId(dialectMatch.dialect, lineNum, innerContent),
4946
- type: dialectMatch.dialect,
4947
- from: line.from,
4948
- to: closeLineObj.to,
4949
- startLine: lineNum,
4950
- endLine: closeLine,
4951
- contentFrom,
4952
- contentTo,
4953
- sport: dialectMatch.sport,
4954
- contentId: wodWikiCore.blockContentId(innerContent)
4955
- });
4956
- } else if (widgetMatch) {
4957
- sections.push({
4958
- id: generateSectionId("widget", lineNum, innerContent),
4959
- type: "widget",
4960
- widgetName: widgetMatch,
4961
- from: line.from,
4962
- to: closeLineObj.to,
4963
- startLine: lineNum,
4964
- endLine: closeLine,
4965
- contentFrom,
4966
- contentTo
4967
- });
4968
- } else if (contentMatch) {
4969
- sections.push({
4970
- id: generateSectionId("query", lineNum, innerContent),
4971
- type: "query",
4972
- from: line.from,
4973
- to: closeLineObj.to,
4974
- startLine: lineNum,
4975
- endLine: closeLine,
4976
- contentFrom,
4977
- contentTo,
4978
- queryType: contentMatch.widgetType,
4979
- queryError: contentMatch.widgetError
4980
- });
4981
- } else if (genericFence) {
4982
- sections.push({
4983
- id: generateSectionId("code", lineNum, innerContent),
4984
- type: "code",
4985
- from: line.from,
4986
- to: closeLineObj.to,
4987
- startLine: lineNum,
4988
- endLine: closeLine,
4989
- contentFrom,
4990
- contentTo
4991
- });
4992
- }
4993
- lineNum = closeLine + 1;
4994
- mdStartLine = lineNum;
4995
- mdStartPos = lineNum <= state.doc.lines ? state.doc.line(lineNum).from : state.doc.length;
4996
- continue;
4997
- }
4998
- if (trimmed === "---") {
4999
- const lineCount = state.doc.lines;
5000
- const nextLineText = lineNum < lineCount ? state.doc.line(lineNum + 1).text.trim() : "";
5001
- if (nextLineText !== "") {
5002
- let foundClose = false;
5003
- let closeLine = lineNum;
5004
- let hasKeyValueLine = false;
5005
- for (let j = lineNum + 1; j <= lineCount; j++) {
5006
- const jTrimmed = state.doc.line(j).text.trim();
5007
- if (matchDialectFence(jTrimmed) || matchGenericFence(jTrimmed)) break;
5008
- if (jTrimmed === "---") {
5009
- closeLine = j;
5010
- foundClose = true;
5011
- break;
5012
- }
5013
- if (/^[A-Za-z_][\w-]*\s*:/.test(jTrimmed)) {
5014
- hasKeyValueLine = true;
4901
+ var sectionField = state.StateField.define({
4902
+ create(state) {
4903
+ const initial = state.facet(sectionIdentity);
4904
+ const rawContent = initial?.rawContent ?? state.doc.toString();
4905
+ if (rawContent.replace(/\r\n|\r/g, "\n") !== state.doc.toString()) throw new Error("Editor source and identity map disagree");
4906
+ if (initial) wodWikiCore.validateNoteBlocks(rawContent, initial.blocks, initial.sourceRevision, { registeredWidgets: state.facet(registeredSectionWidgets) });
4907
+ const savedVersions = Object.fromEntries(Object.values(initial?.blocks ?? {}).map((block) => [block.id, block.version]));
4908
+ return deriveState(state, rawContent, initial?.sourceRevision ?? 1, initial?.blocks ?? {}, savedVersions);
4909
+ },
4910
+ update(value, tr) {
4911
+ let rawContent = value.rawContent;
4912
+ let lineage = value.noteBlocks;
4913
+ let sourceRevision = value.sourceRevision;
4914
+ let savedVersions = value.savedVersions;
4915
+ if (tr.docChanged) {
4916
+ const { rawStarts } = sourceCoordinates(rawContent);
4917
+ const changes = [];
4918
+ const lineBreak = rawContent.includes("\r\n") ? "\r\n" : rawContent.includes("\r") ? "\r" : "\n";
4919
+ tr.changes.iterChanges((fromA, toA, fromB, toB) => changes.push({
4920
+ from: toSourcePosition(tr.startState, rawStarts, fromA),
4921
+ to: toSourcePosition(tr.startState, rawStarts, toA),
4922
+ insert: tr.newDoc.sliceString(fromB, toB, lineBreak)
4923
+ }));
4924
+ lineage = wodWikiCore.mapNoteBlockChanges(lineage, changes);
4925
+ for (let i = changes.length - 1; i >= 0; i--) {
4926
+ const change = changes[i];
4927
+ rawContent = rawContent.slice(0, change.from) + change.insert + rawContent.slice(change.to);
4928
+ }
4929
+ if (tr.isUserEvent("move.drop")) {
4930
+ const moves = [];
4931
+ tr.changes.iterChanges((fromA, toA, fromB, toB) => moves.push({ fromA, toA, fromB, toB }));
4932
+ const deletion = moves.filter((change) => change.toA > change.fromA && change.fromB === change.toB);
4933
+ const insertion = moves.filter((change) => change.fromA === change.toA && change.toB > change.fromB);
4934
+ if (deletion.length === 1 && insertion.length === 1) {
4935
+ const removed = deletion[0];
4936
+ const added = insertion[0];
4937
+ if (tr.startState.doc.sliceString(removed.fromA, removed.toA) === tr.newDoc.sliceString(added.fromB, added.toB)) {
4938
+ const currentStarts = sourceCoordinates(rawContent).rawStarts;
4939
+ for (const section of value.sections) {
4940
+ const block = value.noteBlocks[section.id];
4941
+ if (block && section.from >= removed.fromA && section.to <= removed.toA) {
4942
+ lineage[block.id] = {
4943
+ ...block,
4944
+ from: toSourcePosition(tr.state, currentStarts, added.fromB + section.from - removed.fromA),
4945
+ to: toSourcePosition(tr.state, currentStarts, added.fromB + section.to - removed.fromA)
4946
+ };
4947
+ }
4948
+ }
5015
4949
  }
5016
4950
  }
5017
- if (foundClose && hasKeyValueLine) {
5018
- flushMarkdown(lineNum - 1, line.from);
5019
- const closeLineObj = state.doc.line(closeLine);
5020
- const content = state.doc.sliceString(line.from, closeLineObj.to);
5021
- sections.push({
5022
- id: generateSectionId("frontmatter", lineNum, content),
5023
- type: "frontmatter",
5024
- from: line.from,
5025
- to: closeLineObj.to,
5026
- startLine: lineNum,
5027
- endLine: closeLine,
5028
- contentFrom: line.to + 1,
5029
- contentTo: closeLineObj.from - 1
5030
- });
5031
- lineNum = closeLine + 1;
5032
- mdStartLine = lineNum;
5033
- mdStartPos = lineNum <= lineCount ? state.doc.line(lineNum).from : state.doc.length;
5034
- continue;
4951
+ }
4952
+ if (tr.isUserEvent("move.line")) {
4953
+ const currentStarts = sourceCoordinates(rawContent).rawStarts;
4954
+ for (let i = 0; i < tr.startState.selection.ranges.length; i++) {
4955
+ const before = tr.startState.selection.ranges[i];
4956
+ const after = tr.newSelection.ranges[i];
4957
+ if (!after) continue;
4958
+ const firstLine = tr.startState.doc.lineAt(before.from);
4959
+ const lastLine = tr.startState.doc.lineAt(before.to > before.from && tr.startState.doc.lineAt(before.to).from === before.to ? before.to - 1 : before.to);
4960
+ const delta = after.anchor - before.anchor;
4961
+ for (const section of value.sections) {
4962
+ const block = value.noteBlocks[section.id];
4963
+ if (block && section.from >= firstLine.from && section.to <= lastLine.to) {
4964
+ lineage[block.id] = {
4965
+ ...block,
4966
+ from: toSourcePosition(tr.state, currentStarts, section.from + delta),
4967
+ to: toSourcePosition(tr.state, currentStarts, section.to + delta)
4968
+ };
4969
+ }
4970
+ }
5035
4971
  }
5036
4972
  }
5037
4973
  }
5038
- if (currentMdLines.length === 0) {
5039
- mdStartLine = lineNum;
5040
- mdStartPos = line.from;
5041
- }
5042
- currentMdLines.push(line.text);
5043
- lineNum++;
5044
- }
5045
- flushMarkdown(state.doc.lines, state.doc.length);
5046
- return sections;
5047
- }
5048
- var sectionField = state.StateField.define({
5049
- create(state) {
5050
- return { sections: parseSections(state) };
5051
- },
5052
- update(value, tr) {
5053
- if (tr.docChanged || tr.effects.some((e) => e.is(forceSectionParse))) {
5054
- const newSections = parseSections(tr.state);
5055
- return { sections: mapIdentities(value.sections, newSections) };
4974
+ for (const effect of tr.effects) {
4975
+ if (effect.is(sectionSaved)) {
4976
+ sourceRevision = Math.max(sourceRevision, effect.value.sourceRevision);
4977
+ savedVersions = { ...savedVersions };
4978
+ for (const block of Object.values(effect.value.blocks)) savedVersions[block.id] = Math.max(savedVersions[block.id] ?? 1, block.version);
4979
+ }
4980
+ if (effect.is(sectionRestore)) {
4981
+ if (effect.value.rawContent.replace(/\r\n|\r/g, "\n") !== tr.newDoc.toString()) throw new Error("Restored source does not match editor");
4982
+ wodWikiCore.validateNoteBlocks(effect.value.rawContent, effect.value.blocks, effect.value.sourceRevision, { registeredWidgets: tr.state.facet(registeredSectionWidgets) });
4983
+ rawContent = effect.value.rawContent;
4984
+ lineage = effect.value.blocks;
4985
+ sourceRevision = effect.value.sourceRevision;
4986
+ savedVersions = { ...savedVersions, ...Object.fromEntries(Object.values(lineage).map((block) => [block.id, block.version])) };
4987
+ }
4988
+ if (effect.is(restoreHistoryIdentity)) {
4989
+ const exactHistory = tr.effects.some((candidate) => candidate.is(restoreHistoryIdentity) && candidate.value.rawContent.replace(/\r\n|\r/g, "\n") === tr.newDoc.toString());
4990
+ if (exactHistory && effect.value.rawContent.replace(/\r\n|\r/g, "\n") !== tr.newDoc.toString()) continue;
4991
+ if (effect.value.rawContent.replace(/\r\n|\r/g, "\n") === tr.newDoc.toString()) rawContent = effect.value.rawContent;
4992
+ const { rawStarts } = sourceCoordinates(rawContent);
4993
+ lineage = Object.fromEntries(Object.values(effect.value.blocks).map((block) => [block.id, {
4994
+ ...block,
4995
+ from: toSourcePosition(tr.state, rawStarts, block.from),
4996
+ to: toSourcePosition(tr.state, rawStarts, block.to)
4997
+ }]));
4998
+ }
4999
+ if (effect.is(sectionMove)) {
5000
+ const prior = value.noteBlocks[effect.value.id];
5001
+ if (!prior || lineage[prior.id]) throw new Error("Explicit move must remove the original occurrence");
5002
+ const { rawStarts } = sourceCoordinates(rawContent);
5003
+ const from = toSourcePosition(tr.state, rawStarts, effect.value.from);
5004
+ const to = toSourcePosition(tr.state, rawStarts, effect.value.to);
5005
+ if (rawContent.slice(from, to) !== value.rawContent.slice(prior.from, prior.to)) throw new Error("Explicit move changed source");
5006
+ lineage = { ...lineage, [prior.id]: { ...prior, from, to } };
5007
+ }
5008
+ }
5009
+ if (tr.docChanged || tr.effects.some((effect) => effect.is(forceSectionParse) || effect.is(sectionRestore) || effect.is(sectionSaved) || effect.is(restoreHistoryIdentity))) {
5010
+ const previous = value.sections.map((section) => ({ ...section, from: tr.changes.mapPos(section.from, 1), to: tr.changes.mapPos(section.to, -1) }));
5011
+ return deriveState(tr.state, rawContent, sourceRevision, lineage, savedVersions, previous);
5056
5012
  }
5057
5013
  return value;
5058
5014
  }
5059
5015
  });
5016
+ var sectionIdentityHistory = commands.invertedEffects.of((tr) => {
5017
+ const value = tr.startState.field(sectionField, false);
5018
+ return value && tr.docChanged ? [restoreHistoryIdentity.of({ rawContent: value.rawContent, blocks: toEditorBlocks(value) })] : [];
5019
+ });
5060
5020
  function sectionAtPos(state, pos) {
5061
- const { sections } = state.field(sectionField);
5062
- return sections.find((s) => pos >= s.from && pos <= s.to) ?? null;
5021
+ return state.field(sectionField).sections.find((section) => pos >= section.from && pos <= section.to) ?? null;
5063
5022
  }
5064
5023
  function activeCursorSection(state) {
5065
- const pos = state.selection.main.head;
5066
- return sectionAtPos(state, pos);
5024
+ return sectionAtPos(state, state.selection.main.head);
5067
5025
  }
5068
5026
 
5069
5027
  // src/extensions/whiteboard-linter.ts
@@ -6937,18 +6895,9 @@ function dispatchExpandRuntimePanel(view, sectionId, expanded) {
6937
6895
  function sessionQueryWql(resultId) {
6938
6896
  return `:session{result:${resultId}}`;
6939
6897
  }
6940
- function sessionQueryInsert(state, blockId, resultId, runBlock) {
6898
+ function sessionQueryInsert(state, blockId, resultId) {
6941
6899
  const sections = state.field(sectionField).sections;
6942
- let section = sections.find((s) => s.id === blockId);
6943
- if (!section && runBlock?.contentId) {
6944
- section = sections.find((s) => s.contentId === runBlock.contentId);
6945
- }
6946
- if (!section && runBlock?.id) {
6947
- section = sections.find((s) => s.id === runBlock.id);
6948
- }
6949
- if (!section && runBlock) {
6950
- section = sections.find((s) => s.type === "time" || s.type === "log");
6951
- }
6900
+ const section = sections.find((s) => s.id === blockId);
6952
6901
  if (!section || section.type !== "time" && section.type !== "log") {
6953
6902
  return null;
6954
6903
  }
@@ -13056,6 +13005,7 @@ function editorPreset(optionsOrDialect = "markdown") {
13056
13005
  extensions.push(
13057
13006
  markdown({ codeLanguages: resolveCodeLanguage }),
13058
13007
  sectionField,
13008
+ sectionIdentityHistory,
13059
13009
  previewDecorations,
13060
13010
  wodLinter,
13061
13011
  wodAutocompletion,
@@ -13075,13 +13025,13 @@ function editorPreset(optionsOrDialect = "markdown") {
13075
13025
  }
13076
13026
 
13077
13027
  // src/version.ts
13078
- var VERSION = "0.35.2116";
13079
- var GIT_SHA = "a4d411f";
13080
- var BUILD_TIME = "2026-10-12T00:14:24.795Z";
13028
+ var VERSION = "0.35.2119";
13029
+ var GIT_SHA = "e0eb840";
13030
+ var BUILD_TIME = "2026-10-13T06:24:52.520Z";
13081
13031
  var SEMVER = {
13082
- version: "0.35.2116",
13083
- gitSha: "a4d411f",
13084
- buildTime: "2026-10-12T00:14:24.795Z"
13032
+ version: "0.35.2119",
13033
+ gitSha: "e0eb840",
13034
+ buildTime: "2026-10-13T06:24:52.520Z"
13085
13035
  };
13086
13036
 
13087
13037
  Object.defineProperty(exports, "CONTENT_GROUPING_DIMENSIONS", {
@@ -13219,6 +13169,7 @@ exports.queryBlockPreview = queryBlockPreview;
13219
13169
  exports.readSessionRpe = readSessionRpe;
13220
13170
  exports.readStoredUnit = readStoredUnit;
13221
13171
  exports.registerCustomCompletionSource = registerCustomCompletionSource;
13172
+ exports.registeredSectionWidgets = registeredSectionWidgets;
13222
13173
  exports.removeRuntimePanel = removeRuntimePanel;
13223
13174
  exports.resolveQueryDraft = resolveQueryDraft;
13224
13175
  exports.runtimePanelField = runtimePanelField;
@@ -13226,6 +13177,11 @@ exports.saveBlockQuerySource = saveBlockQuerySource;
13226
13177
  exports.sectionAtPos = sectionAtPos;
13227
13178
  exports.sectionField = sectionField;
13228
13179
  exports.sectionGeometry = sectionGeometry;
13180
+ exports.sectionIdentity = sectionIdentity;
13181
+ exports.sectionIdentityHistory = sectionIdentityHistory;
13182
+ exports.sectionMove = sectionMove;
13183
+ exports.sectionRestore = sectionRestore;
13184
+ exports.sectionSaved = sectionSaved;
13229
13185
  exports.sessionQueryInsert = sessionQueryInsert;
13230
13186
  exports.sessionQueryWql = sessionQueryWql;
13231
13187
  exports.setGutterHighlights = setGutterHighlights;