@heojeongbo/wirestage 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (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 +126 -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 +102 -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 +43 -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 +120 -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 +62 -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 +107 -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 +129 -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 +117 -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 +43 -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 +160 -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 +248 -0
  363. package/dist/widgets/stage/lib/create-stage.js.map +1 -0
  364. package/dist/widgets/stage/lib/http-router.d.ts +35 -0
  365. package/dist/widgets/stage/lib/http-router.d.ts.map +1 -0
  366. package/dist/widgets/stage/lib/http-router.js +455 -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 +9 -0
  381. package/dist/widgets/stage/lib/response-stream.d.ts.map +1 -0
  382. package/dist/widgets/stage/lib/response-stream.js +56 -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 +204 -0
  387. package/dist/widgets/stage/lib/socket-router.js.map +1 -0
  388. package/dist/widgets/stage/model/stage.d.ts +86 -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 +147 -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 +108 -0
  411. package/src/entities/plugin/model/stream.ts +43 -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 +128 -0
  434. package/src/features/sse/lib/encode.ts +28 -0
  435. package/src/features/sse/model/types.ts +66 -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 +141 -0
  445. package/src/features/websocket/lib/wire.ts +78 -0
  446. package/src/features/websocket/model/types.ts +130 -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 +145 -0
  454. package/src/shared/api/stream-server/index.ts +7 -0
  455. package/src/shared/api/stream-server/stream-server.ts +246 -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 +305 -0
  483. package/src/widgets/stage/lib/http-router.ts +620 -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 +66 -0
  488. package/src/widgets/stage/lib/socket-router.ts +271 -0
  489. package/src/widgets/stage/model/stage.ts +108 -0
@@ -0,0 +1,147 @@
1
+ import type { Clock } from "../../../shared/lib/clock/index.js";
2
+ import { WirestageError } from "../../../shared/lib/errors/index.js";
3
+ import type {
4
+ Frame,
5
+ FrameFilter,
6
+ FrameInit,
7
+ Timeline,
8
+ TimelineCursor,
9
+ } from "../model/frame.js";
10
+ import { compileFilter } from "./filter.js";
11
+ import { createPayload } from "./payload.js";
12
+ import { formatFrames, snapshotFrames } from "./snapshot.js";
13
+
14
+ export interface TimelineOptions {
15
+ readonly clock: Clock;
16
+ /**
17
+ * Frames kept before the oldest are dropped. A 60 Hz data channel makes
18
+ * 3,600 frames a minute; the default holds a long test without letting a
19
+ * soak run grow without bound.
20
+ */
21
+ readonly capacity?: number;
22
+ /**
23
+ * Told when a subscriber throws. By default the first such error is
24
+ * thrown to whoever appended the frame, once every subscriber has run.
25
+ */
26
+ readonly onListenerError?: (error: unknown) => void;
27
+ }
28
+
29
+ const DEFAULT_CAPACITY = 100_000;
30
+
31
+ /**
32
+ * The append-only log every protocol writes to. Order is arrival order (`seq`),
33
+ * not timestamp order: the stage flushes page buffers before every read, so
34
+ * arrival order is also the order things happened in.
35
+ */
36
+ export function createTimeline(options: TimelineOptions): Timeline {
37
+ const capacity = options.capacity ?? DEFAULT_CAPACITY;
38
+ if (!Number.isInteger(capacity) || capacity < 1)
39
+ throw new WirestageError(
40
+ "INVALID_ARGUMENT",
41
+ `timeline capacity must be a positive integer, got ${capacity}`,
42
+ );
43
+ let frames: Frame[] = [];
44
+ let evicted = 0;
45
+ let seq = 0;
46
+ const listeners = new Set<(frame: Frame) => void>();
47
+
48
+ const query = (filter: FrameFilter | undefined): Frame[] => {
49
+ if (filter === undefined) return frames.slice();
50
+ return frames.filter(compileFilter(filter));
51
+ };
52
+
53
+ /** Index of the first frame with `seq` greater than `position`. */
54
+ const indexAfter = (position: number): number => {
55
+ const first = frames[0];
56
+ if (first === undefined) return 0;
57
+ return Math.max(0, position - first.seq + 1);
58
+ };
59
+
60
+ return {
61
+ append(init: FrameInit): Frame {
62
+ const frame: Frame = {
63
+ seq: ++seq,
64
+ at: init.at ?? options.clock.now(),
65
+ protocol: init.protocol,
66
+ kind: init.kind,
67
+ direction: init.direction,
68
+ endpoint: init.endpoint,
69
+ source: init.source,
70
+ payload: createPayload(init.data),
71
+ value: init.value,
72
+ meta: init.meta ?? {},
73
+ page: init.page,
74
+ context: init.context,
75
+ correlation: init.correlation,
76
+ };
77
+ frames.push(frame);
78
+ if (frames.length > capacity) {
79
+ // Drop a tenth at once: shifting one frame per append would make a
80
+ // full timeline O(n) per frame.
81
+ const drop = Math.max(1, Math.floor(capacity / 10));
82
+ frames = frames.slice(drop);
83
+ evicted += drop;
84
+ }
85
+ // The frame is on the timeline whatever a subscriber does with it,
86
+ // and one that throws does not starve the rest.
87
+ const failures: unknown[] = [];
88
+ for (const listener of listeners) {
89
+ try {
90
+ listener(frame);
91
+ } catch (error) {
92
+ failures.push(error);
93
+ }
94
+ }
95
+ if (failures.length > 0) {
96
+ if (options.onListenerError === undefined) throw failures[0];
97
+ for (const failure of failures) options.onListenerError(failure);
98
+ }
99
+ return frame;
100
+ },
101
+ frames: query,
102
+ last(filter) {
103
+ const match = compileFilter(filter);
104
+ return frames.findLast(match);
105
+ },
106
+ marker(name) {
107
+ return frames.findLast((f) => f.kind === "marker" && f.endpoint === name);
108
+ },
109
+ subscribe(listener) {
110
+ listeners.add(listener);
111
+ return () => {
112
+ listeners.delete(listener);
113
+ };
114
+ },
115
+ cursor(): TimelineCursor {
116
+ let position = seq;
117
+ return {
118
+ take(filter) {
119
+ const fresh = frames.slice(indexAfter(position));
120
+ position = seq;
121
+ return filter === undefined
122
+ ? fresh
123
+ : fresh.filter(compileFilter(filter));
124
+ },
125
+ get position() {
126
+ return position;
127
+ },
128
+ };
129
+ },
130
+ clear() {
131
+ frames = [];
132
+ },
133
+ snapshot(filter, snapshotOptions) {
134
+ return snapshotFrames(query(filter), evicted, snapshotOptions);
135
+ },
136
+ format(filter, formatOptions) {
137
+ return formatFrames(query(filter), formatOptions);
138
+ },
139
+ get size() {
140
+ return frames.length;
141
+ },
142
+ get evicted() {
143
+ return evicted;
144
+ },
145
+ capacity,
146
+ };
147
+ }
@@ -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,147 @@
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`).
53
+ */
54
+ | {
55
+ readonly type: "fulfill";
56
+ readonly status?: number;
57
+ readonly headers?: Readonly<Record<string, string>>;
58
+ readonly body?: Uint8Array | string;
59
+ }
60
+ /**
61
+ * Answer with a response that stays open (server streams, SSE): `open`
62
+ * gets the stream to write. The request is redirected to the stage's
63
+ * local stream server, which `route.fulfill` cannot stand in for because
64
+ * it takes the whole body at once.
65
+ */
66
+ | {
67
+ readonly type: "stream";
68
+ open(stream: ResponseStream): void | Promise<void>;
69
+ }
70
+ /** Send to the network, optionally rewritten. Lower rules are skipped. */
71
+ | {
72
+ readonly type: "continue";
73
+ readonly url?: string;
74
+ readonly method?: string;
75
+ readonly headers?: Readonly<Record<string, string>>;
76
+ readonly body?: Uint8Array | string;
77
+ }
78
+ /** Let the next matching rule (or the network) decide. */
79
+ | { readonly type: "fallback" }
80
+ /** Fail the request at the network level. */
81
+ | { readonly type: "abort"; readonly error?: AbortErrorCode };
82
+
83
+ /** The network's answer to a request a rule passed through. */
84
+ export interface PassthroughResponse {
85
+ readonly status: number;
86
+ readonly headers: Readonly<Record<string, string>>;
87
+ /** Undefined when the browser did not keep the body (redirects, some errors). */
88
+ readonly body: Uint8Array | undefined;
89
+ }
90
+
91
+ export interface HttpRule {
92
+ /** The `protocol` of the frames this rule records. */
93
+ readonly protocol: string;
94
+ /** Names the rule in logs and diagnostics. */
95
+ readonly label: string;
96
+ readonly url: UrlMatcher;
97
+ /** Upper-case HTTP methods. Any method when omitted. */
98
+ readonly method?: string | readonly string[];
99
+ /** Stop matching after this many handled requests. */
100
+ readonly times?: number;
101
+ /** A last, request-aware condition; false falls back to the next rule. */
102
+ readonly match?: (request: HttpRequestView) => boolean;
103
+ /**
104
+ * Record the raw request and how it ended as frames. Default true. A plugin
105
+ * that records decoded frames of its own (Connect) turns this off. A
106
+ * request several recording rules of one protocol see is recorded once.
107
+ */
108
+ readonly record?: boolean;
109
+ /** The frame endpoint for a request. Defaults to the URL path. */
110
+ readonly endpoint?: (request: HttpRequestView) => string;
111
+ handle(request: HttpRequestView): HttpOutcome | Promise<HttpOutcome>;
112
+ /**
113
+ * Called with the network's response to a request this rule passed on
114
+ * (`continue` or `fallback`). Not called when another rule answered it:
115
+ * that response is a stub's, not the network's.
116
+ */
117
+ readonly onPassthroughResponse?: (
118
+ response: PassthroughResponse,
119
+ request: HttpRequestView,
120
+ ) => void;
121
+ /**
122
+ * Called when a request this rule passed on failed at the network level,
123
+ * with the browser's error text (`net::ERR_CONNECTION_RESET`, ...).
124
+ */
125
+ readonly onPassthroughFailure?: (
126
+ error: string | undefined,
127
+ request: HttpRequestView,
128
+ ) => void;
129
+ }
130
+
131
+ export interface HttpRuleHandle {
132
+ /** Requests this rule handled (matched and decided), not merely saw. */
133
+ readonly hits: number;
134
+ readonly active: boolean;
135
+ /** Stop matching, in every attached context. */
136
+ remove(): Promise<void>;
137
+ }
138
+
139
+ /**
140
+ * Where plugins put HTTP rules. Rules apply to every attached context, present
141
+ * and future. Later rules win, like Playwright routes and MSW's `use()`, so a
142
+ * test can override a suite-wide stub for one case; a rule that answers
143
+ * `fallback` hands the request to the next one down.
144
+ */
145
+ export interface HttpRouter {
146
+ add(rule: HttpRule): Promise<HttpRuleHandle>;
147
+ }
@@ -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
+ }