@dxos/plugin-sheet 0.8.4-main.3fbcb4aa9b → 0.8.4-main.43cb759274

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.
Files changed (124) hide show
  1. package/LICENSE +102 -5
  2. package/PLUGIN.mdl +359 -0
  3. package/dist/lib/neutral/{SheetContainer-ZOVKGHLT.mjs → SheetArticle-5AJRM3V3.mjs} +6 -6
  4. package/dist/lib/neutral/SheetArticle-5AJRM3V3.mjs.map +7 -0
  5. package/dist/lib/neutral/SheetPlugin.mjs +14 -3
  6. package/dist/lib/neutral/SheetPlugin.mjs.map +4 -4
  7. package/dist/lib/neutral/SheetPlugin.workerd.mjs +21 -0
  8. package/dist/lib/neutral/SheetPlugin.workerd.mjs.map +7 -0
  9. package/dist/lib/neutral/{anchor-sort-TTCKGX7V.mjs → anchor-sort-2POWTKTD.mjs} +3 -3
  10. package/dist/lib/neutral/anchor-sort-2POWTKTD.mjs.map +7 -0
  11. package/dist/lib/neutral/capabilities/index.mjs +6 -6
  12. package/dist/lib/neutral/{chunk-4GWJDLTH.mjs → chunk-3AIMSE7U.mjs} +4 -4
  13. package/dist/lib/neutral/{chunk-4GWJDLTH.mjs.map → chunk-3AIMSE7U.mjs.map} +3 -3
  14. package/dist/lib/neutral/chunk-7ZUM64KO.mjs +8 -0
  15. package/dist/lib/neutral/{chunk-4SBAIU6F.mjs → chunk-ERHMBRSU.mjs} +2 -2
  16. package/dist/lib/neutral/{chunk-4SBAIU6F.mjs.map → chunk-ERHMBRSU.mjs.map} +2 -2
  17. package/dist/lib/neutral/{chunk-KC2SMDNF.mjs → chunk-EUM3RVML.mjs} +21 -20
  18. package/dist/lib/neutral/chunk-EUM3RVML.mjs.map +7 -0
  19. package/dist/lib/neutral/chunk-FQHTXKMF.mjs +34 -0
  20. package/dist/lib/neutral/chunk-FQHTXKMF.mjs.map +7 -0
  21. package/dist/lib/neutral/{comment-config-ZBWNCJMZ.mjs → comment-config-6JAROASH.mjs} +3 -2
  22. package/dist/lib/neutral/comment-config-6JAROASH.mjs.map +7 -0
  23. package/dist/lib/neutral/components/index.mjs +10 -9
  24. package/dist/lib/neutral/components/index.mjs.map +3 -3
  25. package/dist/lib/neutral/{compute-graph-registry-IEQBF5XZ.mjs → compute-graph-registry-YYINTFC2.mjs} +11 -5
  26. package/dist/lib/neutral/compute-graph-registry-YYINTFC2.mjs.map +7 -0
  27. package/dist/lib/neutral/containers/index.mjs +2 -2
  28. package/dist/lib/neutral/containers/index.mjs.map +3 -3
  29. package/dist/lib/neutral/{create-object-OKQAXJCW.mjs → create-object-6FZSSROF.mjs} +3 -2
  30. package/dist/lib/neutral/create-object-6FZSSROF.mjs.map +7 -0
  31. package/dist/lib/neutral/{drop-axis-G6UOXG54.mjs → drop-axis-MO3KUU4C.mjs} +2 -2
  32. package/dist/lib/neutral/index.mjs +5 -5
  33. package/dist/lib/neutral/{insert-axis-ZFFNG22G.mjs → insert-axis-V7E5PTMG.mjs} +2 -2
  34. package/dist/lib/neutral/{markdown-I2AKJYPF.mjs → markdown-O37EE3ER.mjs} +2 -2
  35. package/dist/lib/neutral/meta.json +1 -1
  36. package/dist/lib/neutral/meta.mjs +1 -1
  37. package/dist/lib/neutral/operations/index.mjs +1 -1
  38. package/dist/lib/neutral/plugin.mjs +4 -4
  39. package/dist/lib/neutral/{react-surface-ID4JCAFR.mjs → react-surface-4H3PC4WG.mjs} +5 -5
  40. package/dist/lib/neutral/react-surface-4H3PC4WG.mjs.map +7 -0
  41. package/dist/lib/neutral/{restore-axis-44DM6N54.mjs → restore-axis-BAM44OPG.mjs} +2 -2
  42. package/dist/lib/neutral/{scroll-to-anchor-WHX3HJC7.mjs → scroll-to-anchor-TBE2FTTT.mjs} +3 -3
  43. package/dist/lib/neutral/translations.mjs +2 -1
  44. package/dist/lib/neutral/translations.mjs.map +3 -3
  45. package/dist/lib/neutral/types/index.mjs +1 -1
  46. package/dist/types/src/SheetPlugin.d.ts.map +1 -1
  47. package/dist/types/src/SheetPlugin.workerd.d.ts +4 -0
  48. package/dist/types/src/SheetPlugin.workerd.d.ts.map +1 -0
  49. package/dist/types/src/capabilities/compute-graph-registry.d.ts +6 -0
  50. package/dist/types/src/capabilities/compute-graph-registry.d.ts.map +1 -1
  51. package/dist/types/src/capabilities/create-object.d.ts.map +1 -1
  52. package/dist/types/src/components/ComputeGraph/compute-graph.stories.d.ts.map +1 -1
  53. package/dist/types/src/components/SheetStatusbar/SheetStatusbar.d.ts.map +1 -1
  54. package/dist/types/src/containers/{SheetContainer/SheetContainer.d.ts → SheetArticle/SheetArticle.d.ts} +3 -3
  55. package/dist/types/src/containers/SheetArticle/SheetArticle.d.ts.map +1 -0
  56. package/dist/types/src/containers/{SheetContainer/SheetContainer.stories.d.ts → SheetArticle/SheetArticle.stories.d.ts} +2 -2
  57. package/dist/types/src/containers/SheetArticle/SheetArticle.stories.d.ts.map +1 -0
  58. package/dist/types/src/containers/SheetArticle/index.d.ts +2 -0
  59. package/dist/types/src/containers/SheetArticle/index.d.ts.map +1 -0
  60. package/dist/types/src/containers/index.d.ts +1 -1
  61. package/dist/types/src/containers/index.d.ts.map +1 -1
  62. package/dist/types/src/meta.d.ts +1 -1
  63. package/dist/types/src/meta.d.ts.map +1 -1
  64. package/dist/types/src/model/sheet-model.d.ts +25 -1
  65. package/dist/types/src/model/sheet-model.d.ts.map +1 -1
  66. package/dist/types/src/testing/testing.d.ts +2 -2
  67. package/dist/types/src/testing/testing.d.ts.map +1 -1
  68. package/dist/types/src/translations.d.ts.map +1 -1
  69. package/dist/types/src/types/Sheet.d.ts +3 -4
  70. package/dist/types/src/types/Sheet.d.ts.map +1 -1
  71. package/dist/types/src/types/SheetOperation.d.ts.map +1 -1
  72. package/dist/types/tsconfig.tsbuildinfo +1 -1
  73. package/package.json +62 -79
  74. package/src/SheetPlugin.test.ts +1 -1
  75. package/src/SheetPlugin.tsx +8 -3
  76. package/src/SheetPlugin.workerd.ts +18 -0
  77. package/src/capabilities/anchor-sort.ts +2 -2
  78. package/src/capabilities/comment-config.ts +2 -1
  79. package/src/capabilities/compute-graph-registry.ts +20 -7
  80. package/src/capabilities/create-object.ts +2 -1
  81. package/src/capabilities/react-surface.tsx +4 -4
  82. package/src/components/ComputeGraph/compute-graph.stories.tsx +8 -3
  83. package/src/components/SheetContent/SheetContent.stories.tsx +2 -2
  84. package/src/components/SheetContent/SheetContent.tsx +1 -1
  85. package/src/components/SheetContent/util.ts +1 -1
  86. package/src/components/SheetStatusbar/SheetStatusbar.tsx +2 -1
  87. package/src/components/SheetToolbar/SheetToolbar.tsx +1 -1
  88. package/src/containers/{SheetContainer/SheetContainer.stories.tsx → SheetArticle/SheetArticle.stories.tsx} +8 -8
  89. package/src/containers/{SheetContainer/SheetContainer.tsx → SheetArticle/SheetArticle.tsx} +5 -5
  90. package/src/containers/SheetArticle/index.ts +5 -0
  91. package/src/containers/index.ts +1 -1
  92. package/src/extensions/compute.stories.tsx +2 -2
  93. package/src/extensions/editor/sheet-extension.ts +1 -1
  94. package/src/integrations/thread-ranges.ts +3 -3
  95. package/src/meta.ts +18 -6
  96. package/src/model/sheet-model.ts +2 -2
  97. package/src/playwright/sheet.spec.ts +1 -1
  98. package/src/sanity.test.ts +5 -1
  99. package/src/translations.ts +2 -1
  100. package/src/types/Sheet.ts +4 -10
  101. package/src/types/SheetOperation.ts +14 -5
  102. package/src/types/util.ts +3 -3
  103. package/src/vite-env.d.ts +10 -0
  104. package/dist/lib/neutral/SheetContainer-ZOVKGHLT.mjs.map +0 -7
  105. package/dist/lib/neutral/anchor-sort-TTCKGX7V.mjs.map +0 -7
  106. package/dist/lib/neutral/chunk-KC2SMDNF.mjs.map +0 -7
  107. package/dist/lib/neutral/chunk-YFHTB6MX.mjs +0 -8
  108. package/dist/lib/neutral/chunk-ZWOQCLH7.mjs +0 -21
  109. package/dist/lib/neutral/chunk-ZWOQCLH7.mjs.map +0 -7
  110. package/dist/lib/neutral/comment-config-ZBWNCJMZ.mjs.map +0 -7
  111. package/dist/lib/neutral/compute-graph-registry-IEQBF5XZ.mjs.map +0 -7
  112. package/dist/lib/neutral/create-object-OKQAXJCW.mjs.map +0 -7
  113. package/dist/lib/neutral/react-surface-ID4JCAFR.mjs.map +0 -7
  114. package/dist/types/src/containers/SheetContainer/SheetContainer.d.ts.map +0 -1
  115. package/dist/types/src/containers/SheetContainer/SheetContainer.stories.d.ts.map +0 -1
  116. package/dist/types/src/containers/SheetContainer/index.d.ts +0 -2
  117. package/dist/types/src/containers/SheetContainer/index.d.ts.map +0 -1
  118. package/src/containers/SheetContainer/index.ts +0 -5
  119. /package/dist/lib/neutral/{chunk-YFHTB6MX.mjs.map → chunk-7ZUM64KO.mjs.map} +0 -0
  120. /package/dist/lib/neutral/{drop-axis-G6UOXG54.mjs.map → drop-axis-MO3KUU4C.mjs.map} +0 -0
  121. /package/dist/lib/neutral/{insert-axis-ZFFNG22G.mjs.map → insert-axis-V7E5PTMG.mjs.map} +0 -0
  122. /package/dist/lib/neutral/{markdown-I2AKJYPF.mjs.map → markdown-O37EE3ER.mjs.map} +0 -0
  123. /package/dist/lib/neutral/{restore-axis-44DM6N54.mjs.map → restore-axis-BAM44OPG.mjs.map} +0 -0
  124. /package/dist/lib/neutral/{scroll-to-anchor-WHX3HJC7.mjs.map → scroll-to-anchor-TBE2FTTT.mjs.map} +0 -0
@@ -4,10 +4,10 @@ import "./chunk-J5LGTIGS.mjs";
4
4
  import * as Effect from "effect/Effect";
5
5
  import { Capability } from "@dxos/app-framework";
6
6
  import { AppCapabilities } from "@dxos/app-toolkit";
7
- import { Relation } from "@dxos/echo";
7
+ import { Relation, Type } from "@dxos/echo";
8
8
  import { Sheet, compareIndexPositions } from "#types";
9
9
  var anchor_sort_default = Capability.makeModule(() => Effect.succeed(Capability.contributes(AppCapabilities.AnchorSort, {
10
- key: Sheet.Sheet.typename,
10
+ key: Type.getTypename(Sheet.Sheet),
11
11
  sort: (anchorA, anchorB) => {
12
12
  const sheet = Relation.getTarget(anchorA);
13
13
  if (sheet !== Relation.getTarget(anchorB)) {
@@ -19,4 +19,4 @@ var anchor_sort_default = Capability.makeModule(() => Effect.succeed(Capability.
19
19
  export {
20
20
  anchor_sort_default as default
21
21
  };
22
- //# sourceMappingURL=anchor-sort-TTCKGX7V.mjs.map
22
+ //# sourceMappingURL=anchor-sort-2POWTKTD.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/capabilities/anchor-sort.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2025 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capability } from '@dxos/app-framework';\nimport { AppCapabilities } from '@dxos/app-toolkit';\nimport { Relation, Type } from '@dxos/echo';\n\nimport { Sheet, compareIndexPositions } from '#types';\n\nexport default Capability.makeModule(() =>\n Effect.succeed(\n Capability.contributes(AppCapabilities.AnchorSort, {\n key: Type.getTypename(Sheet.Sheet),\n sort: (anchorA, anchorB) => {\n const sheet = Relation.getTarget(anchorA) as Sheet.Sheet;\n if (sheet !== Relation.getTarget(anchorB)) {\n return 0;\n }\n\n return !anchorA.anchor || !anchorB.anchor ? 0 : compareIndexPositions(sheet, anchorA.anchor, anchorB.anchor);\n },\n }),\n ),\n);\n"],
5
+ "mappings": ";;;AAIA,YAAYA,YAAY;AAExB,SAASC,kBAAkB;AAC3B,SAASC,uBAAuB;AAChC,SAASC,UAAUC,YAAY;AAE/B,SAASC,OAAOC,6BAA6B;AAE7C,IAAA,sBAAeL,WAAWM,WAAW,MAC5BC,eACLP,WAAWQ,YAAYP,gBAAgBQ,YAAY;EACjDC,KAAKP,KAAKQ,YAAYP,MAAMA,KAAK;EACjCQ,MAAM,CAACC,SAASC,YAAAA;AACd,UAAMC,QAAQb,SAASc,UAAUH,OAAAA;AACjC,QAAIE,UAAUb,SAASc,UAAUF,OAAAA,GAAU;AACzC,aAAO;IACT;AAEA,WAAO,CAACD,QAAQI,UAAU,CAACH,QAAQG,SAAS,IAAIZ,sBAAsBU,OAAOF,QAAQI,QAAQH,QAAQG,MAAM;EAC7G;AACF,CAAA,CAAA,CAAA;",
6
+ "names": ["Effect", "Capability", "AppCapabilities", "Relation", "Type", "Sheet", "compareIndexPositions", "makeModule", "succeed", "contributes", "AnchorSort", "key", "getTypename", "sort", "anchorA", "anchorB", "sheet", "getTarget", "anchor"]
7
+ }
@@ -2,13 +2,13 @@ import "../chunk-J5LGTIGS.mjs";
2
2
 
3
3
  // src/capabilities/index.ts
4
4
  import { Capability } from "@dxos/app-framework";
5
- var AnchorSort = Capability.lazy("AnchorSort", () => import("../anchor-sort-TTCKGX7V.mjs"));
6
- var CommentConfig = Capability.lazy("CommentConfig", () => import("../comment-config-ZBWNCJMZ.mjs"));
7
- var ComputeGraphRegistry = Capability.lazy("ComputeGraphRegistry", () => import("../compute-graph-registry-IEQBF5XZ.mjs"));
8
- var CreateObject = Capability.lazy("CreateObject", () => import("../create-object-OKQAXJCW.mjs"));
9
- var Markdown = Capability.lazy("Markdown", () => import("../markdown-I2AKJYPF.mjs"));
5
+ var AnchorSort = Capability.lazy("AnchorSort", () => import("../anchor-sort-2POWTKTD.mjs"));
6
+ var CommentConfig = Capability.lazy("CommentConfig", () => import("../comment-config-6JAROASH.mjs"));
7
+ var ComputeGraphRegistry = Capability.lazy("ComputeGraphRegistry", () => import("../compute-graph-registry-YYINTFC2.mjs"));
8
+ var CreateObject = Capability.lazy("CreateObject", () => import("../create-object-6FZSSROF.mjs"));
9
+ var Markdown = Capability.lazy("Markdown", () => import("../markdown-O37EE3ER.mjs"));
10
10
  var OperationHandler = Capability.lazy("OperationHandler", () => import("../operation-handler-TB6LFV2H.mjs"));
11
- var ReactSurface = Capability.lazy("ReactSurface", () => import("../react-surface-ID4JCAFR.mjs"));
11
+ var ReactSurface = Capability.lazy("ReactSurface", () => import("../react-surface-4H3PC4WG.mjs"));
12
12
  var SheetState = Capability.lazy("SheetState", () => import("../state-HPA27MX2.mjs"));
13
13
  var UndoMappings = Capability.lazy("UndoMappings", () => import("../undo-mappings-3FQLSTCZ.mjs"));
14
14
  export {
@@ -4,9 +4,9 @@ import { useOperationInvoker } from "@dxos/app-framework/ui";
4
4
  import { LayoutOperation } from "@dxos/app-toolkit";
5
5
  import { debounce } from "@dxos/async";
6
6
  import { inRange } from "@dxos/compute-hyperformula";
7
- import { Obj, Relation } from "@dxos/echo";
7
+ import { Filter, Obj, Query, Relation } from "@dxos/echo";
8
8
  import { ThreadOperation } from "@dxos/plugin-thread";
9
- import { Filter, Query, useQuery } from "@dxos/react-client/echo";
9
+ import { useQuery } from "@dxos/react-client/echo";
10
10
  import { linkedSegment } from "@dxos/react-ui-attention";
11
11
  import { AnchoredTo, Thread } from "@dxos/types";
12
12
  import { useSheetContext } from "#components";
@@ -49,7 +49,7 @@ var useSelectThreadOnCellFocus = () => {
49
49
  if (closestThread) {
50
50
  void (async () => {
51
51
  await invokePromise(ThreadOperation.Select, {
52
- current: Relation.getDXN(closestThread).toString()
52
+ current: Relation.getURI(closestThread)
53
53
  });
54
54
  await invokePromise(LayoutOperation.UpdateCompanion, {
55
55
  subject: linkedSegment("comments")
@@ -80,4 +80,4 @@ export {
80
80
  parseThreadAnchorAsCellRange,
81
81
  useSelectThreadOnCellFocus
82
82
  };
83
- //# sourceMappingURL=chunk-4GWJDLTH.mjs.map
83
+ //# sourceMappingURL=chunk-3AIMSE7U.mjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/integrations/thread-ranges.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { useCallback, useEffect, useMemo } from 'react';\n\nimport { useOperationInvoker } from '@dxos/app-framework/ui';\nimport { LayoutOperation } from '@dxos/app-toolkit';\nimport { debounce } from '@dxos/async';\nimport { type CellAddress, type CompleteCellRange, inRange } from '@dxos/compute-hyperformula';\nimport { Obj, Relation } from '@dxos/echo';\nimport { ThreadOperation } from '@dxos/plugin-thread';\nimport { Filter, Query, useQuery } from '@dxos/react-client/echo';\nimport { linkedSegment } from '@dxos/react-ui-attention';\nimport { AnchoredTo, Thread } from '@dxos/types';\n\nimport { useSheetContext } from '#components';\n\nexport const completeCellRangeToThreadCursor = (range: CompleteCellRange): string => {\n return `${range.from.col},${range.from.row},${range.to.col},${range.to.row}`;\n};\n\nexport const parseThreadAnchorAsCellRange = (cursor: string): CompleteCellRange | null => {\n const coords = cursor.split(',');\n if (coords.length !== 4) {\n return null;\n } else {\n const [fromCol, fromRow, toCol, toRow] = coords;\n return {\n from: { col: parseInt(fromCol), row: parseInt(fromRow) },\n to: { col: parseInt(toCol), row: parseInt(toRow) },\n };\n }\n};\n\nexport const useSelectThreadOnCellFocus = () => {\n const { model, cursor } = useSheetContext();\n const { invokePromise } = useOperationInvoker();\n\n const db = Obj.getDatabase(model.sheet);\n const anchors = useQuery(db, Query.select(Filter.id(model.sheet.id)).targetOf(AnchoredTo.AnchoredTo));\n\n const selectClosestThread = useCallback(\n (cellAddress: CellAddress) => {\n if (!cellAddress) {\n return;\n }\n\n const closestThread = anchors.find((anchor) => {\n const source = Relation.getSource(anchor);\n if (anchor.anchor && Obj.instanceOf(Thread.Thread, source)) {\n const range = parseThreadAnchorAsCellRange(anchor.anchor);\n return range ? inRange(range, cellAddress) : false;\n } else {\n return false;\n }\n });\n\n if (closestThread) {\n void (async () => {\n await invokePromise(ThreadOperation.Select, { current: Relation.getDXN(closestThread).toString() });\n await invokePromise(LayoutOperation.UpdateCompanion, {\n subject: linkedSegment('comments'),\n });\n })();\n }\n },\n [invokePromise, anchors],\n );\n\n const debounced = useMemo(() => {\n return debounce((cellCoords: CellAddress) => requestAnimationFrame(() => selectClosestThread(cellCoords)), 50);\n }, [selectClosestThread]);\n\n useEffect(() => {\n if (!cursor) {\n return;\n }\n\n debounced(cursor);\n }, [cursor, debounced]);\n};\n"],
5
- "mappings": ";AAIA,SAASA,aAAaC,WAAWC,eAAe;AAEhD,SAASC,2BAA2B;AACpC,SAASC,uBAAuB;AAChC,SAASC,gBAAgB;AACzB,SAAmDC,eAAe;AAClE,SAASC,KAAKC,gBAAgB;AAC9B,SAASC,uBAAuB;AAChC,SAASC,QAAQC,OAAOC,gBAAgB;AACxC,SAASC,qBAAqB;AAC9B,SAASC,YAAYC,cAAc;AAEnC,SAASC,uBAAuB;AAMzB,IAAMC,+BAA+B,CAACC,WAAAA;AAC3C,QAAMC,SAASD,OAAOE,MAAM,GAAA;AAC5B,MAAID,OAAOE,WAAW,GAAG;AACvB,WAAO;EACT,OAAO;AACL,UAAM,CAACC,SAASC,SAASC,OAAOC,KAAAA,IAASN;AACzC,WAAO;MACLO,MAAM;QAAEC,KAAKC,SAASN,OAAAA;QAAUO,KAAKD,SAASL,OAAAA;MAAS;MACvDO,IAAI;QAAEH,KAAKC,SAASJ,KAAAA;QAAQK,KAAKD,SAASH,KAAAA;MAAO;IACnD;EACF;AACF;AAEO,IAAMM,6BAA6B,MAAA;AACxC,QAAM,EAAEC,OAAOd,OAAM,IAAKe,gBAAAA;AAC1B,QAAM,EAAEC,cAAa,IAAKC,oBAAAA;AAE1B,QAAMC,KAAKC,IAAIC,YAAYN,MAAMO,KAAK;AACtC,QAAMC,UAAUC,SAASL,IAAIM,MAAMC,OAAOC,OAAOC,GAAGb,MAAMO,MAAMM,EAAE,CAAA,EAAGC,SAASC,WAAWA,UAAU,CAAA;AAEnG,QAAMC,sBAAsBC,YAC1B,CAACC,gBAAAA;AACC,QAAI,CAACA,aAAa;AAChB;IACF;AAEA,UAAMC,gBAAgBX,QAAQY,KAAK,CAACC,WAAAA;AAClC,YAAMC,SAASC,SAASC,UAAUH,MAAAA;AAClC,UAAIA,OAAOA,UAAUhB,IAAIoB,WAAWC,OAAOA,QAAQJ,MAAAA,GAAS;AAC1D,cAAMK,QAAQ1C,6BAA6BoC,OAAOA,MAAM;AACxD,eAAOM,QAAQC,QAAQD,OAAOT,WAAAA,IAAe;MAC/C,OAAO;AACL,eAAO;MACT;IACF,CAAA;AAEA,QAAIC,eAAe;AACjB,YAAM,YAAA;AACJ,cAAMjB,cAAc2B,gBAAgBC,QAAQ;UAAEC,SAASR,SAASS,OAAOb,aAAAA,EAAec,SAAQ;QAAG,CAAA;AACjG,cAAM/B,cAAcgC,gBAAgBC,iBAAiB;UACnDC,SAASC,cAAc,UAAA;QACzB,CAAA;MACF,GAAA;IACF;EACF,GACA;IAACnC;IAAeM;GAAQ;AAG1B,QAAM8B,YAAYC,QAAQ,MAAA;AACxB,WAAOC,SAAS,CAACC,eAA4BC,sBAAsB,MAAM1B,oBAAoByB,UAAAA,CAAAA,GAAc,EAAA;EAC7G,GAAG;IAACzB;GAAoB;AAExB2B,YAAU,MAAA;AACR,QAAI,CAACzD,QAAQ;AACX;IACF;AAEAoD,cAAUpD,MAAAA;EACZ,GAAG;IAACA;IAAQoD;GAAU;AACxB;",
6
- "names": ["useCallback", "useEffect", "useMemo", "useOperationInvoker", "LayoutOperation", "debounce", "inRange", "Obj", "Relation", "ThreadOperation", "Filter", "Query", "useQuery", "linkedSegment", "AnchoredTo", "Thread", "useSheetContext", "parseThreadAnchorAsCellRange", "cursor", "coords", "split", "length", "fromCol", "fromRow", "toCol", "toRow", "from", "col", "parseInt", "row", "to", "useSelectThreadOnCellFocus", "model", "useSheetContext", "invokePromise", "useOperationInvoker", "db", "Obj", "getDatabase", "sheet", "anchors", "useQuery", "Query", "select", "Filter", "id", "targetOf", "AnchoredTo", "selectClosestThread", "useCallback", "cellAddress", "closestThread", "find", "anchor", "source", "Relation", "getSource", "instanceOf", "Thread", "range", "inRange", "ThreadOperation", "Select", "current", "getDXN", "toString", "LayoutOperation", "UpdateCompanion", "subject", "linkedSegment", "debounced", "useMemo", "debounce", "cellCoords", "requestAnimationFrame", "useEffect"]
4
+ "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { useCallback, useEffect, useMemo } from 'react';\n\nimport { useOperationInvoker } from '@dxos/app-framework/ui';\nimport { LayoutOperation } from '@dxos/app-toolkit';\nimport { debounce } from '@dxos/async';\nimport { type CellAddress, type CompleteCellRange, inRange } from '@dxos/compute-hyperformula';\nimport { Filter, Obj, Query, Relation } from '@dxos/echo';\nimport { ThreadOperation } from '@dxos/plugin-thread';\nimport { useQuery } from '@dxos/react-client/echo';\nimport { linkedSegment } from '@dxos/react-ui-attention';\nimport { AnchoredTo, Thread } from '@dxos/types';\n\nimport { useSheetContext } from '#components';\n\nexport const completeCellRangeToThreadCursor = (range: CompleteCellRange): string => {\n return `${range.from.col},${range.from.row},${range.to.col},${range.to.row}`;\n};\n\nexport const parseThreadAnchorAsCellRange = (cursor: string): CompleteCellRange | null => {\n const coords = cursor.split(',');\n if (coords.length !== 4) {\n return null;\n } else {\n const [fromCol, fromRow, toCol, toRow] = coords;\n return {\n from: { col: parseInt(fromCol), row: parseInt(fromRow) },\n to: { col: parseInt(toCol), row: parseInt(toRow) },\n };\n }\n};\n\nexport const useSelectThreadOnCellFocus = () => {\n const { model, cursor } = useSheetContext();\n const { invokePromise } = useOperationInvoker();\n\n const db = Obj.getDatabase(model.sheet);\n const anchors = useQuery(db, Query.select(Filter.id(model.sheet.id)).targetOf(AnchoredTo.AnchoredTo));\n\n const selectClosestThread = useCallback(\n (cellAddress: CellAddress) => {\n if (!cellAddress) {\n return;\n }\n\n const closestThread = anchors.find((anchor) => {\n const source = Relation.getSource(anchor);\n if (anchor.anchor && Obj.instanceOf(Thread.Thread, source)) {\n const range = parseThreadAnchorAsCellRange(anchor.anchor);\n return range ? inRange(range, cellAddress) : false;\n } else {\n return false;\n }\n });\n\n if (closestThread) {\n void (async () => {\n await invokePromise(ThreadOperation.Select, { current: Relation.getURI(closestThread) });\n await invokePromise(LayoutOperation.UpdateCompanion, {\n subject: linkedSegment('comments'),\n });\n })();\n }\n },\n [invokePromise, anchors],\n );\n\n const debounced = useMemo(() => {\n return debounce((cellCoords: CellAddress) => requestAnimationFrame(() => selectClosestThread(cellCoords)), 50);\n }, [selectClosestThread]);\n\n useEffect(() => {\n if (!cursor) {\n return;\n }\n\n debounced(cursor);\n }, [cursor, debounced]);\n};\n"],
5
+ "mappings": ";AAIA,SAASA,aAAaC,WAAWC,eAAe;AAEhD,SAASC,2BAA2B;AACpC,SAASC,uBAAuB;AAChC,SAASC,gBAAgB;AACzB,SAAmDC,eAAe;AAClE,SAASC,QAAQC,KAAKC,OAAOC,gBAAgB;AAC7C,SAASC,uBAAuB;AAChC,SAASC,gBAAgB;AACzB,SAASC,qBAAqB;AAC9B,SAASC,YAAYC,cAAc;AAEnC,SAASC,uBAAuB;AAMzB,IAAMC,+BAA+B,CAACC,WAAAA;AAC3C,QAAMC,SAASD,OAAOE,MAAM,GAAA;AAC5B,MAAID,OAAOE,WAAW,GAAG;AACvB,WAAO;EACT,OAAO;AACL,UAAM,CAACC,SAASC,SAASC,OAAOC,KAAAA,IAASN;AACzC,WAAO;MACLO,MAAM;QAAEC,KAAKC,SAASN,OAAAA;QAAUO,KAAKD,SAASL,OAAAA;MAAS;MACvDO,IAAI;QAAEH,KAAKC,SAASJ,KAAAA;QAAQK,KAAKD,SAASH,KAAAA;MAAO;IACnD;EACF;AACF;AAEO,IAAMM,6BAA6B,MAAA;AACxC,QAAM,EAAEC,OAAOd,OAAM,IAAKe,gBAAAA;AAC1B,QAAM,EAAEC,cAAa,IAAKC,oBAAAA;AAE1B,QAAMC,KAAKC,IAAIC,YAAYN,MAAMO,KAAK;AACtC,QAAMC,UAAUC,SAASL,IAAIM,MAAMC,OAAOC,OAAOC,GAAGb,MAAMO,MAAMM,EAAE,CAAA,EAAGC,SAASC,WAAWA,UAAU,CAAA;AAEnG,QAAMC,sBAAsBC,YAC1B,CAACC,gBAAAA;AACC,QAAI,CAACA,aAAa;AAChB;IACF;AAEA,UAAMC,gBAAgBX,QAAQY,KAAK,CAACC,WAAAA;AAClC,YAAMC,SAASC,SAASC,UAAUH,MAAAA;AAClC,UAAIA,OAAOA,UAAUhB,IAAIoB,WAAWC,OAAOA,QAAQJ,MAAAA,GAAS;AAC1D,cAAMK,QAAQ1C,6BAA6BoC,OAAOA,MAAM;AACxD,eAAOM,QAAQC,QAAQD,OAAOT,WAAAA,IAAe;MAC/C,OAAO;AACL,eAAO;MACT;IACF,CAAA;AAEA,QAAIC,eAAe;AACjB,YAAM,YAAA;AACJ,cAAMjB,cAAc2B,gBAAgBC,QAAQ;UAAEC,SAASR,SAASS,OAAOb,aAAAA;QAAe,CAAA;AACtF,cAAMjB,cAAc+B,gBAAgBC,iBAAiB;UACnDC,SAASC,cAAc,UAAA;QACzB,CAAA;MACF,GAAA;IACF;EACF,GACA;IAAClC;IAAeM;GAAQ;AAG1B,QAAM6B,YAAYC,QAAQ,MAAA;AACxB,WAAOC,SAAS,CAACC,eAA4BC,sBAAsB,MAAMzB,oBAAoBwB,UAAAA,CAAAA,GAAc,EAAA;EAC7G,GAAG;IAACxB;GAAoB;AAExB0B,YAAU,MAAA;AACR,QAAI,CAACxD,QAAQ;AACX;IACF;AAEAmD,cAAUnD,MAAAA;EACZ,GAAG;IAACA;IAAQmD;GAAU;AACxB;",
6
+ "names": ["useCallback", "useEffect", "useMemo", "useOperationInvoker", "LayoutOperation", "debounce", "inRange", "Filter", "Obj", "Query", "Relation", "ThreadOperation", "useQuery", "linkedSegment", "AnchoredTo", "Thread", "useSheetContext", "parseThreadAnchorAsCellRange", "cursor", "coords", "split", "length", "fromCol", "fromRow", "toCol", "toRow", "from", "col", "parseInt", "row", "to", "useSelectThreadOnCellFocus", "model", "useSheetContext", "invokePromise", "useOperationInvoker", "db", "Obj", "getDatabase", "sheet", "anchors", "useQuery", "Query", "select", "Filter", "id", "targetOf", "AnchoredTo", "selectClosestThread", "useCallback", "cellAddress", "closestThread", "find", "anchor", "source", "Relation", "getSource", "instanceOf", "Thread", "range", "inRange", "ThreadOperation", "Select", "current", "getURI", "LayoutOperation", "UpdateCompanion", "subject", "linkedSegment", "debounced", "useMemo", "debounce", "cellCoords", "requestAnimationFrame", "useEffect"]
7
7
  }
@@ -0,0 +1,8 @@
1
+ // src/operations/index.ts
2
+ import { OperationHandlerSet } from "@dxos/compute";
3
+ var SheetOperationHandlerSet = OperationHandlerSet.lazy(() => import("./drop-axis-MO3KUU4C.mjs"), () => import("./insert-axis-V7E5PTMG.mjs"), () => import("./restore-axis-BAM44OPG.mjs"), () => import("./scroll-to-anchor-TBE2FTTT.mjs"));
4
+
5
+ export {
6
+ SheetOperationHandlerSet
7
+ };
8
+ //# sourceMappingURL=chunk-7ZUM64KO.mjs.map
@@ -127,7 +127,7 @@ var sheetExtension = ({ debug, functions = [] }) => {
127
127
  activateOnTyping: true,
128
128
  closeOnBlur: !debug,
129
129
  icons: false,
130
- tooltipClass: () => mx("!-left-[1px] !top-[33px] !-m-0 border border-h-0! [&>ul]:!min-w-[198px]", "[&>ul>li[aria-selected]]:!bg-accent-surface", "border-separator")
130
+ tooltipClass: () => mx("!-left-[1px] !top-[33px] !-m-0 border border-h-0! [&>ul]:!min-w-[198px]", "[&>ul>li[aria-selected]]:!bg-accent-bg", "border-separator")
131
131
  }),
132
132
  keymap.of([
133
133
  {
@@ -231,4 +231,4 @@ export {
231
231
  sheetExtension,
232
232
  rangeExtension
233
233
  };
234
- //# sourceMappingURL=chunk-4SBAIU6F.mjs.map
234
+ //# sourceMappingURL=chunk-ERHMBRSU.mjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/extensions/compute.ts", "../../../src/extensions/editor/sheet-extension.ts"],
4
- "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { syntaxTree } from '@codemirror/language';\nimport {\n type EditorState,\n type Extension,\n type RangeSet,\n RangeSetBuilder,\n StateEffect,\n StateField,\n type Transaction,\n} from '@codemirror/state';\nimport { Decoration, EditorView, ViewPlugin, WidgetType } from '@codemirror/view';\n\nimport { type CleanupFn, debounce } from '@dxos/async';\nimport {\n type CellAddress,\n type CellScalarValue,\n type ComputeGraph,\n type ComputeNode,\n createSheetName,\n} from '@dxos/compute-hyperformula';\nimport { invariant } from '@dxos/invariant';\nimport { documentId, singleValueFacet } from '@dxos/ui-editor';\n\nconst LANGUAGE_TAG = 'dx';\n\n// TODO(burdon): Create marker just for our decorator?\nconst updateAllDecorations = StateEffect.define<void>();\n\nexport const computeGraphFacet = singleValueFacet<ComputeGraph>();\n\nexport type ComputeOptions = {};\n\nexport const compute = (_options: ComputeOptions = {}): Extension => {\n let computeNode: ComputeNode | undefined;\n\n const update = (state: EditorState, current?: RangeSet<Decoration>) => {\n const builder = new RangeSetBuilder<Decoration>();\n if (computeNode) {\n computeNode.clear();\n syntaxTree(state).iterate({\n enter: (node) => {\n switch (node.name) {\n case 'FencedCode': {\n const cursor = state.selection.main.head;\n if (state.readOnly || cursor < node.from || cursor > node.to) {\n const info = node.node.getChild('CodeInfo');\n if (info) {\n const type = state.sliceDoc(info.from, info.to);\n const text = node.node.getChild('CodeText');\n if (type === LANGUAGE_TAG && text) {\n const formula = state.sliceDoc(text.from, text.to);\n const iter = current?.iter(node.node.from);\n if (iter?.value && iter?.value.spec.formula === formula) {\n // Add existing widget.\n builder.add(node.from, node.to, iter.value);\n } else {\n // TODO(burdon): Create ordered list of cells on each decoration run.\n const cell: CellAddress = { col: node.node.from, row: 0 };\n invariant(computeNode);\n // NOTE: This triggers re-render (below).\n computeNode.setValue(cell, formula);\n const value = computeNode.getValue(cell);\n builder.add(\n node.from,\n node.to,\n Decoration.replace({\n widget: new ComputeWidget(formula, value),\n formula,\n }),\n );\n }\n }\n }\n }\n\n break;\n }\n }\n },\n });\n }\n\n return builder.finish();\n };\n\n return [\n ViewPlugin.fromClass(\n class {\n // Graph subscription.\n private _subscription?: CleanupFn;\n constructor(view: EditorView) {\n const id = view.state.facet(documentId);\n const computeGraph = view.state.facet(computeGraphFacet);\n if (id && computeGraph) {\n queueMicrotask(async () => {\n computeNode = computeGraph.getOrCreateNode(createSheetName({ type: '', id }));\n await computeNode.open();\n\n // Trigger re-render if values updated.\n // TODO(burdon): Trigger only if formula value updated (currently triggered during render).\n this._subscription = computeNode.update.on(\n debounce(({ type, ...rest }) => {\n if (type === 'valuesUpdated') {\n view.dispatch({\n effects: updateAllDecorations.of(),\n });\n }\n }, 250),\n );\n });\n }\n }\n\n destroy() {\n this._subscription?.();\n void computeNode?.close();\n computeNode = undefined;\n }\n },\n ),\n\n StateField.define<RangeSet<Decoration>>({\n create: (state) => update(state),\n update: (rangeSet: RangeSet<Decoration>, tr: Transaction) => update(tr.state, rangeSet),\n provide: (field) => EditorView.decorations.from(field),\n }),\n ];\n};\n\n// TODO(burdon): Click to edit.\nclass ComputeWidget extends WidgetType {\n constructor(\n private readonly formula: string,\n private readonly value: CellScalarValue,\n ) {\n super();\n }\n\n override toDOM(_view: EditorView): HTMLDivElement {\n const div = document.createElement('div');\n div.setAttribute('title', this.formula);\n div.innerText = String(this.value);\n return div;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport {\n type Completion,\n type CompletionContext,\n type CompletionResult,\n acceptCompletion,\n autocompletion,\n completionStatus,\n startCompletion,\n} from '@codemirror/autocomplete';\nimport { HighlightStyle, type Language, syntaxHighlighting } from '@codemirror/language';\nimport { type Extension } from '@codemirror/state';\nimport { type EditorView, ViewPlugin, type ViewUpdate, keymap } from '@codemirror/view';\nimport { type SyntaxNode } from '@lezer/common';\nimport { tags } from '@lezer/highlight';\nimport { spreadsheet } from 'codemirror-lang-spreadsheet';\n\nimport { type FunctionDefinition } from '@dxos/compute-hyperformula';\nimport { RANGE_NOTATION } from '@dxos/compute-hyperformula';\nimport { singleValueFacet } from '@dxos/ui-editor';\nimport { mx } from '@dxos/ui-theme';\n\n/**\n * https://codemirror.net/examples/styling\n * https://lezer.codemirror.net/docs/ref/#highlight\n * https://github.com/luizzappa/codemirror-lang-spreadsheet/blob/main/src/index.ts#L28 (mapping)\n */\n// TODO(burdon): Define light/dark.\nconst highlightStyles = HighlightStyle.define([\n // Function.\n {\n tag: tags.name,\n class: 'text-accent-text',\n },\n // Range.\n {\n tag: tags.tagName,\n class: 'text-pink-text',\n },\n // Values.\n {\n tag: tags.number,\n class: 'text-teal-text',\n },\n {\n tag: tags.bool,\n class: 'text-teal-text',\n },\n {\n tag: tags.string,\n class: 'text-teal-text',\n },\n // Error.\n {\n tag: tags.invalid,\n class: 'text-un-accent',\n },\n]);\n\nconst languageFacet = singleValueFacet<Language>();\n\nexport type SheetExtensionOptions = {\n debug?: boolean;\n functions?: FunctionDefinition[];\n};\n\n/**\n * Spreadsheet formula extension and parser.\n * https://github.com/luizzappa/codemirror-lang-spreadsheet\n * https://github.com/luizzappa/codemirror-app-spreadsheet/blob/master/src/editor.ts\n * https://github.com/codemirror/lang-example\n * https://hyperformula.handsontable.com/guide/key-concepts.html#grammar\n */\nexport const sheetExtension = ({ debug, functions = [] }: SheetExtensionOptions): Extension => {\n const { extension, language } = spreadsheet({\n idiom: 'en-US',\n decimalSeparator: '.',\n });\n\n const createCompletion = (name: string) => {\n const { section = 'Custom', description, syntax } = functions.find((value) => value.name === name) ?? {};\n\n return {\n section,\n label: name,\n info: () => {\n if (!description && !syntax) {\n return null;\n }\n\n // TODO(burdon): Standardize color styles.\n const root = document.createElement('div');\n root.className = 'flex flex-col gap-2 text-sm';\n\n const title = document.createElement('h2');\n title.innerText = name;\n title.className = 'text-lg font-mono text-accent-text';\n root.appendChild(title);\n\n if (description) {\n const info = document.createElement('p');\n info.innerText = description;\n info.className = 'text-subdued';\n root.appendChild(info);\n }\n\n if (syntax) {\n const detail = document.createElement('pre');\n detail.innerText = syntax;\n detail.className = 'whitespace-pre-wrap text-green-text';\n root.appendChild(detail);\n }\n\n return root;\n },\n apply: (view, completion, from, to) => {\n const insertParens = to === view.state.doc.toString().length;\n view.dispatch(\n view.state.update({\n changes: {\n from,\n to,\n insert: completion.label + (insertParens ? '()' : ''),\n },\n selection: {\n anchor: from + completion.label.length + 1,\n },\n }),\n );\n },\n } satisfies Completion;\n };\n\n return [\n extension,\n languageFacet.of(language),\n language.data.of({\n autocomplete: (context: CompletionContext): CompletionResult | null => {\n if (context.state.doc.toString()[0] !== '=') {\n return null;\n }\n const match = context.matchBefore(/\\w*/);\n if (!match || match.from === match.to) {\n return null;\n }\n\n const text = match.text.toUpperCase();\n if (!context.explicit && match.text.length < 2) {\n return null;\n }\n\n return {\n from: match.from,\n options:\n functions?.filter(({ name }) => name.startsWith(text)).map(({ name }) => createCompletion(name)) ?? [],\n };\n },\n }),\n\n syntaxHighlighting(highlightStyles),\n autocompletion({\n aboveCursor: false,\n defaultKeymap: true,\n activateOnTyping: true,\n closeOnBlur: !debug,\n icons: false,\n tooltipClass: () =>\n mx(\n '!-left-[1px] !top-[33px] !-m-0 border border-h-0! [&>ul]:!min-w-[198px]',\n '[&>ul>li[aria-selected]]:!bg-accent-surface',\n 'border-separator',\n ),\n }),\n keymap.of([\n {\n key: 'Tab',\n run: (view) => {\n return completionStatus(view.state) === 'active' ? acceptCompletion(view) : startCompletion(view);\n },\n },\n ]),\n\n // Parsing.\n // StateField.define({\n // create: (state) => {},\n // update: (value, tr) => {\n // log.info('update');\n // syntaxTree(tr.state).iterate({\n // enter: ({ type, from, to }) => {\n // log.info('node', { type: type.name, from, to });\n // },\n // });\n // },\n // }),\n ];\n};\n\nexport type SelectionRange = { from: number; to: number };\n\nexport interface RangeController {\n setRange(range: string): void;\n}\n\nexport type RangeExtensionOptions = {\n /**\n * Provides controller callback when extension is initialized.\n */\n onInit?: (controller: RangeController) => void;\n /**\n * Called when the active range changes.\n * @param state The current state.\n * @param state.activeRange undefined if no range is active, otherwise a possibly partially defined range.\n */\n onStateChange?: (state: { activeRange: string | undefined }) => void;\n};\n\n/**\n * Tracks the currently active cell within a formula and provides a callback to modify it.\n */\nexport const rangeExtension = ({ onInit, onStateChange }: RangeExtensionOptions): Extension => {\n let view: EditorView;\n let activeRange: SelectionRange | undefined;\n\n // Called externally to provide current range.\n const notifier: RangeController = {\n setRange: (range: string) => {\n if (activeRange) {\n view.dispatch(\n view.state.update({\n changes: { ...activeRange, insert: range.toString() },\n selection: { anchor: activeRange.from + range.length },\n }),\n );\n }\n\n view.focus();\n },\n };\n\n return ViewPlugin.fromClass(\n class {\n constructor(_view: EditorView) {\n view = _view;\n onInit?.(notifier);\n }\n\n update(view: ViewUpdate) {\n const { anchor } = view.state.selection.ranges[0];\n\n // Find first Range or cell at cursor.\n activeRange = undefined;\n const language = view.state.facet(languageFacet);\n const { topNode } = language.parser.parse(view.state.doc.toString());\n visitTree(topNode, ({ type, from, to }) => {\n if (from <= anchor && to >= anchor) {\n switch (type.name) {\n case 'Function':\n // Mark but keep looking.\n activeRange = { from: to, to };\n break;\n\n case 'CloseParen':\n // Mark but keep looking.\n activeRange = { from, to: from };\n break;\n\n case 'RangeToken':\n case 'CellToken':\n activeRange = { from, to };\n return true;\n }\n }\n\n return false;\n });\n\n // Allow start of formula.\n if (!activeRange && view.state.doc.toString()[0] === '=') {\n const str = view.state.doc.sliceString(1);\n if (RANGE_NOTATION.test(str)) {\n activeRange = { from: 1, to: str.length + 1 };\n } else {\n activeRange = { from: str.length + 1, to: str.length + 1 };\n }\n }\n\n onStateChange?.({\n activeRange: activeRange ? view.state.doc.sliceString(activeRange.from, activeRange.to) : undefined,\n });\n }\n },\n );\n};\n\n/**\n * Lezer parse result visitor.\n */\nconst visitTree = (node: SyntaxNode, callback: (node: SyntaxNode) => boolean): boolean => {\n if (callback(node)) {\n return true;\n }\n\n for (let child = node.firstChild; child !== null; child = child.nextSibling) {\n if (visitTree(child, callback)) {\n return true;\n }\n }\n\n return false;\n};\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { syntaxTree } from '@codemirror/language';\nimport {\n type EditorState,\n type Extension,\n type RangeSet,\n RangeSetBuilder,\n StateEffect,\n StateField,\n type Transaction,\n} from '@codemirror/state';\nimport { Decoration, EditorView, ViewPlugin, WidgetType } from '@codemirror/view';\n\nimport { type CleanupFn, debounce } from '@dxos/async';\nimport {\n type CellAddress,\n type CellScalarValue,\n type ComputeGraph,\n type ComputeNode,\n createSheetName,\n} from '@dxos/compute-hyperformula';\nimport { invariant } from '@dxos/invariant';\nimport { documentId, singleValueFacet } from '@dxos/ui-editor';\n\nconst LANGUAGE_TAG = 'dx';\n\n// TODO(burdon): Create marker just for our decorator?\nconst updateAllDecorations = StateEffect.define<void>();\n\nexport const computeGraphFacet = singleValueFacet<ComputeGraph>();\n\nexport type ComputeOptions = {};\n\nexport const compute = (_options: ComputeOptions = {}): Extension => {\n let computeNode: ComputeNode | undefined;\n\n const update = (state: EditorState, current?: RangeSet<Decoration>) => {\n const builder = new RangeSetBuilder<Decoration>();\n if (computeNode) {\n computeNode.clear();\n syntaxTree(state).iterate({\n enter: (node) => {\n switch (node.name) {\n case 'FencedCode': {\n const cursor = state.selection.main.head;\n if (state.readOnly || cursor < node.from || cursor > node.to) {\n const info = node.node.getChild('CodeInfo');\n if (info) {\n const type = state.sliceDoc(info.from, info.to);\n const text = node.node.getChild('CodeText');\n if (type === LANGUAGE_TAG && text) {\n const formula = state.sliceDoc(text.from, text.to);\n const iter = current?.iter(node.node.from);\n if (iter?.value && iter?.value.spec.formula === formula) {\n // Add existing widget.\n builder.add(node.from, node.to, iter.value);\n } else {\n // TODO(burdon): Create ordered list of cells on each decoration run.\n const cell: CellAddress = { col: node.node.from, row: 0 };\n invariant(computeNode);\n // NOTE: This triggers re-render (below).\n computeNode.setValue(cell, formula);\n const value = computeNode.getValue(cell);\n builder.add(\n node.from,\n node.to,\n Decoration.replace({\n widget: new ComputeWidget(formula, value),\n formula,\n }),\n );\n }\n }\n }\n }\n\n break;\n }\n }\n },\n });\n }\n\n return builder.finish();\n };\n\n return [\n ViewPlugin.fromClass(\n class {\n // Graph subscription.\n private _subscription?: CleanupFn;\n constructor(view: EditorView) {\n const id = view.state.facet(documentId);\n const computeGraph = view.state.facet(computeGraphFacet);\n if (id && computeGraph) {\n queueMicrotask(async () => {\n computeNode = computeGraph.getOrCreateNode(createSheetName({ type: '', id }));\n await computeNode.open();\n\n // Trigger re-render if values updated.\n // TODO(burdon): Trigger only if formula value updated (currently triggered during render).\n this._subscription = computeNode.update.on(\n debounce(({ type, ...rest }) => {\n if (type === 'valuesUpdated') {\n view.dispatch({\n effects: updateAllDecorations.of(),\n });\n }\n }, 250),\n );\n });\n }\n }\n\n destroy() {\n this._subscription?.();\n void computeNode?.close();\n computeNode = undefined;\n }\n },\n ),\n\n StateField.define<RangeSet<Decoration>>({\n create: (state) => update(state),\n update: (rangeSet: RangeSet<Decoration>, tr: Transaction) => update(tr.state, rangeSet),\n provide: (field) => EditorView.decorations.from(field),\n }),\n ];\n};\n\n// TODO(burdon): Click to edit.\nclass ComputeWidget extends WidgetType {\n constructor(\n private readonly formula: string,\n private readonly value: CellScalarValue,\n ) {\n super();\n }\n\n override toDOM(_view: EditorView): HTMLDivElement {\n const div = document.createElement('div');\n div.setAttribute('title', this.formula);\n div.innerText = String(this.value);\n return div;\n }\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport {\n type Completion,\n type CompletionContext,\n type CompletionResult,\n acceptCompletion,\n autocompletion,\n completionStatus,\n startCompletion,\n} from '@codemirror/autocomplete';\nimport { HighlightStyle, type Language, syntaxHighlighting } from '@codemirror/language';\nimport { type Extension } from '@codemirror/state';\nimport { type EditorView, ViewPlugin, type ViewUpdate, keymap } from '@codemirror/view';\nimport { type SyntaxNode } from '@lezer/common';\nimport { tags } from '@lezer/highlight';\nimport { spreadsheet } from 'codemirror-lang-spreadsheet';\n\nimport { type FunctionDefinition } from '@dxos/compute-hyperformula';\nimport { RANGE_NOTATION } from '@dxos/compute-hyperformula';\nimport { singleValueFacet } from '@dxos/ui-editor';\nimport { mx } from '@dxos/ui-theme';\n\n/**\n * https://codemirror.net/examples/styling\n * https://lezer.codemirror.net/docs/ref/#highlight\n * https://github.com/luizzappa/codemirror-lang-spreadsheet/blob/main/src/index.ts#L28 (mapping)\n */\n// TODO(burdon): Define light/dark.\nconst highlightStyles = HighlightStyle.define([\n // Function.\n {\n tag: tags.name,\n class: 'text-accent-text',\n },\n // Range.\n {\n tag: tags.tagName,\n class: 'text-pink-text',\n },\n // Values.\n {\n tag: tags.number,\n class: 'text-teal-text',\n },\n {\n tag: tags.bool,\n class: 'text-teal-text',\n },\n {\n tag: tags.string,\n class: 'text-teal-text',\n },\n // Error.\n {\n tag: tags.invalid,\n class: 'text-un-accent',\n },\n]);\n\nconst languageFacet = singleValueFacet<Language>();\n\nexport type SheetExtensionOptions = {\n debug?: boolean;\n functions?: FunctionDefinition[];\n};\n\n/**\n * Spreadsheet formula extension and parser.\n * https://github.com/luizzappa/codemirror-lang-spreadsheet\n * https://github.com/luizzappa/codemirror-app-spreadsheet/blob/master/src/editor.ts\n * https://github.com/codemirror/lang-example\n * https://hyperformula.handsontable.com/guide/key-concepts.html#grammar\n */\nexport const sheetExtension = ({ debug, functions = [] }: SheetExtensionOptions): Extension => {\n const { extension, language } = spreadsheet({\n idiom: 'en-US',\n decimalSeparator: '.',\n });\n\n const createCompletion = (name: string) => {\n const { section = 'Custom', description, syntax } = functions.find((value) => value.name === name) ?? {};\n\n return {\n section,\n label: name,\n info: () => {\n if (!description && !syntax) {\n return null;\n }\n\n // TODO(burdon): Standardize color styles.\n const root = document.createElement('div');\n root.className = 'flex flex-col gap-2 text-sm';\n\n const title = document.createElement('h2');\n title.innerText = name;\n title.className = 'text-lg font-mono text-accent-text';\n root.appendChild(title);\n\n if (description) {\n const info = document.createElement('p');\n info.innerText = description;\n info.className = 'text-subdued';\n root.appendChild(info);\n }\n\n if (syntax) {\n const detail = document.createElement('pre');\n detail.innerText = syntax;\n detail.className = 'whitespace-pre-wrap text-green-text';\n root.appendChild(detail);\n }\n\n return root;\n },\n apply: (view, completion, from, to) => {\n const insertParens = to === view.state.doc.toString().length;\n view.dispatch(\n view.state.update({\n changes: {\n from,\n to,\n insert: completion.label + (insertParens ? '()' : ''),\n },\n selection: {\n anchor: from + completion.label.length + 1,\n },\n }),\n );\n },\n } satisfies Completion;\n };\n\n return [\n extension,\n languageFacet.of(language),\n language.data.of({\n autocomplete: (context: CompletionContext): CompletionResult | null => {\n if (context.state.doc.toString()[0] !== '=') {\n return null;\n }\n const match = context.matchBefore(/\\w*/);\n if (!match || match.from === match.to) {\n return null;\n }\n\n const text = match.text.toUpperCase();\n if (!context.explicit && match.text.length < 2) {\n return null;\n }\n\n return {\n from: match.from,\n options:\n functions?.filter(({ name }) => name.startsWith(text)).map(({ name }) => createCompletion(name)) ?? [],\n };\n },\n }),\n\n syntaxHighlighting(highlightStyles),\n autocompletion({\n aboveCursor: false,\n defaultKeymap: true,\n activateOnTyping: true,\n closeOnBlur: !debug,\n icons: false,\n tooltipClass: () =>\n mx(\n '!-left-[1px] !top-[33px] !-m-0 border border-h-0! [&>ul]:!min-w-[198px]',\n '[&>ul>li[aria-selected]]:!bg-accent-bg',\n 'border-separator',\n ),\n }),\n keymap.of([\n {\n key: 'Tab',\n run: (view) => {\n return completionStatus(view.state) === 'active' ? acceptCompletion(view) : startCompletion(view);\n },\n },\n ]),\n\n // Parsing.\n // StateField.define({\n // create: (state) => {},\n // update: (value, tr) => {\n // log.info('update');\n // syntaxTree(tr.state).iterate({\n // enter: ({ type, from, to }) => {\n // log.info('node', { type: type.name, from, to });\n // },\n // });\n // },\n // }),\n ];\n};\n\nexport type SelectionRange = { from: number; to: number };\n\nexport interface RangeController {\n setRange(range: string): void;\n}\n\nexport type RangeExtensionOptions = {\n /**\n * Provides controller callback when extension is initialized.\n */\n onInit?: (controller: RangeController) => void;\n /**\n * Called when the active range changes.\n * @param state The current state.\n * @param state.activeRange undefined if no range is active, otherwise a possibly partially defined range.\n */\n onStateChange?: (state: { activeRange: string | undefined }) => void;\n};\n\n/**\n * Tracks the currently active cell within a formula and provides a callback to modify it.\n */\nexport const rangeExtension = ({ onInit, onStateChange }: RangeExtensionOptions): Extension => {\n let view: EditorView;\n let activeRange: SelectionRange | undefined;\n\n // Called externally to provide current range.\n const notifier: RangeController = {\n setRange: (range: string) => {\n if (activeRange) {\n view.dispatch(\n view.state.update({\n changes: { ...activeRange, insert: range.toString() },\n selection: { anchor: activeRange.from + range.length },\n }),\n );\n }\n\n view.focus();\n },\n };\n\n return ViewPlugin.fromClass(\n class {\n constructor(_view: EditorView) {\n view = _view;\n onInit?.(notifier);\n }\n\n update(view: ViewUpdate) {\n const { anchor } = view.state.selection.ranges[0];\n\n // Find first Range or cell at cursor.\n activeRange = undefined;\n const language = view.state.facet(languageFacet);\n const { topNode } = language.parser.parse(view.state.doc.toString());\n visitTree(topNode, ({ type, from, to }) => {\n if (from <= anchor && to >= anchor) {\n switch (type.name) {\n case 'Function':\n // Mark but keep looking.\n activeRange = { from: to, to };\n break;\n\n case 'CloseParen':\n // Mark but keep looking.\n activeRange = { from, to: from };\n break;\n\n case 'RangeToken':\n case 'CellToken':\n activeRange = { from, to };\n return true;\n }\n }\n\n return false;\n });\n\n // Allow start of formula.\n if (!activeRange && view.state.doc.toString()[0] === '=') {\n const str = view.state.doc.sliceString(1);\n if (RANGE_NOTATION.test(str)) {\n activeRange = { from: 1, to: str.length + 1 };\n } else {\n activeRange = { from: str.length + 1, to: str.length + 1 };\n }\n }\n\n onStateChange?.({\n activeRange: activeRange ? view.state.doc.sliceString(activeRange.from, activeRange.to) : undefined,\n });\n }\n },\n );\n};\n\n/**\n * Lezer parse result visitor.\n */\nconst visitTree = (node: SyntaxNode, callback: (node: SyntaxNode) => boolean): boolean => {\n if (callback(node)) {\n return true;\n }\n\n for (let child = node.firstChild; child !== null; child = child.nextSibling) {\n if (visitTree(child, callback)) {\n return true;\n }\n }\n\n return false;\n};\n"],
5
+ "mappings": "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",
6
6
  "names": ["syntaxTree", "RangeSetBuilder", "StateEffect", "StateField", "Decoration", "EditorView", "ViewPlugin", "WidgetType", "debounce", "createSheetName", "invariant", "documentId", "singleValueFacet", "_options", "computeNode", "acceptCompletion", "autocompletion", "completionStatus", "startCompletion", "HighlightStyle", "syntaxHighlighting", "ViewPlugin", "keymap", "tags", "spreadsheet", "RANGE_NOTATION", "singleValueFacet", "mx", "highlightStyles", "define", "tag", "name", "class", "tagName", "number", "bool", "string", "invalid", "languageFacet", "sheetExtension", "debug", "functions", "extension", "language", "idiom", "decimalSeparator", "createCompletion", "section", "description", "syntax", "find", "value", "label", "info", "root", "document", "createElement", "className", "title", "innerText", "appendChild", "detail", "apply", "view", "completion", "from", "to", "insertParens", "state", "doc", "toString", "length", "dispatch", "update", "changes", "insert", "selection", "anchor", "of", "data", "autocomplete", "context", "match", "matchBefore", "text", "toUpperCase", "explicit", "options", "filter", "startsWith", "map", "aboveCursor", "defaultKeymap", "activateOnTyping", "closeOnBlur", "icons", "tooltipClass", "key", "run", "rangeExtension", "onInit", "onStateChange", "activeRange", "notifier", "setRange", "range", "focus", "fromClass", "_view", "ranges", "undefined", "facet", "topNode", "parser", "parse", "visitTree", "type", "str", "sliceString", "test", "node", "callback", "child", "firstChild", "nextSibling"]
7
7
  }
@@ -49,14 +49,13 @@ __export(Sheet_exports, {
49
49
  });
50
50
  import * as Schema from "effect/Schema";
51
51
  import { addressFromA1Notation as addressFromA1Notation2, isFormula as isFormula2 } from "@dxos/compute-hyperformula";
52
- import { Annotation, Obj, Type } from "@dxos/echo";
52
+ import { DXN, Annotation, Obj, Type } from "@dxos/echo";
53
53
  import { FormInputAnnotation } from "@dxos/echo/internal";
54
54
 
55
55
  // src/types/util.ts
56
56
  import { addressFromA1Notation, addressToA1Notation, isFormula } from "@dxos/compute-hyperformula";
57
57
  import { randomBytes } from "@dxos/crypto";
58
- import { invariant } from "@dxos/invariant";
59
- var __dxlog_file = "/__w/dxos/dxos/packages/plugins/plugin-sheet/src/types/util.ts";
58
+ import { assertArgument } from "@dxos/invariant";
60
59
  var MAX_ROWS = 500;
61
60
  var MAX_COLS = 676;
62
61
  var DEFAULT_ROWS = 50;
@@ -128,13 +127,13 @@ var compareIndexPositions = (sheet, indexA, indexB) => {
128
127
  }
129
128
  };
130
129
  var mapFormulaRefsToIndices = (sheet, formula) => {
131
- invariant(isFormula(formula), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 96, S: void 0, A: ["isFormula(formula)", ""] });
130
+ assertArgument(isFormula(formula), "formula");
132
131
  return formula.replace(/([a-zA-Z]+)([0-9]+)/g, (match) => {
133
132
  return addressToIndex(sheet, addressFromA1Notation(match));
134
133
  });
135
134
  };
136
135
  var mapFormulaIndicesToRefs = (sheet, formula) => {
137
- invariant(isFormula(formula), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 104, S: void 0, A: ["isFormula(formula)", ""] });
136
+ assertArgument(isFormula(formula), "formula");
138
137
  return formula.replace(/([a-zA-Z0-9]+)@([a-zA-Z0-9]+)/g, (idx) => {
139
138
  return addressToA1Notation(addressFromIndex(sheet, idx));
140
139
  });
@@ -178,13 +177,10 @@ var Sheet = Schema.Struct({
178
177
  }).pipe(FormInputAnnotation.set(false)),
179
178
  // Cell formatting referenced by indexed range.
180
179
  ranges: Schema.Array(Range).pipe(FormInputAnnotation.set(false))
181
- }).pipe(Type.object({
182
- typename: "org.dxos.type.sheet",
183
- version: "0.1.0"
184
- }), Annotation.IconAnnotation.set({
180
+ }).pipe(Annotation.IconAnnotation.set({
185
181
  icon: "ph--grid-nine--regular",
186
182
  hue: "indigo"
187
- }));
183
+ }), Type.makeObject(DXN.make("org.dxos.type.sheet", "0.1.0")));
188
184
  var make = ({ name, cells = {}, ...size } = {}) => {
189
185
  const sheet = Obj.make(Sheet, {
190
186
  name,
@@ -248,13 +244,15 @@ __export(SheetOperation_exports, {
248
244
  import * as Schema3 from "effect/Schema";
249
245
  import { Capability as Capability2 } from "@dxos/app-framework";
250
246
  import { Operation } from "@dxos/compute";
247
+ import { DXN as DXN2 } from "@dxos/keys";
251
248
  import { meta as meta2 } from "#meta";
252
- var SHEET_OPERATION = `${meta2.id}.operation`;
249
+ var makeKey = (name) => DXN2.make(`${meta2.id}.operation.${name}`);
253
250
  var Axis = Schema3.Union(Schema3.Literal("row"), Schema3.Literal("col"));
254
251
  var InsertAxis = Operation.make({
255
252
  meta: {
256
- key: `${SHEET_OPERATION}.axis-insert`,
257
- name: "Insert Axis"
253
+ key: makeKey("axisInsert"),
254
+ name: "Insert Axis",
255
+ icon: "ph--plus--regular"
258
256
  },
259
257
  input: Schema3.Struct({
260
258
  model: Schema3.Any,
@@ -283,8 +281,9 @@ var DropAxisOutput = Schema3.Struct({
283
281
  });
284
282
  var DropAxis = Operation.make({
285
283
  meta: {
286
- key: `${SHEET_OPERATION}.axis-drop`,
287
- name: "Drop Axis"
284
+ key: makeKey("axisDrop"),
285
+ name: "Drop Axis",
286
+ icon: "ph--trash--regular"
288
287
  },
289
288
  input: Schema3.Struct({
290
289
  model: Schema3.Any,
@@ -295,8 +294,9 @@ var DropAxis = Operation.make({
295
294
  });
296
295
  var ScrollToAnchor = Operation.make({
297
296
  meta: {
298
- key: `${SHEET_OPERATION}.scroll-to-anchor`,
299
- name: "Scroll To Anchor"
297
+ key: makeKey("scrollToAnchor"),
298
+ name: "Scroll To Anchor",
299
+ icon: "ph--anchor-simple--regular"
300
300
  },
301
301
  services: [
302
302
  Capability2.Service
@@ -316,8 +316,9 @@ var ScrollToAnchor = Operation.make({
316
316
  });
317
317
  var RestoreAxis = Operation.make({
318
318
  meta: {
319
- key: `${SHEET_OPERATION}.restore-axis`,
320
- name: "Restore Axis"
319
+ key: makeKey("restoreAxis"),
320
+ name: "Restore Axis",
321
+ icon: "ph--clock-counter-clockwise--regular"
321
322
  },
322
323
  input: Schema3.Struct({
323
324
  model: Schema3.Any.annotations({
@@ -370,4 +371,4 @@ export {
370
371
  SheetCapabilities_exports,
371
372
  SheetOperation_exports
372
373
  };
373
- //# sourceMappingURL=chunk-KC2SMDNF.mjs.map
374
+ //# sourceMappingURL=chunk-EUM3RVML.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/types/sheet-range-types.ts", "../../../src/types/types.ts", "../../../src/types/Sheet.ts", "../../../src/types/util.ts", "../../../src/types/SheetCapabilities.ts", "../../../src/types/SheetOperation.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2024 DXOS.org\n//\n\nimport { type ClassNameValue } from '@dxos/react-ui';\n\nimport { type Sheet } from '../types';\n\nexport const alignKey = 'alignment';\nexport type AlignKey = typeof alignKey;\nexport type AlignValue = 'start' | 'center' | 'end';\n\nexport const commentKey = 'comment';\nexport type CommentKey = typeof commentKey;\nexport type CommentValue = string;\n\nexport const styleKey = 'style';\nexport type StyleKey = typeof styleKey;\nexport type StyleValue = 'highlight' | 'softwrap';\n\n// TODO(burdon): Reconcile with plugin-table.\nexport const cellClassNameForRange = ({ key, value }: Sheet.Sheet['ranges'][number]): ClassNameValue => {\n switch (key) {\n case alignKey:\n switch (value) {\n case 'start':\n return 'text-start';\n case 'center':\n return 'text-center';\n case 'end':\n return 'text-end';\n default:\n return undefined;\n }\n\n case commentKey:\n return 'bg-grid-comment';\n\n case styleKey:\n switch (value) {\n case 'highlight':\n return 'bg-grid-highlight!';\n case 'softwrap':\n return 'whitespace-normal!';\n default:\n return undefined;\n }\n\n default:\n return undefined;\n }\n};\n", "//\n// Copyright 2023 DXOS.org\n//\n\nimport * as Schema from 'effect/Schema';\n\nimport * as Sheet from './Sheet';\n\n// TODO(wittjosiah): Factor out. This is `DxGridAxis` from `@dxos/react-ui-grid`.\nconst ActionAxis = Schema.Union(Schema.Literal('row'), Schema.Literal('col'));\n\nexport namespace SheetAction {\n export const RestoreAxis = Schema.Struct({\n axis: ActionAxis,\n axisIndex: Schema.String,\n index: Schema.Number,\n axisMeta: Sheet.RowColumnMeta,\n values: Schema.Array(Schema.Any),\n });\n\n export type RestoreAxis = Schema.Schema.Type<typeof RestoreAxis>;\n}\n", "//\n// Copyright 2023 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Schema from 'effect/Schema';\n\nimport { addressFromA1Notation, isFormula } from '@dxos/compute-hyperformula';\nimport { DXN, Annotation, Obj, Type } from '@dxos/echo';\nimport { FormInputAnnotation } from '@dxos/echo/internal';\n\nimport { addressToIndex, initialize, mapFormulaRefsToIndices } from './util';\n\nexport type SheetSize = {\n rows: number;\n columns: number;\n};\n\nexport const CellValue = Schema.Struct({\n // TODO(burdon): How to store dates (datetime, date, time), percentages, etc.\n // Consider import/export; natural access for other plugins. Special handling for currency (precision).\n // TODO(burdon): Automerge (long string) or short string or number.\n value: Schema.Any,\n});\n\nexport type CellValue = Schema.Schema.Type<typeof CellValue>;\n\n// TODO(burdon): IMPORTANT: Reconcile with Field definition.\nexport const Range = Schema.Struct({\n range: Schema.String,\n key: Schema.String,\n value: Schema.String,\n});\n\nexport type Range = Schema.Schema.Type<typeof Range>;\n\n// TODO(burdon): Visibility, locked, frozen, etc.\nexport const RowColumnMeta = Schema.Struct({\n size: Schema.optional(Schema.Number),\n});\n\n// TODO(burdon): Reconcile col/column (across packages).\n// TODO(burdon): Index to all updates when rows/columns are inserted/deleted.\nexport const Sheet = Schema.Struct({\n name: Schema.optional(Schema.String),\n\n // Sparse map of cells referenced by index.\n cells: Schema.Record({ key: Schema.String, value: CellValue }).pipe(FormInputAnnotation.set(false)),\n\n // Ordered row indices.\n rows: Schema.Array(Schema.String).pipe(FormInputAnnotation.set(false)),\n\n // Ordered column indices.\n columns: Schema.Array(Schema.String).pipe(FormInputAnnotation.set(false)),\n\n // Row metadata referenced by index.\n rowMeta: Schema.Record({ key: Schema.String, value: RowColumnMeta }).pipe(FormInputAnnotation.set(false)),\n\n // Column metadata referenced by index.\n columnMeta: Schema.Record({ key: Schema.String, value: RowColumnMeta }).pipe(FormInputAnnotation.set(false)),\n\n // Cell formatting referenced by indexed range.\n ranges: Schema.Array(Range).pipe(FormInputAnnotation.set(false)),\n}).pipe(\n Annotation.IconAnnotation.set({ icon: 'ph--grid-nine--regular', hue: 'indigo' }),\n Type.makeObject(DXN.make('org.dxos.type.sheet', '0.1.0')),\n);\n\nexport type Sheet = Type.InstanceType<typeof Sheet>;\n\nexport type SheetProps = {\n name?: string;\n cells?: Record<string, CellValue>;\n} & Partial<SheetSize>;\n\nexport const make = ({ name, cells = {}, ...size }: SheetProps = {}) => {\n const sheet = Obj.make(Sheet, { name, cells: {}, rows: [], columns: [], rowMeta: {}, columnMeta: {}, ranges: [] });\n\n // Initialize and set cells within Obj.update to satisfy change context requirements.\n Obj.update(sheet, (sheet) => {\n initialize(sheet, size);\n\n if (cells) {\n Object.entries(cells).forEach(([key, { value }]) => {\n const idx = addressToIndex(sheet, addressFromA1Notation(key));\n if (isFormula(value)) {\n value = mapFormulaRefsToIndices(sheet, value);\n }\n\n sheet.cells[idx] = { value };\n });\n }\n });\n\n return sheet;\n};\n", "//\n// Copyright 2024 DXOS.org\n//\n\nimport {\n type CellAddress,\n type CellRange,\n type CompleteCellRange,\n addressFromA1Notation,\n addressToA1Notation,\n isFormula,\n} from '@dxos/compute-hyperformula';\nimport { randomBytes } from '@dxos/crypto';\nimport { type Obj } from '@dxos/echo';\nimport { assertArgument } from '@dxos/invariant';\n\nimport { type Sheet } from '../types';\n\nexport const MAX_ROWS = 500;\nexport const MAX_COLS = 676; // 26^2;\n\nexport const DEFAULT_ROWS = 50;\nexport const DEFAULT_COLS = 26;\n\n// TODO(burdon): Factor out from dxos/protocols to new common package.\nexport class ApiError extends Error {}\n\nexport class ReadonlyException extends ApiError {}\n\nexport class RangeException extends ApiError {\n constructor(n: number) {\n super();\n }\n}\n\n/**\n * With a string length of 8, the chance of a collision is 0.02% for a sheet with 10,000 strings.\n */\nexport const createIndex = (length = 8): string => {\n const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n const charactersLength = characters.length;\n const randomBuffer = randomBytes(length);\n return Array.from(randomBuffer, (byte) => characters[byte % charactersLength]).join('');\n};\n\nexport const createIndices = (length: number): string[] => Array.from({ length }).map(() => createIndex());\n\nexport const insertIndices = (indices: string[], i: number, n: number, max: number) => {\n if (i + n > max) {\n throw new RangeException(i + n);\n }\n\n const idx = createIndices(n);\n indices.splice(i, 0, ...idx);\n return idx;\n};\n\nexport const initialize = (\n sheet: Obj.Mutable<Sheet.Sheet>,\n { rows = DEFAULT_ROWS, columns = DEFAULT_COLS }: Partial<Sheet.SheetSize> = {},\n) => {\n if (!sheet.rows.length) {\n insertIndices(sheet.rows, 0, rows, MAX_ROWS);\n }\n if (!sheet.columns.length) {\n insertIndices(sheet.columns, 0, columns, MAX_COLS);\n }\n};\n\n/**\n * E.g., \"A1\" => \"CA2@CB3\".\n */\nexport const addressToIndex = (sheet: Sheet.Sheet, cell: CellAddress): string => {\n return `${sheet.columns[cell.col]}@${sheet.rows[cell.row]}`;\n};\n\n/**\n * E.g., \"CA2@CB3\" => \"A1\".\n */\nexport const addressFromIndex = (sheet: Sheet.Sheet, idx: string): CellAddress => {\n const [column, row] = idx.split('@');\n return {\n col: sheet.columns.indexOf(column),\n row: sheet.rows.indexOf(row),\n };\n};\n\n/**\n * E.g., \"A1:B2\" => \"CA2@CB3:CC4@CD5\".\n */\nexport const rangeToIndex = (sheet: Sheet.Sheet, range: CellRange): string => {\n return [range.from, range.to ?? range.from].map((cell) => addressToIndex(sheet, cell)).join(':');\n};\n\n/**\n * E.g., \"CA2@CB3:CC4@CD5\" => \"A1:B2\".\n */\nexport const rangeFromIndex = (sheet: Sheet.Sheet, idx: string): CompleteCellRange => {\n const [from, to] = idx.split(':').map((index) => addressFromIndex(sheet, index));\n return { from, to };\n};\n\n/**\n * Compares the positions of two cell indexes in a sheet.\n * Sorts primarily by row, then by column if rows are equal.\n */\nexport const compareIndexPositions = (sheet: Sheet.Sheet, indexA: string, indexB: string): number => {\n const { row: rowA, col: columnA } = addressFromIndex(sheet, indexA);\n const { row: rowB, col: columnB } = addressFromIndex(sheet, indexB);\n\n // Sort by row first, then by column.\n if (rowA !== rowB) {\n return rowA - rowB;\n } else {\n return columnA - columnB;\n }\n};\n\n// TODO(burdon): Tests.\n\n/**\n * Map from A1 notation to indices.\n */\nexport const mapFormulaRefsToIndices = (sheet: Sheet.Sheet, formula: string): string => {\n assertArgument(isFormula(formula), 'formula');\n return formula.replace(/([a-zA-Z]+)([0-9]+)/g, (match) => {\n return addressToIndex(sheet, addressFromA1Notation(match));\n });\n};\n\n/**\n * Map from indices to A1 notation.\n */\nexport const mapFormulaIndicesToRefs = (sheet: Sheet.Sheet, formula: string): string => {\n assertArgument(isFormula(formula), 'formula');\n return formula.replace(/([a-zA-Z0-9]+)@([a-zA-Z0-9]+)/g, (idx) => {\n return addressToA1Notation(addressFromIndex(sheet, idx));\n });\n};\n", "//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport { Capability } from '@dxos/app-framework';\nimport { type ComputeGraphRegistry as ComputeGraphRegistryType } from '@dxos/compute-hyperformula';\nimport { type DxGridElement, type GridContentProps } from '@dxos/react-ui-grid';\n\nimport { meta } from '#meta';\n\nexport type GridEntry = { grid: DxGridElement; setActiveRefs: (refs: GridContentProps['activeRefs']) => void };\n\nexport type GridRegistry = {\n register: (attendableId: string, grid: DxGridElement, setActiveRefs: GridEntry['setActiveRefs']) => void;\n unregister: (attendableId: string) => void;\n get: (attendableId: string) => GridEntry | undefined;\n};\n\nexport const ComputeGraphRegistry = Capability.make<ComputeGraphRegistryType>(\n `${meta.id}.capability.compute-graph-registry`,\n);\n\n/** Registry of active grid instances keyed by attendable ID. */\nexport const GridInstances = Capability.make<GridRegistry>(`${meta.id}.capability.grid-instances`);\n", "//\n// Copyright 2025 DXOS.org\n//\n\n// @import-as-namespace\n\nimport * as Schema from 'effect/Schema';\n\nimport { Capability } from '@dxos/app-framework';\nimport { Operation } from '@dxos/compute';\nimport { DXN } from '@dxos/keys';\n\nimport { meta } from '#meta';\n\nconst makeKey = (name: string) => DXN.make(`${meta.id}.operation.${name}`);\n\n// TODO(wittjosiah): Factor out. This is `DxGridAxis` from `@dxos/react-ui-grid`.\nconst Axis = Schema.Union(Schema.Literal('row'), Schema.Literal('col'));\n\nexport const InsertAxis = Operation.make({\n meta: { key: makeKey('axisInsert'), name: 'Insert Axis', icon: 'ph--plus--regular' },\n input: Schema.Struct({\n model: Schema.Any,\n axis: Axis,\n index: Schema.Number,\n count: Schema.optional(Schema.Number),\n }),\n output: Schema.Void,\n});\n\nexport const DropAxisOutput = Schema.Struct({\n axis: Axis.annotations({ description: 'The axis type (row or col).' }),\n axisIndex: Schema.String.annotations({ description: 'The dropped axis index.' }),\n index: Schema.Number.annotations({ description: 'The position the axis was at.' }),\n axisMeta: Schema.Any.annotations({ description: 'The row/column metadata.' }),\n values: Schema.Array(Schema.Any).annotations({ description: 'The cell values that were dropped.' }),\n});\n\nexport type DropAxisOutput = Schema.Schema.Type<typeof DropAxisOutput>;\n\nexport const DropAxis = Operation.make({\n meta: { key: makeKey('axisDrop'), name: 'Drop Axis', icon: 'ph--trash--regular' },\n input: Schema.Struct({\n model: Schema.Any,\n axis: Axis,\n axisIndex: Schema.String,\n }),\n output: DropAxisOutput,\n});\n\nexport const ScrollToAnchor = Operation.make({\n meta: {\n key: makeKey('scrollToAnchor'),\n name: 'Scroll To Anchor',\n icon: 'ph--anchor-simple--regular',\n },\n services: [Capability.Service],\n input: Schema.Struct({\n subject: Schema.String.annotations({ description: 'Attendable ID of the sheet.' }),\n cursor: Schema.String.annotations({ description: 'Cell range coordinates.' }),\n ref: Schema.optional(Schema.Any.annotations({ description: 'Active refs for highlighting.' })),\n }),\n output: Schema.Void,\n});\n\n/**\n * Restore a dropped axis (inverse of DropAxis).\n */\nexport const RestoreAxis = Operation.make({\n meta: {\n key: makeKey('restoreAxis'),\n name: 'Restore Axis',\n icon: 'ph--clock-counter-clockwise--regular',\n },\n input: Schema.Struct({\n model: Schema.Any.annotations({ description: 'The sheet model.' }),\n axis: Axis.annotations({ description: 'The axis type (row or col).' }),\n axisIndex: Schema.String.annotations({ description: 'The axis index to restore.' }),\n index: Schema.Number.annotations({ description: 'The position to restore at.' }),\n axisMeta: Schema.Any.annotations({ description: 'The row/column metadata.' }),\n values: Schema.Array(Schema.Any).annotations({ description: 'The cell values to restore.' }),\n }),\n output: Schema.Void,\n});\n"],
5
+ "mappings": "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",
6
+ "names": ["alignKey", "commentKey", "styleKey", "cellClassNameForRange", "key", "value", "undefined", "Schema", "Schema", "addressFromA1Notation", "isFormula", "DXN", "Annotation", "Obj", "Type", "FormInputAnnotation", "addressFromA1Notation", "addressToA1Notation", "isFormula", "randomBytes", "assertArgument", "MAX_ROWS", "MAX_COLS", "DEFAULT_ROWS", "DEFAULT_COLS", "ApiError", "Error", "ReadonlyException", "RangeException", "n", "createIndex", "length", "characters", "charactersLength", "randomBuffer", "Array", "from", "byte", "join", "createIndices", "map", "insertIndices", "indices", "i", "max", "idx", "splice", "initialize", "sheet", "rows", "columns", "addressToIndex", "cell", "col", "row", "addressFromIndex", "column", "split", "indexOf", "rangeToIndex", "range", "to", "rangeFromIndex", "index", "compareIndexPositions", "indexA", "indexB", "rowA", "columnA", "rowB", "columnB", "mapFormulaRefsToIndices", "formula", "replace", "match", "mapFormulaIndicesToRefs", "CellValue", "Struct", "value", "Any", "Range", "range", "String", "key", "RowColumnMeta", "size", "optional", "Number", "Sheet", "name", "cells", "Record", "pipe", "FormInputAnnotation", "set", "rows", "Array", "columns", "rowMeta", "columnMeta", "ranges", "Annotation", "IconAnnotation", "icon", "hue", "Type", "makeObject", "DXN", "make", "sheet", "Obj", "update", "initialize", "Object", "entries", "forEach", "idx", "addressToIndex", "addressFromA1Notation", "isFormula", "mapFormulaRefsToIndices", "ActionAxis", "Union", "Literal", "SheetAction", "RestoreAxis", "Struct", "axis", "axisIndex", "String", "index", "Number", "axisMeta", "RowColumnMeta", "values", "Array", "Any", "Capability", "meta", "ComputeGraphRegistry", "make", "id", "GridInstances", "Schema", "Capability", "Operation", "DXN", "meta", "makeKey", "name", "make", "id", "Axis", "Union", "Literal", "InsertAxis", "key", "icon", "input", "Struct", "model", "Any", "axis", "index", "Number", "count", "optional", "output", "Void", "DropAxisOutput", "annotations", "description", "axisIndex", "String", "axisMeta", "values", "Array", "DropAxis", "ScrollToAnchor", "services", "Service", "subject", "cursor", "ref", "RestoreAxis"]
7
+ }
@@ -0,0 +1,34 @@
1
+ // src/meta.ts
2
+ import { Plugin } from "@dxos/app-framework";
3
+ import { DXN } from "@dxos/keys";
4
+ import { trim } from "@dxos/util";
5
+ var meta = Plugin.makeMeta({
6
+ key: DXN.make("org.dxos.plugin.sheet"),
7
+ name: "Sheet",
8
+ author: "DXOS",
9
+ description: trim`
10
+ Full-featured spreadsheet for DXOS Composer backed by ECHO for local-first, real-time collaborative editing.
11
+ Cells, row/column metadata, and range-based formatting are all stored as ECHO objects and replicated to peers instantly.
12
+
13
+ Formula evaluation is powered by HyperFormula, providing over 400 built-in functions covering arithmetic, statistics,
14
+ text manipulation, date/time, financial, and logical operations. Formulas are stored with internal cell indices and
15
+ translated to A1-notation on display, keeping references stable across row and column insertions.
16
+
17
+ The plugin integrates with plugin-markdown to expose formula results inside document fenced code blocks, and
18
+ contributes anchor-navigation support so other plugins can scroll and highlight specific cell ranges by DXN reference.
19
+ AI agents can invoke sheet operations — insert/drop axes, scroll to anchor, and read or write cell values — through
20
+ the standard operations framework.
21
+ `,
22
+ icon: "ph--grid-nine--regular",
23
+ iconHue: "indigo",
24
+ source: "https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-sheet",
25
+ spec: "PLUGIN.mdl",
26
+ screenshots: [
27
+ "https://dxos.network/plugin-details-sheet-dark.png"
28
+ ]
29
+ });
30
+
31
+ export {
32
+ meta
33
+ };
34
+ //# sourceMappingURL=chunk-FQHTXKMF.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/meta.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport { Plugin } from '@dxos/app-framework';\nimport { DXN } from '@dxos/keys';\nimport { trim } from '@dxos/util';\n\nexport const meta = Plugin.makeMeta({\n key: DXN.make('org.dxos.plugin.sheet'),\n name: 'Sheet',\n author: 'DXOS',\n description: trim`\n Full-featured spreadsheet for DXOS Composer backed by ECHO for local-first, real-time collaborative editing.\n Cells, row/column metadata, and range-based formatting are all stored as ECHO objects and replicated to peers instantly.\n\n Formula evaluation is powered by HyperFormula, providing over 400 built-in functions covering arithmetic, statistics,\n text manipulation, date/time, financial, and logical operations. Formulas are stored with internal cell indices and\n translated to A1-notation on display, keeping references stable across row and column insertions.\n\n The plugin integrates with plugin-markdown to expose formula results inside document fenced code blocks, and\n contributes anchor-navigation support so other plugins can scroll and highlight specific cell ranges by DXN reference.\n AI agents can invoke sheet operations — insert/drop axes, scroll to anchor, and read or write cell values — through\n the standard operations framework.\n `,\n icon: 'ph--grid-nine--regular',\n iconHue: 'indigo',\n source: 'https://github.com/dxos/dxos/tree/main/packages/plugins/plugin-sheet',\n spec: 'PLUGIN.mdl',\n screenshots: ['https://dxos.network/plugin-details-sheet-dark.png'],\n});\n"],
5
+ "mappings": ";AAIA,SAASA,cAAc;AACvB,SAASC,WAAW;AACpB,SAASC,YAAY;AAEd,IAAMC,OAAOH,OAAOI,SAAS;EAClCC,KAAKJ,IAAIK,KAAK,uBAAA;EACdC,MAAM;EACNC,QAAQ;EACRC,aAAaP;;;;;;;;;;;;;EAabQ,MAAM;EACNC,SAAS;EACTC,QAAQ;EACRC,MAAM;EACNC,aAAa;IAAC;;AAChB,CAAA;",
6
+ "names": ["Plugin", "DXN", "trim", "meta", "makeMeta", "key", "make", "name", "author", "description", "icon", "iconHue", "source", "spec", "screenshots"]
7
+ }
@@ -4,11 +4,12 @@ import "./chunk-J5LGTIGS.mjs";
4
4
  import * as Effect from "effect/Effect";
5
5
  import { Capability } from "@dxos/app-framework";
6
6
  import { AppCapabilities } from "@dxos/app-toolkit";
7
+ import { Type } from "@dxos/echo";
7
8
  import { SheetOperation } from "#types";
8
9
  import { Sheet } from "#types";
9
10
  var comment_config_default = Capability.makeModule(Effect.fnUntraced(function* () {
10
11
  const config = {
11
- id: Sheet.Sheet.typename,
12
+ id: Type.getTypename(Sheet.Sheet),
12
13
  comments: "anchored",
13
14
  scrollToAnchor: SheetOperation.ScrollToAnchor
14
15
  };
@@ -17,4 +18,4 @@ var comment_config_default = Capability.makeModule(Effect.fnUntraced(function* (
17
18
  export {
18
19
  comment_config_default as default
19
20
  };
20
- //# sourceMappingURL=comment-config-ZBWNCJMZ.mjs.map
21
+ //# sourceMappingURL=comment-config-6JAROASH.mjs.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../../src/capabilities/comment-config.ts"],
4
+ "sourcesContent": ["//\n// Copyright 2023 DXOS.org\n//\n\nimport * as Effect from 'effect/Effect';\n\nimport { Capability } from '@dxos/app-framework';\nimport { AppCapabilities } from '@dxos/app-toolkit';\n// eslint-disable-next-line unused-imports/no-unused-imports\nimport type { Operation } from '@dxos/compute';\nimport { Type } from '@dxos/echo';\n\nimport { SheetOperation } from '#types';\nimport { Sheet } from '#types';\n\nexport default Capability.makeModule(\n Effect.fnUntraced(function* () {\n const config: AppCapabilities.CommentConfig = {\n id: Type.getTypename(Sheet.Sheet),\n comments: 'anchored',\n scrollToAnchor: SheetOperation.ScrollToAnchor,\n };\n return Capability.contributes(AppCapabilities.CommentConfig, config);\n }),\n);\n"],
5
+ "mappings": ";;;AAIA,YAAYA,YAAY;AAExB,SAASC,kBAAkB;AAC3B,SAASC,uBAAuB;AAGhC,SAASC,YAAY;AAErB,SAASC,sBAAsB;AAC/B,SAASC,aAAa;AAEtB,IAAA,yBAAeJ,WAAWK,WACjBC,kBAAW,aAAA;AAChB,QAAMC,SAAwC;IAC5CC,IAAIN,KAAKO,YAAYL,MAAMA,KAAK;IAChCM,UAAU;IACVC,gBAAgBR,eAAeS;EACjC;AACA,SAAOZ,WAAWa,YAAYZ,gBAAgBa,eAAeP,MAAAA;AAC/D,CAAA,CAAA;",
6
+ "names": ["Effect", "Capability", "AppCapabilities", "Type", "SheetOperation", "Sheet", "makeModule", "fnUntraced", "config", "id", "getTypename", "comments", "scrollToAnchor", "ScrollToAnchor", "contributes", "CommentConfig"]
7
+ }
@@ -1,10 +1,10 @@
1
+ import {
2
+ useSelectThreadOnCellFocus
3
+ } from "../chunk-3AIMSE7U.mjs";
1
4
  import {
2
5
  rangeExtension,
3
6
  sheetExtension
4
- } from "../chunk-4SBAIU6F.mjs";
5
- import {
6
- useSelectThreadOnCellFocus
7
- } from "../chunk-4GWJDLTH.mjs";
7
+ } from "../chunk-ERHMBRSU.mjs";
8
8
  import "../chunk-J5LGTIGS.mjs";
9
9
 
10
10
  // src/components/ComputeGraph/ComputeGraphContextProvider.tsx
@@ -41,9 +41,9 @@ import { rangeToA1Notation } from "@dxos/compute-hyperformula";
41
41
  import { Obj as Obj2 } from "@dxos/echo";
42
42
  import { defaultColSize, defaultRowSize } from "@dxos/lit-grid";
43
43
  import { DropdownMenu, Icon, useTranslation } from "@dxos/react-ui";
44
+ import { composable, composableProps } from "@dxos/react-ui";
44
45
  import { useAttention } from "@dxos/react-ui-attention";
45
46
  import { Grid as Grid2, GridCellEditor, closestCell, editorKeys, parseCellIndex } from "@dxos/react-ui-grid";
46
- import { composable, composableProps } from "@dxos/ui-theme";
47
47
  import { meta } from "#meta";
48
48
  import { SheetOperation } from "#types";
49
49
  import { DEFAULT_COLS, DEFAULT_ROWS, SheetCapabilities } from "#types";
@@ -59,7 +59,7 @@ import { DetailedCellError, ExportedCellChange, addressFromA1Notation, addressTo
59
59
  import { Resource } from "@dxos/context";
60
60
  import { Obj } from "@dxos/echo";
61
61
  import { Format, TypeEnum } from "@dxos/echo/internal";
62
- import { invariant } from "@dxos/invariant";
62
+ import { assertArgument, invariant } from "@dxos/invariant";
63
63
  import { PublicKey } from "@dxos/keys";
64
64
  import { log } from "@dxos/log";
65
65
  import { MAX_COLS, MAX_ROWS, ReadonlyException, addressFromIndex, addressToIndex, initialize, insertIndices, mapFormulaIndicesToRefs, mapFormulaRefsToIndices } from "#types";
@@ -500,7 +500,7 @@ var SheetModel = class extends Resource {
500
500
  * Map from indices to A1 notation.
501
501
  */
502
502
  mapFormulaIndicesToRefs(formula) {
503
- invariant(isFormula(formula), void 0, { "~LogMeta": "~LogMeta", F: __dxlog_file, L: 458, S: this, A: ["isFormula(formula)", ""] });
503
+ assertArgument(isFormula(formula), "formula");
504
504
  return formula.replace(/([a-zA-Z0-9]+)@([a-zA-Z0-9]+)/g, (idx) => {
505
505
  return addressToA1Notation(addressFromIndex(this._sheet, idx));
506
506
  });
@@ -1171,7 +1171,8 @@ var SheetContent = composable((props, forwardedRef) => {
1171
1171
  import React4 from "react";
1172
1172
  import { addressToA1Notation as addressToA1Notation2, isFormula as isFormula2, rangeToA1Notation as rangeToA1Notation2 } from "@dxos/compute-hyperformula";
1173
1173
  import { Icon as Icon2 } from "@dxos/react-ui";
1174
- import { composable as composable2, composableProps as composableProps2, mx as mx2 } from "@dxos/ui-theme";
1174
+ import { composable as composable2, composableProps as composableProps2 } from "@dxos/react-ui";
1175
+ import { mx as mx2 } from "@dxos/ui-theme";
1175
1176
  import { mapFormulaIndicesToRefs as mapFormulaIndicesToRefs2 } from "#types";
1176
1177
  var SheetStatusbar = composable2((props, forwardedRef) => {
1177
1178
  const { className, ...rest } = composableProps2(props);
@@ -1212,8 +1213,8 @@ var SheetStatusbar = composable2((props, forwardedRef) => {
1212
1213
  import { Atom as Atom2, RegistryContext as RegistryContext4 } from "@effect-atom/atom-react";
1213
1214
  import React5, { useContext as useContext6, useMemo as useMemo3 } from "react";
1214
1215
  import { useAppGraph } from "@dxos/app-toolkit/ui";
1216
+ import { composable as composable3, composableProps as composableProps3 } from "@dxos/react-ui";
1215
1217
  import { Menu, createGapSeparator, useMenuActions } from "@dxos/react-ui-menu";
1216
- import { composable as composable3, composableProps as composableProps3 } from "@dxos/ui-theme";
1217
1218
 
1218
1219
  // src/components/SheetToolbar/align.ts
1219
1220
  import { RegistryContext } from "@effect-atom/atom-react";