@xiuchang-midscene/shared 2.0.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 (382) hide show
  1. package/README.md +9 -0
  2. package/dist/es/baseDB.mjs +109 -0
  3. package/dist/es/baseDB.mjs.bak +109 -0
  4. package/dist/es/build/copy-static.mjs +31 -0
  5. package/dist/es/build/copy-static.mjs.bak +31 -0
  6. package/dist/es/build/rspack-config.mjs +4 -0
  7. package/dist/es/build/rspack-config.mjs.bak +4 -0
  8. package/dist/es/cli/cli-runner.mjs +140 -0
  9. package/dist/es/cli/cli-runner.mjs.bak +140 -0
  10. package/dist/es/cli/index.mjs +2 -0
  11. package/dist/es/cli/index.mjs.bak +2 -0
  12. package/dist/es/common.mjs +37 -0
  13. package/dist/es/common.mjs.bak +37 -0
  14. package/dist/es/constants/example-code.mjs +223 -0
  15. package/dist/es/constants/example-code.mjs.bak +223 -0
  16. package/dist/es/constants/index.mjs +23 -0
  17. package/dist/es/constants/index.mjs.bak +23 -0
  18. package/dist/es/env/basic.mjs +6 -0
  19. package/dist/es/env/basic.mjs.bak +6 -0
  20. package/dist/es/env/constants.mjs +70 -0
  21. package/dist/es/env/constants.mjs.bak +70 -0
  22. package/dist/es/env/global-config-manager.mjs +94 -0
  23. package/dist/es/env/global-config-manager.mjs.bak +94 -0
  24. package/dist/es/env/helper.mjs +43 -0
  25. package/dist/es/env/helper.mjs.bak +43 -0
  26. package/dist/es/env/index.mjs +5 -0
  27. package/dist/es/env/index.mjs.bak +5 -0
  28. package/dist/es/env/init-debug.mjs +18 -0
  29. package/dist/es/env/init-debug.mjs.bak +18 -0
  30. package/dist/es/env/model-config-manager.mjs +79 -0
  31. package/dist/es/env/model-config-manager.mjs.bak +79 -0
  32. package/dist/es/env/parse-model-config.mjs +132 -0
  33. package/dist/es/env/parse-model-config.mjs.bak +132 -0
  34. package/dist/es/env/types.mjs +220 -0
  35. package/dist/es/env/types.mjs.bak +220 -0
  36. package/dist/es/env/utils.mjs +26 -0
  37. package/dist/es/env/utils.mjs.bak +26 -0
  38. package/dist/es/extractor/constants.mjs +2 -0
  39. package/dist/es/extractor/constants.mjs.bak +2 -0
  40. package/dist/es/extractor/debug.mjs +6 -0
  41. package/dist/es/extractor/debug.mjs.bak +6 -0
  42. package/dist/es/extractor/dom-util.mjs +92 -0
  43. package/dist/es/extractor/dom-util.mjs.bak +92 -0
  44. package/dist/es/extractor/index.mjs +5 -0
  45. package/dist/es/extractor/index.mjs.bak +5 -0
  46. package/dist/es/extractor/locator.mjs +250 -0
  47. package/dist/es/extractor/locator.mjs.bak +250 -0
  48. package/dist/es/extractor/tree.mjs +78 -0
  49. package/dist/es/extractor/tree.mjs.bak +78 -0
  50. package/dist/es/extractor/util.mjs +245 -0
  51. package/dist/es/extractor/util.mjs.bak +245 -0
  52. package/dist/es/extractor/web-extractor.mjs +303 -0
  53. package/dist/es/extractor/web-extractor.mjs.bak +303 -0
  54. package/dist/es/img/box-select.mjs +824 -0
  55. package/dist/es/img/box-select.mjs.bak +824 -0
  56. package/dist/es/img/canvas-fallback.mjs +238 -0
  57. package/dist/es/img/canvas-fallback.mjs.bak +238 -0
  58. package/dist/es/img/get-photon.mjs +45 -0
  59. package/dist/es/img/get-photon.mjs.bak +45 -0
  60. package/dist/es/img/get-sharp.mjs +11 -0
  61. package/dist/es/img/get-sharp.mjs.bak +11 -0
  62. package/dist/es/img/index.mjs +4 -0
  63. package/dist/es/img/index.mjs.bak +4 -0
  64. package/dist/es/img/info.mjs +29 -0
  65. package/dist/es/img/info.mjs.bak +29 -0
  66. package/dist/es/img/transform.mjs +295 -0
  67. package/dist/es/img/transform.mjs.bak +295 -0
  68. package/dist/es/index.mjs +4 -0
  69. package/dist/es/index.mjs.bak +4 -0
  70. package/dist/es/logger.mjs +64 -0
  71. package/dist/es/logger.mjs.bak +64 -0
  72. package/dist/es/mcp/base-server.mjs +281 -0
  73. package/dist/es/mcp/base-server.mjs.bak +281 -0
  74. package/dist/es/mcp/base-tools.mjs +91 -0
  75. package/dist/es/mcp/base-tools.mjs.bak +91 -0
  76. package/dist/es/mcp/chrome-path.mjs +35 -0
  77. package/dist/es/mcp/chrome-path.mjs.bak +35 -0
  78. package/dist/es/mcp/index.mjs +7 -0
  79. package/dist/es/mcp/index.mjs.bak +7 -0
  80. package/dist/es/mcp/inject-report-html-plugin.mjs +53 -0
  81. package/dist/es/mcp/inject-report-html-plugin.mjs.bak +53 -0
  82. package/dist/es/mcp/launcher-helper.mjs +52 -0
  83. package/dist/es/mcp/launcher-helper.mjs.bak +52 -0
  84. package/dist/es/mcp/tool-generator.mjs +297 -0
  85. package/dist/es/mcp/tool-generator.mjs.bak +297 -0
  86. package/dist/es/mcp/types.mjs +3 -0
  87. package/dist/es/mcp/types.mjs.bak +3 -0
  88. package/dist/es/node/fs.mjs +44 -0
  89. package/dist/es/node/fs.mjs.bak +44 -0
  90. package/dist/es/node/index.mjs +2 -0
  91. package/dist/es/node/index.mjs.bak +2 -0
  92. package/dist/es/node/port.mjs +24 -0
  93. package/dist/es/node/port.mjs.bak +24 -0
  94. package/dist/es/oss/demo.mjs +30 -0
  95. package/dist/es/oss/demo.mjs.bak +30 -0
  96. package/dist/es/oss/index.mjs +90 -0
  97. package/dist/es/oss/index.mjs.bak +90 -0
  98. package/dist/es/polyfills/async-hooks.mjs +2 -0
  99. package/dist/es/polyfills/async-hooks.mjs.bak +2 -0
  100. package/dist/es/polyfills/index.mjs +1 -0
  101. package/dist/es/polyfills/index.mjs.bak +1 -0
  102. package/dist/es/types/index.mjs +3 -0
  103. package/dist/es/types/index.mjs.bak +3 -0
  104. package/dist/es/us-keyboard-layout.mjs +1414 -0
  105. package/dist/es/us-keyboard-layout.mjs.LICENSE.txt +5 -0
  106. package/dist/es/us-keyboard-layout.mjs.bak +1414 -0
  107. package/dist/es/utils.mjs +72 -0
  108. package/dist/es/utils.mjs.bak +72 -0
  109. package/dist/es/zod-schema-utils.mjs +54 -0
  110. package/dist/es/zod-schema-utils.mjs.bak +54 -0
  111. package/dist/lib/baseDB.js +149 -0
  112. package/dist/lib/baseDB.js.bak +149 -0
  113. package/dist/lib/build/copy-static.js +79 -0
  114. package/dist/lib/build/copy-static.js.bak +79 -0
  115. package/dist/lib/build/rspack-config.js +38 -0
  116. package/dist/lib/build/rspack-config.js.bak +38 -0
  117. package/dist/lib/cli/cli-runner.js +196 -0
  118. package/dist/lib/cli/cli-runner.js.bak +196 -0
  119. package/dist/lib/cli/index.js +48 -0
  120. package/dist/lib/cli/index.js.bak +48 -0
  121. package/dist/lib/common.js +93 -0
  122. package/dist/lib/common.js.bak +93 -0
  123. package/dist/lib/constants/example-code.js +260 -0
  124. package/dist/lib/constants/example-code.js.bak +260 -0
  125. package/dist/lib/constants/index.js +96 -0
  126. package/dist/lib/constants/index.js.bak +96 -0
  127. package/dist/lib/env/basic.js +40 -0
  128. package/dist/lib/env/basic.js.bak +40 -0
  129. package/dist/lib/env/constants.js +113 -0
  130. package/dist/lib/env/constants.js.bak +113 -0
  131. package/dist/lib/env/global-config-manager.js +128 -0
  132. package/dist/lib/env/global-config-manager.js.bak +128 -0
  133. package/dist/lib/env/helper.js +80 -0
  134. package/dist/lib/env/helper.js.bak +80 -0
  135. package/dist/lib/env/index.js +90 -0
  136. package/dist/lib/env/index.js.bak +90 -0
  137. package/dist/lib/env/init-debug.js +52 -0
  138. package/dist/lib/env/init-debug.js.bak +52 -0
  139. package/dist/lib/env/model-config-manager.js +113 -0
  140. package/dist/lib/env/model-config-manager.js.bak +113 -0
  141. package/dist/lib/env/parse-model-config.js +178 -0
  142. package/dist/lib/env/parse-model-config.js.bak +178 -0
  143. package/dist/lib/env/types.js +554 -0
  144. package/dist/lib/env/types.js.bak +554 -0
  145. package/dist/lib/env/utils.js +72 -0
  146. package/dist/lib/env/utils.js.bak +72 -0
  147. package/dist/lib/extractor/constants.js +42 -0
  148. package/dist/lib/extractor/constants.js.bak +42 -0
  149. package/dist/lib/extractor/debug.js +12 -0
  150. package/dist/lib/extractor/debug.js.bak +12 -0
  151. package/dist/lib/extractor/dom-util.js +153 -0
  152. package/dist/lib/extractor/dom-util.js.bak +153 -0
  153. package/dist/lib/extractor/index.js +81 -0
  154. package/dist/lib/extractor/index.js.bak +81 -0
  155. package/dist/lib/extractor/locator.js +296 -0
  156. package/dist/lib/extractor/locator.js.bak +296 -0
  157. package/dist/lib/extractor/tree.js +124 -0
  158. package/dist/lib/extractor/tree.js.bak +124 -0
  159. package/dist/lib/extractor/util.js +336 -0
  160. package/dist/lib/extractor/util.js.bak +336 -0
  161. package/dist/lib/extractor/web-extractor.js +349 -0
  162. package/dist/lib/extractor/web-extractor.js.bak +349 -0
  163. package/dist/lib/img/box-select.js +875 -0
  164. package/dist/lib/img/box-select.js.bak +875 -0
  165. package/dist/lib/img/canvas-fallback.js +305 -0
  166. package/dist/lib/img/canvas-fallback.js.bak +305 -0
  167. package/dist/lib/img/get-photon.js +82 -0
  168. package/dist/lib/img/get-photon.js.bak +82 -0
  169. package/dist/lib/img/get-sharp.js +45 -0
  170. package/dist/lib/img/get-sharp.js.bak +45 -0
  171. package/dist/lib/img/index.js +95 -0
  172. package/dist/lib/img/index.js.bak +95 -0
  173. package/dist/lib/img/info.js +83 -0
  174. package/dist/lib/img/info.js.bak +83 -0
  175. package/dist/lib/img/transform.js +387 -0
  176. package/dist/lib/img/transform.js.bak +387 -0
  177. package/dist/lib/index.js +47 -0
  178. package/dist/lib/index.js.bak +47 -0
  179. package/dist/lib/logger.js +114 -0
  180. package/dist/lib/logger.js.bak +114 -0
  181. package/dist/lib/mcp/base-server.js +331 -0
  182. package/dist/lib/mcp/base-server.js.bak +331 -0
  183. package/dist/lib/mcp/base-tools.js +125 -0
  184. package/dist/lib/mcp/base-tools.js.bak +125 -0
  185. package/dist/lib/mcp/chrome-path.js +72 -0
  186. package/dist/lib/mcp/chrome-path.js.bak +72 -0
  187. package/dist/lib/mcp/index.js +100 -0
  188. package/dist/lib/mcp/index.js.bak +100 -0
  189. package/dist/lib/mcp/inject-report-html-plugin.js +98 -0
  190. package/dist/lib/mcp/inject-report-html-plugin.js.bak +98 -0
  191. package/dist/lib/mcp/launcher-helper.js +86 -0
  192. package/dist/lib/mcp/launcher-helper.js.bak +86 -0
  193. package/dist/lib/mcp/tool-generator.js +334 -0
  194. package/dist/lib/mcp/tool-generator.js.bak +334 -0
  195. package/dist/lib/mcp/types.js +40 -0
  196. package/dist/lib/mcp/types.js.bak +40 -0
  197. package/dist/lib/node/fs.js +97 -0
  198. package/dist/lib/node/fs.js.bak +97 -0
  199. package/dist/lib/node/index.js +65 -0
  200. package/dist/lib/node/index.js.bak +65 -0
  201. package/dist/lib/node/port.js +61 -0
  202. package/dist/lib/node/port.js.bak +61 -0
  203. package/dist/lib/oss/demo.js +36 -0
  204. package/dist/lib/oss/demo.js.bak +36 -0
  205. package/dist/lib/oss/index.js +138 -0
  206. package/dist/lib/oss/index.js.bak +138 -0
  207. package/dist/lib/polyfills/async-hooks.js +36 -0
  208. package/dist/lib/polyfills/async-hooks.js.bak +36 -0
  209. package/dist/lib/polyfills/index.js +58 -0
  210. package/dist/lib/polyfills/index.js.bak +58 -0
  211. package/dist/lib/types/index.js +37 -0
  212. package/dist/lib/types/index.js.bak +37 -0
  213. package/dist/lib/us-keyboard-layout.js +1457 -0
  214. package/dist/lib/us-keyboard-layout.js.LICENSE.txt +5 -0
  215. package/dist/lib/us-keyboard-layout.js.bak +1457 -0
  216. package/dist/lib/utils.js +148 -0
  217. package/dist/lib/utils.js.bak +148 -0
  218. package/dist/lib/zod-schema-utils.js +97 -0
  219. package/dist/lib/zod-schema-utils.js.bak +97 -0
  220. package/dist/types/baseDB.d.ts +25 -0
  221. package/dist/types/baseDB.d.ts.bak +25 -0
  222. package/dist/types/build/copy-static.d.ts +31 -0
  223. package/dist/types/build/copy-static.d.ts.bak +31 -0
  224. package/dist/types/build/rspack-config.d.ts +8 -0
  225. package/dist/types/build/rspack-config.d.ts.bak +8 -0
  226. package/dist/types/cli/cli-runner.d.ts +14 -0
  227. package/dist/types/cli/cli-runner.d.ts.bak +14 -0
  228. package/dist/types/cli/index.d.ts +2 -0
  229. package/dist/types/cli/index.d.ts.bak +2 -0
  230. package/dist/types/common.d.ts +12 -0
  231. package/dist/types/common.d.ts.bak +12 -0
  232. package/dist/types/constants/example-code.d.ts +2 -0
  233. package/dist/types/constants/example-code.d.ts.bak +2 -0
  234. package/dist/types/constants/index.d.ts +21 -0
  235. package/dist/types/constants/index.d.ts.bak +21 -0
  236. package/dist/types/env/basic.d.ts +6 -0
  237. package/dist/types/env/basic.d.ts.bak +6 -0
  238. package/dist/types/env/constants.d.ts +40 -0
  239. package/dist/types/env/constants.d.ts.bak +40 -0
  240. package/dist/types/env/global-config-manager.d.ts +32 -0
  241. package/dist/types/env/global-config-manager.d.ts.bak +32 -0
  242. package/dist/types/env/helper.d.ts +4 -0
  243. package/dist/types/env/helper.d.ts.bak +4 -0
  244. package/dist/types/env/index.d.ts +4 -0
  245. package/dist/types/env/index.d.ts.bak +4 -0
  246. package/dist/types/env/init-debug.d.ts +1 -0
  247. package/dist/types/env/init-debug.d.ts.bak +1 -0
  248. package/dist/types/env/model-config-manager.d.ts +25 -0
  249. package/dist/types/env/model-config-manager.d.ts.bak +25 -0
  250. package/dist/types/env/parse-model-config.d.ts +31 -0
  251. package/dist/types/env/parse-model-config.d.ts.bak +31 -0
  252. package/dist/types/env/types.d.ts +318 -0
  253. package/dist/types/env/types.d.ts.bak +318 -0
  254. package/dist/types/env/utils.d.ts +38 -0
  255. package/dist/types/env/utils.d.ts.bak +38 -0
  256. package/dist/types/extractor/constants.d.ts +1 -0
  257. package/dist/types/extractor/constants.d.ts.bak +1 -0
  258. package/dist/types/extractor/debug.d.ts +1 -0
  259. package/dist/types/extractor/debug.d.ts.bak +1 -0
  260. package/dist/types/extractor/dom-util.d.ts +56 -0
  261. package/dist/types/extractor/dom-util.d.ts.bak +56 -0
  262. package/dist/types/extractor/index.d.ts +32 -0
  263. package/dist/types/extractor/index.d.ts.bak +32 -0
  264. package/dist/types/extractor/locator.d.ts +9 -0
  265. package/dist/types/extractor/locator.d.ts.bak +9 -0
  266. package/dist/types/extractor/tree.d.ts +6 -0
  267. package/dist/types/extractor/tree.d.ts.bak +6 -0
  268. package/dist/types/extractor/util.d.ts +47 -0
  269. package/dist/types/extractor/util.d.ts.bak +47 -0
  270. package/dist/types/extractor/web-extractor.d.ts +19 -0
  271. package/dist/types/extractor/web-extractor.d.ts.bak +19 -0
  272. package/dist/types/img/box-select.d.ts +26 -0
  273. package/dist/types/img/box-select.d.ts.bak +26 -0
  274. package/dist/types/img/canvas-fallback.d.ts +105 -0
  275. package/dist/types/img/canvas-fallback.d.ts.bak +105 -0
  276. package/dist/types/img/get-photon.d.ts +19 -0
  277. package/dist/types/img/get-photon.d.ts.bak +19 -0
  278. package/dist/types/img/get-sharp.d.ts +3 -0
  279. package/dist/types/img/get-sharp.d.ts.bak +3 -0
  280. package/dist/types/img/index.d.ts +3 -0
  281. package/dist/types/img/index.d.ts.bak +3 -0
  282. package/dist/types/img/info.d.ts +29 -0
  283. package/dist/types/img/info.d.ts.bak +29 -0
  284. package/dist/types/img/transform.d.ts +107 -0
  285. package/dist/types/img/transform.d.ts.bak +107 -0
  286. package/dist/types/index.d.ts +4 -0
  287. package/dist/types/index.d.ts.bak +4 -0
  288. package/dist/types/logger.d.ts +5 -0
  289. package/dist/types/logger.d.ts.bak +5 -0
  290. package/dist/types/mcp/base-server.d.ts +93 -0
  291. package/dist/types/mcp/base-server.d.ts.bak +93 -0
  292. package/dist/types/mcp/base-tools.d.ts +79 -0
  293. package/dist/types/mcp/base-tools.d.ts.bak +79 -0
  294. package/dist/types/mcp/chrome-path.d.ts +2 -0
  295. package/dist/types/mcp/chrome-path.d.ts.bak +2 -0
  296. package/dist/types/mcp/index.d.ts +7 -0
  297. package/dist/types/mcp/index.d.ts.bak +7 -0
  298. package/dist/types/mcp/inject-report-html-plugin.d.ts +18 -0
  299. package/dist/types/mcp/inject-report-html-plugin.d.ts.bak +18 -0
  300. package/dist/types/mcp/launcher-helper.d.ts +94 -0
  301. package/dist/types/mcp/launcher-helper.d.ts.bak +94 -0
  302. package/dist/types/mcp/tool-generator.d.ts +10 -0
  303. package/dist/types/mcp/tool-generator.d.ts.bak +10 -0
  304. package/dist/types/mcp/types.d.ts +103 -0
  305. package/dist/types/mcp/types.d.ts.bak +103 -0
  306. package/dist/types/node/fs.d.ts +15 -0
  307. package/dist/types/node/fs.d.ts.bak +15 -0
  308. package/dist/types/node/index.d.ts +2 -0
  309. package/dist/types/node/index.d.ts.bak +2 -0
  310. package/dist/types/node/port.d.ts +8 -0
  311. package/dist/types/node/port.d.ts.bak +8 -0
  312. package/dist/types/oss/demo.d.ts +1 -0
  313. package/dist/types/oss/demo.d.ts.bak +1 -0
  314. package/dist/types/oss/index.d.ts +34 -0
  315. package/dist/types/oss/index.d.ts.bak +34 -0
  316. package/dist/types/polyfills/async-hooks.d.ts +6 -0
  317. package/dist/types/polyfills/async-hooks.d.ts.bak +6 -0
  318. package/dist/types/polyfills/index.d.ts +4 -0
  319. package/dist/types/polyfills/index.d.ts.bak +4 -0
  320. package/dist/types/types/index.d.ts +34 -0
  321. package/dist/types/types/index.d.ts.bak +34 -0
  322. package/dist/types/us-keyboard-layout.d.ts +32 -0
  323. package/dist/types/us-keyboard-layout.d.ts.bak +32 -0
  324. package/dist/types/utils.d.ts +34 -0
  325. package/dist/types/utils.d.ts.bak +34 -0
  326. package/dist/types/zod-schema-utils.d.ts +23 -0
  327. package/dist/types/zod-schema-utils.d.ts.bak +23 -0
  328. package/package.json +132 -0
  329. package/src/baseDB.ts +158 -0
  330. package/src/build/copy-static.ts +68 -0
  331. package/src/build/rspack-config.ts +12 -0
  332. package/src/cli/cli-runner.ts +224 -0
  333. package/src/cli/index.ts +8 -0
  334. package/src/common.ts +67 -0
  335. package/src/constants/example-code.ts +223 -0
  336. package/src/constants/index.ts +29 -0
  337. package/src/env/basic.ts +12 -0
  338. package/src/env/constants.ts +234 -0
  339. package/src/env/global-config-manager.ts +191 -0
  340. package/src/env/helper.ts +58 -0
  341. package/src/env/index.ts +4 -0
  342. package/src/env/init-debug.ts +34 -0
  343. package/src/env/model-config-manager.ts +149 -0
  344. package/src/env/parse-model-config.ts +294 -0
  345. package/src/env/types.ts +547 -0
  346. package/src/env/utils.ts +89 -0
  347. package/src/extractor/constants.ts +5 -0
  348. package/src/extractor/debug.ts +10 -0
  349. package/src/extractor/dom-util.ts +226 -0
  350. package/src/extractor/index.ts +48 -0
  351. package/src/extractor/locator.ts +469 -0
  352. package/src/extractor/tree.ts +179 -0
  353. package/src/extractor/util.ts +482 -0
  354. package/src/extractor/web-extractor.ts +481 -0
  355. package/src/img/box-select.ts +588 -0
  356. package/src/img/canvas-fallback.ts +393 -0
  357. package/src/img/get-photon.ts +108 -0
  358. package/src/img/get-sharp.ts +18 -0
  359. package/src/img/index.ts +26 -0
  360. package/src/img/info.ts +75 -0
  361. package/src/img/transform.ts +594 -0
  362. package/src/index.ts +8 -0
  363. package/src/logger.ts +96 -0
  364. package/src/mcp/base-server.ts +502 -0
  365. package/src/mcp/base-tools.ts +185 -0
  366. package/src/mcp/chrome-path.ts +48 -0
  367. package/src/mcp/index.ts +7 -0
  368. package/src/mcp/inject-report-html-plugin.ts +119 -0
  369. package/src/mcp/launcher-helper.ts +200 -0
  370. package/src/mcp/tool-generator.ts +429 -0
  371. package/src/mcp/types.ts +112 -0
  372. package/src/node/fs.ts +84 -0
  373. package/src/node/index.ts +2 -0
  374. package/src/node/port.ts +37 -0
  375. package/src/oss/demo.ts +61 -0
  376. package/src/oss/index.ts +187 -0
  377. package/src/polyfills/async-hooks.ts +6 -0
  378. package/src/polyfills/index.ts +4 -0
  379. package/src/types/index.ts +52 -0
  380. package/src/us-keyboard-layout.ts +723 -0
  381. package/src/utils.ts +149 -0
  382. package/src/zod-schema-utils.ts +133 -0
@@ -0,0 +1,393 @@
1
+ /**
2
+ * Canvas-based fallback for image processing when Photon WASM fails to load.
3
+ * Provides a compatible API with Photon for browser environments.
4
+ */
5
+
6
+ import { getDebug } from '../logger';
7
+
8
+ const debug = getDebug('img:canvas-fallback');
9
+
10
+ /**
11
+ * Canvas-based image class that mimics PhotonImage API
12
+ */
13
+ export class CanvasImage {
14
+ private canvas: HTMLCanvasElement;
15
+ private ctx: CanvasRenderingContext2D;
16
+ private _width: number;
17
+ private _height: number;
18
+
19
+ constructor(canvas: HTMLCanvasElement) {
20
+ this.canvas = canvas;
21
+ const ctx = canvas.getContext('2d');
22
+ if (!ctx) {
23
+ throw new Error('Failed to get 2d context');
24
+ }
25
+ this.ctx = ctx;
26
+ this._width = canvas.width;
27
+ this._height = canvas.height;
28
+ }
29
+
30
+ get_width(): number {
31
+ return this._width;
32
+ }
33
+
34
+ get_height(): number {
35
+ return this._height;
36
+ }
37
+
38
+ get_raw_pixels(): Uint8Array {
39
+ const imageData = this.ctx.getImageData(0, 0, this._width, this._height);
40
+ return new Uint8Array(imageData.data.buffer);
41
+ }
42
+
43
+ get_bytes_jpeg(quality: number): Uint8Array {
44
+ const dataUrl = this.canvas.toDataURL('image/jpeg', quality / 100);
45
+ const base64 = dataUrl.split(',')[1];
46
+ const binary = atob(base64);
47
+ const bytes = new Uint8Array(binary.length);
48
+ for (let i = 0; i < binary.length; i++) {
49
+ bytes[i] = binary.charCodeAt(i);
50
+ }
51
+ return bytes;
52
+ }
53
+
54
+ free(): void {
55
+ // No-op for Canvas, garbage collector will handle it
56
+ }
57
+
58
+ // Internal method to get canvas for composition
59
+ _getCanvas(): HTMLCanvasElement {
60
+ return this.canvas;
61
+ }
62
+
63
+ _getContext(): CanvasRenderingContext2D {
64
+ return this.ctx;
65
+ }
66
+
67
+ /**
68
+ * Create a CanvasImage from a base64 string
69
+ */
70
+ static async new_from_base64(base64Body: string): Promise<CanvasImage> {
71
+ return new Promise((resolve, reject) => {
72
+ const img = new Image();
73
+ img.onload = () => {
74
+ const canvas = document.createElement('canvas');
75
+ canvas.width = img.width;
76
+ canvas.height = img.height;
77
+ const ctx = canvas.getContext('2d');
78
+ if (!ctx) {
79
+ reject(new Error('Failed to get 2d context'));
80
+ return;
81
+ }
82
+ ctx.drawImage(img, 0, 0);
83
+ resolve(new CanvasImage(canvas));
84
+ };
85
+ img.onerror = () => {
86
+ reject(new Error('Failed to load image'));
87
+ };
88
+ // Handle both with and without data URL prefix
89
+ if (base64Body.startsWith('data:')) {
90
+ img.src = base64Body;
91
+ } else {
92
+ img.src = `data:image/png;base64,${base64Body}`;
93
+ }
94
+ });
95
+ }
96
+
97
+ /**
98
+ * Create a CanvasImage from a byte array (async version)
99
+ */
100
+ static async new_from_byteslice(bytes: Uint8Array): Promise<CanvasImage> {
101
+ return new Promise((resolve, reject) => {
102
+ const blob = new Blob([bytes], { type: 'image/png' });
103
+ const url = URL.createObjectURL(blob);
104
+ const img = new Image();
105
+
106
+ img.onload = () => {
107
+ const canvas = document.createElement('canvas');
108
+ canvas.width = img.width;
109
+ canvas.height = img.height;
110
+ const ctx = canvas.getContext('2d');
111
+ if (!ctx) {
112
+ URL.revokeObjectURL(url);
113
+ reject(new Error('Failed to get 2d context'));
114
+ return;
115
+ }
116
+ ctx.drawImage(img, 0, 0);
117
+ URL.revokeObjectURL(url);
118
+ resolve(new CanvasImage(canvas));
119
+ };
120
+
121
+ img.onerror = () => {
122
+ URL.revokeObjectURL(url);
123
+ reject(new Error('Failed to load image from bytes'));
124
+ };
125
+
126
+ img.src = url;
127
+ });
128
+ }
129
+ }
130
+
131
+ /**
132
+ * Sampling filter enum (compatible with Photon)
133
+ */
134
+ export const CanvasSamplingFilter = {
135
+ Nearest: 'nearest',
136
+ Triangle: 'triangle',
137
+ CatmullRom: 'catmullrom',
138
+ Gaussian: 'gaussian',
139
+ Lanczos3: 'lanczos3',
140
+ } as const;
141
+
142
+ /**
143
+ * RGBA color class (compatible with Photon)
144
+ */
145
+ export class CanvasRgba {
146
+ r: number;
147
+ g: number;
148
+ b: number;
149
+ a: number;
150
+
151
+ constructor(r: number, g: number, b: number, a: number) {
152
+ this.r = r;
153
+ this.g = g;
154
+ this.b = b;
155
+ this.a = a;
156
+ }
157
+ }
158
+
159
+ /**
160
+ * Resize an image
161
+ */
162
+ export function canvasResize(
163
+ image: CanvasImage,
164
+ newWidth: number,
165
+ newHeight: number,
166
+ _filter: string,
167
+ ): CanvasImage {
168
+ const canvas = document.createElement('canvas');
169
+ canvas.width = newWidth;
170
+ canvas.height = newHeight;
171
+ const ctx = canvas.getContext('2d');
172
+ if (!ctx) {
173
+ throw new Error('Failed to get 2d context');
174
+ }
175
+
176
+ // Enable image smoothing for better quality
177
+ ctx.imageSmoothingEnabled = true;
178
+ ctx.imageSmoothingQuality = 'high';
179
+
180
+ ctx.drawImage(image._getCanvas(), 0, 0, newWidth, newHeight);
181
+ return new CanvasImage(canvas);
182
+ }
183
+
184
+ /**
185
+ * Crop an image
186
+ */
187
+ export function canvasCrop(
188
+ image: CanvasImage,
189
+ x1: number,
190
+ y1: number,
191
+ x2: number,
192
+ y2: number,
193
+ ): CanvasImage {
194
+ const width = x2 - x1;
195
+ const height = y2 - y1;
196
+ const canvas = document.createElement('canvas');
197
+ canvas.width = width;
198
+ canvas.height = height;
199
+ const ctx = canvas.getContext('2d');
200
+ if (!ctx) {
201
+ throw new Error('Failed to get 2d context');
202
+ }
203
+ ctx.drawImage(image._getCanvas(), x1, y1, width, height, 0, 0, width, height);
204
+ return new CanvasImage(canvas);
205
+ }
206
+
207
+ /**
208
+ * Add padding to the right of an image
209
+ */
210
+ export function canvasPaddingRight(
211
+ image: CanvasImage,
212
+ padding: number,
213
+ color: CanvasRgba,
214
+ ): CanvasImage {
215
+ const newWidth = image.get_width() + padding;
216
+ const height = image.get_height();
217
+ const canvas = document.createElement('canvas');
218
+ canvas.width = newWidth;
219
+ canvas.height = height;
220
+ const ctx = canvas.getContext('2d');
221
+ if (!ctx) {
222
+ throw new Error('Failed to get 2d context');
223
+ }
224
+
225
+ // Fill with color
226
+ ctx.fillStyle = `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a / 255})`;
227
+ ctx.fillRect(0, 0, newWidth, height);
228
+
229
+ // Draw original image
230
+ ctx.drawImage(image._getCanvas(), 0, 0);
231
+ return new CanvasImage(canvas);
232
+ }
233
+
234
+ /**
235
+ * Add padding to the bottom of an image
236
+ */
237
+ export function canvasPaddingBottom(
238
+ image: CanvasImage,
239
+ padding: number,
240
+ color: CanvasRgba,
241
+ ): CanvasImage {
242
+ const width = image.get_width();
243
+ const newHeight = image.get_height() + padding;
244
+ const canvas = document.createElement('canvas');
245
+ canvas.width = width;
246
+ canvas.height = newHeight;
247
+ const ctx = canvas.getContext('2d');
248
+ if (!ctx) {
249
+ throw new Error('Failed to get 2d context');
250
+ }
251
+
252
+ // Fill with color
253
+ ctx.fillStyle = `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a / 255})`;
254
+ ctx.fillRect(0, 0, width, newHeight);
255
+
256
+ // Draw original image
257
+ ctx.drawImage(image._getCanvas(), 0, 0);
258
+ return new CanvasImage(canvas);
259
+ }
260
+
261
+ /**
262
+ * Add uniform padding to an image
263
+ */
264
+ export function canvasPaddingUniform(
265
+ image: CanvasImage,
266
+ padding: number,
267
+ color: CanvasRgba,
268
+ ): CanvasImage {
269
+ const newWidth = image.get_width() + padding * 2;
270
+ const newHeight = image.get_height() + padding * 2;
271
+ const canvas = document.createElement('canvas');
272
+ canvas.width = newWidth;
273
+ canvas.height = newHeight;
274
+ const ctx = canvas.getContext('2d');
275
+ if (!ctx) {
276
+ throw new Error('Failed to get 2d context');
277
+ }
278
+
279
+ // Fill with color
280
+ ctx.fillStyle = `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a / 255})`;
281
+ ctx.fillRect(0, 0, newWidth, newHeight);
282
+
283
+ // Draw original image centered
284
+ ctx.drawImage(image._getCanvas(), padding, padding);
285
+ return new CanvasImage(canvas);
286
+ }
287
+
288
+ /**
289
+ * Add padding to the left of an image
290
+ */
291
+ export function canvasPaddingLeft(
292
+ image: CanvasImage,
293
+ padding: number,
294
+ color: CanvasRgba,
295
+ ): CanvasImage {
296
+ const newWidth = image.get_width() + padding;
297
+ const height = image.get_height();
298
+ const canvas = document.createElement('canvas');
299
+ canvas.width = newWidth;
300
+ canvas.height = height;
301
+ const ctx = canvas.getContext('2d');
302
+ if (!ctx) {
303
+ throw new Error('Failed to get 2d context');
304
+ }
305
+
306
+ // Fill with color
307
+ ctx.fillStyle = `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a / 255})`;
308
+ ctx.fillRect(0, 0, newWidth, height);
309
+
310
+ // Draw original image offset by padding
311
+ ctx.drawImage(image._getCanvas(), padding, 0);
312
+ return new CanvasImage(canvas);
313
+ }
314
+
315
+ /**
316
+ * Add padding to the top of an image
317
+ */
318
+ export function canvasPaddingTop(
319
+ image: CanvasImage,
320
+ padding: number,
321
+ color: CanvasRgba,
322
+ ): CanvasImage {
323
+ const width = image.get_width();
324
+ const newHeight = image.get_height() + padding;
325
+ const canvas = document.createElement('canvas');
326
+ canvas.width = width;
327
+ canvas.height = newHeight;
328
+ const ctx = canvas.getContext('2d');
329
+ if (!ctx) {
330
+ throw new Error('Failed to get 2d context');
331
+ }
332
+
333
+ // Fill with color
334
+ ctx.fillStyle = `rgba(${color.r}, ${color.g}, ${color.b}, ${color.a / 255})`;
335
+ ctx.fillRect(0, 0, width, newHeight);
336
+
337
+ // Draw original image offset by padding
338
+ ctx.drawImage(image._getCanvas(), 0, padding);
339
+ return new CanvasImage(canvas);
340
+ }
341
+
342
+ /**
343
+ * Watermark an image (overlay one image on another)
344
+ */
345
+ export function canvasWatermark(
346
+ base: CanvasImage,
347
+ overlay: CanvasImage,
348
+ x: number,
349
+ y: number,
350
+ ): CanvasImage {
351
+ const canvas = document.createElement('canvas');
352
+ canvas.width = base.get_width();
353
+ canvas.height = base.get_height();
354
+ const ctx = canvas.getContext('2d');
355
+ if (!ctx) {
356
+ throw new Error('Failed to get 2d context');
357
+ }
358
+
359
+ // Draw base image
360
+ ctx.drawImage(base._getCanvas(), 0, 0);
361
+
362
+ // Draw overlay at position
363
+ ctx.drawImage(overlay._getCanvas(), x, y);
364
+ return new CanvasImage(canvas);
365
+ }
366
+
367
+ /**
368
+ * Create and return the canvas fallback module with Photon-compatible API
369
+ */
370
+ export function createCanvasFallbackModule() {
371
+ debug('Creating Canvas fallback module');
372
+ console.log(
373
+ '[midscene:img] Using Canvas fallback (Photon WASM not available)',
374
+ );
375
+
376
+ return {
377
+ PhotonImage: CanvasImage,
378
+ SamplingFilter: CanvasSamplingFilter,
379
+ resize: canvasResize,
380
+ crop: canvasCrop,
381
+ open_image: () => {
382
+ throw new Error('open_image not supported in Canvas fallback');
383
+ },
384
+ base64_to_image: CanvasImage.new_from_base64,
385
+ padding_uniform: canvasPaddingUniform,
386
+ padding_left: canvasPaddingLeft,
387
+ padding_right: canvasPaddingRight,
388
+ padding_top: canvasPaddingTop,
389
+ padding_bottom: canvasPaddingBottom,
390
+ watermark: canvasWatermark,
391
+ Rgba: CanvasRgba,
392
+ };
393
+ }
@@ -0,0 +1,108 @@
1
+ import { getDebug } from '../logger';
2
+ import { ifInBrowser, ifInNode, ifInWorker } from '../utils';
3
+
4
+ const debug = getDebug('img');
5
+
6
+ let photonModule: any = null;
7
+ let isInitialized = false;
8
+ let usingCanvasFallback = false;
9
+
10
+ export default async function getPhoton(): Promise<{
11
+ PhotonImage: typeof import('@silvia-odwyer/photon-node').PhotonImage;
12
+ SamplingFilter: typeof import('@silvia-odwyer/photon-node').SamplingFilter;
13
+ resize: typeof import('@silvia-odwyer/photon-node').resize;
14
+ crop: typeof import('@silvia-odwyer/photon-node').crop;
15
+ open_image: typeof import('@silvia-odwyer/photon-node').open_image;
16
+ base64_to_image: typeof import('@silvia-odwyer/photon-node').base64_to_image;
17
+ padding_uniform: typeof import('@silvia-odwyer/photon-node').padding_uniform;
18
+ padding_left: typeof import('@silvia-odwyer/photon-node').padding_left;
19
+ padding_right: typeof import('@silvia-odwyer/photon-node').padding_right;
20
+ padding_top: typeof import('@silvia-odwyer/photon-node').padding_top;
21
+ padding_bottom: typeof import('@silvia-odwyer/photon-node').padding_bottom;
22
+ watermark: typeof import('@silvia-odwyer/photon-node').watermark;
23
+ Rgba: typeof import('@silvia-odwyer/photon-node').Rgba;
24
+ }> {
25
+ if (photonModule && isInitialized) {
26
+ return photonModule;
27
+ }
28
+
29
+ const env = ifInBrowser
30
+ ? 'browser'
31
+ : ifInWorker
32
+ ? 'worker'
33
+ : ifInNode
34
+ ? 'node'
35
+ : 'unknown';
36
+ debug(`Loading photon module in ${env} environment`);
37
+
38
+ // Try to load Photon first
39
+ try {
40
+ if (ifInBrowser || ifInWorker) {
41
+ // Regular browser environment: use @silvia-odwyer/photon
42
+ const photon = await import('@silvia-odwyer/photon');
43
+ if (typeof photon.default === 'function') {
44
+ // for browser environment, ensure WASM module is correctly initialized
45
+ await photon.default();
46
+ }
47
+ debug('Photon loaded: @silvia-odwyer/photon (browser/worker)');
48
+ photonModule = photon;
49
+ } else if (ifInNode) {
50
+ // Node.js environment: use @silvia-odwyer/photon-node
51
+ photonModule = await import('@silvia-odwyer/photon-node');
52
+ debug('Photon loaded: @silvia-odwyer/photon-node (node)');
53
+ }
54
+
55
+ // verify that the critical functions exist (only for Photon, not Canvas fallback)
56
+ if (!photonModule?.PhotonImage) {
57
+ throw new Error('PhotonImage is not available');
58
+ }
59
+ // new_from_byteslice may be sync (Photon) or async (Canvas), both are acceptable
60
+ if (
61
+ !photonModule.PhotonImage.new_from_byteslice &&
62
+ !photonModule.PhotonImage.new_from_base64
63
+ ) {
64
+ throw new Error(
65
+ 'PhotonImage.new_from_byteslice or new_from_base64 is not available',
66
+ );
67
+ }
68
+
69
+ isInitialized = true;
70
+ return photonModule;
71
+ } catch (error) {
72
+ debug(
73
+ `Photon load failed: ${error instanceof Error ? error.message : String(error)}`,
74
+ );
75
+
76
+ // In browser environment, fall back to Canvas API
77
+ if (ifInBrowser) {
78
+ console.warn(
79
+ `[midscene:img] Photon WASM failed to load, falling back to Canvas API. Error: ${error instanceof Error ? error.message : String(error)}`,
80
+ );
81
+
82
+ try {
83
+ const { createCanvasFallbackModule } = await import(
84
+ './canvas-fallback'
85
+ );
86
+ photonModule = createCanvasFallbackModule();
87
+ usingCanvasFallback = true;
88
+ isInitialized = true;
89
+ return photonModule;
90
+ } catch (fallbackError) {
91
+ debug(
92
+ `Canvas fallback also failed: ${fallbackError instanceof Error ? fallbackError.message : String(fallbackError)}`,
93
+ );
94
+ }
95
+ }
96
+
97
+ throw new Error(
98
+ `Failed to load photon module: ${error instanceof Error ? error.message : String(error)}`,
99
+ );
100
+ }
101
+ }
102
+
103
+ /**
104
+ * Check if we're using the Canvas fallback instead of Photon
105
+ */
106
+ export function isUsingCanvasFallback(): boolean {
107
+ return usingCanvasFallback;
108
+ }
@@ -0,0 +1,18 @@
1
+ import { ifInNode } from '../utils';
2
+ type TSharpModule = typeof import('sharp');
3
+
4
+ export default async function getSharp(): Promise<TSharpModule> {
5
+ if (!ifInNode) {
6
+ throw new Error('Sharp is only available in Node.js environment');
7
+ }
8
+
9
+ try {
10
+ // @ts-ignore
11
+ const sharp = await import('sharp');
12
+ return sharp.default;
13
+ } catch (error) {
14
+ throw new Error(
15
+ `Failed to load sharp module: ${error instanceof Error ? error.message : String(error)}`,
16
+ );
17
+ }
18
+ }
@@ -0,0 +1,26 @@
1
+ export {
2
+ imageInfoOfBase64,
3
+ isValidPNGImageBuffer,
4
+ isValidJPEGImageBuffer,
5
+ isValidImageBuffer,
6
+ } from './info';
7
+ export {
8
+ resizeAndConvertImgBuffer,
9
+ resizeImgBase64,
10
+ convertToJpegBase64,
11
+ zoomForGPT4o,
12
+ saveBase64Image,
13
+ paddingToMatchBlockByBase64,
14
+ cropByRect,
15
+ scaleImage,
16
+ localImg2Base64,
17
+ httpImg2Base64,
18
+ preProcessImageUrl,
19
+ parseBase64,
20
+ createImgBase64ByFormat,
21
+ } from './transform';
22
+ export {
23
+ processImageElementInfo,
24
+ compositeElementInfoImg,
25
+ annotateRects,
26
+ } from './box-select';
@@ -0,0 +1,75 @@
1
+ import assert from 'node:assert';
2
+ import type { Size } from '../types';
3
+ import getPhoton from './get-photon';
4
+
5
+ export interface ImageInfo extends Size {}
6
+
7
+ /**
8
+ * Retrieves the dimensions of an image from a base64-encoded string
9
+ *
10
+ * @param imageBase64 - The base64-encoded image data
11
+ * @returns A Promise that resolves to an object containing the width and height of the image
12
+ * @throws Error if the image data is invalid
13
+ */
14
+ export async function imageInfoOfBase64(
15
+ imageBase64: string,
16
+ ): Promise<ImageInfo> {
17
+ const { PhotonImage } = await getPhoton();
18
+ const base64Data = imageBase64.replace(/^data:image\/\w+;base64,/, '');
19
+ // Support both sync (Photon) and async (Canvas fallback) versions
20
+ const result = PhotonImage.new_from_base64(base64Data);
21
+ const image = result instanceof Promise ? await result : result;
22
+ const width = image.get_width();
23
+ const height = image.get_height();
24
+ image.free();
25
+ assert(width && height, 'Invalid image: cannot get width or height');
26
+ return { width, height };
27
+ }
28
+
29
+ /**
30
+ * Check if the Buffer is a valid PNG image
31
+ * @param buffer The Buffer to check
32
+ * @returns true if the Buffer is a valid PNG image, otherwise false
33
+ */
34
+ export function isValidPNGImageBuffer(buffer: Buffer): boolean {
35
+ if (!buffer || buffer.length < 8) {
36
+ return false;
37
+ }
38
+
39
+ // Check PNG signature (8 bytes): 89 50 4E 47 0D 0A 1A 0A
40
+ // This is more robust than just checking the first 4 bytes
41
+ const isPNG =
42
+ buffer[0] === 0x89 &&
43
+ buffer[1] === 0x50 &&
44
+ buffer[2] === 0x4e &&
45
+ buffer[3] === 0x47 &&
46
+ buffer[4] === 0x0d &&
47
+ buffer[5] === 0x0a &&
48
+ buffer[6] === 0x1a &&
49
+ buffer[7] === 0x0a;
50
+
51
+ return isPNG;
52
+ }
53
+
54
+ /**
55
+ * Check if the Buffer is a valid JPEG image
56
+ * @param buffer The Buffer to check
57
+ * @returns true if the Buffer is a valid JPEG image, otherwise false
58
+ */
59
+ export function isValidJPEGImageBuffer(buffer: Buffer): boolean {
60
+ if (!buffer || buffer.length < 3) {
61
+ return false;
62
+ }
63
+
64
+ // Check JPEG signature (3 bytes): FF D8 FF
65
+ return buffer[0] === 0xff && buffer[1] === 0xd8 && buffer[2] === 0xff;
66
+ }
67
+
68
+ /**
69
+ * Check if the Buffer is a valid image (PNG or JPEG)
70
+ * @param buffer The Buffer to check
71
+ * @returns true if the Buffer is a valid PNG or JPEG image, otherwise false
72
+ */
73
+ export function isValidImageBuffer(buffer: Buffer): boolean {
74
+ return isValidPNGImageBuffer(buffer) || isValidJPEGImageBuffer(buffer);
75
+ }