@yuzhouu/canvas-kit 0.1.2

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 (263) hide show
  1. package/README.md +145 -0
  2. package/_vendor/canvas-core/bindings/BindingUtil.ts +92 -0
  3. package/_vendor/canvas-core/bindings/BindingUtilRegistry.ts +22 -0
  4. package/_vendor/canvas-core/bindings/arrow/arrowBindingHelpers.ts +52 -0
  5. package/_vendor/canvas-core/contextMenu.ts +85 -0
  6. package/_vendor/canvas-core/editor/Editor.ts +2614 -0
  7. package/_vendor/canvas-core/editor/HistoryManager.ts +83 -0
  8. package/_vendor/canvas-core/editor/StateNode.ts +162 -0
  9. package/_vendor/canvas-core/editor/camera.ts +6 -0
  10. package/_vendor/canvas-core/editor/clipboard.ts +478 -0
  11. package/_vendor/canvas-core/editor/commands.ts +833 -0
  12. package/_vendor/canvas-core/editor/edgeScroll.ts +37 -0
  13. package/_vendor/canvas-core/editor/editorComputedHelpers.ts +257 -0
  14. package/_vendor/canvas-core/editor/editorSelectionTransforms.ts +116 -0
  15. package/_vendor/canvas-core/editor/events.ts +93 -0
  16. package/_vendor/canvas-core/editor/index.ts +12 -0
  17. package/_vendor/canvas-core/editor/interactions.ts +101 -0
  18. package/_vendor/canvas-core/editor/internal.ts +22 -0
  19. package/_vendor/canvas-core/editor/managers/BindingManager.ts +262 -0
  20. package/_vendor/canvas-core/editor/managers/CameraManager.ts +147 -0
  21. package/_vendor/canvas-core/editor/managers/ClipboardManager.ts +32 -0
  22. package/_vendor/canvas-core/editor/managers/DocumentSnapshotManager.ts +256 -0
  23. package/_vendor/canvas-core/editor/managers/InputsManager.ts +319 -0
  24. package/_vendor/canvas-core/editor/managers/InteractionTransientManager.ts +218 -0
  25. package/_vendor/canvas-core/editor/managers/QueryManager.ts +837 -0
  26. package/_vendor/canvas-core/editor/managers/RenderWindowManager.ts +347 -0
  27. package/_vendor/canvas-core/editor/managers/SelectionLayoutManager.ts +196 -0
  28. package/_vendor/canvas-core/editor/managers/SelectionManager.ts +98 -0
  29. package/_vendor/canvas-core/editor/managers/SelectionOverlayManager.ts +308 -0
  30. package/_vendor/canvas-core/editor/managers/ShapeEditingManager.ts +226 -0
  31. package/_vendor/canvas-core/editor/managers/ShapeGeometryManager.ts +162 -0
  32. package/_vendor/canvas-core/editor/managers/ShapeHierarchyManager.ts +797 -0
  33. package/_vendor/canvas-core/editor/managers/SideEffectManager.ts +83 -0
  34. package/_vendor/canvas-core/editor/managers/SnapManager.ts +433 -0
  35. package/_vendor/canvas-core/editor/managers/SnapSnapshotBuilder.ts +430 -0
  36. package/_vendor/canvas-core/editor/managers/SpatialIndexManager.ts +354 -0
  37. package/_vendor/canvas-core/editor/managers/ToolManager.ts +81 -0
  38. package/_vendor/canvas-core/editor/managers/queryState.ts +583 -0
  39. package/_vendor/canvas-core/editor/managers/selectionGeometry.ts +287 -0
  40. package/_vendor/canvas-core/editor/managers/shapeOrder.ts +350 -0
  41. package/_vendor/canvas-core/editor/managers/shapeReparenting.ts +160 -0
  42. package/_vendor/canvas-core/editor/managers/snapCalculations.ts +412 -0
  43. package/_vendor/canvas-core/editor/managers/snapGeometry.ts +202 -0
  44. package/_vendor/canvas-core/editor/managers/snapIndicators.ts +403 -0
  45. package/_vendor/canvas-core/editor/managers/snapTypes.ts +122 -0
  46. package/_vendor/canvas-core/editor/queries/shapeTransforms.ts +171 -0
  47. package/_vendor/canvas-core/editor/renderWindow.ts +439 -0
  48. package/_vendor/canvas-core/editor/resizeGeometry.ts +654 -0
  49. package/_vendor/canvas-core/editor/selection.ts +489 -0
  50. package/_vendor/canvas-core/editor/selectionHandleInteractions.ts +43 -0
  51. package/_vendor/canvas-core/editor/selectionOverlay.ts +567 -0
  52. package/_vendor/canvas-core/exports/integrity.ts +174 -0
  53. package/_vendor/canvas-core/exports/svg.ts +494 -0
  54. package/_vendor/canvas-core/geometry/Box.ts +80 -0
  55. package/_vendor/canvas-core/geometry/Ellipse2d.ts +67 -0
  56. package/_vendor/canvas-core/geometry/Geometry2d.ts +52 -0
  57. package/_vendor/canvas-core/geometry/Mat.ts +92 -0
  58. package/_vendor/canvas-core/geometry/Polyline2d.ts +63 -0
  59. package/_vendor/canvas-core/geometry/Rectangle2d.ts +64 -0
  60. package/_vendor/canvas-core/geometry/Vec.ts +123 -0
  61. package/_vendor/canvas-core/geometry/index.ts +13 -0
  62. package/_vendor/canvas-core/geometry/segments.ts +65 -0
  63. package/_vendor/canvas-core/index.ts +391 -0
  64. package/_vendor/canvas-core/plugins/index.ts +5 -0
  65. package/_vendor/canvas-core/plugins/types.ts +53 -0
  66. package/_vendor/canvas-core/reactivity.ts +16 -0
  67. package/_vendor/canvas-core/schema/records.ts +221 -0
  68. package/_vendor/canvas-core/schema/snapshots.ts +527 -0
  69. package/_vendor/canvas-core/shapes/ShapeUtil.ts +516 -0
  70. package/_vendor/canvas-core/shapes/ShapeUtilRegistry.ts +26 -0
  71. package/_vendor/canvas-core/shapes/capabilities.ts +67 -0
  72. package/_vendor/canvas-core/shapes/types.ts +20 -0
  73. package/_vendor/canvas-core/toolbar.ts +148 -0
  74. package/_vendor/canvas-core/tools/hand/HandTool.ts +75 -0
  75. package/_vendor/canvas-core/tools/index.ts +2 -0
  76. package/_vendor/canvas-core/tools/select/SelectTool.ts +33 -0
  77. package/_vendor/canvas-core/tools/select/selectContainment.ts +104 -0
  78. package/_vendor/canvas-core/tools/select/selectToolHelpers.ts +801 -0
  79. package/_vendor/canvas-core/tools/select/states/BrushingState.ts +145 -0
  80. package/_vendor/canvas-core/tools/select/states/DraggingSelectionHandleInteractionState.ts +116 -0
  81. package/_vendor/canvas-core/tools/select/states/IdleState.ts +159 -0
  82. package/_vendor/canvas-core/tools/select/states/PointingCanvasState.ts +41 -0
  83. package/_vendor/canvas-core/tools/select/states/PointingResizeHandleState.ts +78 -0
  84. package/_vendor/canvas-core/tools/select/states/PointingRotateHandleState.ts +64 -0
  85. package/_vendor/canvas-core/tools/select/states/PointingSelectionHandleInteractionState.ts +34 -0
  86. package/_vendor/canvas-core/tools/select/states/PointingShapeState.ts +140 -0
  87. package/_vendor/canvas-core/tools/select/states/ResizingState.ts +171 -0
  88. package/_vendor/canvas-core/tools/select/states/RotatingState.ts +124 -0
  89. package/_vendor/canvas-core/tools/select/states/SelectStateNode.ts +128 -0
  90. package/_vendor/canvas-core/tools/select/states/TranslatingState.ts +139 -0
  91. package/_vendor/canvas-core/tools/select/states/index.ts +11 -0
  92. package/_vendor/canvas-plugin-api/feature.ts +204 -0
  93. package/_vendor/canvas-plugin-api/index.ts +142 -0
  94. package/_vendor/canvas-product-react/api/apiRegistry.ts +35 -0
  95. package/_vendor/canvas-product-react/api/canvasProductApi.ts +422 -0
  96. package/_vendor/canvas-product-react/api/index.ts +31 -0
  97. package/_vendor/canvas-product-react/capabilities/clipboard/clipboardService.ts +36 -0
  98. package/_vendor/canvas-product-react/capabilities/clipboard/systemClipboard.ts +245 -0
  99. package/_vendor/canvas-product-react/capabilities/context-menu/systemContextMenu.ts +396 -0
  100. package/_vendor/canvas-product-react/capabilities/context-menu/useContextMenuSurface.ts +59 -0
  101. package/_vendor/canvas-product-react/capabilities/export/useSvgExport.ts +156 -0
  102. package/_vendor/canvas-product-react/capabilities/history/useHistoryControls.ts +23 -0
  103. package/_vendor/canvas-product-react/capabilities/pages/usePageControls.ts +41 -0
  104. package/_vendor/canvas-product-react/capabilities/toolbar/systemToolbar.ts +490 -0
  105. package/_vendor/canvas-product-react/capabilities/toolbar/useToolbarSurfaces.ts +92 -0
  106. package/_vendor/canvas-product-react/capabilities/zoom/useZoomControls.ts +27 -0
  107. package/_vendor/canvas-product-react/index.ts +84 -0
  108. package/_vendor/canvas-product-react/persistence/index.ts +18 -0
  109. package/_vendor/canvas-product-react/persistence/localSnapshotPersistence.ts +294 -0
  110. package/_vendor/canvas-product-react/runtime/CanvasProductRoot.tsx +250 -0
  111. package/_vendor/canvas-product-react/runtime/productDefinition.ts +72 -0
  112. package/_vendor/canvas-product-react/runtime/productServices.ts +96 -0
  113. package/_vendor/canvas-react/components/CanvasView.tsx +796 -0
  114. package/_vendor/canvas-react/components/OverlayLayer.tsx +879 -0
  115. package/_vendor/canvas-react/components/PageSpace.tsx +34 -0
  116. package/_vendor/canvas-react/components/ShapeLayer.tsx +428 -0
  117. package/_vendor/canvas-react/components/index.ts +4 -0
  118. package/_vendor/canvas-react/hooks/useEditor.ts +11 -0
  119. package/_vendor/canvas-react/hooks/useValue.ts +14 -0
  120. package/_vendor/canvas-react/host/CanvasRendererRegistryContext.tsx +14 -0
  121. package/_vendor/canvas-react/host/contextMenuRegistry.ts +61 -0
  122. package/_vendor/canvas-react/host/domEventGuards.ts +61 -0
  123. package/_vendor/canvas-react/host/index.ts +38 -0
  124. package/_vendor/canvas-react/host/pluginHost.ts +635 -0
  125. package/_vendor/canvas-react/host/rendererRegistry.tsx +58 -0
  126. package/_vendor/canvas-react/host/toolbarRegistry.ts +100 -0
  127. package/_vendor/canvas-react/index.ts +3 -0
  128. package/_vendor/plugin-arrow/ArrowBindingUtil.ts +239 -0
  129. package/_vendor/plugin-arrow/ArrowShapeUtil.ts +311 -0
  130. package/_vendor/plugin-arrow/ArrowTool.ts +208 -0
  131. package/_vendor/plugin-arrow/arrowGeometry.ts +441 -0
  132. package/_vendor/plugin-arrow/arrowTerminalBindingResolver.ts +253 -0
  133. package/_vendor/plugin-arrow/arrowTerminalCommands.ts +230 -0
  134. package/_vendor/plugin-arrow/canvas.tsx +92 -0
  135. package/_vendor/plugin-arrow/core.ts +409 -0
  136. package/_vendor/plugin-arrow/feature.ts +20 -0
  137. package/_vendor/plugin-arrow/index.ts +28 -0
  138. package/_vendor/plugin-arrow/selectionHandleInteractions.ts +154 -0
  139. package/_vendor/plugin-arrow/types.ts +63 -0
  140. package/_vendor/plugin-draw/DrawShapeRenderer.tsx +60 -0
  141. package/_vendor/plugin-draw/DrawShapeUtil.ts +372 -0
  142. package/_vendor/plugin-draw/DrawTool.ts +444 -0
  143. package/_vendor/plugin-draw/canvas.tsx +24 -0
  144. package/_vendor/plugin-draw/core.ts +515 -0
  145. package/_vendor/plugin-draw/drawGeometry.ts +491 -0
  146. package/_vendor/plugin-draw/drawHitTest.ts +271 -0
  147. package/_vendor/plugin-draw/drawInterpolation.ts +250 -0
  148. package/_vendor/plugin-draw/drawPath.ts +550 -0
  149. package/_vendor/plugin-draw/drawSegments.ts +106 -0
  150. package/_vendor/plugin-draw/drawSelectionTransform.ts +67 -0
  151. package/_vendor/plugin-draw/drawShapeGeometry.ts +307 -0
  152. package/_vendor/plugin-draw/drawStrokeGeometry.ts +454 -0
  153. package/_vendor/plugin-draw/feature.ts +20 -0
  154. package/_vendor/plugin-draw/index.ts +31 -0
  155. package/_vendor/plugin-draw/types.ts +36 -0
  156. package/_vendor/plugin-eraser/EraserTool.ts +297 -0
  157. package/_vendor/plugin-eraser/canvas.tsx +616 -0
  158. package/_vendor/plugin-eraser/core.ts +49 -0
  159. package/_vendor/plugin-eraser/feature.ts +20 -0
  160. package/_vendor/plugin-eraser/index.ts +4 -0
  161. package/_vendor/plugin-frame/FrameShapeUtil.ts +173 -0
  162. package/_vendor/plugin-frame/FrameTool.ts +225 -0
  163. package/_vendor/plugin-frame/canvas.tsx +75 -0
  164. package/_vendor/plugin-frame/core.ts +534 -0
  165. package/_vendor/plugin-frame/feature.ts +20 -0
  166. package/_vendor/plugin-frame/index.ts +6 -0
  167. package/_vendor/plugin-geo/GeoShapeUtil.ts +463 -0
  168. package/_vendor/plugin-geo/GeoTools.ts +247 -0
  169. package/_vendor/plugin-geo/canvas.tsx +90 -0
  170. package/_vendor/plugin-geo/core.ts +495 -0
  171. package/_vendor/plugin-geo/feature.ts +20 -0
  172. package/_vendor/plugin-geo/index.ts +7 -0
  173. package/_vendor/plugin-geo/types.ts +27 -0
  174. package/_vendor/plugin-group/GroupShapeUtil.ts +59 -0
  175. package/_vendor/plugin-group/canvas.tsx +59 -0
  176. package/_vendor/plugin-group/core.ts +40 -0
  177. package/_vendor/plugin-group/feature.ts +20 -0
  178. package/_vendor/plugin-group/index.ts +5 -0
  179. package/_vendor/plugin-image/ImageShapeUtil.ts +95 -0
  180. package/_vendor/plugin-image/canvas.tsx +212 -0
  181. package/_vendor/plugin-image/core.ts +542 -0
  182. package/_vendor/plugin-image/crop.ts +770 -0
  183. package/_vendor/plugin-image/cropInteractions.ts +350 -0
  184. package/_vendor/plugin-image/cropSession.ts +38 -0
  185. package/_vendor/plugin-image/feature.ts +20 -0
  186. package/_vendor/plugin-image/index.ts +29 -0
  187. package/_vendor/plugin-image/types.ts +55 -0
  188. package/_vendor/plugin-image-product-react/ImageImportController.tsx +143 -0
  189. package/_vendor/plugin-image-product-react/imageAssetService.ts +52 -0
  190. package/_vendor/plugin-image-product-react/imageBlobStore.ts +315 -0
  191. package/_vendor/plugin-image-product-react/imageHostActions.ts +438 -0
  192. package/_vendor/plugin-image-product-react/imageProductApi.ts +88 -0
  193. package/_vendor/plugin-image-product-react/imageToolbarHostBridge.ts +48 -0
  194. package/_vendor/plugin-image-product-react/imageToolbarRuntime.ts +21 -0
  195. package/_vendor/plugin-image-product-react/index.ts +60 -0
  196. package/_vendor/plugin-image-product-react/snapshotGuards.ts +33 -0
  197. package/_vendor/plugin-image-product-react/svgImageAssetInliner.ts +54 -0
  198. package/_vendor/plugin-image-product-react/useImageImport.ts +64 -0
  199. package/_vendor/plugin-laser/LaserTool.ts +154 -0
  200. package/_vendor/plugin-laser/canvas.tsx +645 -0
  201. package/_vendor/plugin-laser/core.ts +49 -0
  202. package/_vendor/plugin-laser/feature.ts +20 -0
  203. package/_vendor/plugin-laser/index.ts +4 -0
  204. package/_vendor/plugin-text/ArrowLabelBindingUtil.ts +336 -0
  205. package/_vendor/plugin-text/GeoLabelBindingUtil.ts +391 -0
  206. package/_vendor/plugin-text/TextShapeSvgExporter.ts +101 -0
  207. package/_vendor/plugin-text/TextShapeUtil.ts +284 -0
  208. package/_vendor/plugin-text/TextTool.ts +228 -0
  209. package/_vendor/plugin-text/canvas.tsx +115 -0
  210. package/_vendor/plugin-text/core.ts +422 -0
  211. package/_vendor/plugin-text/feature.ts +20 -0
  212. package/_vendor/plugin-text/host/RichTextEditingBox.tsx +144 -0
  213. package/_vendor/plugin-text/host/RichTextToolbar.tsx +266 -0
  214. package/_vendor/plugin-text/host/TiptapTextEditor.tsx +191 -0
  215. package/_vendor/plugin-text/host/richTextRendering.tsx +49 -0
  216. package/_vendor/plugin-text/host/textDomSelection.ts +93 -0
  217. package/_vendor/plugin-text/host/textEditingBoxStyle.ts +36 -0
  218. package/_vendor/plugin-text/host/textEntryFocus.ts +307 -0
  219. package/_vendor/plugin-text/host/textFontLoader.ts +149 -0
  220. package/_vendor/plugin-text/host/textMeasurement.ts +258 -0
  221. package/_vendor/plugin-text/host/textMeasurementSync.ts +77 -0
  222. package/_vendor/plugin-text/host/textRangeSelection.ts +134 -0
  223. package/_vendor/plugin-text/host/textShapeRendererRuntime.tsx +89 -0
  224. package/_vendor/plugin-text/host/textShapeSync.ts +173 -0
  225. package/_vendor/plugin-text/host/tiptapTextEditorController.ts +148 -0
  226. package/_vendor/plugin-text/index.ts +18 -0
  227. package/_vendor/plugin-text/richTextUtils.ts +259 -0
  228. package/_vendor/plugin-text/textInteractions.ts +366 -0
  229. package/_vendor/plugin-text/textLabelHelpers.ts +235 -0
  230. package/_vendor/plugin-text/textShapeHelpers.ts +123 -0
  231. package/_vendor/plugin-text/textStyle.ts +96 -0
  232. package/_vendor/plugin-text/textTypes.ts +48 -0
  233. package/_vendor/signals/atom.ts +74 -0
  234. package/_vendor/signals/computed.ts +132 -0
  235. package/_vendor/signals/core.ts +130 -0
  236. package/_vendor/signals/effect.ts +117 -0
  237. package/_vendor/signals/index.ts +9 -0
  238. package/_vendor/signals/types.ts +17 -0
  239. package/_vendor/store/Store.ts +171 -0
  240. package/_vendor/store/diff.ts +229 -0
  241. package/_vendor/store/history.ts +177 -0
  242. package/_vendor/store/index.ts +32 -0
  243. package/_vendor/store/types.ts +37 -0
  244. package/api/canvasKitApi.d.ts +29 -0
  245. package/index.css +3 -0
  246. package/index.d.ts +16 -0
  247. package/index.mjs +1 -0
  248. package/internal-modules.d.ts +187 -0
  249. package/package.json +48 -0
  250. package/product/Shell.d.ts +19 -0
  251. package/product/chromeContext.d.ts +70 -0
  252. package/product/createCanvasKitEditor.d.ts +6 -0
  253. package/product/index.d.ts +7 -0
  254. package/product/persistence.d.ts +3 -0
  255. package/product/product.d.ts +22 -0
  256. package/product/useCanvasClipboardShortcuts.d.ts +6 -0
  257. package/product-iyBbEPIs.mjs +4 -0
  258. package/product.mjs +1 -0
  259. package/standard/extensions.d.ts +1 -0
  260. package/standard/index.d.ts +3 -0
  261. package/standard/standardApi.d.ts +91 -0
  262. package/standard-BmrxwqpJ.mjs +44 -0
  263. package/standard.mjs +1 -0
@@ -0,0 +1,635 @@
1
+ import {
2
+ SET_ACTIVE_TOOL_TOOLBAR_ACTION_ID,
3
+ TOGGLE_TOOL_LOCKED_TOOLBAR_ACTION_ID,
4
+ ShapeCapabilitySupport,
5
+ } from "@land/canvas-core";
6
+ import {
7
+ resolveLandExtensions,
8
+ type CanvasPluginComponent,
9
+ type CanvasPluginProvider,
10
+ type LandExtension,
11
+ type LandFeatureBundle,
12
+ type LandCanvasPlugin,
13
+ } from "@land/canvas-plugin-api";
14
+ import type { LandCorePlugin } from "@land/canvas-core";
15
+ import {
16
+ createCanvasRendererRegistry,
17
+ type CanvasRendererRegistry,
18
+ } from "./rendererRegistry";
19
+ import {
20
+ createCanvasDomEventGuardRegistry,
21
+ type CanvasDomEventGuardRegistry,
22
+ } from "./domEventGuards";
23
+ import {
24
+ createCanvasToolbarRegistry,
25
+ type CanvasToolbarRegistry,
26
+ } from "./toolbarRegistry";
27
+ import {
28
+ createCanvasContextMenuRegistry,
29
+ type CanvasContextMenuRegistry,
30
+ } from "./contextMenuRegistry";
31
+
32
+ const HOST_TOOLBAR_ACTION_IDS = [
33
+ SET_ACTIVE_TOOL_TOOLBAR_ACTION_ID,
34
+ TOGGLE_TOOL_LOCKED_TOOLBAR_ACTION_ID,
35
+ "system.clipboard.copy",
36
+ "system.clipboard.cut",
37
+ "system.clipboard.paste",
38
+ "system.clipboard.paste-at-point",
39
+ "system.selection.duplicate",
40
+ "system.selection.select-all",
41
+ ];
42
+
43
+ export type CanvasPluginHostSource = "built-in" | "dev-sample";
44
+ export type CanvasPluginHostVerdict = "pass" | "fail";
45
+
46
+ export interface CreateCanvasPluginHostRuntimeOptions {
47
+ source?: CanvasPluginHostSource;
48
+ }
49
+
50
+ export interface CanvasPluginHostManifestEntry {
51
+ id: string;
52
+ extensionName: string;
53
+ source: CanvasPluginHostSource;
54
+ corePluginIds: string[];
55
+ canvasPluginIds: string[];
56
+ interactionHandlerIds: string[];
57
+ toolbarActionIds: string[];
58
+ toolbarContributionIds: string[];
59
+ toolbarContributions: CanvasPluginHostManifestToolbarContributionEntry[];
60
+ contextMenuContributionIds: string[];
61
+ contextMenuContributions: CanvasPluginHostManifestContextMenuContributionEntry[];
62
+ domEventGuardIds: string[];
63
+ canvasProviderIds: string[];
64
+ canvasComponentIds: string[];
65
+ shapeTypes: string[];
66
+ }
67
+
68
+ export interface CanvasPluginHostManifestToolbarContributionEntry {
69
+ id: string;
70
+ surface: string;
71
+ placement: string;
72
+ actionIds: string[];
73
+ }
74
+
75
+ export interface CanvasPluginHostManifestContextMenuContributionEntry {
76
+ id: string;
77
+ target: string;
78
+ actionIds: string[];
79
+ }
80
+
81
+ export interface CanvasPluginHostRuntime {
82
+ corePlugins: LandCorePlugin[];
83
+ canvasPlugins: LandCanvasPlugin[];
84
+ canvasProviders: CanvasPluginProvider[];
85
+ canvasComponents: CanvasPluginComponent[];
86
+ rendererRegistry: CanvasRendererRegistry;
87
+ domEventGuardRegistry: CanvasDomEventGuardRegistry;
88
+ toolbarRegistry: CanvasToolbarRegistry;
89
+ contextMenuRegistry: CanvasContextMenuRegistry;
90
+ manifest: CanvasPluginHostManifestEntry[];
91
+ validation: CanvasPluginHostValidationSummary;
92
+ externalPluginIds: string[];
93
+ ignoreStoredSnapshots: boolean;
94
+ disablePersistence: boolean;
95
+ }
96
+
97
+ export type CanvasPluginHostValidationIssueSeverity = "error" | "warning";
98
+
99
+ export interface CanvasPluginHostValidationIssue {
100
+ severity: CanvasPluginHostValidationIssueSeverity;
101
+ code:
102
+ | "duplicate-feature-id"
103
+ | "duplicate-core-plugin-id"
104
+ | "duplicate-canvas-plugin-id"
105
+ | "duplicate-interaction-handler-id"
106
+ | "duplicate-toolbar-action-id"
107
+ | "duplicate-toolbar-contribution-id"
108
+ | "duplicate-context-menu-contribution-id"
109
+ | "duplicate-dom-event-guard-id"
110
+ | "duplicate-canvas-provider-id"
111
+ | "duplicate-canvas-component-id"
112
+ | "missing-toolbar-action"
113
+ | "missing-context-menu-action"
114
+ | "missing-core-plugin"
115
+ | "missing-canvas-plugin"
116
+ | "missing-shape-type"
117
+ | "missing-shape-capability"
118
+ | "missing-shape-util"
119
+ | "missing-svg-exporter"
120
+ | "missing-canvas-renderer";
121
+ featureId: string | null;
122
+ pluginId: string | null;
123
+ shapeType: string | null;
124
+ message: string;
125
+ }
126
+
127
+ export interface CanvasPluginHostShapeValidationSummary {
128
+ featureId: string;
129
+ shapeType: string;
130
+ hasCapability: boolean;
131
+ hasShapeUtil: boolean;
132
+ hasSvgExporter: boolean;
133
+ hasCanvasRenderer: boolean;
134
+ exportSupport: ShapeCapabilitySupport | null;
135
+ }
136
+
137
+ export interface CanvasPluginHostValidationSummary {
138
+ verdict: CanvasPluginHostVerdict;
139
+ issueCount: number;
140
+ errorCount: number;
141
+ warningCount: number;
142
+ issues: CanvasPluginHostValidationIssue[];
143
+ featureIds: string[];
144
+ corePluginIds: string[];
145
+ canvasPluginIds: string[];
146
+ interactionHandlerIds: string[];
147
+ toolbarActionIds: string[];
148
+ toolbarContributionIds: string[];
149
+ contextMenuContributionIds: string[];
150
+ domEventGuardIds: string[];
151
+ canvasProviderIds: string[];
152
+ canvasComponentIds: string[];
153
+ registeredRendererTypes: string[];
154
+ shapeSummaries: CanvasPluginHostShapeValidationSummary[];
155
+ }
156
+
157
+ interface ResolvedCanvasFeature {
158
+ extensionName: string;
159
+ feature: LandFeatureBundle;
160
+ source: CanvasPluginHostSource;
161
+ }
162
+
163
+ export function createCanvasPluginHostRuntime(
164
+ extensions: readonly LandExtension[],
165
+ options: CreateCanvasPluginHostRuntimeOptions = {},
166
+ ): CanvasPluginHostRuntime {
167
+ const source = options.source ?? "built-in";
168
+ const resolvedFeatures = resolveLandExtensions(extensions).flatMap(
169
+ ({ extension, feature }): ResolvedCanvasFeature[] =>
170
+ feature
171
+ ? [
172
+ {
173
+ extensionName: extension.name,
174
+ feature,
175
+ source,
176
+ },
177
+ ]
178
+ : [],
179
+ );
180
+ const corePlugins = resolvedFeatures.flatMap(
181
+ ({ feature }) => feature.corePlugins,
182
+ );
183
+ const canvasPlugins = resolvedFeatures.flatMap(
184
+ ({ feature }) => feature.canvasPlugins,
185
+ );
186
+ const canvasProviders = canvasPlugins.flatMap((plugin) => [
187
+ ...(plugin.canvasProviders ?? []),
188
+ ]);
189
+ const canvasComponents = canvasPlugins.flatMap((plugin) => [
190
+ ...(plugin.canvasComponents ?? []),
191
+ ]);
192
+ const manifest = resolvedFeatures.map(getManifestEntryFromFeature);
193
+ const externalPluginIds = resolvedFeatures
194
+ .filter(({ source: featureSource }) => featureSource !== "built-in")
195
+ .flatMap(({ feature }) => [
196
+ ...feature.corePlugins.map((plugin) => plugin.id),
197
+ ...feature.canvasPlugins.map((plugin) => plugin.id),
198
+ ]);
199
+ const hasExternalPlugins = externalPluginIds.length > 0;
200
+ const rendererRegistry = createCanvasRendererRegistry(canvasPlugins);
201
+
202
+ return {
203
+ corePlugins,
204
+ canvasPlugins,
205
+ canvasProviders,
206
+ canvasComponents,
207
+ rendererRegistry,
208
+ domEventGuardRegistry: createCanvasDomEventGuardRegistry(canvasPlugins),
209
+ toolbarRegistry: createCanvasToolbarRegistry(corePlugins),
210
+ contextMenuRegistry: createCanvasContextMenuRegistry(corePlugins),
211
+ manifest,
212
+ validation: validateCanvasPluginHost({
213
+ corePlugins,
214
+ canvasPlugins,
215
+ rendererRegistry,
216
+ resolvedFeatures,
217
+ }),
218
+ externalPluginIds,
219
+ ignoreStoredSnapshots: hasExternalPlugins,
220
+ disablePersistence: hasExternalPlugins,
221
+ };
222
+ }
223
+
224
+ function validateCanvasPluginHost(
225
+ {
226
+ corePlugins,
227
+ canvasPlugins,
228
+ rendererRegistry,
229
+ resolvedFeatures,
230
+ }: {
231
+ corePlugins: readonly LandCorePlugin[];
232
+ canvasPlugins: readonly LandCanvasPlugin[];
233
+ rendererRegistry: CanvasRendererRegistry;
234
+ resolvedFeatures: readonly ResolvedCanvasFeature[];
235
+ },
236
+ ): CanvasPluginHostValidationSummary {
237
+ const issues: CanvasPluginHostValidationIssue[] = [];
238
+ const featureIds = resolvedFeatures.map(({ feature }) => feature.id);
239
+ const corePluginIds = corePlugins.map((plugin) => plugin.id);
240
+ const canvasPluginIds = canvasPlugins.map((plugin) => plugin.id);
241
+ const interactionHandlerIds = corePlugins.flatMap((plugin) =>
242
+ (plugin.interactionHandlers ?? []).map((handler) => handler.id),
243
+ );
244
+ const toolbarActionIds = corePlugins.flatMap((plugin) =>
245
+ (plugin.toolbarActions ?? []).map((action) => action.id),
246
+ );
247
+ const toolbarContributionIds = corePlugins.flatMap((plugin) =>
248
+ (plugin.toolbarContributions ?? []).map((contribution) => contribution.id),
249
+ );
250
+ const contextMenuContributionIds = corePlugins.flatMap((plugin) =>
251
+ (plugin.contextMenuContributions ?? []).map(
252
+ (contribution) => contribution.id,
253
+ ),
254
+ );
255
+ const knownToolbarActionIds = new Set([
256
+ ...HOST_TOOLBAR_ACTION_IDS,
257
+ ...toolbarActionIds,
258
+ ]);
259
+ const domEventGuardIds = canvasPlugins.flatMap((plugin) =>
260
+ (plugin.domEventGuards ?? []).map((guard) => guard.id),
261
+ );
262
+ const canvasProviderIds = canvasPlugins.flatMap((plugin) =>
263
+ (plugin.canvasProviders ?? []).map((provider) => provider.id),
264
+ );
265
+ const canvasComponentIds = canvasPlugins.flatMap((plugin) =>
266
+ (plugin.canvasComponents ?? []).map((component) => component.id),
267
+ );
268
+ const shapeUtilsByType = new Set(
269
+ corePlugins.flatMap((plugin) =>
270
+ (plugin.shapeUtils ?? []).map((shapeUtil) => shapeUtil.type),
271
+ ),
272
+ );
273
+ const svgExportersByType = new Set(
274
+ corePlugins.flatMap((plugin) =>
275
+ (plugin.shapeSvgExporters ?? []).map((exporter) => exporter.type),
276
+ ),
277
+ );
278
+ const capabilitiesByType = new Map(
279
+ corePlugins.flatMap((plugin) =>
280
+ (plugin.shapeCapabilities ?? []).map((capability) => [
281
+ capability.type,
282
+ capability,
283
+ ]),
284
+ ),
285
+ );
286
+ const rendererTypes = new Set(rendererRegistry.getRegisteredShapeTypes());
287
+
288
+ pushDuplicateIssues({
289
+ code: "duplicate-feature-id",
290
+ ids: featureIds,
291
+ issues,
292
+ messagePrefix: "Duplicate feature id",
293
+ });
294
+ pushDuplicateIssues({
295
+ code: "duplicate-core-plugin-id",
296
+ ids: corePluginIds,
297
+ issues,
298
+ messagePrefix: "Duplicate core plugin id",
299
+ });
300
+ pushDuplicateIssues({
301
+ code: "duplicate-canvas-plugin-id",
302
+ ids: canvasPluginIds,
303
+ issues,
304
+ messagePrefix: "Duplicate canvas plugin id",
305
+ });
306
+ pushDuplicateIssues({
307
+ code: "duplicate-interaction-handler-id",
308
+ ids: interactionHandlerIds,
309
+ issues,
310
+ messagePrefix: "Duplicate interaction handler id",
311
+ });
312
+ pushDuplicateIssues({
313
+ code: "duplicate-toolbar-action-id",
314
+ ids: toolbarActionIds,
315
+ issues,
316
+ messagePrefix: "Duplicate toolbar action id",
317
+ });
318
+ pushDuplicateIssues({
319
+ code: "duplicate-toolbar-contribution-id",
320
+ ids: toolbarContributionIds,
321
+ issues,
322
+ messagePrefix: "Duplicate toolbar contribution id",
323
+ });
324
+ pushDuplicateIssues({
325
+ code: "duplicate-context-menu-contribution-id",
326
+ ids: contextMenuContributionIds,
327
+ issues,
328
+ messagePrefix: "Duplicate context menu contribution id",
329
+ });
330
+ pushMissingToolbarActionIssues({
331
+ resolvedFeatures,
332
+ issues,
333
+ knownToolbarActionIds,
334
+ });
335
+ pushMissingContextMenuActionIssues({
336
+ resolvedFeatures,
337
+ issues,
338
+ knownToolbarActionIds,
339
+ });
340
+ pushDuplicateIssues({
341
+ code: "duplicate-dom-event-guard-id",
342
+ ids: domEventGuardIds,
343
+ issues,
344
+ messagePrefix: "Duplicate DOM event guard id",
345
+ });
346
+ pushDuplicateIssues({
347
+ code: "duplicate-canvas-provider-id",
348
+ ids: canvasProviderIds,
349
+ issues,
350
+ messagePrefix: "Duplicate canvas plugin provider id",
351
+ });
352
+ pushDuplicateIssues({
353
+ code: "duplicate-canvas-component-id",
354
+ ids: canvasComponentIds,
355
+ issues,
356
+ messagePrefix: "Duplicate canvas plugin component id",
357
+ });
358
+
359
+ const shapeSummaries = resolvedFeatures.flatMap(({ feature }) => {
360
+ const isToolOnlyFeature =
361
+ feature.shapeTypes.length === 0 &&
362
+ feature.corePlugins.some(
363
+ (plugin) =>
364
+ (plugin.toolbarContributions ?? []).some(
365
+ (contribution) => contribution.surface === "tool",
366
+ ) || plugin.setup !== undefined,
367
+ );
368
+
369
+ if (feature.corePlugins.length === 0) {
370
+ issues.push({
371
+ severity: "error",
372
+ code: "missing-core-plugin",
373
+ featureId: feature.id,
374
+ pluginId: null,
375
+ shapeType: null,
376
+ message: `Feature ${feature.id} does not include a core plugin.`,
377
+ });
378
+ }
379
+ if (feature.canvasPlugins.length === 0 && !isToolOnlyFeature) {
380
+ issues.push({
381
+ severity: "error",
382
+ code: "missing-canvas-plugin",
383
+ featureId: feature.id,
384
+ pluginId: null,
385
+ shapeType: null,
386
+ message: `Feature ${feature.id} does not include a canvas plugin.`,
387
+ });
388
+ }
389
+ if (feature.shapeTypes.length === 0 && !isToolOnlyFeature) {
390
+ issues.push({
391
+ severity: "error",
392
+ code: "missing-shape-type",
393
+ featureId: feature.id,
394
+ pluginId: null,
395
+ shapeType: null,
396
+ message: `Feature ${feature.id} does not declare shape types.`,
397
+ });
398
+ }
399
+
400
+ return feature.shapeTypes.map((shapeType) => {
401
+ const capability = capabilitiesByType.get(shapeType) ?? null;
402
+ const hasShapeUtil = shapeUtilsByType.has(shapeType);
403
+ const hasSvgExporter = svgExportersByType.has(shapeType);
404
+ const hasCanvasRenderer = rendererTypes.has(shapeType);
405
+ const exportSupport: ShapeCapabilitySupport =
406
+ hasShapeUtil && hasSvgExporter ? "supported" : "missing";
407
+
408
+ if (!capability) {
409
+ issues.push({
410
+ severity: "error",
411
+ code: "missing-shape-capability",
412
+ featureId: feature.id,
413
+ pluginId: null,
414
+ shapeType,
415
+ message: `Shape type ${shapeType} does not have a core capability entry.`,
416
+ });
417
+ }
418
+ if (!hasShapeUtil) {
419
+ issues.push({
420
+ severity: "error",
421
+ code: "missing-shape-util",
422
+ featureId: feature.id,
423
+ pluginId: null,
424
+ shapeType,
425
+ message: `Shape type ${shapeType} does not have a core shape util.`,
426
+ });
427
+ }
428
+ if (capability?.reactRenderer === "supported" && !hasCanvasRenderer) {
429
+ issues.push({
430
+ severity: "error",
431
+ code: "missing-canvas-renderer",
432
+ featureId: feature.id,
433
+ pluginId: null,
434
+ shapeType,
435
+ message: `Shape type ${shapeType} declares React renderer support but no canvas renderer registered.`,
436
+ });
437
+ }
438
+ if (!hasSvgExporter) {
439
+ issues.push({
440
+ severity: "warning",
441
+ code: "missing-svg-exporter",
442
+ featureId: feature.id,
443
+ pluginId: null,
444
+ shapeType,
445
+ message: `Shape type ${shapeType} does not have an SVG exporter.`,
446
+ });
447
+ }
448
+
449
+ return {
450
+ featureId: feature.id,
451
+ shapeType,
452
+ hasCapability: capability !== null,
453
+ hasShapeUtil,
454
+ hasSvgExporter,
455
+ hasCanvasRenderer,
456
+ exportSupport,
457
+ };
458
+ });
459
+ });
460
+ const errorCount = issues.filter((issue) => issue.severity === "error").length;
461
+ const warningCount = issues.length - errorCount;
462
+
463
+ return {
464
+ verdict: errorCount === 0 ? "pass" : "fail",
465
+ issueCount: issues.length,
466
+ errorCount,
467
+ warningCount,
468
+ issues,
469
+ featureIds,
470
+ corePluginIds,
471
+ canvasPluginIds,
472
+ interactionHandlerIds,
473
+ toolbarActionIds,
474
+ toolbarContributionIds,
475
+ contextMenuContributionIds,
476
+ domEventGuardIds,
477
+ canvasProviderIds,
478
+ canvasComponentIds,
479
+ registeredRendererTypes: Array.from(rendererTypes),
480
+ shapeSummaries,
481
+ };
482
+ }
483
+
484
+ function pushDuplicateIssues({
485
+ code,
486
+ ids,
487
+ issues,
488
+ messagePrefix,
489
+ }: {
490
+ code:
491
+ | "duplicate-feature-id"
492
+ | "duplicate-core-plugin-id"
493
+ | "duplicate-canvas-plugin-id"
494
+ | "duplicate-interaction-handler-id"
495
+ | "duplicate-toolbar-action-id"
496
+ | "duplicate-toolbar-contribution-id"
497
+ | "duplicate-context-menu-contribution-id"
498
+ | "duplicate-dom-event-guard-id"
499
+ | "duplicate-canvas-provider-id"
500
+ | "duplicate-canvas-component-id";
501
+ ids: readonly string[];
502
+ issues: CanvasPluginHostValidationIssue[];
503
+ messagePrefix: string;
504
+ }): void {
505
+ const counts = new Map<string, number>();
506
+ for (const id of ids) {
507
+ counts.set(id, (counts.get(id) ?? 0) + 1);
508
+ }
509
+ for (const [id, count] of counts) {
510
+ if (count > 1) {
511
+ issues.push({
512
+ severity: "error",
513
+ code,
514
+ featureId: null,
515
+ pluginId: id,
516
+ shapeType: null,
517
+ message: `${messagePrefix}: ${id}.`,
518
+ });
519
+ }
520
+ }
521
+ }
522
+
523
+ function pushMissingContextMenuActionIssues({
524
+ resolvedFeatures,
525
+ issues,
526
+ knownToolbarActionIds,
527
+ }: {
528
+ resolvedFeatures: readonly ResolvedCanvasFeature[];
529
+ issues: CanvasPluginHostValidationIssue[];
530
+ knownToolbarActionIds: ReadonlySet<string>;
531
+ }): void {
532
+ for (const { feature } of resolvedFeatures) {
533
+ for (const plugin of feature.corePlugins) {
534
+ for (const contribution of plugin.contextMenuContributions ?? []) {
535
+ for (const actionId of contribution.actionIds) {
536
+ if (knownToolbarActionIds.has(actionId)) {
537
+ continue;
538
+ }
539
+ issues.push({
540
+ severity: "error",
541
+ code: "missing-context-menu-action",
542
+ featureId: feature.id,
543
+ pluginId: plugin.id,
544
+ shapeType: null,
545
+ message: `Context menu contribution ${contribution.id} references missing action ${actionId}.`,
546
+ });
547
+ }
548
+ }
549
+ }
550
+ }
551
+ }
552
+
553
+ function pushMissingToolbarActionIssues({
554
+ resolvedFeatures,
555
+ issues,
556
+ knownToolbarActionIds,
557
+ }: {
558
+ resolvedFeatures: readonly ResolvedCanvasFeature[];
559
+ issues: CanvasPluginHostValidationIssue[];
560
+ knownToolbarActionIds: ReadonlySet<string>;
561
+ }): void {
562
+ for (const { feature } of resolvedFeatures) {
563
+ for (const plugin of feature.corePlugins) {
564
+ for (const contribution of plugin.toolbarContributions ?? []) {
565
+ for (const actionId of contribution.actionIds) {
566
+ if (knownToolbarActionIds.has(actionId)) {
567
+ continue;
568
+ }
569
+ issues.push({
570
+ severity: "error",
571
+ code: "missing-toolbar-action",
572
+ featureId: feature.id,
573
+ pluginId: plugin.id,
574
+ shapeType: null,
575
+ message: `Toolbar contribution ${contribution.id} references missing action ${actionId}.`,
576
+ });
577
+ }
578
+ }
579
+ }
580
+ }
581
+ }
582
+
583
+ function getManifestEntryFromFeature(
584
+ resolvedFeature: ResolvedCanvasFeature,
585
+ ): CanvasPluginHostManifestEntry {
586
+ const { extensionName, feature, source } = resolvedFeature;
587
+ return {
588
+ id: feature.id,
589
+ extensionName,
590
+ source,
591
+ corePluginIds: feature.corePlugins.map((plugin) => plugin.id),
592
+ canvasPluginIds: feature.canvasPlugins.map((plugin) => plugin.id),
593
+ interactionHandlerIds: feature.corePlugins.flatMap((plugin) =>
594
+ (plugin.interactionHandlers ?? []).map((handler) => handler.id),
595
+ ),
596
+ toolbarActionIds: feature.corePlugins.flatMap((plugin) =>
597
+ (plugin.toolbarActions ?? []).map((action) => action.id),
598
+ ),
599
+ toolbarContributionIds: feature.corePlugins.flatMap((plugin) =>
600
+ (plugin.toolbarContributions ?? []).map(
601
+ (contribution) => contribution.id,
602
+ ),
603
+ ),
604
+ toolbarContributions: feature.corePlugins.flatMap((plugin) =>
605
+ (plugin.toolbarContributions ?? []).map((contribution) => ({
606
+ id: contribution.id,
607
+ surface: contribution.surface,
608
+ placement: contribution.placement ?? "context",
609
+ actionIds: [...contribution.actionIds],
610
+ })),
611
+ ),
612
+ contextMenuContributionIds: feature.corePlugins.flatMap((plugin) =>
613
+ (plugin.contextMenuContributions ?? []).map(
614
+ (contribution) => contribution.id,
615
+ ),
616
+ ),
617
+ contextMenuContributions: feature.corePlugins.flatMap((plugin) =>
618
+ (plugin.contextMenuContributions ?? []).map((contribution) => ({
619
+ id: contribution.id,
620
+ target: contribution.target,
621
+ actionIds: [...contribution.actionIds],
622
+ })),
623
+ ),
624
+ domEventGuardIds: feature.canvasPlugins.flatMap((plugin) =>
625
+ (plugin.domEventGuards ?? []).map((guard) => guard.id),
626
+ ),
627
+ canvasProviderIds: feature.canvasPlugins.flatMap((plugin) =>
628
+ (plugin.canvasProviders ?? []).map((provider) => provider.id),
629
+ ),
630
+ canvasComponentIds: feature.canvasPlugins.flatMap((plugin) =>
631
+ (plugin.canvasComponents ?? []).map((component) => component.id),
632
+ ),
633
+ shapeTypes: [...feature.shapeTypes],
634
+ };
635
+ }
@@ -0,0 +1,58 @@
1
+ import type { ShapeRecordBase } from "@land/canvas-core";
2
+ import {
3
+ setupCanvasPlugins,
4
+ type AnyRegisteredShapeRenderer,
5
+ type LandCanvasPlugin,
6
+ type RegisteredShapeRenderer,
7
+ } from "@land/canvas-plugin-api";
8
+
9
+ export class CanvasRendererRegistry {
10
+ private readonly registry = new Map<string, AnyRegisteredShapeRenderer>();
11
+ private readonly registeredPluginIds = new Set<string>();
12
+
13
+ registerShapeRenderer<S extends ShapeRecordBase>(
14
+ renderer: RegisteredShapeRenderer<S>,
15
+ ): void {
16
+ this.registry.set(renderer.type, eraseRegisteredShapeRenderer(renderer));
17
+ }
18
+
19
+ getShapeRenderer(
20
+ type: ShapeRecordBase["type"],
21
+ ): AnyRegisteredShapeRenderer | null {
22
+ return this.registry.get(type) ?? null;
23
+ }
24
+
25
+ hasShapeRenderer(type: ShapeRecordBase["type"]): boolean {
26
+ return this.registry.has(type);
27
+ }
28
+
29
+ getRegisteredShapeTypes(): ShapeRecordBase["type"][] {
30
+ return [...this.registry.keys()];
31
+ }
32
+
33
+ registerCanvasPlugins(plugins: readonly LandCanvasPlugin[]): void {
34
+ const pendingPlugins = plugins.filter(
35
+ (plugin) => !this.registeredPluginIds.has(plugin.id),
36
+ );
37
+ setupCanvasPlugins(pendingPlugins, (renderer) =>
38
+ this.registerShapeRenderer(renderer),
39
+ );
40
+ for (const plugin of pendingPlugins) {
41
+ this.registeredPluginIds.add(plugin.id);
42
+ }
43
+ }
44
+ }
45
+
46
+ function eraseRegisteredShapeRenderer<S extends ShapeRecordBase>(
47
+ renderer: RegisteredShapeRenderer<S>,
48
+ ): AnyRegisteredShapeRenderer {
49
+ return renderer as unknown as AnyRegisteredShapeRenderer;
50
+ }
51
+
52
+ export function createCanvasRendererRegistry(
53
+ plugins: readonly LandCanvasPlugin[] = [],
54
+ ): CanvasRendererRegistry {
55
+ const nextRegistry = new CanvasRendererRegistry();
56
+ nextRegistry.registerCanvasPlugins(plugins);
57
+ return nextRegistry;
58
+ }