@graphrefly/graphrefly 0.47.2 → 0.48.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 (266) hide show
  1. package/dist/base/composition/index.cjs +4 -3
  2. package/dist/base/composition/index.cjs.map +1 -1
  3. package/dist/base/composition/index.d.cts +14 -5
  4. package/dist/base/composition/index.d.ts +14 -5
  5. package/dist/base/composition/index.js +8 -8
  6. package/dist/base/index.cjs +152 -78
  7. package/dist/base/index.cjs.map +1 -1
  8. package/dist/base/index.d.cts +2 -2
  9. package/dist/base/index.d.ts +2 -2
  10. package/dist/base/index.js +75 -70
  11. package/dist/base/io/index.cjs +31 -17
  12. package/dist/base/io/index.cjs.map +1 -1
  13. package/dist/base/io/index.d.cts +32 -5
  14. package/dist/base/io/index.d.ts +32 -5
  15. package/dist/base/io/index.js +1 -1
  16. package/dist/base/mutation/index.cjs +21 -0
  17. package/dist/base/mutation/index.cjs.map +1 -1
  18. package/dist/base/mutation/index.d.cts +23 -1
  19. package/dist/base/mutation/index.d.ts +23 -1
  20. package/dist/base/mutation/index.js +3 -1
  21. package/dist/base/sources/browser/index.cjs +5 -3
  22. package/dist/base/sources/browser/index.cjs.map +1 -1
  23. package/dist/base/sources/browser/index.d.cts +20 -2
  24. package/dist/base/sources/browser/index.d.ts +20 -2
  25. package/dist/base/sources/browser/index.js +5 -3
  26. package/dist/base/sources/browser/index.js.map +1 -1
  27. package/dist/base/sources/event/index.cjs +28 -0
  28. package/dist/base/sources/event/index.cjs.map +1 -1
  29. package/dist/base/sources/event/index.d.cts +67 -3
  30. package/dist/base/sources/event/index.d.ts +67 -3
  31. package/dist/base/sources/event/index.js +4 -1
  32. package/dist/base/sources/index.cjs +75 -37
  33. package/dist/base/sources/index.cjs.map +1 -1
  34. package/dist/base/sources/index.d.cts +1 -1
  35. package/dist/base/sources/index.d.ts +1 -1
  36. package/dist/base/sources/index.js +5 -2
  37. package/dist/{chunk-R6ZCSXKX.js → chunk-23MAWVOJ.js} +3 -3
  38. package/dist/{chunk-MS3WPRJR.js → chunk-3REMCHSS.js} +6 -6
  39. package/dist/chunk-3REMCHSS.js.map +1 -0
  40. package/dist/{chunk-CEVNQ74M.js → chunk-3YGXPUHW.js} +2 -2
  41. package/dist/{chunk-CEVNQ74M.js.map → chunk-3YGXPUHW.js.map} +1 -1
  42. package/dist/{chunk-6ZLCPUXS.js → chunk-46X2EFQH.js} +15 -4
  43. package/dist/chunk-46X2EFQH.js.map +1 -0
  44. package/dist/{chunk-NY2PYHNC.js → chunk-5UY3PNFY.js} +12 -5
  45. package/dist/chunk-5UY3PNFY.js.map +1 -0
  46. package/dist/{chunk-FQSQONOU.js → chunk-65OM4XLQ.js} +49 -3
  47. package/dist/chunk-65OM4XLQ.js.map +1 -0
  48. package/dist/{chunk-3PSLNJDU.js → chunk-6DQYBIHW.js} +314 -49
  49. package/dist/chunk-6DQYBIHW.js.map +1 -0
  50. package/dist/{chunk-LDCSZ72P.js → chunk-6YBER5UP.js} +3 -3
  51. package/dist/{chunk-LDCSZ72P.js.map → chunk-6YBER5UP.js.map} +1 -1
  52. package/dist/{chunk-3O3NKZJW.js → chunk-7T7WLEPM.js} +24 -3
  53. package/dist/chunk-7T7WLEPM.js.map +1 -0
  54. package/dist/{chunk-PKPO3JTZ.js → chunk-AQAKDE7F.js} +29 -11
  55. package/dist/chunk-AQAKDE7F.js.map +1 -0
  56. package/dist/{chunk-6MRSX3YK.js → chunk-B5Y5GPD5.js} +2 -2
  57. package/dist/{chunk-BXGZFGZ4.js → chunk-C5QD5DQX.js} +22 -1
  58. package/dist/chunk-C5QD5DQX.js.map +1 -0
  59. package/dist/{chunk-4XCHZRUJ.js → chunk-D5YGR4TP.js} +58 -7
  60. package/dist/chunk-D5YGR4TP.js.map +1 -0
  61. package/dist/{chunk-NPRP3MCV.js → chunk-DHDCOOJU.js} +2 -2
  62. package/dist/chunk-DHDCOOJU.js.map +1 -0
  63. package/dist/{chunk-VP3TIUDF.js → chunk-DVTDF5OI.js} +2 -2
  64. package/dist/{chunk-OXD5LFQP.js → chunk-G7H6PN7P.js} +2 -2
  65. package/dist/{chunk-EL5VHUGK.js → chunk-GGKHHG5Y.js} +32 -18
  66. package/dist/chunk-GGKHHG5Y.js.map +1 -0
  67. package/dist/{chunk-446I4EGD.js → chunk-J5TBZFBD.js} +2 -2
  68. package/dist/{chunk-7AVQIGF6.js → chunk-K4ZYJ4EM.js} +554 -460
  69. package/dist/chunk-K4ZYJ4EM.js.map +1 -0
  70. package/dist/{chunk-QFE5BQH7.js → chunk-LTSI7ULC.js} +2 -2
  71. package/dist/{chunk-5GVURVIG.js → chunk-MMHGYX44.js} +12 -2
  72. package/dist/{chunk-5GVURVIG.js.map → chunk-MMHGYX44.js.map} +1 -1
  73. package/dist/{chunk-KRFGO5QH.js → chunk-MQMTRKY3.js} +118 -43
  74. package/dist/chunk-MQMTRKY3.js.map +1 -0
  75. package/dist/{chunk-42FQ27MQ.js → chunk-MTODGQBR.js} +44 -179
  76. package/dist/chunk-MTODGQBR.js.map +1 -0
  77. package/dist/{chunk-FVINAAKA.js → chunk-NBK6QQMG.js} +14 -13
  78. package/dist/{chunk-FVINAAKA.js.map → chunk-NBK6QQMG.js.map} +1 -1
  79. package/dist/{chunk-KNU73RZW.js → chunk-NSA5K5G2.js} +2 -2
  80. package/dist/{chunk-MLTPJMH6.js → chunk-QQYULEZL.js} +2 -2
  81. package/dist/chunk-QSW4DFKE.js +31 -0
  82. package/dist/chunk-QSW4DFKE.js.map +1 -0
  83. package/dist/{chunk-VAZXUK6G.js → chunk-SUNCHMML.js} +2 -2
  84. package/dist/{chunk-EP4WVQLX.js → chunk-T2U6N3FV.js} +6 -6
  85. package/dist/{chunk-T7SP3EYR.js → chunk-T5URUIIY.js} +33 -24
  86. package/dist/chunk-T5URUIIY.js.map +1 -0
  87. package/dist/{chunk-VNXAF2KE.js → chunk-TPTZZV25.js} +6 -6
  88. package/dist/chunk-TPTZZV25.js.map +1 -0
  89. package/dist/{chunk-IOJDYUA7.js → chunk-V46JWFGV.js} +6 -5
  90. package/dist/chunk-V46JWFGV.js.map +1 -0
  91. package/dist/{chunk-WGDEBIP4.js → chunk-X6ESZDR6.js} +5 -6
  92. package/dist/chunk-X6ESZDR6.js.map +1 -0
  93. package/dist/{chunk-N65E26UL.js → chunk-XEWV254I.js} +2 -2
  94. package/dist/{chunk-N65E26UL.js.map → chunk-XEWV254I.js.map} +1 -1
  95. package/dist/{chunk-PTWADEH3.js → chunk-YBJVKMTM.js} +34 -14
  96. package/dist/chunk-YBJVKMTM.js.map +1 -0
  97. package/dist/{chunk-DDTS7F5O.js → chunk-ZW32BPXV.js} +12 -3
  98. package/dist/chunk-ZW32BPXV.js.map +1 -0
  99. package/dist/compat/index.cjs +51 -4
  100. package/dist/compat/index.cjs.map +1 -1
  101. package/dist/compat/index.d.cts +1 -1
  102. package/dist/compat/index.d.ts +1 -1
  103. package/dist/compat/index.js +6 -6
  104. package/dist/compat/nestjs/index.cjs +51 -4
  105. package/dist/compat/nestjs/index.cjs.map +1 -1
  106. package/dist/compat/nestjs/index.d.cts +1 -1
  107. package/dist/compat/nestjs/index.d.ts +1 -1
  108. package/dist/compat/nestjs/index.js +3 -3
  109. package/dist/{fallback-Bx46zqky.d.cts → fallback-BROR6ZhO.d.cts} +1 -1
  110. package/dist/{fallback-pIWW8A2d.d.ts → fallback-DO80aM_3.d.ts} +1 -1
  111. package/dist/{index-B_p8tnvf.d.cts → index-D1z3XcF9.d.cts} +1 -0
  112. package/dist/{index-_HDSmPyp.d.ts → index-DZ6yua0Q.d.ts} +1 -0
  113. package/dist/index.cjs +2215 -1676
  114. package/dist/index.cjs.map +1 -1
  115. package/dist/index.d.cts +10 -10
  116. package/dist/index.d.ts +10 -10
  117. package/dist/index.js +169 -146
  118. package/dist/index.js.map +1 -1
  119. package/dist/presets/ai/index.cjs +46 -0
  120. package/dist/presets/ai/index.cjs.map +1 -1
  121. package/dist/presets/ai/index.js +12 -12
  122. package/dist/presets/harness/index.cjs +130 -18
  123. package/dist/presets/harness/index.cjs.map +1 -1
  124. package/dist/presets/harness/index.d.cts +15 -5
  125. package/dist/presets/harness/index.d.ts +15 -5
  126. package/dist/presets/harness/index.js +22 -22
  127. package/dist/presets/index.cjs +222 -53
  128. package/dist/presets/index.cjs.map +1 -1
  129. package/dist/presets/index.d.cts +2 -2
  130. package/dist/presets/index.d.ts +2 -2
  131. package/dist/presets/index.js +45 -45
  132. package/dist/presets/inspect/index.cjs +63 -14
  133. package/dist/presets/inspect/index.cjs.map +1 -1
  134. package/dist/presets/inspect/index.d.cts +1 -1
  135. package/dist/presets/inspect/index.d.ts +1 -1
  136. package/dist/presets/inspect/index.js +6 -6
  137. package/dist/presets/resilience/index.cjs +29 -21
  138. package/dist/presets/resilience/index.cjs.map +1 -1
  139. package/dist/presets/resilience/index.d.cts +12 -8
  140. package/dist/presets/resilience/index.d.ts +12 -8
  141. package/dist/presets/resilience/index.js +3 -3
  142. package/dist/{rate-limiter-DpVbSYdH.d.cts → rate-limiter-DC26FM8J.d.cts} +10 -1
  143. package/dist/{rate-limiter-CEALq4N1.d.ts → rate-limiter-DyWpwpQP.d.ts} +10 -1
  144. package/dist/{reactive-layout-fswlBUvX.d.ts → reactive-layout-BBBWH0V_.d.cts} +85 -4
  145. package/dist/{reactive-layout-fswlBUvX.d.cts → reactive-layout-BBBWH0V_.d.ts} +85 -4
  146. package/dist/solutions/index.cjs +168 -47
  147. package/dist/solutions/index.cjs.map +1 -1
  148. package/dist/solutions/index.d.cts +2 -2
  149. package/dist/solutions/index.d.ts +2 -2
  150. package/dist/solutions/index.js +28 -28
  151. package/dist/{spawnable-5mDY501F.d.cts → spawnable-B2IlW60f.d.cts} +23 -2
  152. package/dist/{spawnable-D3lR0oQu.d.ts → spawnable-tttFz2Nh.d.ts} +23 -2
  153. package/dist/testing/index.cjs +94 -0
  154. package/dist/testing/index.cjs.map +1 -0
  155. package/dist/testing/index.d.cts +59 -0
  156. package/dist/testing/index.d.ts +59 -0
  157. package/dist/testing/index.js +73 -0
  158. package/dist/testing/index.js.map +1 -0
  159. package/dist/utils/ai/browser.cjs.map +1 -1
  160. package/dist/utils/ai/browser.d.cts +2 -2
  161. package/dist/utils/ai/browser.d.ts +2 -2
  162. package/dist/utils/ai/browser.js +6 -6
  163. package/dist/utils/ai/browser.js.map +1 -1
  164. package/dist/utils/ai/index.cjs +250 -166
  165. package/dist/utils/ai/index.cjs.map +1 -1
  166. package/dist/utils/ai/index.d.cts +108 -12
  167. package/dist/utils/ai/index.d.ts +108 -12
  168. package/dist/utils/ai/index.js +21 -19
  169. package/dist/utils/ai/node.cjs.map +1 -1
  170. package/dist/utils/ai/node.d.cts +5 -5
  171. package/dist/utils/ai/node.d.ts +5 -5
  172. package/dist/utils/ai/node.js +2 -2
  173. package/dist/utils/ai/node.js.map +1 -1
  174. package/dist/utils/cqrs/index.cjs +29 -3
  175. package/dist/utils/cqrs/index.cjs.map +1 -1
  176. package/dist/utils/cqrs/index.d.cts +12 -7
  177. package/dist/utils/cqrs/index.d.ts +12 -7
  178. package/dist/utils/cqrs/index.js +2 -2
  179. package/dist/utils/demo-shell/index.cjs +45 -19
  180. package/dist/utils/demo-shell/index.cjs.map +1 -1
  181. package/dist/utils/demo-shell/index.d.cts +1 -1
  182. package/dist/utils/demo-shell/index.d.ts +1 -1
  183. package/dist/utils/demo-shell/index.js +2 -2
  184. package/dist/utils/domain-templates/index.cjs.map +1 -1
  185. package/dist/utils/domain-templates/index.js +3 -3
  186. package/dist/utils/graphspec/index.cjs.map +1 -1
  187. package/dist/utils/graphspec/index.js +3 -3
  188. package/dist/utils/index.cjs +1642 -1225
  189. package/dist/utils/index.cjs.map +1 -1
  190. package/dist/utils/index.d.cts +7 -7
  191. package/dist/utils/index.d.ts +7 -7
  192. package/dist/utils/index.js +72 -54
  193. package/dist/utils/inspect/index.cjs +52 -4
  194. package/dist/utils/inspect/index.cjs.map +1 -1
  195. package/dist/utils/inspect/index.d.cts +32 -3
  196. package/dist/utils/inspect/index.d.ts +32 -3
  197. package/dist/utils/inspect/index.js +4 -4
  198. package/dist/utils/job-queue/index.cjs +46 -9
  199. package/dist/utils/job-queue/index.cjs.map +1 -1
  200. package/dist/utils/job-queue/index.d.cts +33 -3
  201. package/dist/utils/job-queue/index.d.ts +33 -3
  202. package/dist/utils/job-queue/index.js +2 -2
  203. package/dist/utils/memory/index.cjs +556 -462
  204. package/dist/utils/memory/index.cjs.map +1 -1
  205. package/dist/utils/memory/index.d.cts +203 -24
  206. package/dist/utils/memory/index.d.ts +203 -24
  207. package/dist/utils/memory/index.js +10 -2
  208. package/dist/utils/messaging/index.cjs.map +1 -1
  209. package/dist/utils/messaging/index.d.cts +4 -3
  210. package/dist/utils/messaging/index.d.ts +4 -3
  211. package/dist/utils/messaging/index.js +2 -2
  212. package/dist/utils/orchestration/index.cjs +9 -0
  213. package/dist/utils/orchestration/index.cjs.map +1 -1
  214. package/dist/utils/orchestration/index.js +3 -3
  215. package/dist/utils/process/index.cjs +32 -2
  216. package/dist/utils/process/index.cjs.map +1 -1
  217. package/dist/utils/process/index.d.cts +4 -3
  218. package/dist/utils/process/index.d.ts +4 -3
  219. package/dist/utils/process/index.js +2 -2
  220. package/dist/utils/reactive-layout/index.cjs +184 -55
  221. package/dist/utils/reactive-layout/index.cjs.map +1 -1
  222. package/dist/utils/reactive-layout/index.d.cts +128 -3
  223. package/dist/utils/reactive-layout/index.d.ts +128 -3
  224. package/dist/utils/reactive-layout/index.js +16 -8
  225. package/dist/utils/reduction/index.cjs.map +1 -1
  226. package/dist/utils/reduction/index.js +2 -2
  227. package/dist/utils/resilience/index.cjs +29 -20
  228. package/dist/utils/resilience/index.cjs.map +1 -1
  229. package/dist/utils/resilience/index.d.cts +1 -1
  230. package/dist/utils/resilience/index.d.ts +1 -1
  231. package/dist/utils/resilience/index.js +2 -2
  232. package/dist/utils/surface/index.cjs.map +1 -1
  233. package/dist/utils/surface/index.js +4 -4
  234. package/package.json +15 -3
  235. package/dist/chunk-3O3NKZJW.js.map +0 -1
  236. package/dist/chunk-3PSLNJDU.js.map +0 -1
  237. package/dist/chunk-42FQ27MQ.js.map +0 -1
  238. package/dist/chunk-4XCHZRUJ.js.map +0 -1
  239. package/dist/chunk-6ZLCPUXS.js.map +0 -1
  240. package/dist/chunk-7AVQIGF6.js.map +0 -1
  241. package/dist/chunk-BXGZFGZ4.js.map +0 -1
  242. package/dist/chunk-DDTS7F5O.js.map +0 -1
  243. package/dist/chunk-EL5VHUGK.js.map +0 -1
  244. package/dist/chunk-FQSQONOU.js.map +0 -1
  245. package/dist/chunk-IOJDYUA7.js.map +0 -1
  246. package/dist/chunk-KRFGO5QH.js.map +0 -1
  247. package/dist/chunk-MS3WPRJR.js.map +0 -1
  248. package/dist/chunk-NPRP3MCV.js.map +0 -1
  249. package/dist/chunk-NY2PYHNC.js.map +0 -1
  250. package/dist/chunk-PKPO3JTZ.js.map +0 -1
  251. package/dist/chunk-PTWADEH3.js.map +0 -1
  252. package/dist/chunk-T7SP3EYR.js.map +0 -1
  253. package/dist/chunk-VNXAF2KE.js.map +0 -1
  254. package/dist/chunk-W2BOPXTI.js +0 -1
  255. package/dist/chunk-W2BOPXTI.js.map +0 -1
  256. package/dist/chunk-WGDEBIP4.js.map +0 -1
  257. /package/dist/{chunk-R6ZCSXKX.js.map → chunk-23MAWVOJ.js.map} +0 -0
  258. /package/dist/{chunk-6MRSX3YK.js.map → chunk-B5Y5GPD5.js.map} +0 -0
  259. /package/dist/{chunk-VP3TIUDF.js.map → chunk-DVTDF5OI.js.map} +0 -0
  260. /package/dist/{chunk-OXD5LFQP.js.map → chunk-G7H6PN7P.js.map} +0 -0
  261. /package/dist/{chunk-446I4EGD.js.map → chunk-J5TBZFBD.js.map} +0 -0
  262. /package/dist/{chunk-QFE5BQH7.js.map → chunk-LTSI7ULC.js.map} +0 -0
  263. /package/dist/{chunk-KNU73RZW.js.map → chunk-NSA5K5G2.js.map} +0 -0
  264. /package/dist/{chunk-MLTPJMH6.js.map → chunk-QQYULEZL.js.map} +0 -0
  265. /package/dist/{chunk-VAZXUK6G.js.map → chunk-SUNCHMML.js.map} +0 -0
  266. /package/dist/{chunk-EP4WVQLX.js.map → chunk-T2U6N3FV.js.map} +0 -0
@@ -1,6 +1,230 @@
1
1
  import {
2
2
  emitToMeta
3
3
  } from "./chunk-KN3H5CNT.js";
4
+ import {
5
+ countCells
6
+ } from "./chunk-36NMM65U.js";
7
+
8
+ // src/utils/reactive-layout/measurement-adapters.ts
9
+ var IntlSegmentAdapter = class {
10
+ wordSeg = null;
11
+ graphemeSeg = null;
12
+ constructor() {
13
+ if (typeof Intl === "undefined" || typeof Intl.Segmenter !== "function") {
14
+ throw new TypeError(
15
+ "IntlSegmentAdapter: Intl.Segmenter is not available in this runtime (Hermes / older embedded JS engines). Pass a custom SegmentAdapter via `reactiveLayout({ segmentAdapter })` \u2014 see the SegmentAdapter JSDoc for the polyfill recipe (e.g. `intl-segmenter-polyfill` or `@formatjs/intl-segmenter`)."
16
+ );
17
+ }
18
+ }
19
+ segmentWords(text) {
20
+ if (this.wordSeg === null) {
21
+ this.wordSeg = new Intl.Segmenter(void 0, { granularity: "word" });
22
+ }
23
+ return this.wordSeg.segment(text);
24
+ }
25
+ segmentGraphemes(text) {
26
+ if (this.graphemeSeg === null) {
27
+ this.graphemeSeg = new Intl.Segmenter(void 0, { granularity: "grapheme" });
28
+ }
29
+ return this.graphemeSeg.segment(text);
30
+ }
31
+ };
32
+ var _defaultSegmentAdapter = null;
33
+ function getDefaultSegmentAdapter() {
34
+ if (_defaultSegmentAdapter === null) {
35
+ _defaultSegmentAdapter = new IntlSegmentAdapter();
36
+ }
37
+ return _defaultSegmentAdapter;
38
+ }
39
+ function _resetDefaultSegmentAdapterForTests() {
40
+ _defaultSegmentAdapter = null;
41
+ }
42
+ var CliMeasureAdapter = class {
43
+ cellPx;
44
+ constructor(opts) {
45
+ this.cellPx = opts?.cellPx ?? 8;
46
+ }
47
+ measureSegment(text, _font) {
48
+ return { width: countCells(text) * this.cellPx };
49
+ }
50
+ };
51
+ var InjectedMeasureAdapter = class {
52
+ fn;
53
+ cache;
54
+ constructor(fn, opts) {
55
+ if (typeof fn !== "function") {
56
+ throw new TypeError(
57
+ "InjectedMeasureAdapter: a synchronous (text, font) => widthPx function is required"
58
+ );
59
+ }
60
+ this.fn = fn;
61
+ this.cache = opts?.cache ? /* @__PURE__ */ new Map() : null;
62
+ }
63
+ measureSegment(text, font) {
64
+ if (this.cache) {
65
+ const key = `${font}\0${text}`;
66
+ const hit = this.cache.get(key);
67
+ if (hit !== void 0) return { width: hit };
68
+ const w = this.fn(text, font);
69
+ this.cache.set(key, w);
70
+ return { width: w };
71
+ }
72
+ return { width: this.fn(text, font) };
73
+ }
74
+ clearCache() {
75
+ this.cache?.clear();
76
+ }
77
+ };
78
+ var PrecomputedAdapterKeyError = class extends Error {
79
+ name = "KeyError";
80
+ };
81
+ var PrecomputedAdapter = class {
82
+ metrics;
83
+ fallback;
84
+ constructor(opts) {
85
+ this.metrics = opts.metrics;
86
+ const fb = opts.fallback ?? "per-char";
87
+ if (fb !== "per-char" && fb !== "error") {
88
+ throw new Error(
89
+ `fallback must be 'per-char' or 'error', got ${JSON.stringify(opts.fallback)}`
90
+ );
91
+ }
92
+ this.fallback = fb;
93
+ }
94
+ measureSegment(text, font) {
95
+ const fontMap = this.metrics[font];
96
+ if (fontMap) {
97
+ const w = fontMap[text];
98
+ if (w !== void 0) return { width: w };
99
+ }
100
+ if (this.fallback === "error") {
101
+ throw new PrecomputedAdapterKeyError(
102
+ `PrecomputedAdapter: no metrics for segment ${JSON.stringify(text)} in font ${JSON.stringify(font)}`
103
+ );
104
+ }
105
+ let total = 0;
106
+ if (fontMap) {
107
+ for (const ch of text) {
108
+ const cw = fontMap[ch];
109
+ if (cw !== void 0) {
110
+ total += cw;
111
+ }
112
+ }
113
+ }
114
+ return { width: total };
115
+ }
116
+ };
117
+ var CanvasMeasureAdapter = class {
118
+ ctx = null;
119
+ currentFont = "";
120
+ emojiCorrection;
121
+ constructor(opts) {
122
+ this.emojiCorrection = opts?.emojiCorrection ?? 1;
123
+ }
124
+ getContext() {
125
+ if (!this.ctx) {
126
+ if (typeof OffscreenCanvas === "undefined") {
127
+ throw new Error(
128
+ "CanvasMeasureAdapter requires a browser environment with OffscreenCanvas support. Use CliMeasureAdapter or NodeCanvasMeasureAdapter for Node.js."
129
+ );
130
+ }
131
+ const canvas = new OffscreenCanvas(0, 0);
132
+ const ctx = canvas.getContext("2d");
133
+ if (!ctx) throw new Error("CanvasMeasureAdapter: failed to get 2d context");
134
+ this.ctx = ctx;
135
+ }
136
+ return this.ctx;
137
+ }
138
+ measureSegment(text, font) {
139
+ const ctx = this.getContext();
140
+ if (font !== this.currentFont) {
141
+ ctx.font = font;
142
+ this.currentFont = font;
143
+ }
144
+ let width = ctx.measureText(text).width;
145
+ if (this.emojiCorrection !== 1 && /\p{Emoji_Presentation}/u.test(text)) {
146
+ width *= this.emojiCorrection;
147
+ }
148
+ return { width };
149
+ }
150
+ clearCache() {
151
+ this.currentFont = "";
152
+ }
153
+ };
154
+ var NodeCanvasMeasureAdapter = class {
155
+ ctx = null;
156
+ currentFont = "";
157
+ canvasModule;
158
+ constructor(canvasModule) {
159
+ this.canvasModule = canvasModule;
160
+ }
161
+ getContext() {
162
+ if (!this.ctx) {
163
+ const canvas = this.canvasModule.createCanvas(0, 0);
164
+ const ctx = canvas.getContext("2d");
165
+ if (!ctx) throw new Error("NodeCanvasMeasureAdapter: failed to get 2d context");
166
+ this.ctx = ctx;
167
+ }
168
+ return this.ctx;
169
+ }
170
+ measureSegment(text, font) {
171
+ const ctx = this.getContext();
172
+ if (font !== this.currentFont) {
173
+ ctx.font = font;
174
+ this.currentFont = font;
175
+ }
176
+ return { width: ctx.measureText(text).width };
177
+ }
178
+ clearCache() {
179
+ this.currentFont = "";
180
+ }
181
+ };
182
+ var SvgBoundsAdapter = class {
183
+ measureSvg(content) {
184
+ const viewBoxMatch = content.match(/viewBox\s*=\s*["']([^"']+)["']/);
185
+ if (viewBoxMatch) {
186
+ const parts = viewBoxMatch[1].trim().split(/[\s,]+/);
187
+ if (parts.length >= 4) {
188
+ const w = Number.parseFloat(parts[2]);
189
+ const h = Number.parseFloat(parts[3]);
190
+ if (Number.isFinite(w) && Number.isFinite(h) && w > 0 && h > 0) {
191
+ return { width: w, height: h };
192
+ }
193
+ throw new Error(
194
+ "SvgBoundsAdapter: viewBox width/height are missing, non-finite, or not positive"
195
+ );
196
+ }
197
+ }
198
+ const widthMatch = content.match(/<svg[^>]*\bwidth\s*=\s*["']?([\d.]+)/);
199
+ const heightMatch = content.match(/<svg[^>]*\bheight\s*=\s*["']?([\d.]+)/);
200
+ if (widthMatch && heightMatch) {
201
+ const w = Number.parseFloat(widthMatch[1]);
202
+ const h = Number.parseFloat(heightMatch[1]);
203
+ if (Number.isFinite(w) && Number.isFinite(h) && w > 0 && h > 0) {
204
+ return { width: w, height: h };
205
+ }
206
+ throw new Error(
207
+ "SvgBoundsAdapter: svg width/height attributes are non-finite or not positive"
208
+ );
209
+ }
210
+ throw new Error(
211
+ "SvgBoundsAdapter: cannot determine dimensions \u2014 SVG has no viewBox or width/height attributes"
212
+ );
213
+ }
214
+ };
215
+ var ImageSizeAdapter = class {
216
+ sizes;
217
+ constructor(sizes) {
218
+ this.sizes = new Map(Object.entries(sizes));
219
+ }
220
+ measureImage(src) {
221
+ const dims = this.sizes.get(src);
222
+ if (!dims) {
223
+ throw new Error(`ImageSizeAdapter: no dimensions registered for ${JSON.stringify(src)}`);
224
+ }
225
+ return { width: dims.width, height: dims.height };
226
+ }
227
+ };
4
228
 
5
229
  // src/utils/reactive-layout/reactive-layout.ts
6
230
  import { monotonicNs, node } from "@graphrefly/pure-ts/core";
@@ -59,10 +283,9 @@ var leftStickyPunctuation = /* @__PURE__ */ new Set([
59
283
  function normalizeWhitespace(text) {
60
284
  return text.replace(/[\t\n\r\f ]+/g, " ").replace(/^ | $/g, "");
61
285
  }
62
- function segmentText(normalized) {
63
- const wordSegmenter = new Intl.Segmenter(void 0, { granularity: "word" });
286
+ function segmentText(normalized, segmentAdapter) {
64
287
  const pieces = [];
65
- for (const s of wordSegmenter.segment(normalized)) {
288
+ for (const s of segmentAdapter.segmentWords(normalized)) {
66
289
  const text = s.segment;
67
290
  const isWordLike = s.isWordLike ?? false;
68
291
  const texts = [];
@@ -98,13 +321,11 @@ function segmentText(normalized) {
98
321
  }
99
322
  return pieces;
100
323
  }
101
- function analyzeAndMeasure(text, font, adapter, cache, stats) {
324
+ function analyzeAndMeasure(text, font, adapter, cache, stats, segmentAdapter) {
102
325
  const normalized = normalizeWhitespace(text);
103
326
  if (normalized.length === 0) return [];
104
- const pieces = segmentText(normalized);
105
- const graphemeSegmenter2 = new Intl.Segmenter(void 0, {
106
- granularity: "grapheme"
107
- });
327
+ const segAdapter = segmentAdapter ?? getDefaultSegmentAdapter();
328
+ const pieces = segmentText(normalized, segAdapter);
108
329
  const rawTexts = [];
109
330
  const rawKinds = [];
110
331
  const rawWordLike = [];
@@ -169,7 +390,7 @@ function analyzeAndMeasure(text, font, adapter, cache, stats) {
169
390
  }
170
391
  if (isCJK(t)) {
171
392
  let unitText = "";
172
- for (const gs of graphemeSegmenter2.segment(t)) {
393
+ for (const gs of segAdapter.segmentGraphemes(t)) {
173
394
  const grapheme = gs.segment;
174
395
  if (unitText.length > 0 && kinsokuStart.has(grapheme)) {
175
396
  unitText += grapheme;
@@ -201,7 +422,7 @@ function analyzeAndMeasure(text, font, adapter, cache, stats) {
201
422
  let graphemeWidths = null;
202
423
  if (mergedWordLike[i] && t.length > 1) {
203
424
  const gWidths = [];
204
- for (const gs of graphemeSegmenter2.segment(t)) {
425
+ for (const gs of segAdapter.segmentGraphemes(t)) {
205
426
  gWidths.push(measureCached(gs.segment));
206
427
  }
207
428
  if (gWidths.length > 1) {
@@ -212,10 +433,11 @@ function analyzeAndMeasure(text, font, adapter, cache, stats) {
212
433
  }
213
434
  return segments;
214
435
  }
215
- function computeLineBreaks(segments, maxWidth, adapter, font, cache) {
436
+ function computeLineBreaks(segments, maxWidth, adapter, font, cache, segmentAdapter) {
216
437
  if (segments.length === 0) {
217
438
  return { lines: [], lineCount: 0 };
218
439
  }
440
+ const segAdapter = segmentAdapter ?? getDefaultSegmentAdapter();
219
441
  const lines = [];
220
442
  let lineW = 0;
221
443
  let hasContent = false;
@@ -241,10 +463,7 @@ function computeLineBreaks(segments, maxWidth, adapter, font, cache) {
241
463
  const seg = segments[i];
242
464
  if (seg.kind === "soft-hyphen" || seg.kind === "hard-break") continue;
243
465
  if (i === lineStartSeg && lineStartGrapheme > 0 && seg.graphemeWidths) {
244
- const graphemeSegmenter2 = new Intl.Segmenter(void 0, {
245
- granularity: "grapheme"
246
- });
247
- const graphemes = [...graphemeSegmenter2.segment(seg.text)].map((g) => g.segment);
466
+ const graphemes = [...segAdapter.segmentGraphemes(seg.text)].map((g) => g.segment);
248
467
  text += graphemes.slice(lineStartGrapheme).join("");
249
468
  } else {
250
469
  text += seg.text;
@@ -252,10 +471,7 @@ function computeLineBreaks(segments, maxWidth, adapter, font, cache) {
252
471
  }
253
472
  if (endGrapheme > 0 && endSeg < segments.length) {
254
473
  const seg = segments[endSeg];
255
- const graphemeSegmenter2 = new Intl.Segmenter(void 0, {
256
- granularity: "grapheme"
257
- });
258
- const graphemes = [...graphemeSegmenter2.segment(seg.text)].map((g) => g.segment);
474
+ const graphemes = [...segAdapter.segmentGraphemes(seg.text)].map((g) => g.segment);
259
475
  const startG = lineStartSeg === endSeg ? lineStartGrapheme : 0;
260
476
  text += graphemes.slice(startG, endGrapheme).join("");
261
477
  }
@@ -386,26 +602,19 @@ function computeLineBreaks(segments, maxWidth, adapter, font, cache) {
386
602
  function canBreakAfter(kind) {
387
603
  return kind === "space" || kind === "zero-width-break" || kind === "soft-hyphen";
388
604
  }
389
- var _graphemeSegmenter = null;
390
- function graphemeSegmenter() {
391
- if (_graphemeSegmenter === null) {
392
- _graphemeSegmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
393
- }
394
- return _graphemeSegmenter;
395
- }
396
- function sliceSegmentText(seg, startG, endG) {
605
+ function sliceSegmentText(seg, startG, endG, segmentAdapter) {
397
606
  if (startG === 0 && endG < 0) return seg.text;
398
- const graphemes = [...graphemeSegmenter().segment(seg.text)].map((g) => g.segment);
607
+ const graphemes = [...segmentAdapter.segmentGraphemes(seg.text)].map((g) => g.segment);
399
608
  const stop = endG < 0 ? graphemes.length : endG;
400
609
  return graphemes.slice(startG, stop).join("");
401
610
  }
402
- function buildLineText(segments, startSeg, startG, endSeg, endG, appendHyphen) {
611
+ function buildLineText(segments, startSeg, startG, endSeg, endG, appendHyphen, segmentAdapter) {
403
612
  let text = "";
404
613
  for (let i = startSeg; i < endSeg; i++) {
405
614
  const seg = segments[i];
406
615
  if (seg.kind === "soft-hyphen" || seg.kind === "hard-break") continue;
407
616
  if (i === startSeg && startG > 0) {
408
- text += sliceSegmentText(seg, startG, -1);
617
+ text += sliceSegmentText(seg, startG, -1, segmentAdapter);
409
618
  } else {
410
619
  text += seg.text;
411
620
  }
@@ -413,7 +622,7 @@ function buildLineText(segments, startSeg, startG, endSeg, endG, appendHyphen) {
413
622
  if (endG > 0 && endSeg < segments.length) {
414
623
  const seg = segments[endSeg];
415
624
  const from = startSeg === endSeg ? startG : 0;
416
- text += sliceSegmentText(seg, from, endG);
625
+ text += sliceSegmentText(seg, from, endG, segmentAdapter);
417
626
  }
418
627
  if (appendHyphen) text += "-";
419
628
  return text;
@@ -439,6 +648,7 @@ function resolveHyphenWidth(ctx) {
439
648
  function layoutNextLine(segments, cursor, slotWidth, ctx) {
440
649
  let i = cursor.segmentIndex;
441
650
  const initialG = cursor.graphemeIndex;
651
+ const segAdapter = ctx?.segmentAdapter ?? getDefaultSegmentAdapter();
442
652
  if (i >= segments.length) return null;
443
653
  if (initialG === 0) {
444
654
  while (i < segments.length) {
@@ -504,7 +714,15 @@ function layoutNextLine(segments, cursor, slotWidth, ctx) {
504
714
  if (seg.graphemeWidths) {
505
715
  const overflowed = consumeBreakable(startSeg, startG, seg.graphemeWidths);
506
716
  if (overflowed) {
507
- const text2 = buildLineText(segments, startSeg, startG, lineEndSeg, lineEndG, false);
717
+ const text2 = buildLineText(
718
+ segments,
719
+ startSeg,
720
+ startG,
721
+ lineEndSeg,
722
+ lineEndG,
723
+ false,
724
+ segAdapter
725
+ );
508
726
  return {
509
727
  text: text2,
510
728
  width: lineW,
@@ -527,7 +745,8 @@ function layoutNextLine(segments, cursor, slotWidth, ctx) {
527
745
  startG,
528
746
  lineEndSeg,
529
747
  lineEndG,
530
- endsAtSoftHyphen2
748
+ endsAtSoftHyphen2,
749
+ segAdapter
531
750
  );
532
751
  return {
533
752
  text: text2,
@@ -548,7 +767,15 @@ function layoutNextLine(segments, cursor, slotWidth, ctx) {
548
767
  if (w > slotWidth && seg.graphemeWidths) {
549
768
  const overflowed = consumeBreakable(i, 0, seg.graphemeWidths);
550
769
  if (overflowed) {
551
- const text2 = buildLineText(segments, startSeg, startG, lineEndSeg, lineEndG, false);
770
+ const text2 = buildLineText(
771
+ segments,
772
+ startSeg,
773
+ startG,
774
+ lineEndSeg,
775
+ lineEndG,
776
+ false,
777
+ segAdapter
778
+ );
552
779
  return {
553
780
  text: text2,
554
781
  width: lineW,
@@ -582,7 +809,8 @@ function layoutNextLine(segments, cursor, slotWidth, ctx) {
582
809
  startG,
583
810
  lineEndSeg,
584
811
  lineEndG,
585
- endsAtSoftHyphen2
812
+ endsAtSoftHyphen2,
813
+ segAdapter
586
814
  );
587
815
  return {
588
816
  text: text3,
@@ -598,7 +826,8 @@ function layoutNextLine(segments, cursor, slotWidth, ctx) {
598
826
  startG,
599
827
  pendingBreakSeg,
600
828
  pendingBreakG,
601
- pendingBreakSoftHyphen
829
+ pendingBreakSoftHyphen,
830
+ segAdapter
602
831
  );
603
832
  return {
604
833
  text: text3,
@@ -608,7 +837,15 @@ function layoutNextLine(segments, cursor, slotWidth, ctx) {
608
837
  };
609
838
  }
610
839
  if (w > slotWidth && seg.graphemeWidths) {
611
- const text3 = buildLineText(segments, startSeg, startG, lineEndSeg, lineEndG, false);
840
+ const text3 = buildLineText(
841
+ segments,
842
+ startSeg,
843
+ startG,
844
+ lineEndSeg,
845
+ lineEndG,
846
+ false,
847
+ segAdapter
848
+ );
612
849
  return {
613
850
  text: text3,
614
851
  width: lineW,
@@ -616,7 +853,15 @@ function layoutNextLine(segments, cursor, slotWidth, ctx) {
616
853
  end: { segmentIndex: lineEndSeg, graphemeIndex: lineEndG }
617
854
  };
618
855
  }
619
- const text2 = buildLineText(segments, startSeg, startG, lineEndSeg, lineEndG, false);
856
+ const text2 = buildLineText(
857
+ segments,
858
+ startSeg,
859
+ startG,
860
+ lineEndSeg,
861
+ lineEndG,
862
+ false,
863
+ segAdapter
864
+ );
620
865
  return {
621
866
  text: text2,
622
867
  width: lineW,
@@ -634,7 +879,15 @@ function layoutNextLine(segments, cursor, slotWidth, ctx) {
634
879
  }
635
880
  if (!hasContent) return null;
636
881
  const endsAtSoftHyphen = lineEndSeg > 0 && segments[lineEndSeg - 1]?.kind === "soft-hyphen";
637
- const text = buildLineText(segments, startSeg, startG, lineEndSeg, lineEndG, endsAtSoftHyphen);
882
+ const text = buildLineText(
883
+ segments,
884
+ startSeg,
885
+ startG,
886
+ lineEndSeg,
887
+ lineEndG,
888
+ endsAtSoftHyphen,
889
+ segAdapter
890
+ );
638
891
  return {
639
892
  text,
640
893
  width: lineW + (endsAtSoftHyphen ? hyphenWidth : 0),
@@ -663,11 +916,9 @@ function carveTextLineSlots(base, blocked, minSlotWidth = 0) {
663
916
  }
664
917
  return slots;
665
918
  }
666
- function computeCharPositions(lineBreaks, segments, lineHeight) {
919
+ function computeCharPositions(lineBreaks, segments, lineHeight, segmentAdapter) {
667
920
  const positions = [];
668
- const graphemeSegmenter2 = new Intl.Segmenter(void 0, {
669
- granularity: "grapheme"
670
- });
921
+ const segAdapter = segmentAdapter ?? getDefaultSegmentAdapter();
671
922
  for (let lineIdx = 0; lineIdx < lineBreaks.lines.length; lineIdx++) {
672
923
  const line = lineBreaks.lines[lineIdx];
673
924
  const y = lineIdx * lineHeight;
@@ -678,7 +929,7 @@ function computeCharPositions(lineBreaks, segments, lineHeight) {
678
929
  if (si >= line.endSegment && line.endGrapheme === 0) break;
679
930
  continue;
680
931
  }
681
- const graphemes = [...graphemeSegmenter2.segment(seg.text)].map((g) => g.segment);
932
+ const graphemes = [...segAdapter.segmentGraphemes(seg.text)].map((g) => g.segment);
682
933
  if (graphemes.length === 0) continue;
683
934
  const startG = si === line.startSegment ? line.startGrapheme : 0;
684
935
  let endG;
@@ -699,7 +950,8 @@ function computeCharPositions(lineBreaks, segments, lineHeight) {
699
950
  return positions;
700
951
  }
701
952
  function reactiveLayout(opts) {
702
- const { adapter, name = "reactive-layout" } = opts;
953
+ const { adapter, segmentAdapter: segmentAdapterOpt, name = "reactive-layout" } = opts;
954
+ const segmentAdapter = segmentAdapterOpt ?? getDefaultSegmentAdapter();
703
955
  const g = new Graph(name);
704
956
  const measureCache = /* @__PURE__ */ new Map();
705
957
  const textNode = node([], { name: "text", initial: opts.text ?? "" });
@@ -737,7 +989,8 @@ function reactiveLayout(opts) {
737
989
  fontVal,
738
990
  adapter,
739
991
  measureCache,
740
- measureStats
992
+ measureStats,
993
+ segmentAdapter
741
994
  );
742
995
  const elapsed = monotonicNs() - t0;
743
996
  const lookups = measureStats.hits + measureStats.misses;
@@ -790,7 +1043,8 @@ function reactiveLayout(opts) {
790
1043
  data[1],
791
1044
  adapter,
792
1045
  data[2],
793
- measureCache
1046
+ measureCache,
1047
+ segmentAdapter
794
1048
  )
795
1049
  );
796
1050
  },
@@ -832,7 +1086,8 @@ function reactiveLayout(opts) {
832
1086
  computeCharPositions(
833
1087
  data[0],
834
1088
  data[1],
835
- data[2]
1089
+ data[2],
1090
+ segmentAdapter
836
1091
  )
837
1092
  );
838
1093
  },
@@ -874,6 +1129,16 @@ function reactiveLayout(opts) {
874
1129
  }
875
1130
 
876
1131
  export {
1132
+ IntlSegmentAdapter,
1133
+ getDefaultSegmentAdapter,
1134
+ _resetDefaultSegmentAdapterForTests,
1135
+ CliMeasureAdapter,
1136
+ InjectedMeasureAdapter,
1137
+ PrecomputedAdapter,
1138
+ CanvasMeasureAdapter,
1139
+ NodeCanvasMeasureAdapter,
1140
+ SvgBoundsAdapter,
1141
+ ImageSizeAdapter,
877
1142
  analyzeAndMeasure,
878
1143
  computeLineBreaks,
879
1144
  layoutNextLine,
@@ -881,4 +1146,4 @@ export {
881
1146
  computeCharPositions,
882
1147
  reactiveLayout
883
1148
  };
884
- //# sourceMappingURL=chunk-3PSLNJDU.js.map
1149
+ //# sourceMappingURL=chunk-6DQYBIHW.js.map