@heojeongbo/wirestage 0.0.0-stage → 0.1.1

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 (489) hide show
  1. package/LICENSE +21 -0
  2. package/LICENSES.md +21 -0
  3. package/README.md +150 -2
  4. package/dist/app/playwright/index.d.ts +3 -0
  5. package/dist/app/playwright/index.d.ts.map +1 -0
  6. package/dist/app/playwright/index.js +2 -0
  7. package/dist/app/playwright/index.js.map +1 -0
  8. package/dist/app/playwright/lib/fixture.d.ts +61 -0
  9. package/dist/app/playwright/lib/fixture.d.ts.map +1 -0
  10. package/dist/app/playwright/lib/fixture.js +110 -0
  11. package/dist/app/playwright/lib/fixture.js.map +1 -0
  12. package/dist/connect.d.ts +7 -0
  13. package/dist/connect.d.ts.map +1 -0
  14. package/dist/connect.js +7 -0
  15. package/dist/connect.js.map +1 -0
  16. package/dist/entities/frame/@x/plugin.d.ts +9 -0
  17. package/dist/entities/frame/@x/plugin.d.ts.map +1 -0
  18. package/dist/entities/frame/@x/plugin.js +2 -0
  19. package/dist/entities/frame/@x/plugin.js.map +1 -0
  20. package/dist/entities/frame/index.d.ts +6 -0
  21. package/dist/entities/frame/index.d.ts.map +1 -0
  22. package/dist/entities/frame/index.js +4 -0
  23. package/dist/entities/frame/index.js.map +1 -0
  24. package/dist/entities/frame/lib/filter.d.ts +8 -0
  25. package/dist/entities/frame/lib/filter.d.ts.map +1 -0
  26. package/dist/entities/frame/lib/filter.js +62 -0
  27. package/dist/entities/frame/lib/filter.js.map +1 -0
  28. package/dist/entities/frame/lib/payload.d.ts +8 -0
  29. package/dist/entities/frame/lib/payload.d.ts.map +1 -0
  30. package/dist/entities/frame/lib/payload.js +42 -0
  31. package/dist/entities/frame/lib/payload.js.map +1 -0
  32. package/dist/entities/frame/lib/snapshot.d.ts +15 -0
  33. package/dist/entities/frame/lib/snapshot.d.ts.map +1 -0
  34. package/dist/entities/frame/lib/snapshot.js +90 -0
  35. package/dist/entities/frame/lib/snapshot.js.map +1 -0
  36. package/dist/entities/frame/lib/timeline.d.ts +23 -0
  37. package/dist/entities/frame/lib/timeline.d.ts.map +1 -0
  38. package/dist/entities/frame/lib/timeline.js +122 -0
  39. package/dist/entities/frame/lib/timeline.js.map +1 -0
  40. package/dist/entities/frame/model/frame.d.ts +182 -0
  41. package/dist/entities/frame/model/frame.d.ts.map +1 -0
  42. package/dist/entities/frame/model/frame.js +2 -0
  43. package/dist/entities/frame/model/frame.js.map +1 -0
  44. package/dist/entities/plugin/index.d.ts +9 -0
  45. package/dist/entities/plugin/index.d.ts.map +1 -0
  46. package/dist/entities/plugin/index.js +3 -0
  47. package/dist/entities/plugin/index.js.map +1 -0
  48. package/dist/entities/plugin/lib/define-plugin.d.ts +8 -0
  49. package/dist/entities/plugin/lib/define-plugin.d.ts.map +1 -0
  50. package/dist/entities/plugin/lib/define-plugin.js +9 -0
  51. package/dist/entities/plugin/lib/define-plugin.js.map +1 -0
  52. package/dist/entities/plugin/lib/named.d.ts +10 -0
  53. package/dist/entities/plugin/lib/named.d.ts.map +1 -0
  54. package/dist/entities/plugin/lib/named.js +17 -0
  55. package/dist/entities/plugin/lib/named.js.map +1 -0
  56. package/dist/entities/plugin/model/attachment.d.ts +18 -0
  57. package/dist/entities/plugin/model/attachment.d.ts.map +1 -0
  58. package/dist/entities/plugin/model/attachment.js +2 -0
  59. package/dist/entities/plugin/model/attachment.js.map +1 -0
  60. package/dist/entities/plugin/model/http.d.ts +135 -0
  61. package/dist/entities/plugin/model/http.d.ts.map +1 -0
  62. package/dist/entities/plugin/model/http.js +2 -0
  63. package/dist/entities/plugin/model/http.js.map +1 -0
  64. package/dist/entities/plugin/model/page.d.ts +100 -0
  65. package/dist/entities/plugin/model/page.d.ts.map +1 -0
  66. package/dist/entities/plugin/model/page.js +2 -0
  67. package/dist/entities/plugin/model/page.js.map +1 -0
  68. package/dist/entities/plugin/model/plugin.d.ts +83 -0
  69. package/dist/entities/plugin/model/plugin.d.ts.map +1 -0
  70. package/dist/entities/plugin/model/plugin.js +2 -0
  71. package/dist/entities/plugin/model/plugin.js.map +1 -0
  72. package/dist/entities/plugin/model/socket.d.ts +107 -0
  73. package/dist/entities/plugin/model/socket.d.ts.map +1 -0
  74. package/dist/entities/plugin/model/socket.js +2 -0
  75. package/dist/entities/plugin/model/socket.js.map +1 -0
  76. package/dist/entities/plugin/model/stream.d.ts +46 -0
  77. package/dist/entities/plugin/model/stream.d.ts.map +1 -0
  78. package/dist/entities/plugin/model/stream.js +2 -0
  79. package/dist/entities/plugin/model/stream.js.map +1 -0
  80. package/dist/features/connect/index.d.ts +5 -0
  81. package/dist/features/connect/index.d.ts.map +1 -0
  82. package/dist/features/connect/index.js +4 -0
  83. package/dist/features/connect/index.js.map +1 -0
  84. package/dist/features/connect/lib/calls.d.ts +9 -0
  85. package/dist/features/connect/lib/calls.d.ts.map +1 -0
  86. package/dist/features/connect/lib/calls.js +46 -0
  87. package/dist/features/connect/lib/calls.js.map +1 -0
  88. package/dist/features/connect/lib/client.d.ts +33 -0
  89. package/dist/features/connect/lib/client.d.ts.map +1 -0
  90. package/dist/features/connect/lib/client.js +147 -0
  91. package/dist/features/connect/lib/client.js.map +1 -0
  92. package/dist/features/connect/lib/create-connect.d.ts +14 -0
  93. package/dist/features/connect/lib/create-connect.d.ts.map +1 -0
  94. package/dist/features/connect/lib/create-connect.js +124 -0
  95. package/dist/features/connect/lib/create-connect.js.map +1 -0
  96. package/dist/features/connect/lib/faults.d.ts +18 -0
  97. package/dist/features/connect/lib/faults.d.ts.map +1 -0
  98. package/dist/features/connect/lib/faults.js +85 -0
  99. package/dist/features/connect/lib/faults.js.map +1 -0
  100. package/dist/features/connect/lib/protocol.d.ts +42 -0
  101. package/dist/features/connect/lib/protocol.d.ts.map +1 -0
  102. package/dist/features/connect/lib/protocol.js +228 -0
  103. package/dist/features/connect/lib/protocol.js.map +1 -0
  104. package/dist/features/connect/lib/record.d.ts +14 -0
  105. package/dist/features/connect/lib/record.d.ts.map +1 -0
  106. package/dist/features/connect/lib/record.js +36 -0
  107. package/dist/features/connect/lib/record.js.map +1 -0
  108. package/dist/features/connect/lib/recorder.d.ts +77 -0
  109. package/dist/features/connect/lib/recorder.d.ts.map +1 -0
  110. package/dist/features/connect/lib/recorder.js +209 -0
  111. package/dist/features/connect/lib/recorder.js.map +1 -0
  112. package/dist/features/connect/lib/rules.d.ts +51 -0
  113. package/dist/features/connect/lib/rules.d.ts.map +1 -0
  114. package/dist/features/connect/lib/rules.js +222 -0
  115. package/dist/features/connect/lib/rules.js.map +1 -0
  116. package/dist/features/connect/lib/serve.d.ts +10 -0
  117. package/dist/features/connect/lib/serve.d.ts.map +1 -0
  118. package/dist/features/connect/lib/serve.js +78 -0
  119. package/dist/features/connect/lib/serve.js.map +1 -0
  120. package/dist/features/connect/lib/status-of.d.ts +11 -0
  121. package/dist/features/connect/lib/status-of.d.ts.map +1 -0
  122. package/dist/features/connect/lib/status-of.js +22 -0
  123. package/dist/features/connect/lib/status-of.js.map +1 -0
  124. package/dist/features/connect/lib/stubs.d.ts +18 -0
  125. package/dist/features/connect/lib/stubs.d.ts.map +1 -0
  126. package/dist/features/connect/lib/stubs.js +174 -0
  127. package/dist/features/connect/lib/stubs.js.map +1 -0
  128. package/dist/features/connect/lib/universal.d.ts +19 -0
  129. package/dist/features/connect/lib/universal.d.ts.map +1 -0
  130. package/dist/features/connect/lib/universal.js +71 -0
  131. package/dist/features/connect/lib/universal.js.map +1 -0
  132. package/dist/features/connect/model/types.d.ts +247 -0
  133. package/dist/features/connect/model/types.d.ts.map +1 -0
  134. package/dist/features/connect/model/types.js +2 -0
  135. package/dist/features/connect/model/types.js.map +1 -0
  136. package/dist/features/rest/index.d.ts +5 -0
  137. package/dist/features/rest/index.d.ts.map +1 -0
  138. package/dist/features/rest/index.js +3 -0
  139. package/dist/features/rest/index.js.map +1 -0
  140. package/dist/features/rest/lib/calls.d.ts +8 -0
  141. package/dist/features/rest/lib/calls.d.ts.map +1 -0
  142. package/dist/features/rest/lib/calls.js +32 -0
  143. package/dist/features/rest/lib/calls.js.map +1 -0
  144. package/dist/features/rest/lib/create-rest.d.ts +8 -0
  145. package/dist/features/rest/lib/create-rest.d.ts.map +1 -0
  146. package/dist/features/rest/lib/create-rest.js +136 -0
  147. package/dist/features/rest/lib/create-rest.js.map +1 -0
  148. package/dist/features/rest/lib/path.d.ts +14 -0
  149. package/dist/features/rest/lib/path.d.ts.map +1 -0
  150. package/dist/features/rest/lib/path.js +58 -0
  151. package/dist/features/rest/lib/path.js.map +1 -0
  152. package/dist/features/rest/lib/reply.d.ts +25 -0
  153. package/dist/features/rest/lib/reply.d.ts.map +1 -0
  154. package/dist/features/rest/lib/reply.js +40 -0
  155. package/dist/features/rest/lib/reply.js.map +1 -0
  156. package/dist/features/rest/model/types.d.ts +74 -0
  157. package/dist/features/rest/model/types.d.ts.map +1 -0
  158. package/dist/features/rest/model/types.js +2 -0
  159. package/dist/features/rest/model/types.js.map +1 -0
  160. package/dist/features/sse/index.d.ts +4 -0
  161. package/dist/features/sse/index.d.ts.map +1 -0
  162. package/dist/features/sse/index.js +3 -0
  163. package/dist/features/sse/index.js.map +1 -0
  164. package/dist/features/sse/lib/create-sse.d.ts +9 -0
  165. package/dist/features/sse/lib/create-sse.d.ts.map +1 -0
  166. package/dist/features/sse/lib/create-sse.js +121 -0
  167. package/dist/features/sse/lib/create-sse.js.map +1 -0
  168. package/dist/features/sse/lib/encode.d.ts +8 -0
  169. package/dist/features/sse/lib/encode.d.ts.map +1 -0
  170. package/dist/features/sse/lib/encode.js +29 -0
  171. package/dist/features/sse/lib/encode.js.map +1 -0
  172. package/dist/features/sse/model/types.d.ts +68 -0
  173. package/dist/features/sse/model/types.d.ts.map +1 -0
  174. package/dist/features/sse/model/types.js +2 -0
  175. package/dist/features/sse/model/types.js.map +1 -0
  176. package/dist/features/webrtc/index.d.ts +3 -0
  177. package/dist/features/webrtc/index.d.ts.map +1 -0
  178. package/dist/features/webrtc/index.js +2 -0
  179. package/dist/features/webrtc/index.js.map +1 -0
  180. package/dist/features/webrtc/lib/create-webrtc.d.ts +9 -0
  181. package/dist/features/webrtc/lib/create-webrtc.d.ts.map +1 -0
  182. package/dist/features/webrtc/lib/create-webrtc.js +123 -0
  183. package/dist/features/webrtc/lib/create-webrtc.js.map +1 -0
  184. package/dist/features/webrtc/lib/rtc-page-module.d.ts +22 -0
  185. package/dist/features/webrtc/lib/rtc-page-module.d.ts.map +1 -0
  186. package/dist/features/webrtc/lib/rtc-page-module.js +161 -0
  187. package/dist/features/webrtc/lib/rtc-page-module.js.map +1 -0
  188. package/dist/features/webrtc/lib/to-frame.d.ts +9 -0
  189. package/dist/features/webrtc/lib/to-frame.d.ts.map +1 -0
  190. package/dist/features/webrtc/lib/to-frame.js +43 -0
  191. package/dist/features/webrtc/lib/to-frame.js.map +1 -0
  192. package/dist/features/webrtc/model/types.d.ts +70 -0
  193. package/dist/features/webrtc/model/types.d.ts.map +1 -0
  194. package/dist/features/webrtc/model/types.js +2 -0
  195. package/dist/features/webrtc/model/types.js.map +1 -0
  196. package/dist/features/websocket/index.d.ts +3 -0
  197. package/dist/features/websocket/index.d.ts.map +1 -0
  198. package/dist/features/websocket/index.js +2 -0
  199. package/dist/features/websocket/index.js.map +1 -0
  200. package/dist/features/websocket/lib/create-websocket.d.ts +9 -0
  201. package/dist/features/websocket/lib/create-websocket.d.ts.map +1 -0
  202. package/dist/features/websocket/lib/create-websocket.js +34 -0
  203. package/dist/features/websocket/lib/create-websocket.js.map +1 -0
  204. package/dist/features/websocket/lib/mock.d.ts +6 -0
  205. package/dist/features/websocket/lib/mock.d.ts.map +1 -0
  206. package/dist/features/websocket/lib/mock.js +96 -0
  207. package/dist/features/websocket/lib/mock.js.map +1 -0
  208. package/dist/features/websocket/lib/proxy.d.ts +9 -0
  209. package/dist/features/websocket/lib/proxy.d.ts.map +1 -0
  210. package/dist/features/websocket/lib/proxy.js +120 -0
  211. package/dist/features/websocket/lib/proxy.js.map +1 -0
  212. package/dist/features/websocket/lib/wire.d.ts +16 -0
  213. package/dist/features/websocket/lib/wire.d.ts.map +1 -0
  214. package/dist/features/websocket/lib/wire.js +46 -0
  215. package/dist/features/websocket/lib/wire.js.map +1 -0
  216. package/dist/features/websocket/model/types.d.ts +133 -0
  217. package/dist/features/websocket/model/types.d.ts.map +1 -0
  218. package/dist/features/websocket/model/types.js +2 -0
  219. package/dist/features/websocket/model/types.js.map +1 -0
  220. package/dist/index.d.ts +27 -0
  221. package/dist/index.d.ts.map +1 -0
  222. package/dist/index.js +16 -0
  223. package/dist/index.js.map +1 -0
  224. package/dist/playwright.d.ts +4 -0
  225. package/dist/playwright.d.ts.map +1 -0
  226. package/dist/playwright.js +2 -0
  227. package/dist/playwright.js.map +1 -0
  228. package/dist/rest.d.ts +3 -0
  229. package/dist/rest.d.ts.map +1 -0
  230. package/dist/rest.js +3 -0
  231. package/dist/rest.js.map +1 -0
  232. package/dist/shared/api/http-server/index.d.ts +3 -0
  233. package/dist/shared/api/http-server/index.d.ts.map +1 -0
  234. package/dist/shared/api/http-server/index.js +2 -0
  235. package/dist/shared/api/http-server/index.js.map +1 -0
  236. package/dist/shared/api/http-server/listen.d.ts +25 -0
  237. package/dist/shared/api/http-server/listen.d.ts.map +1 -0
  238. package/dist/shared/api/http-server/listen.js +44 -0
  239. package/dist/shared/api/http-server/listen.js.map +1 -0
  240. package/dist/shared/api/playwright/index.d.ts +2 -0
  241. package/dist/shared/api/playwright/index.d.ts.map +1 -0
  242. package/dist/shared/api/playwright/index.js +2 -0
  243. package/dist/shared/api/playwright/index.js.map +1 -0
  244. package/dist/shared/api/playwright/ports.d.ts +126 -0
  245. package/dist/shared/api/playwright/ports.d.ts.map +1 -0
  246. package/dist/shared/api/playwright/ports.js +11 -0
  247. package/dist/shared/api/playwright/ports.js.map +1 -0
  248. package/dist/shared/api/stream-server/index.d.ts +3 -0
  249. package/dist/shared/api/stream-server/index.d.ts.map +1 -0
  250. package/dist/shared/api/stream-server/index.js +2 -0
  251. package/dist/shared/api/stream-server/index.js.map +1 -0
  252. package/dist/shared/api/stream-server/stream-server.d.ts +45 -0
  253. package/dist/shared/api/stream-server/stream-server.d.ts.map +1 -0
  254. package/dist/shared/api/stream-server/stream-server.js +167 -0
  255. package/dist/shared/api/stream-server/stream-server.js.map +1 -0
  256. package/dist/shared/lib/async/arrivals.d.ts +31 -0
  257. package/dist/shared/lib/async/arrivals.d.ts.map +1 -0
  258. package/dist/shared/lib/async/arrivals.js +57 -0
  259. package/dist/shared/lib/async/arrivals.js.map +1 -0
  260. package/dist/shared/lib/async/async-queue.d.ts +23 -0
  261. package/dist/shared/lib/async/async-queue.d.ts.map +1 -0
  262. package/dist/shared/lib/async/async-queue.js +80 -0
  263. package/dist/shared/lib/async/async-queue.js.map +1 -0
  264. package/dist/shared/lib/async/deferred.d.ts +12 -0
  265. package/dist/shared/lib/async/deferred.d.ts.map +1 -0
  266. package/dist/shared/lib/async/deferred.js +34 -0
  267. package/dist/shared/lib/async/deferred.js.map +1 -0
  268. package/dist/shared/lib/async/index.d.ts +8 -0
  269. package/dist/shared/lib/async/index.d.ts.map +1 -0
  270. package/dist/shared/lib/async/index.js +5 -0
  271. package/dist/shared/lib/async/index.js.map +1 -0
  272. package/dist/shared/lib/async/run-all.d.ts +8 -0
  273. package/dist/shared/lib/async/run-all.d.ts.map +1 -0
  274. package/dist/shared/lib/async/run-all.js +22 -0
  275. package/dist/shared/lib/async/run-all.js.map +1 -0
  276. package/dist/shared/lib/bytes/bytes.d.ts +18 -0
  277. package/dist/shared/lib/bytes/bytes.d.ts.map +1 -0
  278. package/dist/shared/lib/bytes/bytes.js +48 -0
  279. package/dist/shared/lib/bytes/bytes.js.map +1 -0
  280. package/dist/shared/lib/bytes/index.d.ts +3 -0
  281. package/dist/shared/lib/bytes/index.d.ts.map +1 -0
  282. package/dist/shared/lib/bytes/index.js +2 -0
  283. package/dist/shared/lib/bytes/index.js.map +1 -0
  284. package/dist/shared/lib/clock/clock.d.ts +29 -0
  285. package/dist/shared/lib/clock/clock.d.ts.map +1 -0
  286. package/dist/shared/lib/clock/clock.js +85 -0
  287. package/dist/shared/lib/clock/clock.js.map +1 -0
  288. package/dist/shared/lib/clock/index.d.ts +3 -0
  289. package/dist/shared/lib/clock/index.d.ts.map +1 -0
  290. package/dist/shared/lib/clock/index.js +2 -0
  291. package/dist/shared/lib/clock/index.js.map +1 -0
  292. package/dist/shared/lib/cookies/index.d.ts +3 -0
  293. package/dist/shared/lib/cookies/index.d.ts.map +1 -0
  294. package/dist/shared/lib/cookies/index.js +2 -0
  295. package/dist/shared/lib/cookies/index.js.map +1 -0
  296. package/dist/shared/lib/cookies/set-cookie.d.ts +22 -0
  297. package/dist/shared/lib/cookies/set-cookie.d.ts.map +1 -0
  298. package/dist/shared/lib/cookies/set-cookie.js +89 -0
  299. package/dist/shared/lib/cookies/set-cookie.js.map +1 -0
  300. package/dist/shared/lib/envelope/envelope.d.ts +50 -0
  301. package/dist/shared/lib/envelope/envelope.d.ts.map +1 -0
  302. package/dist/shared/lib/envelope/envelope.js +111 -0
  303. package/dist/shared/lib/envelope/envelope.js.map +1 -0
  304. package/dist/shared/lib/envelope/index.d.ts +3 -0
  305. package/dist/shared/lib/envelope/index.d.ts.map +1 -0
  306. package/dist/shared/lib/envelope/index.js +2 -0
  307. package/dist/shared/lib/envelope/index.js.map +1 -0
  308. package/dist/shared/lib/errors/index.d.ts +3 -0
  309. package/dist/shared/lib/errors/index.d.ts.map +1 -0
  310. package/dist/shared/lib/errors/index.js +2 -0
  311. package/dist/shared/lib/errors/index.js.map +1 -0
  312. package/dist/shared/lib/errors/wirestage-error.d.ts +28 -0
  313. package/dist/shared/lib/errors/wirestage-error.d.ts.map +1 -0
  314. package/dist/shared/lib/errors/wirestage-error.js +16 -0
  315. package/dist/shared/lib/errors/wirestage-error.js.map +1 -0
  316. package/dist/shared/lib/id/id.d.ts +10 -0
  317. package/dist/shared/lib/id/id.d.ts.map +1 -0
  318. package/dist/shared/lib/id/id.js +26 -0
  319. package/dist/shared/lib/id/id.js.map +1 -0
  320. package/dist/shared/lib/id/index.d.ts +2 -0
  321. package/dist/shared/lib/id/index.d.ts.map +1 -0
  322. package/dist/shared/lib/id/index.js +2 -0
  323. package/dist/shared/lib/id/index.js.map +1 -0
  324. package/dist/shared/lib/logger/index.d.ts +3 -0
  325. package/dist/shared/lib/logger/index.d.ts.map +1 -0
  326. package/dist/shared/lib/logger/index.js +2 -0
  327. package/dist/shared/lib/logger/index.js.map +1 -0
  328. package/dist/shared/lib/logger/logger.d.ts +46 -0
  329. package/dist/shared/lib/logger/logger.d.ts.map +1 -0
  330. package/dist/shared/lib/logger/logger.js +67 -0
  331. package/dist/shared/lib/logger/logger.js.map +1 -0
  332. package/dist/shared/lib/match/index.d.ts +3 -0
  333. package/dist/shared/lib/match/index.d.ts.map +1 -0
  334. package/dist/shared/lib/match/index.js +2 -0
  335. package/dist/shared/lib/match/index.js.map +1 -0
  336. package/dist/shared/lib/match/url-matcher.d.ts +27 -0
  337. package/dist/shared/lib/match/url-matcher.d.ts.map +1 -0
  338. package/dist/shared/lib/match/url-matcher.js +88 -0
  339. package/dist/shared/lib/match/url-matcher.js.map +1 -0
  340. package/dist/sse.d.ts +3 -0
  341. package/dist/sse.d.ts.map +1 -0
  342. package/dist/sse.js +3 -0
  343. package/dist/sse.js.map +1 -0
  344. package/dist/webrtc.d.ts +3 -0
  345. package/dist/webrtc.d.ts.map +1 -0
  346. package/dist/webrtc.js +3 -0
  347. package/dist/webrtc.js.map +1 -0
  348. package/dist/websocket.d.ts +3 -0
  349. package/dist/websocket.d.ts.map +1 -0
  350. package/dist/websocket.js +3 -0
  351. package/dist/websocket.js.map +1 -0
  352. package/dist/widgets/stage/index.d.ts +3 -0
  353. package/dist/widgets/stage/index.d.ts.map +1 -0
  354. package/dist/widgets/stage/index.js +2 -0
  355. package/dist/widgets/stage/index.js.map +1 -0
  356. package/dist/widgets/stage/lib/attached-context.d.ts +10 -0
  357. package/dist/widgets/stage/lib/attached-context.d.ts.map +1 -0
  358. package/dist/widgets/stage/lib/attached-context.js +2 -0
  359. package/dist/widgets/stage/lib/attached-context.js.map +1 -0
  360. package/dist/widgets/stage/lib/create-stage.d.ts +12 -0
  361. package/dist/widgets/stage/lib/create-stage.d.ts.map +1 -0
  362. package/dist/widgets/stage/lib/create-stage.js +250 -0
  363. package/dist/widgets/stage/lib/create-stage.js.map +1 -0
  364. package/dist/widgets/stage/lib/http-router.d.ts +44 -0
  365. package/dist/widgets/stage/lib/http-router.d.ts.map +1 -0
  366. package/dist/widgets/stage/lib/http-router.js +696 -0
  367. package/dist/widgets/stage/lib/http-router.js.map +1 -0
  368. package/dist/widgets/stage/lib/page-host.d.ts +36 -0
  369. package/dist/widgets/stage/lib/page-host.d.ts.map +1 -0
  370. package/dist/widgets/stage/lib/page-host.js +240 -0
  371. package/dist/widgets/stage/lib/page-host.js.map +1 -0
  372. package/dist/widgets/stage/lib/page-runtime.d.ts +93 -0
  373. package/dist/widgets/stage/lib/page-runtime.d.ts.map +1 -0
  374. package/dist/widgets/stage/lib/page-runtime.js +247 -0
  375. package/dist/widgets/stage/lib/page-runtime.js.map +1 -0
  376. package/dist/widgets/stage/lib/reads.d.ts +21 -0
  377. package/dist/widgets/stage/lib/reads.d.ts.map +1 -0
  378. package/dist/widgets/stage/lib/reads.js +97 -0
  379. package/dist/widgets/stage/lib/reads.js.map +1 -0
  380. package/dist/widgets/stage/lib/response-stream.d.ts +23 -0
  381. package/dist/widgets/stage/lib/response-stream.d.ts.map +1 -0
  382. package/dist/widgets/stage/lib/response-stream.js +108 -0
  383. package/dist/widgets/stage/lib/response-stream.js.map +1 -0
  384. package/dist/widgets/stage/lib/socket-router.d.ts +25 -0
  385. package/dist/widgets/stage/lib/socket-router.d.ts.map +1 -0
  386. package/dist/widgets/stage/lib/socket-router.js +233 -0
  387. package/dist/widgets/stage/lib/socket-router.js.map +1 -0
  388. package/dist/widgets/stage/model/stage.d.ts +88 -0
  389. package/dist/widgets/stage/model/stage.d.ts.map +1 -0
  390. package/dist/widgets/stage/model/stage.js +2 -0
  391. package/dist/widgets/stage/model/stage.js.map +1 -0
  392. package/package.json +140 -5
  393. package/src/app/playwright/index.ts +7 -0
  394. package/src/app/playwright/lib/fixture.ts +201 -0
  395. package/src/connect.ts +6 -0
  396. package/src/entities/frame/@x/plugin.ts +8 -0
  397. package/src/entities/frame/index.ts +19 -0
  398. package/src/entities/frame/lib/filter.ts +58 -0
  399. package/src/entities/frame/lib/payload.ts +42 -0
  400. package/src/entities/frame/lib/snapshot.ts +105 -0
  401. package/src/entities/frame/lib/timeline.ts +147 -0
  402. package/src/entities/frame/model/frame.ts +191 -0
  403. package/src/entities/plugin/index.ts +36 -0
  404. package/src/entities/plugin/lib/define-plugin.ts +12 -0
  405. package/src/entities/plugin/lib/named.ts +21 -0
  406. package/src/entities/plugin/model/attachment.ts +18 -0
  407. package/src/entities/plugin/model/http.ts +156 -0
  408. package/src/entities/plugin/model/page.ts +110 -0
  409. package/src/entities/plugin/model/plugin.ts +96 -0
  410. package/src/entities/plugin/model/socket.ts +113 -0
  411. package/src/entities/plugin/model/stream.ts +46 -0
  412. package/src/features/connect/index.ts +23 -0
  413. package/src/features/connect/lib/calls.ts +58 -0
  414. package/src/features/connect/lib/client.ts +203 -0
  415. package/src/features/connect/lib/create-connect.ts +164 -0
  416. package/src/features/connect/lib/faults.ts +132 -0
  417. package/src/features/connect/lib/protocol.ts +321 -0
  418. package/src/features/connect/lib/record.ts +48 -0
  419. package/src/features/connect/lib/recorder.ts +306 -0
  420. package/src/features/connect/lib/rules.ts +385 -0
  421. package/src/features/connect/lib/serve.ts +114 -0
  422. package/src/features/connect/lib/status-of.ts +20 -0
  423. package/src/features/connect/lib/stubs.ts +282 -0
  424. package/src/features/connect/lib/universal.ts +100 -0
  425. package/src/features/connect/model/types.ts +305 -0
  426. package/src/features/rest/index.ts +23 -0
  427. package/src/features/rest/lib/calls.ts +31 -0
  428. package/src/features/rest/lib/create-rest.ts +169 -0
  429. package/src/features/rest/lib/path.ts +70 -0
  430. package/src/features/rest/lib/reply.ts +74 -0
  431. package/src/features/rest/model/types.ts +113 -0
  432. package/src/features/sse/index.ts +10 -0
  433. package/src/features/sse/lib/create-sse.ts +129 -0
  434. package/src/features/sse/lib/encode.ts +28 -0
  435. package/src/features/sse/model/types.ts +72 -0
  436. package/src/features/webrtc/index.ts +6 -0
  437. package/src/features/webrtc/lib/create-webrtc.ts +149 -0
  438. package/src/features/webrtc/lib/rtc-page-module.ts +189 -0
  439. package/src/features/webrtc/lib/to-frame.ts +63 -0
  440. package/src/features/webrtc/model/types.ts +80 -0
  441. package/src/features/websocket/index.ts +15 -0
  442. package/src/features/websocket/lib/create-websocket.ts +41 -0
  443. package/src/features/websocket/lib/mock.ts +114 -0
  444. package/src/features/websocket/lib/proxy.ts +153 -0
  445. package/src/features/websocket/lib/wire.ts +78 -0
  446. package/src/features/websocket/model/types.ts +134 -0
  447. package/src/index.ts +111 -0
  448. package/src/playwright.ts +8 -0
  449. package/src/rest.ts +2 -0
  450. package/src/shared/api/http-server/index.ts +2 -0
  451. package/src/shared/api/http-server/listen.ts +71 -0
  452. package/src/shared/api/playwright/index.ts +17 -0
  453. package/src/shared/api/playwright/ports.ts +150 -0
  454. package/src/shared/api/stream-server/index.ts +7 -0
  455. package/src/shared/api/stream-server/stream-server.ts +254 -0
  456. package/src/shared/lib/async/arrivals.ts +91 -0
  457. package/src/shared/lib/async/async-queue.ts +101 -0
  458. package/src/shared/lib/async/deferred.ts +38 -0
  459. package/src/shared/lib/async/index.ts +11 -0
  460. package/src/shared/lib/async/run-all.ts +19 -0
  461. package/src/shared/lib/bytes/bytes.ts +53 -0
  462. package/src/shared/lib/bytes/index.ts +9 -0
  463. package/src/shared/lib/clock/clock.ts +114 -0
  464. package/src/shared/lib/clock/index.ts +2 -0
  465. package/src/shared/lib/cookies/index.ts +2 -0
  466. package/src/shared/lib/cookies/set-cookie.ts +105 -0
  467. package/src/shared/lib/envelope/envelope.ts +133 -0
  468. package/src/shared/lib/envelope/index.ts +9 -0
  469. package/src/shared/lib/errors/index.ts +5 -0
  470. package/src/shared/lib/errors/wirestage-error.ts +50 -0
  471. package/src/shared/lib/id/id.ts +29 -0
  472. package/src/shared/lib/id/index.ts +1 -0
  473. package/src/shared/lib/logger/index.ts +12 -0
  474. package/src/shared/lib/logger/logger.ts +126 -0
  475. package/src/shared/lib/match/index.ts +6 -0
  476. package/src/shared/lib/match/url-matcher.ts +107 -0
  477. package/src/sse.ts +2 -0
  478. package/src/webrtc.ts +2 -0
  479. package/src/websocket.ts +2 -0
  480. package/src/widgets/stage/index.ts +9 -0
  481. package/src/widgets/stage/lib/attached-context.ts +10 -0
  482. package/src/widgets/stage/lib/create-stage.ts +307 -0
  483. package/src/widgets/stage/lib/http-router.ts +954 -0
  484. package/src/widgets/stage/lib/page-host.ts +375 -0
  485. package/src/widgets/stage/lib/page-runtime.ts +314 -0
  486. package/src/widgets/stage/lib/reads.ts +128 -0
  487. package/src/widgets/stage/lib/response-stream.ts +139 -0
  488. package/src/widgets/stage/lib/socket-router.ts +300 -0
  489. package/src/widgets/stage/model/stage.ts +110 -0
@@ -0,0 +1,191 @@
1
+ /**
2
+ * Which way a frame travelled, from the page's point of view: `out` left the
3
+ * page (a request, a sent message), `in` reached it. Markers and lifecycle
4
+ * events travel nowhere.
5
+ */
6
+ export type Direction = "out" | "in" | "none";
7
+
8
+ export type FrameKind =
9
+ /** The opening half of an exchange: an HTTP request, an RPC's request message. */
10
+ | "request"
11
+ /** The closing half: an HTTP response, an RPC's status. */
12
+ | "response"
13
+ /** One message on a stream or channel. */
14
+ | "message"
15
+ /** One server-sent event. */
16
+ | "event"
17
+ /** A named point the test placed on the timeline. */
18
+ | "marker"
19
+ /** Something went wrong on purpose or by accident: an abort, a drop, a cut. */
20
+ | "fault"
21
+ /** A channel or connection opened or closed. */
22
+ | "lifecycle";
23
+
24
+ /**
25
+ * Who produced what the frame carries. With `direction` it says who was
26
+ * talking to whom: `out` from `page` is the app speaking, `in` from `stub`
27
+ * is a stub answering it, `in` from `network` the real backend.
28
+ */
29
+ export type FrameSource =
30
+ /** The app in the browser: its requests, the messages it sends. */
31
+ | "page"
32
+ /** The real backend, a real remote peer, or a client outside the browser. */
33
+ | "network"
34
+ /** A stub: its responses, its messages, the faults it injects. */
35
+ | "stub"
36
+ /** The test itself: markers, drive-client requests, injected messages. */
37
+ | "test"
38
+ /** A fake served on a port of its own (`serve()`). */
39
+ | "server";
40
+
41
+ /**
42
+ * A payload as given: bytes, text, or a thunk that encodes on demand. The thunk
43
+ * keeps a high-rate stub from serializing every message twice when nobody ever
44
+ * reads the bytes back.
45
+ */
46
+ export type PayloadInput = Uint8Array | string | (() => Uint8Array);
47
+
48
+ export interface Payload {
49
+ /** True when the frame carries no payload at all. */
50
+ readonly empty: boolean;
51
+ bytes(): Uint8Array;
52
+ /** UTF-8 text of the bytes, or the text as given. */
53
+ text(): string;
54
+ /** `JSON.parse(text())`. Throws on invalid JSON. */
55
+ json<T = unknown>(): T;
56
+ /**
57
+ * Decode with `decoder`, cached per decoder: asserting on the same frame
58
+ * from three helpers decodes it once.
59
+ */
60
+ decode<T>(decoder: (bytes: Uint8Array) => T): T;
61
+ }
62
+
63
+ export interface FrameInit {
64
+ /** The protocol plugin's name: `webrtc`, `connect`, `rest`, ... */
65
+ readonly protocol: string;
66
+ readonly kind: FrameKind;
67
+ readonly direction: Direction;
68
+ /**
69
+ * What the frame is about, in the protocol's own terms: a URL path, an RPC
70
+ * (`pkg.Service/Method`), a channel label, a WebSocket URL, a marker name.
71
+ */
72
+ readonly endpoint: string;
73
+ readonly source: FrameSource;
74
+ /** Epoch milliseconds. Defaults to the stage clock's now. */
75
+ readonly at?: number;
76
+ readonly data?: PayloadInput;
77
+ /** An already-decoded form of the payload, e.g. a protobuf message. */
78
+ readonly value?: unknown;
79
+ readonly meta?: Readonly<Record<string, unknown>>;
80
+ /** The page the frame belongs to (`p1`, ...). */
81
+ readonly page?: string;
82
+ /** The browser context the frame belongs to (`c1`, ...). */
83
+ readonly context?: string;
84
+ /** Links the frames of one exchange: a request, its messages, its response. */
85
+ readonly correlation?: string;
86
+ }
87
+
88
+ export interface Frame {
89
+ /** Arrival order on the timeline, starting at 1. The order to trust. */
90
+ readonly seq: number;
91
+ /** Epoch milliseconds. Informational: page and Node clocks differ slightly. */
92
+ readonly at: number;
93
+ readonly protocol: string;
94
+ readonly kind: FrameKind;
95
+ readonly direction: Direction;
96
+ readonly endpoint: string;
97
+ readonly source: FrameSource;
98
+ readonly payload: Payload;
99
+ readonly value: unknown;
100
+ readonly meta: Readonly<Record<string, unknown>>;
101
+ readonly page: string | undefined;
102
+ readonly context: string | undefined;
103
+ readonly correlation: string | undefined;
104
+ }
105
+
106
+ export interface FrameFilter {
107
+ readonly protocol?: string | readonly string[];
108
+ readonly kind?: FrameKind | readonly FrameKind[];
109
+ readonly direction?: Direction;
110
+ /** Exact match, or a RegExp tested against the endpoint. */
111
+ readonly endpoint?: string | RegExp;
112
+ readonly source?: FrameSource;
113
+ readonly page?: string;
114
+ readonly context?: string;
115
+ readonly correlation?: string;
116
+ /** Only frames whose `seq` is greater. */
117
+ readonly after?: number;
118
+ /** Any further condition. Runs last, so cheap fields filter first. */
119
+ readonly where?: (frame: Frame) => boolean;
120
+ }
121
+
122
+ /** A consumer's position on the timeline: each `take` returns what is new. */
123
+ export interface TimelineCursor {
124
+ /**
125
+ * Frames appended since the previous `take` that match `filter`. The
126
+ * cursor moves past ALL of them, matching or not: "what happened since I
127
+ * last looked", narrowed.
128
+ */
129
+ take(filter?: FrameFilter): Frame[];
130
+ /** The `seq` the cursor has read up to. */
131
+ readonly position: number;
132
+ }
133
+
134
+ export interface SnapshotFrame {
135
+ readonly seq: number;
136
+ readonly at: number;
137
+ readonly protocol: string;
138
+ readonly kind: FrameKind;
139
+ readonly direction: Direction;
140
+ readonly endpoint: string;
141
+ readonly source: FrameSource;
142
+ readonly page?: string;
143
+ readonly context?: string;
144
+ readonly correlation?: string;
145
+ readonly meta?: Readonly<Record<string, unknown>>;
146
+ /** Base64 of the payload, cut at the snapshot's byte limit. */
147
+ readonly data?: string;
148
+ readonly size?: number;
149
+ readonly truncated?: boolean;
150
+ }
151
+
152
+ /** A JSON-safe copy of the timeline, for a test report attachment. */
153
+ export interface TimelineSnapshot {
154
+ readonly frames: readonly SnapshotFrame[];
155
+ /** Frames dropped from the front because the timeline hit its capacity. */
156
+ readonly evicted: number;
157
+ /** Earlier matching frames left out by the snapshot's `limit`. */
158
+ readonly omitted: number;
159
+ }
160
+
161
+ export interface SnapshotOptions {
162
+ /** Bytes of payload kept per frame. Default 4096. */
163
+ readonly maxBytes?: number;
164
+ /** Frames kept, counting back from the newest. Default: all of them. */
165
+ readonly limit?: number;
166
+ }
167
+
168
+ export interface Timeline {
169
+ /** Append a frame and notify subscribers. The only way frames enter. */
170
+ append(init: FrameInit): Frame;
171
+ frames(filter?: FrameFilter): Frame[];
172
+ last(filter?: FrameFilter): Frame | undefined;
173
+ /** The most recent marker with this name. */
174
+ marker(name: string): Frame | undefined;
175
+ /**
176
+ * Called for every appended frame, synchronously, after it is on the
177
+ * timeline. A listener that throws does not stop the others. Returns
178
+ * unsubscribe.
179
+ */
180
+ subscribe(listener: (frame: Frame) => void): () => void;
181
+ /** A new cursor starting at the current end. */
182
+ cursor(): TimelineCursor;
183
+ /** Drop every frame. `seq` keeps counting; `evicted` is left alone. */
184
+ clear(): void;
185
+ snapshot(filter?: FrameFilter, options?: SnapshotOptions): TimelineSnapshot;
186
+ /** A human-readable listing, one line per frame. */
187
+ format(filter?: FrameFilter, options?: { readonly limit?: number }): string;
188
+ readonly size: number;
189
+ readonly evicted: number;
190
+ readonly capacity: number;
191
+ }
@@ -0,0 +1,36 @@
1
+ export { definePlugin } from "./lib/define-plugin.js";
2
+ export { named } from "./lib/named.js";
3
+ export type { Attachment } from "./model/attachment.js";
4
+ export type {
5
+ AbortErrorCode,
6
+ HttpOutcome,
7
+ HttpRequestView,
8
+ HttpRouter,
9
+ HttpRule,
10
+ HttpRuleHandle,
11
+ PassthroughResponse,
12
+ } from "./model/http.js";
13
+ export type {
14
+ PageEntry,
15
+ PageHost,
16
+ PageInstaller,
17
+ PageModule,
18
+ PageModuleEnv,
19
+ PageSource,
20
+ } from "./model/page.js";
21
+ export type {
22
+ AnyWirePlugin,
23
+ PluginApis,
24
+ PluginContext,
25
+ PluginRuntime,
26
+ WaitForOptions,
27
+ WirePlugin,
28
+ } from "./model/plugin.js";
29
+ export type {
30
+ SocketPeer,
31
+ SocketRouter,
32
+ SocketRule,
33
+ SocketRuleHandle,
34
+ SocketView,
35
+ } from "./model/socket.js";
36
+ export type { ResponseStream, StreamEnd } from "./model/stream.js";
@@ -0,0 +1,12 @@
1
+ import type { WirePlugin } from "../model/plugin.js";
2
+
3
+ /**
4
+ * Identity, for inference: it keeps the plugin's `name` a literal type, so
5
+ * `createStage({ plugins: [myPlugin()] })` types `stage.myPlugin` without the
6
+ * author writing the generic arguments out.
7
+ */
8
+ export function definePlugin<const Name extends string, Api>(
9
+ plugin: WirePlugin<Name, Api>,
10
+ ): WirePlugin<Name, Api> {
11
+ return plugin;
12
+ }
@@ -0,0 +1,21 @@
1
+ import type { WirePlugin } from "../model/plugin.js";
2
+
3
+ /**
4
+ * The same plugin under another name: mounted as `stage.<name>`, and
5
+ * recording its frames under that name. What lets one protocol run twice —
6
+ * two backends, two sets of channels — with each instance's traffic apart:
7
+ *
8
+ * plugins: [rest({ baseURL: "/api" }), named("billing", rest({ baseURL: "https://billing.test" }))]
9
+ */
10
+ export function named<const Name extends string, Api>(
11
+ name: Name,
12
+ plugin: WirePlugin<string, Api>,
13
+ ): WirePlugin<Name, Api> {
14
+ return {
15
+ name,
16
+ scope: plugin.scope,
17
+ // Called on the plugin, not copied off it: a plugin written as a class
18
+ // has `setup` on its prototype, which a spread leaves behind.
19
+ setup: (context) => plugin.setup(context),
20
+ };
21
+ }
@@ -0,0 +1,18 @@
1
+ import type { CookieJarPort } from "../../../shared/api/playwright/index.js";
2
+
3
+ /**
4
+ * One browser context the stage is attached to, as a plugin sees it: a
5
+ * frozen view, not the context. The context stays with the stage, and a
6
+ * plugin reaches the browser through the services of its `PluginContext`.
7
+ */
8
+ export interface Attachment {
9
+ /** `c1`, `c2`, ... — what frames name in their `context` field. */
10
+ readonly id: string;
11
+ /** The context's base URL, when the caller supplied one. */
12
+ readonly baseURL: string | undefined;
13
+ /**
14
+ * The context's cookie jar, for a client that calls as the signed-in
15
+ * page: reads and adds go to the context, and nothing else does.
16
+ */
17
+ readonly cookies: CookieJarPort;
18
+ }
@@ -0,0 +1,156 @@
1
+ import type { UrlMatcher } from "../../../shared/lib/match/index.js";
2
+ import type { ResponseStream } from "./stream.js";
3
+
4
+ /**
5
+ * A request a rule is deciding about, read-only and decoded on demand.
6
+ *
7
+ * One per request: every rule the request reaches is given this same object,
8
+ * so a plugin may key what it knows about a request on it (a `WeakMap`), and
9
+ * the frames different rules record for one request share one `correlation`.
10
+ */
11
+ export interface HttpRequestView {
12
+ /** Links every frame of this exchange. */
13
+ readonly correlation: string;
14
+ readonly method: string;
15
+ readonly url: URL;
16
+ /** Lower-cased names. */
17
+ readonly headers: Readonly<Record<string, string>>;
18
+ /** The page that sent it; undefined for service-worker requests. */
19
+ readonly page: string | undefined;
20
+ readonly context: string;
21
+ readonly resourceType: string;
22
+ body(): Uint8Array;
23
+ text(): string;
24
+ json<T = unknown>(): T;
25
+ }
26
+
27
+ /** Playwright's `route.abort` error codes. */
28
+ export type AbortErrorCode =
29
+ | "aborted"
30
+ | "accessdenied"
31
+ | "addressunreachable"
32
+ | "blockedbyclient"
33
+ | "blockedbyresponse"
34
+ | "connectionaborted"
35
+ | "connectionclosed"
36
+ | "connectionfailed"
37
+ | "connectionrefused"
38
+ | "connectionreset"
39
+ | "internetdisconnected"
40
+ | "namenotresolved"
41
+ | "timedout"
42
+ | "failed";
43
+
44
+ /**
45
+ * What a rule decided. A closed union: the router carries each member out
46
+ * through a table keyed by `type`, so a new outcome does not compile until
47
+ * the router knows what to do with it.
48
+ */
49
+ export type HttpOutcome =
50
+ /**
51
+ * Answer with a complete response. A header may carry several values
52
+ * separated by a newline: `set-cookie` is sent as a header line each,
53
+ * any other header as one value, `, `-separated. A header Chromium
54
+ * would refuse — a name that is not a token, a CR or NUL in a value — is
55
+ * the rule's error.
56
+ */
57
+ | {
58
+ readonly type: "fulfill";
59
+ readonly status?: number;
60
+ readonly headers?: Readonly<Record<string, string>>;
61
+ readonly body?: Uint8Array | string;
62
+ }
63
+ /**
64
+ * Answer with a response that stays open (server streams, SSE): `open`
65
+ * gets the stream to write. The request is redirected to the stage's
66
+ * local stream server, which `route.fulfill` cannot stand in for because
67
+ * it takes the whole body at once. An `open` that throws is the rule's
68
+ * error, as a throwing `handle` is: the page gets the 500 while nothing
69
+ * has gone out, and a cut connection after.
70
+ */
71
+ | {
72
+ readonly type: "stream";
73
+ open(stream: ResponseStream): void | Promise<void>;
74
+ }
75
+ /**
76
+ * Send to the network, optionally rewritten. Lower rules are skipped.
77
+ * `url` may be relative to the request's, and keeps its scheme:
78
+ * Playwright rewrites a URL within its scheme only.
79
+ */
80
+ | {
81
+ readonly type: "continue";
82
+ readonly url?: string;
83
+ readonly method?: string;
84
+ readonly headers?: Readonly<Record<string, string>>;
85
+ readonly body?: Uint8Array | string;
86
+ }
87
+ /** Let the next matching rule (or the network) decide. */
88
+ | { readonly type: "fallback" }
89
+ /** Fail the request at the network level. */
90
+ | { readonly type: "abort"; readonly error?: AbortErrorCode };
91
+
92
+ /** The network's answer to a request a rule passed through. */
93
+ export interface PassthroughResponse {
94
+ readonly status: number;
95
+ readonly headers: Readonly<Record<string, string>>;
96
+ /** Undefined when the browser did not keep the body (redirects, some errors). */
97
+ readonly body: Uint8Array | undefined;
98
+ }
99
+
100
+ export interface HttpRule {
101
+ /** The `protocol` of the frames this rule records. */
102
+ readonly protocol: string;
103
+ /** Names the rule in logs and diagnostics. */
104
+ readonly label: string;
105
+ readonly url: UrlMatcher;
106
+ /** Upper-case HTTP methods. Any method when omitted. */
107
+ readonly method?: string | readonly string[];
108
+ /** Stop matching after this many handled requests. */
109
+ readonly times?: number;
110
+ /** A last, request-aware condition; false falls back to the next rule. */
111
+ readonly match?: (request: HttpRequestView) => boolean;
112
+ /**
113
+ * Record the raw request and how it ended as frames. Default true. A plugin
114
+ * that records decoded frames of its own (Connect) turns this off. A
115
+ * request several recording rules of one protocol see is recorded once.
116
+ */
117
+ readonly record?: boolean;
118
+ /** The frame endpoint for a request. Defaults to the URL path. */
119
+ readonly endpoint?: (request: HttpRequestView) => string;
120
+ handle(request: HttpRequestView): HttpOutcome | Promise<HttpOutcome>;
121
+ /**
122
+ * Called with the network's response to a request this rule passed on
123
+ * (`continue` or `fallback`). Not called when another rule answered it:
124
+ * that response is a stub's, not the network's.
125
+ */
126
+ readonly onPassthroughResponse?: (
127
+ response: PassthroughResponse,
128
+ request: HttpRequestView,
129
+ ) => void;
130
+ /**
131
+ * Called when a request this rule passed on failed at the network level,
132
+ * with the browser's error text (`net::ERR_CONNECTION_RESET`, ...).
133
+ */
134
+ readonly onPassthroughFailure?: (
135
+ error: string | undefined,
136
+ request: HttpRequestView,
137
+ ) => void;
138
+ }
139
+
140
+ export interface HttpRuleHandle {
141
+ /** Requests this rule handled (matched and decided), not merely saw. */
142
+ readonly hits: number;
143
+ readonly active: boolean;
144
+ /** Stop matching, in every attached context. */
145
+ remove(): Promise<void>;
146
+ }
147
+
148
+ /**
149
+ * Where plugins put HTTP rules. Rules apply to every attached context, present
150
+ * and future. Later rules win, like Playwright routes and MSW's `use()`, so a
151
+ * test can override a suite-wide stub for one case; a rule that answers
152
+ * `fallback` hands the request to the next one down.
153
+ */
154
+ export interface HttpRouter {
155
+ add(rule: HttpRule): Promise<HttpRuleHandle>;
156
+ }
@@ -0,0 +1,110 @@
1
+ import type { PagePort } from "../../../shared/api/playwright/index.js";
2
+
3
+ /** One thing an in-page module observed, on its way to the timeline. */
4
+ export interface PageEntry {
5
+ /** The module's own discriminator: `out`, `in`, `open`, ... */
6
+ readonly type: string;
7
+ /** Epoch milliseconds, by the page's clock. */
8
+ readonly at: number;
9
+ /** A binary payload, base64. */
10
+ readonly data?: string;
11
+ /** A text payload. */
12
+ readonly text?: string;
13
+ readonly meta?: Readonly<Record<string, unknown>>;
14
+ }
15
+
16
+ /** What the page runtime hands an installer, inside the page. */
17
+ export interface PageModuleEnv<State = unknown, Config = unknown> {
18
+ readonly window: Window & typeof globalThis;
19
+ readonly config: Config;
20
+ /**
21
+ * Queue an entry. Entries are batched and flushed to Node: a document
22
+ * that navigates sends what it holds on `beforeunload`, one that closes
23
+ * (or an iframe removed) on `pagehide`. What it emits after that, on its
24
+ * way out, can be lost.
25
+ */
26
+ emit(entry: PageEntry): void;
27
+ /** The page's epoch-millisecond clock. */
28
+ now(): number;
29
+ /** Bytes to base64. */
30
+ encode(bytes: Uint8Array): string;
31
+ /** Base64 to bytes, in a fresh ArrayBuffer of exactly that size. */
32
+ decode(text: string): Uint8Array;
33
+ /** Answer a command the test sends with `PageHost.command`. */
34
+ onCommand(op: string, handler: (args: never) => unknown): void;
35
+ /**
36
+ * Receive the module's state: shortly after load (it comes from Node, so
37
+ * the document's first script may run before it), and on every change.
38
+ * One that throws does not keep the state from the others: it is logged
39
+ * in Node, or fails the `refresh()` that sent the state.
40
+ */
41
+ onState(handler: (state: State) => void): void;
42
+ /**
43
+ * Undo what `install` did to the page: put back what was wrapped. Runs
44
+ * when the stage detaches, so a document that outlives the stage is left
45
+ * as the stage found it — and in a document the detach did not reach, as
46
+ * soon as the runtime finds the binding gone. One that throws does not
47
+ * stop the others, and is logged in Node while the binding lasts.
48
+ */
49
+ onDetach(handler: () => void): void;
50
+ }
51
+
52
+ /**
53
+ * Runs INSIDE the page, so it is serialized with `Function.prototype.toString`.
54
+ * It must be self-contained — no imports, no closure over module scope — and
55
+ * declared with `function`, since an object-method body does not serialize to
56
+ * a valid expression. `register` refuses one whose source is not a function
57
+ * expression: a method, a bound or a native function.
58
+ */
59
+ export type PageInstaller<State = unknown, Config = unknown> = (
60
+ env: PageModuleEnv<State, Config>,
61
+ ) => void;
62
+
63
+ export interface PageSource {
64
+ readonly page: string;
65
+ readonly context: string;
66
+ }
67
+
68
+ export interface PageModule<State = unknown, Config = unknown> {
69
+ /** Unique per stage; the key commands and entries are routed by. */
70
+ readonly id: string;
71
+ readonly install: PageInstaller<State, Config>;
72
+ /** JSON-serializable; fixed for the life of the attachment. */
73
+ readonly config: Config;
74
+ /** The state a freshly loaded page should start with. JSON-serializable. */
75
+ state(): State;
76
+ /** Entries flushed from a page, in emission order. */
77
+ receive(entries: readonly PageEntry[], source: PageSource): void;
78
+ }
79
+
80
+ /**
81
+ * Where plugins put code that runs in every page. Modules register at setup;
82
+ * the host injects them all as one init script per attached context, with one
83
+ * binding back to Node.
84
+ */
85
+ export interface PageHost {
86
+ /**
87
+ * Add a module to the init script. Throws `INVALID_ARGUMENT` for an id
88
+ * already taken or an installer that does not serialize to a function
89
+ * expression, and `INVALID_STATE` once the stage has been attached.
90
+ */
91
+ register<State, Config>(module: PageModule<State, Config>): void;
92
+ /**
93
+ * Run a module's command handler in every frame of every open page (or of
94
+ * one page, by id) and return each frame's answer. Frames that are going
95
+ * away are skipped; a handler that throws rejects the call.
96
+ */
97
+ command(
98
+ module: string,
99
+ op: string,
100
+ args?: unknown,
101
+ options?: { readonly page?: string },
102
+ ): Promise<unknown[]>;
103
+ /**
104
+ * Send the module's current `state()` to every frame of every open page.
105
+ * Documents loaded later ask for it when their runtime starts.
106
+ */
107
+ refresh(module: string): Promise<void>;
108
+ /** The id frames use for `page`. */
109
+ pageId(page: PagePort): string;
110
+ }
@@ -0,0 +1,96 @@
1
+ import type { Clock } from "../../../shared/lib/clock/index.js";
2
+ import type {
3
+ LogScope,
4
+ ScopedLogger,
5
+ } from "../../../shared/lib/logger/index.js";
6
+ import type { Frame, FrameFilter, Timeline } from "../../frame/@x/plugin.js";
7
+ import type { Attachment } from "./attachment.js";
8
+ import type { HttpRouter } from "./http.js";
9
+ import type { PageHost } from "./page.js";
10
+ import type { SocketRouter } from "./socket.js";
11
+
12
+ export interface WaitForOptions {
13
+ /** Frames to wait for. Default 1. */
14
+ readonly count?: number;
15
+ /** Milliseconds. Default 5000. */
16
+ readonly timeout?: number;
17
+ /** Milliseconds between polls of the page buffers. Default 25. */
18
+ readonly interval?: number;
19
+ }
20
+
21
+ /**
22
+ * Everything a plugin may use. A plugin never drives the browser itself:
23
+ * routing and page hooks go through these services, built and owned by the
24
+ * stage, and that is the seam that lets each plugin be unit-tested against
25
+ * fakes and lets several plugins share one browser context without stepping
26
+ * on each other.
27
+ */
28
+ export interface PluginContext {
29
+ /**
30
+ * The name the plugin is set up under: its own, or the one `named()` gave
31
+ * it. A plugin records its frames with this as their `protocol` (and
32
+ * names its page modules by it), so two instances keep their traffic
33
+ * apart.
34
+ */
35
+ readonly name: string;
36
+ readonly timeline: Timeline;
37
+ readonly clock: Clock;
38
+ /** Scoped to the plugin's declared scope. */
39
+ readonly log: ScopedLogger;
40
+ /** HTTP: fetch, XHR, EventSource, and anything else a route can see. */
41
+ readonly http: HttpRouter;
42
+ /** WebSockets. */
43
+ readonly sockets: SocketRouter;
44
+ /** Code that runs inside every page, for what no route can see. */
45
+ readonly pages: PageHost;
46
+ readonly baseURL: string | undefined;
47
+ attachments(): readonly Attachment[];
48
+ /** Flush every page buffer into the timeline. Call before reading frames. */
49
+ sync(): Promise<void>;
50
+ waitFor(filter: FrameFilter, options?: WaitForOptions): Promise<Frame[]>;
51
+ /**
52
+ * Build on another plugin: set it up inside this one and get its API. A
53
+ * protocol layered on others (GraphQL over HTTP and WebSocket, say) is
54
+ * written in terms of theirs instead of re-deriving them. The stage runs
55
+ * the inner plugin's hooks with the outer's; it is not mounted on the
56
+ * stage. Wrap it in `named()` to keep its frames apart from another
57
+ * instance's.
58
+ */
59
+ use<Api>(plugin: WirePlugin<string, Api>): Api;
60
+ }
61
+
62
+ export interface PluginRuntime<Api> {
63
+ /** Mounted on the stage under the plugin's name. */
64
+ readonly api: Api;
65
+ /** A context was attached. Page modules and HTTP rules are already in place. */
66
+ attach?(attachment: Attachment): void | Promise<void>;
67
+ /** A context is being detached. */
68
+ detach?(attachment: Attachment): void | Promise<void>;
69
+ /** The stage is being disposed; release servers and timers. */
70
+ dispose?(): void | Promise<void>;
71
+ }
72
+
73
+ /**
74
+ * A protocol, as the stage sees it. The stage knows nothing about any
75
+ * protocol in particular: REST, Connect, WebRTC and the rest are all plugins,
76
+ * and a new protocol is a new plugin, not a change to the stage.
77
+ */
78
+ export interface WirePlugin<Name extends string = string, Api = unknown> {
79
+ /** The key its API is mounted under: `stage.<name>`. */
80
+ readonly name: Name;
81
+ /** The badge on the plugin's log lines; eight characters fit the column. */
82
+ readonly scope?: LogScope;
83
+ setup(context: PluginContext): PluginRuntime<Api>;
84
+ }
85
+
86
+ export type AnyWirePlugin = WirePlugin<string, unknown>;
87
+
88
+ /** `{ webrtc: WebRtcApi, connect: ConnectApi }` from `[webrtc(), connect()]`. */
89
+ export type PluginApis<Plugins extends readonly AnyWirePlugin[]> = {
90
+ readonly [Plugin in Plugins[number] as Plugin["name"]]: Plugin extends WirePlugin<
91
+ string,
92
+ infer Api
93
+ >
94
+ ? Api
95
+ : never;
96
+ };