@lvl99dotcom/paintcanvas 0.0.0-stage → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (284) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +131 -2
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.js +5 -0
  5. package/dist/lib/brushes/BrushTipCache/index.d.ts +32 -0
  6. package/dist/lib/brushes/BrushTipCache/index.js +60 -0
  7. package/dist/lib/brushes/StrokeEngine/index.d.ts +171 -0
  8. package/dist/lib/brushes/StrokeEngine/index.js +324 -0
  9. package/dist/lib/brushes/StrokePath/index.d.ts +53 -0
  10. package/dist/lib/brushes/StrokePath/index.js +161 -0
  11. package/dist/lib/brushes/StrokeSampler/index.d.ts +55 -0
  12. package/dist/lib/brushes/StrokeSampler/index.js +75 -0
  13. package/dist/lib/brushes/authors/index.d.ts +55 -0
  14. package/dist/lib/brushes/authors/index.js +60 -0
  15. package/dist/lib/brushes/configRanges/index.d.ts +52 -0
  16. package/dist/lib/brushes/configRanges/index.js +206 -0
  17. package/dist/lib/brushes/index.d.ts +5 -0
  18. package/dist/lib/brushes/index.js +19 -0
  19. package/dist/lib/brushes/params/index.d.ts +108 -0
  20. package/dist/lib/brushes/params/index.js +139 -0
  21. package/dist/lib/brushes/presetFile/index.d.ts +32 -0
  22. package/dist/lib/brushes/presetFile/index.js +55 -0
  23. package/dist/lib/brushes/presets/drawing/brush-pen.js +3 -0
  24. package/dist/lib/brushes/presets/drawing/felt-pen.js +3 -0
  25. package/dist/lib/brushes/presets/drawing/index.d.ts +13 -0
  26. package/dist/lib/brushes/presets/drawing/index.js +88 -0
  27. package/dist/lib/brushes/presets/drawing/pencil-2b.js +3 -0
  28. package/dist/lib/brushes/presets/drawing/pencil-hb.js +3 -0
  29. package/dist/lib/brushes/presets/painting/grass.js +3 -0
  30. package/dist/lib/brushes/presets/painting/hair.js +3 -0
  31. package/dist/lib/brushes/presets/painting/index.d.ts +18 -0
  32. package/dist/lib/brushes/presets/painting/index.js +118 -0
  33. package/dist/lib/brushes/presets/painting/splatter.js +3 -0
  34. package/dist/lib/brushes/presets/painting/textured-paint.js +3 -0
  35. package/dist/lib/brushes/presets/painting/watery-paint.js +3 -0
  36. package/dist/lib/brushes/presets/round/index.d.ts +9 -0
  37. package/dist/lib/brushes/presets/round/index.js +44 -0
  38. package/dist/lib/brushes/presets/round/round.js +3 -0
  39. package/dist/lib/brushes/presets/round/soft-round.js +3 -0
  40. package/dist/lib/brushes/presets/sized/index.d.ts +20 -0
  41. package/dist/lib/brushes/presets/sized/index.js +30 -0
  42. package/dist/lib/brushes/presets/sketching/index.d.ts +14 -0
  43. package/dist/lib/brushes/presets/sketching/index.js +107 -0
  44. package/dist/lib/brushes/presets/square/index.d.ts +7 -0
  45. package/dist/lib/brushes/presets/square/index.js +22 -0
  46. package/dist/lib/brushes/presets/square/square.js +3 -0
  47. package/dist/lib/brushes/shapeImage/index.d.ts +40 -0
  48. package/dist/lib/brushes/shapeImage/index.js +61 -0
  49. package/dist/lib/brushes/types/index.d.ts +243 -0
  50. package/dist/lib/brushes/types/index.js +20 -0
  51. package/dist/lib/classes/BackgroundWork/index.d.ts +55 -0
  52. package/dist/lib/classes/BackgroundWork/index.js +97 -0
  53. package/dist/lib/classes/BrushSettings/index.d.ts +91 -0
  54. package/dist/lib/classes/BrushSettings/index.js +152 -0
  55. package/dist/lib/classes/CustomPresets/index.d.ts +53 -0
  56. package/dist/lib/classes/CustomPresets/index.js +71 -0
  57. package/dist/lib/classes/ExternalSheets/index.d.ts +64 -0
  58. package/dist/lib/classes/ExternalSheets/index.js +112 -0
  59. package/dist/lib/classes/GestureTracker/index.d.ts +62 -0
  60. package/dist/lib/classes/GestureTracker/index.js +122 -0
  61. package/dist/lib/classes/History/index.d.ts +83 -0
  62. package/dist/lib/classes/History/index.js +126 -0
  63. package/dist/lib/classes/HistoryGuard/index.d.ts +58 -0
  64. package/dist/lib/classes/HistoryGuard/index.js +97 -0
  65. package/dist/lib/classes/InputSettings/index.d.ts +74 -0
  66. package/dist/lib/classes/InputSettings/index.js +101 -0
  67. package/dist/lib/classes/KeyboardShortcuts/index.d.ts +48 -0
  68. package/dist/lib/classes/KeyboardShortcuts/index.js +137 -0
  69. package/dist/lib/classes/Layer/index.d.ts +86 -0
  70. package/dist/lib/classes/Layer/index.js +111 -0
  71. package/dist/lib/classes/LayerAutosave/index.d.ts +180 -0
  72. package/dist/lib/classes/LayerAutosave/index.js +346 -0
  73. package/dist/lib/classes/LayerStack/index.d.ts +177 -0
  74. package/dist/lib/classes/LayerStack/index.js +394 -0
  75. package/dist/lib/classes/PaintCanvas/index.d.ts +537 -0
  76. package/dist/lib/classes/PaintCanvas/index.js +965 -0
  77. package/dist/lib/classes/StrokeLog/index.d.ts +149 -0
  78. package/dist/lib/classes/StrokeLog/index.js +257 -0
  79. package/dist/lib/classes/Viewport/index.d.ts +108 -0
  80. package/dist/lib/classes/Viewport/index.js +194 -0
  81. package/dist/lib/document/index.d.ts +17 -0
  82. package/dist/lib/document/index.js +25 -0
  83. package/dist/lib/document/schema.d.ts +132 -0
  84. package/dist/lib/document/schema.js +110 -0
  85. package/dist/lib/i18n/index.d.ts +131 -0
  86. package/dist/lib/i18n/index.js +277 -0
  87. package/dist/lib/image/index.d.ts +90 -0
  88. package/dist/lib/image/index.js +147 -0
  89. package/dist/lib/messages/PatchSender/index.d.ts +75 -0
  90. package/dist/lib/messages/PatchSender/index.js +125 -0
  91. package/dist/lib/messages/index.d.ts +26 -0
  92. package/dist/lib/messages/index.js +59 -0
  93. package/dist/lib/messages/schema.d.ts +1775 -0
  94. package/dist/lib/messages/schema.js +192 -0
  95. package/dist/lib/presets/index.d.ts +32 -0
  96. package/dist/lib/presets/index.js +35 -0
  97. package/dist/lib/presets/schema.d.ts +753 -0
  98. package/dist/lib/presets/schema.js +181 -0
  99. package/dist/lib/rendering/BrushTip/index.d.ts +63 -0
  100. package/dist/lib/rendering/BrushTip/index.js +112 -0
  101. package/dist/lib/rendering/checkerboard/index.d.ts +22 -0
  102. package/dist/lib/rendering/checkerboard/index.js +31 -0
  103. package/dist/lib/rendering/compositing/index.d.ts +64 -0
  104. package/dist/lib/rendering/compositing/index.js +124 -0
  105. package/dist/lib/rendering/cursor/index.d.ts +14 -0
  106. package/dist/lib/rendering/cursor/index.js +39 -0
  107. package/dist/lib/rendering/cursors/index.d.ts +18 -0
  108. package/dist/lib/rendering/cursors/index.js +23 -0
  109. package/dist/lib/rendering/maskOutline/index.d.ts +22 -0
  110. package/dist/lib/rendering/maskOutline/index.js +78 -0
  111. package/dist/lib/rendering/outline/index.d.ts +36 -0
  112. package/dist/lib/rendering/outline/index.js +120 -0
  113. package/dist/lib/rendering/sample/index.d.ts +55 -0
  114. package/dist/lib/rendering/sample/index.js +83 -0
  115. package/dist/lib/rendering/screenshot/index.d.ts +67 -0
  116. package/dist/lib/rendering/screenshot/index.js +96 -0
  117. package/dist/lib/rendering/transformBox/index.d.ts +10 -0
  118. package/dist/lib/rendering/transformBox/index.js +57 -0
  119. package/dist/lib/selection/Lasso/index.d.ts +70 -0
  120. package/dist/lib/selection/Lasso/index.js +156 -0
  121. package/dist/lib/selection/Selection/index.d.ts +86 -0
  122. package/dist/lib/selection/Selection/index.js +228 -0
  123. package/dist/lib/selection/geometry/index.d.ts +37 -0
  124. package/dist/lib/selection/geometry/index.js +57 -0
  125. package/dist/lib/storage/index.d.ts +63 -0
  126. package/dist/lib/storage/index.js +114 -0
  127. package/dist/lib/transform/Transformer/index.d.ts +124 -0
  128. package/dist/lib/transform/Transformer/index.js +286 -0
  129. package/dist/lib/transform/geometry/index.d.ts +95 -0
  130. package/dist/lib/transform/geometry/index.js +258 -0
  131. package/dist/lib/utils/array/index.d.ts +10 -0
  132. package/dist/lib/utils/array/index.js +21 -0
  133. package/dist/lib/utils/gestures/index.d.ts +35 -0
  134. package/dist/lib/utils/gestures/index.js +81 -0
  135. package/dist/lib/utils/navigation/index.d.ts +51 -0
  136. package/dist/lib/utils/navigation/index.js +59 -0
  137. package/dist/lib/utils/random/index.d.ts +18 -0
  138. package/dist/lib/utils/random/index.js +27 -0
  139. package/dist/lib/utils/shortcuts/index.d.ts +74 -0
  140. package/dist/lib/utils/shortcuts/index.js +189 -0
  141. package/dist/lib/validation/validators.generated.d.ts +27 -0
  142. package/dist/lib/validation/validators.generated.js +19826 -0
  143. package/dist/locales/en-GB.js +181 -0
  144. package/dist/locales/en-US.js +181 -0
  145. package/dist/locales/fr.js +181 -0
  146. package/dist/locales/ja.js +181 -0
  147. package/dist/locales/ko.js +181 -0
  148. package/dist/locales/zh-Hans.js +181 -0
  149. package/dist/locales/zh-Hant.js +181 -0
  150. package/dist/package.js +3 -0
  151. package/dist/testing/app.d.ts +7 -0
  152. package/dist/testing/app.js +16 -0
  153. package/dist/testing/elements.d.ts +42 -0
  154. package/dist/testing/elements.js +58 -0
  155. package/dist/testing/fakeCanvas.d.ts +21 -0
  156. package/dist/testing/fakeCanvas.js +26 -0
  157. package/dist/testing/layerStore.d.ts +26 -0
  158. package/dist/testing/layerStore.js +43 -0
  159. package/dist/testing/locks.d.ts +15 -0
  160. package/dist/testing/locks.js +41 -0
  161. package/dist/testing/recordingCanvas.d.ts +14 -0
  162. package/dist/testing/recordingCanvas.js +28 -0
  163. package/dist/testing/recordingContext.d.ts +10 -0
  164. package/dist/testing/recordingContext.js +19 -0
  165. package/dist/ui/ChangeController/index.d.ts +40 -0
  166. package/dist/ui/ChangeController/index.js +62 -0
  167. package/dist/ui/base/index.d.ts +69 -0
  168. package/dist/ui/base/index.js +94 -0
  169. package/dist/ui/elements/PaintCanvas/index.d.ts +249 -0
  170. package/dist/ui/elements/PaintCanvas/index.js +584 -0
  171. package/dist/ui/elements/PaintCanvas/style.js +3 -0
  172. package/dist/ui/elements/PcBrushConfig/index.d.ts +130 -0
  173. package/dist/ui/elements/PcBrushConfig/index.js +465 -0
  174. package/dist/ui/elements/PcBrushConfig/style.js +3 -0
  175. package/dist/ui/elements/PcBrushMenu/index.d.ts +121 -0
  176. package/dist/ui/elements/PcBrushMenu/index.js +362 -0
  177. package/dist/ui/elements/PcBrushMenu/style.js +3 -0
  178. package/dist/ui/elements/PcBrushTest/index.d.ts +71 -0
  179. package/dist/ui/elements/PcBrushTest/index.js +136 -0
  180. package/dist/ui/elements/PcBrushTest/style.js +3 -0
  181. package/dist/ui/elements/PcButton/index.d.ts +57 -0
  182. package/dist/ui/elements/PcButton/index.js +124 -0
  183. package/dist/ui/elements/PcButtonGroup/index.d.ts +44 -0
  184. package/dist/ui/elements/PcButtonGroup/index.js +93 -0
  185. package/dist/ui/elements/PcCanvas/index.d.ts +356 -0
  186. package/dist/ui/elements/PcCanvas/index.js +1004 -0
  187. package/dist/ui/elements/PcCanvas/style.js +3 -0
  188. package/dist/ui/elements/PcCanvasMap/index.d.ts +96 -0
  189. package/dist/ui/elements/PcCanvasMap/index.js +187 -0
  190. package/dist/ui/elements/PcCanvasMap/style.js +3 -0
  191. package/dist/ui/elements/PcContextMenu/index.d.ts +72 -0
  192. package/dist/ui/elements/PcContextMenu/index.js +148 -0
  193. package/dist/ui/elements/PcDialog/index.d.ts +63 -0
  194. package/dist/ui/elements/PcDialog/index.js +114 -0
  195. package/dist/ui/elements/PcIcon/index.d.ts +36 -0
  196. package/dist/ui/elements/PcIcon/index.js +43 -0
  197. package/dist/ui/elements/PcIconToggle/index.d.ts +46 -0
  198. package/dist/ui/elements/PcIconToggle/index.js +87 -0
  199. package/dist/ui/elements/PcInfoTip/index.d.ts +40 -0
  200. package/dist/ui/elements/PcInfoTip/index.js +95 -0
  201. package/dist/ui/elements/PcInputSettings/index.d.ts +69 -0
  202. package/dist/ui/elements/PcInputSettings/index.js +154 -0
  203. package/dist/ui/elements/PcLayerItem/index.d.ts +221 -0
  204. package/dist/ui/elements/PcLayerItem/index.js +561 -0
  205. package/dist/ui/elements/PcLayerItem/style.js +3 -0
  206. package/dist/ui/elements/PcLayersMenu/index.d.ts +108 -0
  207. package/dist/ui/elements/PcLayersMenu/index.js +208 -0
  208. package/dist/ui/elements/PcLayersMenu/style.js +3 -0
  209. package/dist/ui/elements/PcMatch/index.d.ts +31 -0
  210. package/dist/ui/elements/PcMatch/index.js +58 -0
  211. package/dist/ui/elements/PcPanel/index.d.ts +43 -0
  212. package/dist/ui/elements/PcPanel/index.js +51 -0
  213. package/dist/ui/elements/PcPopover/index.d.ts +48 -0
  214. package/dist/ui/elements/PcPopover/index.js +86 -0
  215. package/dist/ui/elements/PcSlider/index.d.ts +57 -0
  216. package/dist/ui/elements/PcSlider/index.js +88 -0
  217. package/dist/ui/elements/PcStats/index.d.ts +54 -0
  218. package/dist/ui/elements/PcStats/index.js +144 -0
  219. package/dist/ui/elements/PcThemePicker/index.d.ts +56 -0
  220. package/dist/ui/elements/PcThemePicker/index.js +134 -0
  221. package/dist/ui/elements/PcToast/index.d.ts +58 -0
  222. package/dist/ui/elements/PcToast/index.js +110 -0
  223. package/dist/ui/elements/PcToggleCheckbox/index.d.ts +37 -0
  224. package/dist/ui/elements/PcToggleCheckbox/index.js +105 -0
  225. package/dist/ui/elements/PcToolSettings/index.d.ts +128 -0
  226. package/dist/ui/elements/PcToolSettings/index.js +549 -0
  227. package/dist/ui/elements/PcToolSettings/style.js +3 -0
  228. package/dist/ui/elements/PcToolbar/index.d.ts +71 -0
  229. package/dist/ui/elements/PcToolbar/index.js +190 -0
  230. package/dist/ui/elements/PcToolbar/style.js +3 -0
  231. package/dist/ui/icons/images/brush.js +3 -0
  232. package/dist/ui/icons/images/circle-mask.js +3 -0
  233. package/dist/ui/icons/images/clipboard.js +3 -0
  234. package/dist/ui/icons/images/cursor.js +3 -0
  235. package/dist/ui/icons/images/eraser.js +3 -0
  236. package/dist/ui/icons/images/eyedropper.js +3 -0
  237. package/dist/ui/icons/images/flip-horizontal.js +3 -0
  238. package/dist/ui/icons/images/flip-vertical.js +3 -0
  239. package/dist/ui/icons/images/focus-pen.js +3 -0
  240. package/dist/ui/icons/images/freehand-mask.js +3 -0
  241. package/dist/ui/icons/images/hidden.js +3 -0
  242. package/dist/ui/icons/images/layers.js +3 -0
  243. package/dist/ui/icons/images/linked.js +3 -0
  244. package/dist/ui/icons/images/locked.js +3 -0
  245. package/dist/ui/icons/images/moon.js +3 -0
  246. package/dist/ui/icons/images/pan.js +3 -0
  247. package/dist/ui/icons/images/polygon-mask.js +3 -0
  248. package/dist/ui/icons/images/pressure.js +3 -0
  249. package/dist/ui/icons/images/randomise.js +3 -0
  250. package/dist/ui/icons/images/rectangle-mask.js +3 -0
  251. package/dist/ui/icons/images/redo.js +3 -0
  252. package/dist/ui/icons/images/rotate-90-left.js +3 -0
  253. package/dist/ui/icons/images/rotate-90-right.js +3 -0
  254. package/dist/ui/icons/images/smoothing-bezier-cubic.js +3 -0
  255. package/dist/ui/icons/images/smoothing-bezier-quad.js +3 -0
  256. package/dist/ui/icons/images/smoothing-linear.js +3 -0
  257. package/dist/ui/icons/images/star.js +3 -0
  258. package/dist/ui/icons/images/sun.js +3 -0
  259. package/dist/ui/icons/images/tilt.js +3 -0
  260. package/dist/ui/icons/images/undo.js +3 -0
  261. package/dist/ui/icons/images/unlinked.js +3 -0
  262. package/dist/ui/icons/images/unlocked.js +3 -0
  263. package/dist/ui/icons/images/visible.js +3 -0
  264. package/dist/ui/icons/images/zoom-in.js +3 -0
  265. package/dist/ui/icons/images/zoom-out.js +3 -0
  266. package/dist/ui/icons/images/zoom.js +3 -0
  267. package/dist/ui/icons/index.d.ts +42 -0
  268. package/dist/ui/icons/index.js +130 -0
  269. package/dist/ui/index.d.ts +21 -0
  270. package/dist/ui/index.js +22 -0
  271. package/dist/ui/layout/index.d.ts +88 -0
  272. package/dist/ui/layout/index.js +96 -0
  273. package/dist/ui/styles/index.d.ts +13 -0
  274. package/dist/ui/styles/index.js +195 -0
  275. package/dist/ui/tokens/index.d.ts +29 -0
  276. package/dist/ui/tokens/index.js +114 -0
  277. package/locales/en-GB.json +179 -0
  278. package/locales/en-US.json +179 -0
  279. package/locales/fr.json +179 -0
  280. package/locales/ja.json +179 -0
  281. package/locales/ko.json +179 -0
  282. package/locales/zh-Hans.json +179 -0
  283. package/locales/zh-Hant.json +179 -0
  284. package/package.json +97 -3
@@ -0,0 +1,125 @@
1
+ import { ImageEncoding, encodeRgbaDeflate } from "../../image/index.js";
2
+ import { drawLayers } from "../../rendering/compositing/index.js";
3
+ import { createPatchMessage } from "../index.js";
4
+ // src/lib/messages/PatchSender/index.ts
5
+ /** How long to wait after a change before sending, so quick changes go together */
6
+ var PATCH_DELAY_MS = 200;
7
+ /**
8
+ * The smallest box containing every pixel that differs between two images of the same size (one 32-bit value per
9
+ * pixel), or undefined if they are the same.
10
+ *
11
+ * @example
12
+ * changedArea(before, after, 100, 100); // [10, 20, 31, 45]
13
+ */
14
+ var changedArea = (before, after, width, height) => {
15
+ let x1 = width;
16
+ let y1 = height;
17
+ let x2 = -1;
18
+ let y2 = -1;
19
+ for (let y = 0; y < height; y++) {
20
+ const row = y * width;
21
+ for (let x = 0; x < width; x++) {
22
+ if (before[row + x] === after[row + x]) continue;
23
+ if (x < x1) x1 = x;
24
+ if (x > x2) x2 = x;
25
+ if (y < y1) y1 = y;
26
+ y2 = y;
27
+ }
28
+ }
29
+ return x2 < 0 ? void 0 : [
30
+ x1,
31
+ y1,
32
+ x2 + 1,
33
+ y2 + 1
34
+ ];
35
+ };
36
+ /**
37
+ * Copy a box of RGBA pixels out of a whole image.
38
+ *
39
+ * @example
40
+ * cropRgba(imageData.data, imageData.width, [10, 10, 20, 20]); // 10 × 10 pixels
41
+ */
42
+ var cropRgba = (rgba, width, [x1, y1, x2, y2]) => {
43
+ const rowBytes = (x2 - x1) * 4;
44
+ const cropped = new Uint8ClampedArray(rowBytes * (y2 - y1));
45
+ for (let y = y1; y < y2; y++) {
46
+ const start = (y * width + x1) * 4;
47
+ cropped.set(rgba.subarray(start, start + rowBytes), (y - y1) * rowBytes);
48
+ }
49
+ return cropped;
50
+ };
51
+ /**
52
+ * Sends the user's drawing as patches. Shortly after any change (and once `whenIdle` runs it), it flattens the
53
+ * user's own layers, compares the result with what it last sent, and sends only the area that changed. This covers every kind of change (strokes,
54
+ * erasing, moving pixels, layer settings and order) without each tool reporting what it changed.
55
+ *
56
+ * @example
57
+ * const sync = new PatchSender({ width, height, layers: () => canvas.layers.layers, send, createCanvas });
58
+ * app.layers.addEventListener("change", () => sync.schedule());
59
+ */
60
+ var PatchSender = class {
61
+ options;
62
+ canvas;
63
+ context;
64
+ /** The pixels last sent (all transparent to start with) */
65
+ sent;
66
+ timer;
67
+ /** Whether it has stopped (a sync waiting for `whenIdle` doesn't run) */
68
+ stopped = false;
69
+ /** The sync in progress, so syncs never overlap */
70
+ running = Promise.resolve();
71
+ constructor(options) {
72
+ this.options = options;
73
+ this.canvas = options.createCanvas(options.width, options.height);
74
+ this.context = this.canvas.getContext("2d", { willReadFrequently: true });
75
+ this.sent = new Uint8ClampedArray(options.width * options.height * 4);
76
+ }
77
+ /**
78
+ * Send the changes soon (changes within the delay go together), once `whenIdle` runs the sync.
79
+ */
80
+ schedule() {
81
+ clearTimeout(this.timer);
82
+ this.timer = setTimeout(() => {
83
+ const run = () => this.stopped ? void 0 : this.sync().catch(() => void 0);
84
+ if (this.options.whenIdle) this.options.whenIdle(run);
85
+ else run();
86
+ }, this.options.delayMs ?? 200);
87
+ }
88
+ /**
89
+ * Send what changed since the last sync now. Resolves once sent; if sending fails, the changes go with the next sync.
90
+ */
91
+ sync() {
92
+ clearTimeout(this.timer);
93
+ this.running = this.running.catch(() => void 0).then(() => this.sendChanges());
94
+ return this.running;
95
+ }
96
+ /** Flatten the layers and send the changed area, if any */
97
+ async sendChanges() {
98
+ const { width, height, send } = this.options;
99
+ this.context.clearRect(0, 0, width, height);
100
+ drawLayers(this.context, this.options.layers());
101
+ const current = this.context.getImageData(0, 0, width, height).data;
102
+ const area = changedArea(new Uint32Array(this.sent.buffer), new Uint32Array(current.buffer), width, height);
103
+ if (!area) return;
104
+ const data = await encodeRgbaDeflate(cropRgba(current, width, area), area);
105
+ await send(createPatchMessage(area, ImageEncoding.RgbaDeflate, data));
106
+ this.sent = current;
107
+ }
108
+ /**
109
+ * Count pixels as already sent (e.g. the user's earlier work, restored from a shared drawing's history), so they aren't
110
+ * sent again.
111
+ */
112
+ markSent(area, rgba) {
113
+ const [x1, y1, x2, y2] = area;
114
+ const rowBytes = (x2 - x1) * 4;
115
+ for (let y = y1; y < y2; y++) this.sent.set(rgba.subarray((y - y1) * rowBytes, (y - y1 + 1) * rowBytes), (y * this.options.width + x1) * 4);
116
+ }
117
+ /**
118
+ * Stop any pending sync.
119
+ */
120
+ stop() {
121
+ this.stopped = true;
122
+ clearTimeout(this.timer);
123
+ }
124
+ };
125
+ export { PATCH_DELAY_MS, changedArea, cropRgba, PatchSender as default };
@@ -0,0 +1,26 @@
1
+ import type { BoundingBox, ImageEncoding } from "../image";
2
+ import { type CanvasMessage, type PatchMessage } from "./schema";
3
+ export * from "./schema";
4
+ /** Result of checking a received message */
5
+ export type MessageValidationResult = {
6
+ valid: true;
7
+ value: CanvasMessage;
8
+ } | {
9
+ valid: false;
10
+ errors: string[];
11
+ };
12
+ /**
13
+ * Make a patch message.
14
+ *
15
+ * @example
16
+ * createPatchMessage([0, 0, 10, 10], ImageEncoding.RgbaDeflate, data);
17
+ */
18
+ export declare const createPatchMessage: (coords: BoundingBox, encoding: ImageEncoding, data: string) => PatchMessage;
19
+ /**
20
+ * Check a received (untrusted) drawing message: its protocol version, its kind, its schema, and that a patch's area
21
+ * isn't empty.
22
+ *
23
+ * @example
24
+ * validateCanvasMessage(JSON.parse(text)); // { valid: true, value: { protocol: 1, type: "patch", … } }
25
+ */
26
+ export declare const validateCanvasMessage: (input: unknown) => MessageValidationResult;
@@ -0,0 +1,59 @@
1
+ import { formatErrors } from "../presets/index.js";
2
+ import { validateHistoryMessage, validatePatchMessage, validateStrokeMessage } from "../validation/validators.generated.js";
3
+ import { CanvasMessageType, MAX_MESSAGE_CANVAS_SIZE, MAX_PATCH_DATA_LENGTH, MAX_STROKE_POINTS, PROTOCOL_VERSION, historyMessageSchema, messageSchemas, patchMessageSchema, strokeMessageSchema, strokePresetSchema } from "./schema.js";
4
+ // src/lib/messages/index.ts
5
+ /**
6
+ * Make a patch message.
7
+ *
8
+ * @example
9
+ * createPatchMessage([0, 0, 10, 10], ImageEncoding.RgbaDeflate, data);
10
+ */
11
+ var createPatchMessage = (coords, encoding, data) => ({
12
+ protocol: 1,
13
+ type: CanvasMessageType.Patch,
14
+ coords,
15
+ encoding,
16
+ data
17
+ });
18
+ /** The validator for each kind of message */
19
+ var VALIDATORS = {
20
+ [CanvasMessageType.Patch]: validatePatchMessage,
21
+ [CanvasMessageType.Stroke]: validateStrokeMessage,
22
+ [CanvasMessageType.Undo]: validateHistoryMessage,
23
+ [CanvasMessageType.Redo]: validateHistoryMessage
24
+ };
25
+ /**
26
+ * Check a received (untrusted) drawing message: its protocol version, its kind, its schema, and that a patch's area
27
+ * isn't empty.
28
+ *
29
+ * @example
30
+ * validateCanvasMessage(JSON.parse(text)); // { valid: true, value: { protocol: 1, type: "patch", … } }
31
+ */
32
+ var validateCanvasMessage = (input) => {
33
+ const record = typeof input === "object" && input !== null ? input : {};
34
+ if (record.protocol !== 1) return {
35
+ valid: false,
36
+ errors: [`/protocol must be 1`]
37
+ };
38
+ const validate = Object.hasOwn(VALIDATORS, record.type) ? VALIDATORS[record.type] : void 0;
39
+ if (!validate) return {
40
+ valid: false,
41
+ errors: ["/type is not a drawing message"]
42
+ };
43
+ if (!validate(input)) return {
44
+ valid: false,
45
+ errors: formatErrors(validate.errors)
46
+ };
47
+ if (input.type === CanvasMessageType.Patch) {
48
+ const [x1, y1, x2, y2] = input.coords;
49
+ if (x2 <= x1 || y2 <= y1) return {
50
+ valid: false,
51
+ errors: ["/coords must not be empty"]
52
+ };
53
+ }
54
+ return {
55
+ valid: true,
56
+ value: input
57
+ };
58
+ };
59
+ export { CanvasMessageType, MAX_MESSAGE_CANVAS_SIZE, MAX_PATCH_DATA_LENGTH, MAX_STROKE_POINTS, PROTOCOL_VERSION, createPatchMessage, historyMessageSchema, messageSchemas, patchMessageSchema, strokeMessageSchema, strokePresetSchema, validateCanvasMessage };