@xom11/whiteboard 0.27.0 → 0.29.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 (67) hide show
  1. package/dist/ai.d.mts +236 -295
  2. package/dist/ai.d.ts +236 -295
  3. package/dist/ai.js +6015 -7577
  4. package/dist/ai.js.map +1 -1
  5. package/dist/ai.mjs +4804 -5426
  6. package/dist/ai.mjs.map +1 -1
  7. package/dist/catalog.json +4 -4
  8. package/dist/{chunk-D5JLJ3PT.mjs → chunk-5JM35CXV.mjs} +4 -4
  9. package/dist/{chunk-D5JLJ3PT.mjs.map → chunk-5JM35CXV.mjs.map} +1 -1
  10. package/dist/{chunk-KYMBUTPO.mjs → chunk-BU5KLO3P.mjs} +3 -3
  11. package/dist/{chunk-KYMBUTPO.mjs.map → chunk-BU5KLO3P.mjs.map} +1 -1
  12. package/dist/{chunk-AJAHD35N.mjs → chunk-E6EDOPGT.mjs} +3 -105
  13. package/dist/chunk-E6EDOPGT.mjs.map +1 -0
  14. package/dist/{chunk-KZGPSTZI.mjs → chunk-GEC2D2EQ.mjs} +4 -4
  15. package/dist/{chunk-KZGPSTZI.mjs.map → chunk-GEC2D2EQ.mjs.map} +1 -1
  16. package/dist/{chunk-AYJPOHCI.mjs → chunk-H22OZYTW.mjs} +3 -3
  17. package/dist/{chunk-AYJPOHCI.mjs.map → chunk-H22OZYTW.mjs.map} +1 -1
  18. package/dist/{chunk-I3L56GVH.mjs → chunk-OQIQNKPQ.mjs} +3 -3
  19. package/dist/{chunk-I3L56GVH.mjs.map → chunk-OQIQNKPQ.mjs.map} +1 -1
  20. package/dist/{chunk-4ETJ4CDY.mjs → chunk-QRUAEXLR.mjs} +4 -4
  21. package/dist/{chunk-4ETJ4CDY.mjs.map → chunk-QRUAEXLR.mjs.map} +1 -1
  22. package/dist/{chunk-HLAOGXEK.mjs → chunk-V3YJ6JFL.mjs} +3 -3
  23. package/dist/{chunk-HLAOGXEK.mjs.map → chunk-V3YJ6JFL.mjs.map} +1 -1
  24. package/dist/{chunk-D5LWSN2Y.mjs → chunk-ZTQBUKLJ.mjs} +30 -13
  25. package/dist/chunk-ZTQBUKLJ.mjs.map +1 -0
  26. package/dist/geometry-2d.d.mts +1 -2
  27. package/dist/geometry-2d.d.ts +1 -2
  28. package/dist/geometry-2d.js +961 -3586
  29. package/dist/geometry-2d.js.map +1 -1
  30. package/dist/geometry-2d.mjs +3 -3
  31. package/dist/geometry-3d.d.mts +1 -2
  32. package/dist/geometry-3d.d.ts +1 -2
  33. package/dist/geometry-3d.js +28 -11
  34. package/dist/geometry-3d.js.map +1 -1
  35. package/dist/geometry-3d.mjs +3 -3
  36. package/dist/graph-2d.d.mts +1 -2
  37. package/dist/graph-2d.d.ts +1 -2
  38. package/dist/graph-2d.js +28 -11
  39. package/dist/graph-2d.js.map +1 -1
  40. package/dist/graph-2d.mjs +3 -3
  41. package/dist/{host-M26FS244.mjs → host-2ISGVO7O.mjs} +5 -5
  42. package/dist/{host-M26FS244.mjs.map → host-2ISGVO7O.mjs.map} +1 -1
  43. package/dist/{host-HAYCJJ2T.mjs → host-HKMZSCIT.mjs} +142 -318
  44. package/dist/host-HKMZSCIT.mjs.map +1 -0
  45. package/dist/{host-LTJHAY5A.mjs → host-HOSJHQ5H.mjs} +6 -6
  46. package/dist/{host-LTJHAY5A.mjs.map → host-HOSJHQ5H.mjs.map} +1 -1
  47. package/dist/index.d.mts +9 -6
  48. package/dist/index.d.ts +9 -6
  49. package/dist/index.js +913 -3540
  50. package/dist/index.js.map +1 -1
  51. package/dist/index.mjs +17 -16
  52. package/dist/index.mjs.map +1 -1
  53. package/dist/latex.d.mts +1 -2
  54. package/dist/latex.d.ts +1 -2
  55. package/dist/serialize-N4G6RFBB.mjs +9 -0
  56. package/dist/{serialize-C3LSUMSA.mjs.map → serialize-N4G6RFBB.mjs.map} +1 -1
  57. package/dist/{types-zc_Pa0mp.d.ts → types-C3FjpoUi.d.mts} +22 -229
  58. package/dist/{types-zc_Pa0mp.d.mts → types-C3FjpoUi.d.ts} +22 -229
  59. package/package.json +1 -9
  60. package/dist/chunk-AJAHD35N.mjs.map +0 -1
  61. package/dist/chunk-D5LWSN2Y.mjs.map +0 -1
  62. package/dist/chunk-T3SOHYB2.mjs +0 -851
  63. package/dist/chunk-T3SOHYB2.mjs.map +0 -1
  64. package/dist/handleExtractProblem-C-U5KluK.d.mts +0 -158
  65. package/dist/handleExtractProblem-C-U5KluK.d.ts +0 -158
  66. package/dist/host-HAYCJJ2T.mjs.map +0 -1
  67. package/dist/serialize-C3LSUMSA.mjs +0 -9
package/dist/latex.d.mts CHANGED
@@ -1,5 +1,4 @@
1
- import { B as BaseStampCustomData, S as StampType } from './types-zc_Pa0mp.mjs';
2
- import 'zod';
1
+ import { B as BaseStampCustomData, S as StampType } from './types-C3FjpoUi.mjs';
3
2
  import 'react';
4
3
  import '@excalidraw/excalidraw/element/types';
5
4
 
package/dist/latex.d.ts CHANGED
@@ -1,5 +1,4 @@
1
- import { B as BaseStampCustomData, S as StampType } from './types-zc_Pa0mp.js';
2
- import 'zod';
1
+ import { B as BaseStampCustomData, S as StampType } from './types-C3FjpoUi.js';
3
2
  import 'react';
4
3
  import '@excalidraw/excalidraw/element/types';
5
4
 
@@ -0,0 +1,9 @@
1
+ "use client";
2
+ export { parseSceneState, stringifySceneState } from './chunk-V3YJ6JFL.mjs';
3
+ import './chunk-ZTQBUKLJ.mjs';
4
+ import './chunk-IHUFOV7L.mjs';
5
+ import './chunk-73Q7ADVL.mjs';
6
+ import './chunk-B4NJJZFR.mjs';
7
+ import './chunk-J5LGTIGS.mjs';
8
+ //# sourceMappingURL=serialize-N4G6RFBB.mjs.map
9
+ //# sourceMappingURL=serialize-N4G6RFBB.mjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":[],"names":[],"mappings":"","file":"serialize-C3LSUMSA.mjs"}
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"serialize-N4G6RFBB.mjs"}
@@ -1,231 +1,24 @@
1
- import { z } from 'zod';
2
1
  import { ReactNode, ComponentType, RefAttributes } from 'react';
3
2
  import { ExcalidrawElement } from '@excalidraw/excalidraw/element/types';
4
3
 
5
- declare const NameZ: z.ZodString;
6
-
7
- type Name = z.infer<typeof NameZ>;
8
- type DslDistanceSpec = {
9
- kind: 'circleRadius';
10
- circle: Name;
11
- scale?: number;
12
- offset?: number;
13
- } | {
14
- kind: 'segmentLength';
15
- p1: Name;
16
- p2: Name;
17
- scale?: number;
18
- offset?: number;
19
- } | {
20
- kind: 'literal';
21
- value: number;
22
- scale?: number;
23
- offset?: number;
24
- };
25
- type DslPointT = {
26
- name: Name;
27
- kind: 'free';
4
+ /**
5
+ * Snapshot tiến trình dựng hình geometry-2d, phát ra trong lúc GV thao tác
6
+ * (trước khi chèn ảnh thật). Consumer broadcast cho học sinh để vẽ ghost preview.
7
+ * Toạ độ + kích thước tính theo board-units của Excalidraw.
8
+ */
9
+ interface GeometryDraftPreview {
10
+ /** SVG markup của hình đang dựng (đã render từ state hiện tại). */
11
+ svg: string;
12
+ /** Board-units width (= intrinsic px của SVG ở zoom 1). */
13
+ width: number;
14
+ /** Board-units height. */
15
+ height: number;
16
+ /** Board-coord góc trên-trái nơi ảnh sẽ được chèn. */
28
17
  x: number;
29
18
  y: number;
30
- } | {
31
- name: Name;
32
- kind: 'midpoint';
33
- p1: Name;
34
- p2: Name;
35
- visible?: boolean;
36
- } | {
37
- name: Name;
38
- kind: 'onSegment';
39
- segmentId: Name;
40
- t: number;
41
- } | {
42
- name: Name;
43
- kind: 'onLine';
44
- lineId: Name;
45
- t: number;
46
- } | {
47
- name: Name;
48
- kind: 'onCircle';
49
- circleId: Name;
50
- theta: number;
51
- } | {
52
- name: Name;
53
- kind: 'perpFoot';
54
- from: Name;
55
- onLine: Name;
56
- } | {
57
- name: Name;
58
- kind: 'circumcenter';
59
- vertices: [Name, Name, Name];
60
- } | {
61
- name: Name;
62
- kind: 'incenter';
63
- vertices: [Name, Name, Name];
64
- } | {
65
- name: Name;
66
- kind: 'centroid';
67
- vertices: [Name, Name, Name];
68
- } | {
69
- name: Name;
70
- kind: 'orthocenter';
71
- vertices: [Name, Name, Name];
72
- } | {
73
- name: Name;
74
- kind: 'intersection';
75
- ref1: Name;
76
- ref2: Name;
77
- branch?: 0 | 1;
78
- } | {
79
- name: Name;
80
- kind: 'secondIntersection';
81
- line: Name;
82
- circle: Name;
83
- other: Name;
84
- } | {
85
- name: Name;
86
- kind: 'circleIntersection';
87
- c1: Name;
88
- c2: Name;
89
- which: 0 | 1;
90
- } | {
91
- name: Name;
92
- kind: 'circleSecondIntersection';
93
- c1: Name;
94
- c2: Name;
95
- exclude: Name;
96
- } | {
97
- name: Name;
98
- kind: 'tangencyPoint';
99
- circle: Name;
100
- onLine: Name;
101
- } | {
102
- name: Name;
103
- kind: 'tangentPointExt';
104
- from: Name;
105
- circle: Name;
106
- which: 0 | 1;
107
- } | {
108
- name: Name;
109
- kind: 'arcMidpoint';
110
- circle: Name;
111
- a: Name;
112
- b: Name;
113
- notContaining: Name;
114
- } | {
115
- name: Name;
116
- kind: 'excenter';
117
- vertices: [Name, Name, Name];
118
- opposite: Name;
119
- } | {
120
- name: Name;
121
- kind: 'reflectPoint';
122
- of: Name;
123
- through: Name;
124
- } | {
125
- name: Name;
126
- kind: 'reflectLine';
127
- of: Name;
128
- through: Name;
129
- } | {
130
- name: Name;
131
- kind: 'pointAtDistance';
132
- from: Name;
133
- through: Name;
134
- distance: DslDistanceSpec;
135
- };
136
- type DslShapeT = {
137
- name: Name;
138
- kind: 'segment';
139
- p1: Name;
140
- p2: Name;
141
- } | {
142
- name: Name;
143
- kind: 'line';
144
- p1: Name;
145
- p2: Name;
146
- } | {
147
- name: Name;
148
- kind: 'ray';
149
- origin: Name;
150
- through: Name;
151
- } | {
152
- name: Name;
153
- kind: 'polygon';
154
- vertices: Name[];
155
- } | {
156
- name: Name;
157
- kind: 'perpendicular';
158
- throughPoint: Name;
159
- toLine: Name;
160
- } | {
161
- name: Name;
162
- kind: 'parallel';
163
- throughPoint: Name;
164
- toLine: Name;
165
- } | {
166
- name: Name;
167
- kind: 'perpBisector';
168
- p1: Name;
169
- p2: Name;
170
- } | {
171
- name: Name;
172
- kind: 'angleBisector';
173
- p1: Name;
174
- vertex: Name;
175
- p2: Name;
176
- } | {
177
- name: Name;
178
- kind: 'lineThrough';
179
- points: Name[];
180
- } | {
181
- name: Name;
182
- kind: 'radicalAxis';
183
- circle1: Name;
184
- circle2: Name;
185
- } | {
186
- name: Name;
187
- kind: 'tangent';
188
- throughPoint: Name;
189
- toCircle: Name;
190
- branch?: 0 | 1 | 'on';
191
- } | {
192
- name: Name;
193
- kind: 'circleCP';
194
- center: Name;
195
- surfacePoint: Name;
196
- visible?: boolean;
197
- } | {
198
- name: Name;
199
- kind: 'circle3';
200
- p1: Name;
201
- p2: Name;
202
- p3: Name;
203
- } | {
204
- name: Name;
205
- kind: 'circleDiameter';
206
- p1: Name;
207
- p2: Name;
208
- visible?: boolean;
209
- } | {
210
- name: Name;
211
- kind: 'circleCR';
212
- center: Name;
213
- radius: number;
214
- } | {
215
- name: Name;
216
- kind: 'incircle';
217
- vertices: [Name, Name, Name];
218
- } | {
219
- name: Name;
220
- kind: 'excircle';
221
- vertices: [Name, Name, Name];
222
- opposite: Name;
223
- };
224
- type DslInputT = {
225
- version: 1;
226
- points: DslPointT[];
227
- shapes: DslShapeT[];
228
- };
19
+ /** Counter tăng dần để consumer bỏ khung cũ khi kênh lossy reorder. */
20
+ seq: number;
21
+ }
229
22
 
230
23
  type SceneObject<A = Record<string, unknown>> = {
231
24
  id: string;
@@ -297,15 +90,10 @@ interface AiFigureProgress {
297
90
  *
298
91
  * `onProgress` là optional: nếu consumer dùng streaming endpoint (SSE),
299
92
  * forward chunk events vào đây. Non-streaming impl bỏ qua.
300
- *
301
- * `currentDsl` (MỚI cho multi-step refine): khi caller có hình hiện tại
302
- * (state.order.length > 0) và muốn AI sửa/thêm → pass currentDsl. Consumer
303
- * branch sang refine endpoint. Không pass → build endpoint cũ.
304
93
  */
305
94
  type GenerateGeometryFigure = (problem: string, options: {
306
95
  signal: AbortSignal;
307
96
  onProgress?: (info: AiFigureProgress) => void;
308
- currentDsl?: DslInputT;
309
97
  }) => Promise<AiFigureUiResult>;
310
98
  /**
311
99
  * Kết quả trả về từ `restoreFileFromCustomData`. Chứa đủ thông tin để
@@ -345,6 +133,11 @@ interface StampHostProps {
345
133
  isDark: boolean;
346
134
  /** Optional client-safe bridge for the geometry-2d AI prompt editor. */
347
135
  generateGeometryFigure?: GenerateGeometryFigure;
136
+ /**
137
+ * Chỉ geometry-2d dùng: phát snapshot hình đang dựng (debounced) để consumer
138
+ * broadcast cho học sinh xem live. `null` = clear ghost (đã chèn / huỷ / rỗng).
139
+ */
140
+ onGeometryDraft?: (draft: GeometryDraftPreview | null) => void;
348
141
  }
349
142
  /**
350
143
  * Imperative API mà main view truy cập qua ref:
@@ -415,4 +208,4 @@ interface StampType<TCustomData extends BaseStampCustomData = BaseStampCustomDat
415
208
  experimental?: boolean;
416
209
  }
417
210
 
418
- export type { AiFigureProgress as A, BaseStampCustomData as B, DslInputT as D, GenerateGeometryFigure as G, StampType as S, AiFigureUiResult as a, State as b };
211
+ export type { AiFigureProgress as A, BaseStampCustomData as B, GenerateGeometryFigure as G, StampType as S, GeometryDraftPreview as a, AiFigureUiResult as b, State as c };
@@ -1,231 +1,24 @@
1
- import { z } from 'zod';
2
1
  import { ReactNode, ComponentType, RefAttributes } from 'react';
3
2
  import { ExcalidrawElement } from '@excalidraw/excalidraw/element/types';
4
3
 
5
- declare const NameZ: z.ZodString;
6
-
7
- type Name = z.infer<typeof NameZ>;
8
- type DslDistanceSpec = {
9
- kind: 'circleRadius';
10
- circle: Name;
11
- scale?: number;
12
- offset?: number;
13
- } | {
14
- kind: 'segmentLength';
15
- p1: Name;
16
- p2: Name;
17
- scale?: number;
18
- offset?: number;
19
- } | {
20
- kind: 'literal';
21
- value: number;
22
- scale?: number;
23
- offset?: number;
24
- };
25
- type DslPointT = {
26
- name: Name;
27
- kind: 'free';
4
+ /**
5
+ * Snapshot tiến trình dựng hình geometry-2d, phát ra trong lúc GV thao tác
6
+ * (trước khi chèn ảnh thật). Consumer broadcast cho học sinh để vẽ ghost preview.
7
+ * Toạ độ + kích thước tính theo board-units của Excalidraw.
8
+ */
9
+ interface GeometryDraftPreview {
10
+ /** SVG markup của hình đang dựng (đã render từ state hiện tại). */
11
+ svg: string;
12
+ /** Board-units width (= intrinsic px của SVG ở zoom 1). */
13
+ width: number;
14
+ /** Board-units height. */
15
+ height: number;
16
+ /** Board-coord góc trên-trái nơi ảnh sẽ được chèn. */
28
17
  x: number;
29
18
  y: number;
30
- } | {
31
- name: Name;
32
- kind: 'midpoint';
33
- p1: Name;
34
- p2: Name;
35
- visible?: boolean;
36
- } | {
37
- name: Name;
38
- kind: 'onSegment';
39
- segmentId: Name;
40
- t: number;
41
- } | {
42
- name: Name;
43
- kind: 'onLine';
44
- lineId: Name;
45
- t: number;
46
- } | {
47
- name: Name;
48
- kind: 'onCircle';
49
- circleId: Name;
50
- theta: number;
51
- } | {
52
- name: Name;
53
- kind: 'perpFoot';
54
- from: Name;
55
- onLine: Name;
56
- } | {
57
- name: Name;
58
- kind: 'circumcenter';
59
- vertices: [Name, Name, Name];
60
- } | {
61
- name: Name;
62
- kind: 'incenter';
63
- vertices: [Name, Name, Name];
64
- } | {
65
- name: Name;
66
- kind: 'centroid';
67
- vertices: [Name, Name, Name];
68
- } | {
69
- name: Name;
70
- kind: 'orthocenter';
71
- vertices: [Name, Name, Name];
72
- } | {
73
- name: Name;
74
- kind: 'intersection';
75
- ref1: Name;
76
- ref2: Name;
77
- branch?: 0 | 1;
78
- } | {
79
- name: Name;
80
- kind: 'secondIntersection';
81
- line: Name;
82
- circle: Name;
83
- other: Name;
84
- } | {
85
- name: Name;
86
- kind: 'circleIntersection';
87
- c1: Name;
88
- c2: Name;
89
- which: 0 | 1;
90
- } | {
91
- name: Name;
92
- kind: 'circleSecondIntersection';
93
- c1: Name;
94
- c2: Name;
95
- exclude: Name;
96
- } | {
97
- name: Name;
98
- kind: 'tangencyPoint';
99
- circle: Name;
100
- onLine: Name;
101
- } | {
102
- name: Name;
103
- kind: 'tangentPointExt';
104
- from: Name;
105
- circle: Name;
106
- which: 0 | 1;
107
- } | {
108
- name: Name;
109
- kind: 'arcMidpoint';
110
- circle: Name;
111
- a: Name;
112
- b: Name;
113
- notContaining: Name;
114
- } | {
115
- name: Name;
116
- kind: 'excenter';
117
- vertices: [Name, Name, Name];
118
- opposite: Name;
119
- } | {
120
- name: Name;
121
- kind: 'reflectPoint';
122
- of: Name;
123
- through: Name;
124
- } | {
125
- name: Name;
126
- kind: 'reflectLine';
127
- of: Name;
128
- through: Name;
129
- } | {
130
- name: Name;
131
- kind: 'pointAtDistance';
132
- from: Name;
133
- through: Name;
134
- distance: DslDistanceSpec;
135
- };
136
- type DslShapeT = {
137
- name: Name;
138
- kind: 'segment';
139
- p1: Name;
140
- p2: Name;
141
- } | {
142
- name: Name;
143
- kind: 'line';
144
- p1: Name;
145
- p2: Name;
146
- } | {
147
- name: Name;
148
- kind: 'ray';
149
- origin: Name;
150
- through: Name;
151
- } | {
152
- name: Name;
153
- kind: 'polygon';
154
- vertices: Name[];
155
- } | {
156
- name: Name;
157
- kind: 'perpendicular';
158
- throughPoint: Name;
159
- toLine: Name;
160
- } | {
161
- name: Name;
162
- kind: 'parallel';
163
- throughPoint: Name;
164
- toLine: Name;
165
- } | {
166
- name: Name;
167
- kind: 'perpBisector';
168
- p1: Name;
169
- p2: Name;
170
- } | {
171
- name: Name;
172
- kind: 'angleBisector';
173
- p1: Name;
174
- vertex: Name;
175
- p2: Name;
176
- } | {
177
- name: Name;
178
- kind: 'lineThrough';
179
- points: Name[];
180
- } | {
181
- name: Name;
182
- kind: 'radicalAxis';
183
- circle1: Name;
184
- circle2: Name;
185
- } | {
186
- name: Name;
187
- kind: 'tangent';
188
- throughPoint: Name;
189
- toCircle: Name;
190
- branch?: 0 | 1 | 'on';
191
- } | {
192
- name: Name;
193
- kind: 'circleCP';
194
- center: Name;
195
- surfacePoint: Name;
196
- visible?: boolean;
197
- } | {
198
- name: Name;
199
- kind: 'circle3';
200
- p1: Name;
201
- p2: Name;
202
- p3: Name;
203
- } | {
204
- name: Name;
205
- kind: 'circleDiameter';
206
- p1: Name;
207
- p2: Name;
208
- visible?: boolean;
209
- } | {
210
- name: Name;
211
- kind: 'circleCR';
212
- center: Name;
213
- radius: number;
214
- } | {
215
- name: Name;
216
- kind: 'incircle';
217
- vertices: [Name, Name, Name];
218
- } | {
219
- name: Name;
220
- kind: 'excircle';
221
- vertices: [Name, Name, Name];
222
- opposite: Name;
223
- };
224
- type DslInputT = {
225
- version: 1;
226
- points: DslPointT[];
227
- shapes: DslShapeT[];
228
- };
19
+ /** Counter tăng dần để consumer bỏ khung cũ khi kênh lossy reorder. */
20
+ seq: number;
21
+ }
229
22
 
230
23
  type SceneObject<A = Record<string, unknown>> = {
231
24
  id: string;
@@ -297,15 +90,10 @@ interface AiFigureProgress {
297
90
  *
298
91
  * `onProgress` là optional: nếu consumer dùng streaming endpoint (SSE),
299
92
  * forward chunk events vào đây. Non-streaming impl bỏ qua.
300
- *
301
- * `currentDsl` (MỚI cho multi-step refine): khi caller có hình hiện tại
302
- * (state.order.length > 0) và muốn AI sửa/thêm → pass currentDsl. Consumer
303
- * branch sang refine endpoint. Không pass → build endpoint cũ.
304
93
  */
305
94
  type GenerateGeometryFigure = (problem: string, options: {
306
95
  signal: AbortSignal;
307
96
  onProgress?: (info: AiFigureProgress) => void;
308
- currentDsl?: DslInputT;
309
97
  }) => Promise<AiFigureUiResult>;
310
98
  /**
311
99
  * Kết quả trả về từ `restoreFileFromCustomData`. Chứa đủ thông tin để
@@ -345,6 +133,11 @@ interface StampHostProps {
345
133
  isDark: boolean;
346
134
  /** Optional client-safe bridge for the geometry-2d AI prompt editor. */
347
135
  generateGeometryFigure?: GenerateGeometryFigure;
136
+ /**
137
+ * Chỉ geometry-2d dùng: phát snapshot hình đang dựng (debounced) để consumer
138
+ * broadcast cho học sinh xem live. `null` = clear ghost (đã chèn / huỷ / rỗng).
139
+ */
140
+ onGeometryDraft?: (draft: GeometryDraftPreview | null) => void;
348
141
  }
349
142
  /**
350
143
  * Imperative API mà main view truy cập qua ref:
@@ -415,4 +208,4 @@ interface StampType<TCustomData extends BaseStampCustomData = BaseStampCustomDat
415
208
  experimental?: boolean;
416
209
  }
417
210
 
418
- export type { AiFigureProgress as A, BaseStampCustomData as B, DslInputT as D, GenerateGeometryFigure as G, StampType as S, AiFigureUiResult as a, State as b };
211
+ export type { AiFigureProgress as A, BaseStampCustomData as B, GenerateGeometryFigure as G, StampType as S, GeometryDraftPreview as a, AiFigureUiResult as b, State as c };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@xom11/whiteboard",
3
- "version": "0.27.0",
3
+ "version": "0.29.0",
4
4
  "private": false,
5
5
  "description": "Excalidraw + JSXGraph + KaTeX whiteboard component (drawing, geometry stamps, LaTeX stamps).",
6
6
  "repository": {
@@ -118,17 +118,9 @@
118
118
  "vite": "^8.0.13"
119
119
  },
120
120
  "dependencies": {
121
- "@anthropic-ai/claude-agent-sdk": "^0.3.161",
122
- "@anthropic-ai/sdk": "^0.98.0",
123
121
  "immer": "^10.2.0",
124
122
  "pdfjs-dist": "^5.7.284",
125
- "tesseract.js": "^7.0.0",
126
123
  "zod": "^3.23.8",
127
124
  "zod-to-json-schema": "^3.25.2"
128
- },
129
- "overrides": {
130
- "@anthropic-ai/claude-agent-sdk": {
131
- "zod": "$zod"
132
- }
133
125
  }
134
126
  }