@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.
- package/LICENSE +21 -0
- package/LICENSES.md +21 -0
- package/README.md +150 -2
- package/dist/app/playwright/index.d.ts +3 -0
- package/dist/app/playwright/index.d.ts.map +1 -0
- package/dist/app/playwright/index.js +2 -0
- package/dist/app/playwright/index.js.map +1 -0
- package/dist/app/playwright/lib/fixture.d.ts +61 -0
- package/dist/app/playwright/lib/fixture.d.ts.map +1 -0
- package/dist/app/playwright/lib/fixture.js +110 -0
- package/dist/app/playwright/lib/fixture.js.map +1 -0
- package/dist/connect.d.ts +7 -0
- package/dist/connect.d.ts.map +1 -0
- package/dist/connect.js +7 -0
- package/dist/connect.js.map +1 -0
- package/dist/entities/frame/@x/plugin.d.ts +9 -0
- package/dist/entities/frame/@x/plugin.d.ts.map +1 -0
- package/dist/entities/frame/@x/plugin.js +2 -0
- package/dist/entities/frame/@x/plugin.js.map +1 -0
- package/dist/entities/frame/index.d.ts +6 -0
- package/dist/entities/frame/index.d.ts.map +1 -0
- package/dist/entities/frame/index.js +4 -0
- package/dist/entities/frame/index.js.map +1 -0
- package/dist/entities/frame/lib/filter.d.ts +8 -0
- package/dist/entities/frame/lib/filter.d.ts.map +1 -0
- package/dist/entities/frame/lib/filter.js +62 -0
- package/dist/entities/frame/lib/filter.js.map +1 -0
- package/dist/entities/frame/lib/payload.d.ts +8 -0
- package/dist/entities/frame/lib/payload.d.ts.map +1 -0
- package/dist/entities/frame/lib/payload.js +42 -0
- package/dist/entities/frame/lib/payload.js.map +1 -0
- package/dist/entities/frame/lib/snapshot.d.ts +15 -0
- package/dist/entities/frame/lib/snapshot.d.ts.map +1 -0
- package/dist/entities/frame/lib/snapshot.js +90 -0
- package/dist/entities/frame/lib/snapshot.js.map +1 -0
- package/dist/entities/frame/lib/timeline.d.ts +23 -0
- package/dist/entities/frame/lib/timeline.d.ts.map +1 -0
- package/dist/entities/frame/lib/timeline.js +122 -0
- package/dist/entities/frame/lib/timeline.js.map +1 -0
- package/dist/entities/frame/model/frame.d.ts +182 -0
- package/dist/entities/frame/model/frame.d.ts.map +1 -0
- package/dist/entities/frame/model/frame.js +2 -0
- package/dist/entities/frame/model/frame.js.map +1 -0
- package/dist/entities/plugin/index.d.ts +9 -0
- package/dist/entities/plugin/index.d.ts.map +1 -0
- package/dist/entities/plugin/index.js +3 -0
- package/dist/entities/plugin/index.js.map +1 -0
- package/dist/entities/plugin/lib/define-plugin.d.ts +8 -0
- package/dist/entities/plugin/lib/define-plugin.d.ts.map +1 -0
- package/dist/entities/plugin/lib/define-plugin.js +9 -0
- package/dist/entities/plugin/lib/define-plugin.js.map +1 -0
- package/dist/entities/plugin/lib/named.d.ts +10 -0
- package/dist/entities/plugin/lib/named.d.ts.map +1 -0
- package/dist/entities/plugin/lib/named.js +17 -0
- package/dist/entities/plugin/lib/named.js.map +1 -0
- package/dist/entities/plugin/model/attachment.d.ts +18 -0
- package/dist/entities/plugin/model/attachment.d.ts.map +1 -0
- package/dist/entities/plugin/model/attachment.js +2 -0
- package/dist/entities/plugin/model/attachment.js.map +1 -0
- package/dist/entities/plugin/model/http.d.ts +135 -0
- package/dist/entities/plugin/model/http.d.ts.map +1 -0
- package/dist/entities/plugin/model/http.js +2 -0
- package/dist/entities/plugin/model/http.js.map +1 -0
- package/dist/entities/plugin/model/page.d.ts +100 -0
- package/dist/entities/plugin/model/page.d.ts.map +1 -0
- package/dist/entities/plugin/model/page.js +2 -0
- package/dist/entities/plugin/model/page.js.map +1 -0
- package/dist/entities/plugin/model/plugin.d.ts +83 -0
- package/dist/entities/plugin/model/plugin.d.ts.map +1 -0
- package/dist/entities/plugin/model/plugin.js +2 -0
- package/dist/entities/plugin/model/plugin.js.map +1 -0
- package/dist/entities/plugin/model/socket.d.ts +107 -0
- package/dist/entities/plugin/model/socket.d.ts.map +1 -0
- package/dist/entities/plugin/model/socket.js +2 -0
- package/dist/entities/plugin/model/socket.js.map +1 -0
- package/dist/entities/plugin/model/stream.d.ts +46 -0
- package/dist/entities/plugin/model/stream.d.ts.map +1 -0
- package/dist/entities/plugin/model/stream.js +2 -0
- package/dist/entities/plugin/model/stream.js.map +1 -0
- package/dist/features/connect/index.d.ts +5 -0
- package/dist/features/connect/index.d.ts.map +1 -0
- package/dist/features/connect/index.js +4 -0
- package/dist/features/connect/index.js.map +1 -0
- package/dist/features/connect/lib/calls.d.ts +9 -0
- package/dist/features/connect/lib/calls.d.ts.map +1 -0
- package/dist/features/connect/lib/calls.js +46 -0
- package/dist/features/connect/lib/calls.js.map +1 -0
- package/dist/features/connect/lib/client.d.ts +33 -0
- package/dist/features/connect/lib/client.d.ts.map +1 -0
- package/dist/features/connect/lib/client.js +147 -0
- package/dist/features/connect/lib/client.js.map +1 -0
- package/dist/features/connect/lib/create-connect.d.ts +14 -0
- package/dist/features/connect/lib/create-connect.d.ts.map +1 -0
- package/dist/features/connect/lib/create-connect.js +124 -0
- package/dist/features/connect/lib/create-connect.js.map +1 -0
- package/dist/features/connect/lib/faults.d.ts +18 -0
- package/dist/features/connect/lib/faults.d.ts.map +1 -0
- package/dist/features/connect/lib/faults.js +85 -0
- package/dist/features/connect/lib/faults.js.map +1 -0
- package/dist/features/connect/lib/protocol.d.ts +42 -0
- package/dist/features/connect/lib/protocol.d.ts.map +1 -0
- package/dist/features/connect/lib/protocol.js +228 -0
- package/dist/features/connect/lib/protocol.js.map +1 -0
- package/dist/features/connect/lib/record.d.ts +14 -0
- package/dist/features/connect/lib/record.d.ts.map +1 -0
- package/dist/features/connect/lib/record.js +36 -0
- package/dist/features/connect/lib/record.js.map +1 -0
- package/dist/features/connect/lib/recorder.d.ts +77 -0
- package/dist/features/connect/lib/recorder.d.ts.map +1 -0
- package/dist/features/connect/lib/recorder.js +209 -0
- package/dist/features/connect/lib/recorder.js.map +1 -0
- package/dist/features/connect/lib/rules.d.ts +51 -0
- package/dist/features/connect/lib/rules.d.ts.map +1 -0
- package/dist/features/connect/lib/rules.js +222 -0
- package/dist/features/connect/lib/rules.js.map +1 -0
- package/dist/features/connect/lib/serve.d.ts +10 -0
- package/dist/features/connect/lib/serve.d.ts.map +1 -0
- package/dist/features/connect/lib/serve.js +78 -0
- package/dist/features/connect/lib/serve.js.map +1 -0
- package/dist/features/connect/lib/status-of.d.ts +11 -0
- package/dist/features/connect/lib/status-of.d.ts.map +1 -0
- package/dist/features/connect/lib/status-of.js +22 -0
- package/dist/features/connect/lib/status-of.js.map +1 -0
- package/dist/features/connect/lib/stubs.d.ts +18 -0
- package/dist/features/connect/lib/stubs.d.ts.map +1 -0
- package/dist/features/connect/lib/stubs.js +174 -0
- package/dist/features/connect/lib/stubs.js.map +1 -0
- package/dist/features/connect/lib/universal.d.ts +19 -0
- package/dist/features/connect/lib/universal.d.ts.map +1 -0
- package/dist/features/connect/lib/universal.js +71 -0
- package/dist/features/connect/lib/universal.js.map +1 -0
- package/dist/features/connect/model/types.d.ts +247 -0
- package/dist/features/connect/model/types.d.ts.map +1 -0
- package/dist/features/connect/model/types.js +2 -0
- package/dist/features/connect/model/types.js.map +1 -0
- package/dist/features/rest/index.d.ts +5 -0
- package/dist/features/rest/index.d.ts.map +1 -0
- package/dist/features/rest/index.js +3 -0
- package/dist/features/rest/index.js.map +1 -0
- package/dist/features/rest/lib/calls.d.ts +8 -0
- package/dist/features/rest/lib/calls.d.ts.map +1 -0
- package/dist/features/rest/lib/calls.js +32 -0
- package/dist/features/rest/lib/calls.js.map +1 -0
- package/dist/features/rest/lib/create-rest.d.ts +8 -0
- package/dist/features/rest/lib/create-rest.d.ts.map +1 -0
- package/dist/features/rest/lib/create-rest.js +136 -0
- package/dist/features/rest/lib/create-rest.js.map +1 -0
- package/dist/features/rest/lib/path.d.ts +14 -0
- package/dist/features/rest/lib/path.d.ts.map +1 -0
- package/dist/features/rest/lib/path.js +58 -0
- package/dist/features/rest/lib/path.js.map +1 -0
- package/dist/features/rest/lib/reply.d.ts +25 -0
- package/dist/features/rest/lib/reply.d.ts.map +1 -0
- package/dist/features/rest/lib/reply.js +40 -0
- package/dist/features/rest/lib/reply.js.map +1 -0
- package/dist/features/rest/model/types.d.ts +74 -0
- package/dist/features/rest/model/types.d.ts.map +1 -0
- package/dist/features/rest/model/types.js +2 -0
- package/dist/features/rest/model/types.js.map +1 -0
- package/dist/features/sse/index.d.ts +4 -0
- package/dist/features/sse/index.d.ts.map +1 -0
- package/dist/features/sse/index.js +3 -0
- package/dist/features/sse/index.js.map +1 -0
- package/dist/features/sse/lib/create-sse.d.ts +9 -0
- package/dist/features/sse/lib/create-sse.d.ts.map +1 -0
- package/dist/features/sse/lib/create-sse.js +121 -0
- package/dist/features/sse/lib/create-sse.js.map +1 -0
- package/dist/features/sse/lib/encode.d.ts +8 -0
- package/dist/features/sse/lib/encode.d.ts.map +1 -0
- package/dist/features/sse/lib/encode.js +29 -0
- package/dist/features/sse/lib/encode.js.map +1 -0
- package/dist/features/sse/model/types.d.ts +68 -0
- package/dist/features/sse/model/types.d.ts.map +1 -0
- package/dist/features/sse/model/types.js +2 -0
- package/dist/features/sse/model/types.js.map +1 -0
- package/dist/features/webrtc/index.d.ts +3 -0
- package/dist/features/webrtc/index.d.ts.map +1 -0
- package/dist/features/webrtc/index.js +2 -0
- package/dist/features/webrtc/index.js.map +1 -0
- package/dist/features/webrtc/lib/create-webrtc.d.ts +9 -0
- package/dist/features/webrtc/lib/create-webrtc.d.ts.map +1 -0
- package/dist/features/webrtc/lib/create-webrtc.js +123 -0
- package/dist/features/webrtc/lib/create-webrtc.js.map +1 -0
- package/dist/features/webrtc/lib/rtc-page-module.d.ts +22 -0
- package/dist/features/webrtc/lib/rtc-page-module.d.ts.map +1 -0
- package/dist/features/webrtc/lib/rtc-page-module.js +161 -0
- package/dist/features/webrtc/lib/rtc-page-module.js.map +1 -0
- package/dist/features/webrtc/lib/to-frame.d.ts +9 -0
- package/dist/features/webrtc/lib/to-frame.d.ts.map +1 -0
- package/dist/features/webrtc/lib/to-frame.js +43 -0
- package/dist/features/webrtc/lib/to-frame.js.map +1 -0
- package/dist/features/webrtc/model/types.d.ts +70 -0
- package/dist/features/webrtc/model/types.d.ts.map +1 -0
- package/dist/features/webrtc/model/types.js +2 -0
- package/dist/features/webrtc/model/types.js.map +1 -0
- package/dist/features/websocket/index.d.ts +3 -0
- package/dist/features/websocket/index.d.ts.map +1 -0
- package/dist/features/websocket/index.js +2 -0
- package/dist/features/websocket/index.js.map +1 -0
- package/dist/features/websocket/lib/create-websocket.d.ts +9 -0
- package/dist/features/websocket/lib/create-websocket.d.ts.map +1 -0
- package/dist/features/websocket/lib/create-websocket.js +34 -0
- package/dist/features/websocket/lib/create-websocket.js.map +1 -0
- package/dist/features/websocket/lib/mock.d.ts +6 -0
- package/dist/features/websocket/lib/mock.d.ts.map +1 -0
- package/dist/features/websocket/lib/mock.js +96 -0
- package/dist/features/websocket/lib/mock.js.map +1 -0
- package/dist/features/websocket/lib/proxy.d.ts +9 -0
- package/dist/features/websocket/lib/proxy.d.ts.map +1 -0
- package/dist/features/websocket/lib/proxy.js +120 -0
- package/dist/features/websocket/lib/proxy.js.map +1 -0
- package/dist/features/websocket/lib/wire.d.ts +16 -0
- package/dist/features/websocket/lib/wire.d.ts.map +1 -0
- package/dist/features/websocket/lib/wire.js +46 -0
- package/dist/features/websocket/lib/wire.js.map +1 -0
- package/dist/features/websocket/model/types.d.ts +133 -0
- package/dist/features/websocket/model/types.d.ts.map +1 -0
- package/dist/features/websocket/model/types.js +2 -0
- package/dist/features/websocket/model/types.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/index.js.map +1 -0
- package/dist/playwright.d.ts +4 -0
- package/dist/playwright.d.ts.map +1 -0
- package/dist/playwright.js +2 -0
- package/dist/playwright.js.map +1 -0
- package/dist/rest.d.ts +3 -0
- package/dist/rest.d.ts.map +1 -0
- package/dist/rest.js +3 -0
- package/dist/rest.js.map +1 -0
- package/dist/shared/api/http-server/index.d.ts +3 -0
- package/dist/shared/api/http-server/index.d.ts.map +1 -0
- package/dist/shared/api/http-server/index.js +2 -0
- package/dist/shared/api/http-server/index.js.map +1 -0
- package/dist/shared/api/http-server/listen.d.ts +25 -0
- package/dist/shared/api/http-server/listen.d.ts.map +1 -0
- package/dist/shared/api/http-server/listen.js +44 -0
- package/dist/shared/api/http-server/listen.js.map +1 -0
- package/dist/shared/api/playwright/index.d.ts +2 -0
- package/dist/shared/api/playwright/index.d.ts.map +1 -0
- package/dist/shared/api/playwright/index.js +2 -0
- package/dist/shared/api/playwright/index.js.map +1 -0
- package/dist/shared/api/playwright/ports.d.ts +126 -0
- package/dist/shared/api/playwright/ports.d.ts.map +1 -0
- package/dist/shared/api/playwright/ports.js +11 -0
- package/dist/shared/api/playwright/ports.js.map +1 -0
- package/dist/shared/api/stream-server/index.d.ts +3 -0
- package/dist/shared/api/stream-server/index.d.ts.map +1 -0
- package/dist/shared/api/stream-server/index.js +2 -0
- package/dist/shared/api/stream-server/index.js.map +1 -0
- package/dist/shared/api/stream-server/stream-server.d.ts +45 -0
- package/dist/shared/api/stream-server/stream-server.d.ts.map +1 -0
- package/dist/shared/api/stream-server/stream-server.js +167 -0
- package/dist/shared/api/stream-server/stream-server.js.map +1 -0
- package/dist/shared/lib/async/arrivals.d.ts +31 -0
- package/dist/shared/lib/async/arrivals.d.ts.map +1 -0
- package/dist/shared/lib/async/arrivals.js +57 -0
- package/dist/shared/lib/async/arrivals.js.map +1 -0
- package/dist/shared/lib/async/async-queue.d.ts +23 -0
- package/dist/shared/lib/async/async-queue.d.ts.map +1 -0
- package/dist/shared/lib/async/async-queue.js +80 -0
- package/dist/shared/lib/async/async-queue.js.map +1 -0
- package/dist/shared/lib/async/deferred.d.ts +12 -0
- package/dist/shared/lib/async/deferred.d.ts.map +1 -0
- package/dist/shared/lib/async/deferred.js +34 -0
- package/dist/shared/lib/async/deferred.js.map +1 -0
- package/dist/shared/lib/async/index.d.ts +8 -0
- package/dist/shared/lib/async/index.d.ts.map +1 -0
- package/dist/shared/lib/async/index.js +5 -0
- package/dist/shared/lib/async/index.js.map +1 -0
- package/dist/shared/lib/async/run-all.d.ts +8 -0
- package/dist/shared/lib/async/run-all.d.ts.map +1 -0
- package/dist/shared/lib/async/run-all.js +22 -0
- package/dist/shared/lib/async/run-all.js.map +1 -0
- package/dist/shared/lib/bytes/bytes.d.ts +18 -0
- package/dist/shared/lib/bytes/bytes.d.ts.map +1 -0
- package/dist/shared/lib/bytes/bytes.js +48 -0
- package/dist/shared/lib/bytes/bytes.js.map +1 -0
- package/dist/shared/lib/bytes/index.d.ts +3 -0
- package/dist/shared/lib/bytes/index.d.ts.map +1 -0
- package/dist/shared/lib/bytes/index.js +2 -0
- package/dist/shared/lib/bytes/index.js.map +1 -0
- package/dist/shared/lib/clock/clock.d.ts +29 -0
- package/dist/shared/lib/clock/clock.d.ts.map +1 -0
- package/dist/shared/lib/clock/clock.js +85 -0
- package/dist/shared/lib/clock/clock.js.map +1 -0
- package/dist/shared/lib/clock/index.d.ts +3 -0
- package/dist/shared/lib/clock/index.d.ts.map +1 -0
- package/dist/shared/lib/clock/index.js +2 -0
- package/dist/shared/lib/clock/index.js.map +1 -0
- package/dist/shared/lib/cookies/index.d.ts +3 -0
- package/dist/shared/lib/cookies/index.d.ts.map +1 -0
- package/dist/shared/lib/cookies/index.js +2 -0
- package/dist/shared/lib/cookies/index.js.map +1 -0
- package/dist/shared/lib/cookies/set-cookie.d.ts +22 -0
- package/dist/shared/lib/cookies/set-cookie.d.ts.map +1 -0
- package/dist/shared/lib/cookies/set-cookie.js +89 -0
- package/dist/shared/lib/cookies/set-cookie.js.map +1 -0
- package/dist/shared/lib/envelope/envelope.d.ts +50 -0
- package/dist/shared/lib/envelope/envelope.d.ts.map +1 -0
- package/dist/shared/lib/envelope/envelope.js +111 -0
- package/dist/shared/lib/envelope/envelope.js.map +1 -0
- package/dist/shared/lib/envelope/index.d.ts +3 -0
- package/dist/shared/lib/envelope/index.d.ts.map +1 -0
- package/dist/shared/lib/envelope/index.js +2 -0
- package/dist/shared/lib/envelope/index.js.map +1 -0
- package/dist/shared/lib/errors/index.d.ts +3 -0
- package/dist/shared/lib/errors/index.d.ts.map +1 -0
- package/dist/shared/lib/errors/index.js +2 -0
- package/dist/shared/lib/errors/index.js.map +1 -0
- package/dist/shared/lib/errors/wirestage-error.d.ts +28 -0
- package/dist/shared/lib/errors/wirestage-error.d.ts.map +1 -0
- package/dist/shared/lib/errors/wirestage-error.js +16 -0
- package/dist/shared/lib/errors/wirestage-error.js.map +1 -0
- package/dist/shared/lib/id/id.d.ts +10 -0
- package/dist/shared/lib/id/id.d.ts.map +1 -0
- package/dist/shared/lib/id/id.js +26 -0
- package/dist/shared/lib/id/id.js.map +1 -0
- package/dist/shared/lib/id/index.d.ts +2 -0
- package/dist/shared/lib/id/index.d.ts.map +1 -0
- package/dist/shared/lib/id/index.js +2 -0
- package/dist/shared/lib/id/index.js.map +1 -0
- package/dist/shared/lib/logger/index.d.ts +3 -0
- package/dist/shared/lib/logger/index.d.ts.map +1 -0
- package/dist/shared/lib/logger/index.js +2 -0
- package/dist/shared/lib/logger/index.js.map +1 -0
- package/dist/shared/lib/logger/logger.d.ts +46 -0
- package/dist/shared/lib/logger/logger.d.ts.map +1 -0
- package/dist/shared/lib/logger/logger.js +67 -0
- package/dist/shared/lib/logger/logger.js.map +1 -0
- package/dist/shared/lib/match/index.d.ts +3 -0
- package/dist/shared/lib/match/index.d.ts.map +1 -0
- package/dist/shared/lib/match/index.js +2 -0
- package/dist/shared/lib/match/index.js.map +1 -0
- package/dist/shared/lib/match/url-matcher.d.ts +27 -0
- package/dist/shared/lib/match/url-matcher.d.ts.map +1 -0
- package/dist/shared/lib/match/url-matcher.js +88 -0
- package/dist/shared/lib/match/url-matcher.js.map +1 -0
- package/dist/sse.d.ts +3 -0
- package/dist/sse.d.ts.map +1 -0
- package/dist/sse.js +3 -0
- package/dist/sse.js.map +1 -0
- package/dist/webrtc.d.ts +3 -0
- package/dist/webrtc.d.ts.map +1 -0
- package/dist/webrtc.js +3 -0
- package/dist/webrtc.js.map +1 -0
- package/dist/websocket.d.ts +3 -0
- package/dist/websocket.d.ts.map +1 -0
- package/dist/websocket.js +3 -0
- package/dist/websocket.js.map +1 -0
- package/dist/widgets/stage/index.d.ts +3 -0
- package/dist/widgets/stage/index.d.ts.map +1 -0
- package/dist/widgets/stage/index.js +2 -0
- package/dist/widgets/stage/index.js.map +1 -0
- package/dist/widgets/stage/lib/attached-context.d.ts +10 -0
- package/dist/widgets/stage/lib/attached-context.d.ts.map +1 -0
- package/dist/widgets/stage/lib/attached-context.js +2 -0
- package/dist/widgets/stage/lib/attached-context.js.map +1 -0
- package/dist/widgets/stage/lib/create-stage.d.ts +12 -0
- package/dist/widgets/stage/lib/create-stage.d.ts.map +1 -0
- package/dist/widgets/stage/lib/create-stage.js +250 -0
- package/dist/widgets/stage/lib/create-stage.js.map +1 -0
- package/dist/widgets/stage/lib/http-router.d.ts +44 -0
- package/dist/widgets/stage/lib/http-router.d.ts.map +1 -0
- package/dist/widgets/stage/lib/http-router.js +696 -0
- package/dist/widgets/stage/lib/http-router.js.map +1 -0
- package/dist/widgets/stage/lib/page-host.d.ts +36 -0
- package/dist/widgets/stage/lib/page-host.d.ts.map +1 -0
- package/dist/widgets/stage/lib/page-host.js +240 -0
- package/dist/widgets/stage/lib/page-host.js.map +1 -0
- package/dist/widgets/stage/lib/page-runtime.d.ts +93 -0
- package/dist/widgets/stage/lib/page-runtime.d.ts.map +1 -0
- package/dist/widgets/stage/lib/page-runtime.js +247 -0
- package/dist/widgets/stage/lib/page-runtime.js.map +1 -0
- package/dist/widgets/stage/lib/reads.d.ts +21 -0
- package/dist/widgets/stage/lib/reads.d.ts.map +1 -0
- package/dist/widgets/stage/lib/reads.js +97 -0
- package/dist/widgets/stage/lib/reads.js.map +1 -0
- package/dist/widgets/stage/lib/response-stream.d.ts +23 -0
- package/dist/widgets/stage/lib/response-stream.d.ts.map +1 -0
- package/dist/widgets/stage/lib/response-stream.js +108 -0
- package/dist/widgets/stage/lib/response-stream.js.map +1 -0
- package/dist/widgets/stage/lib/socket-router.d.ts +25 -0
- package/dist/widgets/stage/lib/socket-router.d.ts.map +1 -0
- package/dist/widgets/stage/lib/socket-router.js +233 -0
- package/dist/widgets/stage/lib/socket-router.js.map +1 -0
- package/dist/widgets/stage/model/stage.d.ts +88 -0
- package/dist/widgets/stage/model/stage.d.ts.map +1 -0
- package/dist/widgets/stage/model/stage.js +2 -0
- package/dist/widgets/stage/model/stage.js.map +1 -0
- package/package.json +140 -5
- package/src/app/playwright/index.ts +7 -0
- package/src/app/playwright/lib/fixture.ts +201 -0
- package/src/connect.ts +6 -0
- package/src/entities/frame/@x/plugin.ts +8 -0
- package/src/entities/frame/index.ts +19 -0
- package/src/entities/frame/lib/filter.ts +58 -0
- package/src/entities/frame/lib/payload.ts +42 -0
- package/src/entities/frame/lib/snapshot.ts +105 -0
- package/src/entities/frame/lib/timeline.ts +147 -0
- package/src/entities/frame/model/frame.ts +191 -0
- package/src/entities/plugin/index.ts +36 -0
- package/src/entities/plugin/lib/define-plugin.ts +12 -0
- package/src/entities/plugin/lib/named.ts +21 -0
- package/src/entities/plugin/model/attachment.ts +18 -0
- package/src/entities/plugin/model/http.ts +156 -0
- package/src/entities/plugin/model/page.ts +110 -0
- package/src/entities/plugin/model/plugin.ts +96 -0
- package/src/entities/plugin/model/socket.ts +113 -0
- package/src/entities/plugin/model/stream.ts +46 -0
- package/src/features/connect/index.ts +23 -0
- package/src/features/connect/lib/calls.ts +58 -0
- package/src/features/connect/lib/client.ts +203 -0
- package/src/features/connect/lib/create-connect.ts +164 -0
- package/src/features/connect/lib/faults.ts +132 -0
- package/src/features/connect/lib/protocol.ts +321 -0
- package/src/features/connect/lib/record.ts +48 -0
- package/src/features/connect/lib/recorder.ts +306 -0
- package/src/features/connect/lib/rules.ts +385 -0
- package/src/features/connect/lib/serve.ts +114 -0
- package/src/features/connect/lib/status-of.ts +20 -0
- package/src/features/connect/lib/stubs.ts +282 -0
- package/src/features/connect/lib/universal.ts +100 -0
- package/src/features/connect/model/types.ts +305 -0
- package/src/features/rest/index.ts +23 -0
- package/src/features/rest/lib/calls.ts +31 -0
- package/src/features/rest/lib/create-rest.ts +169 -0
- package/src/features/rest/lib/path.ts +70 -0
- package/src/features/rest/lib/reply.ts +74 -0
- package/src/features/rest/model/types.ts +113 -0
- package/src/features/sse/index.ts +10 -0
- package/src/features/sse/lib/create-sse.ts +129 -0
- package/src/features/sse/lib/encode.ts +28 -0
- package/src/features/sse/model/types.ts +72 -0
- package/src/features/webrtc/index.ts +6 -0
- package/src/features/webrtc/lib/create-webrtc.ts +149 -0
- package/src/features/webrtc/lib/rtc-page-module.ts +189 -0
- package/src/features/webrtc/lib/to-frame.ts +63 -0
- package/src/features/webrtc/model/types.ts +80 -0
- package/src/features/websocket/index.ts +15 -0
- package/src/features/websocket/lib/create-websocket.ts +41 -0
- package/src/features/websocket/lib/mock.ts +114 -0
- package/src/features/websocket/lib/proxy.ts +153 -0
- package/src/features/websocket/lib/wire.ts +78 -0
- package/src/features/websocket/model/types.ts +134 -0
- package/src/index.ts +111 -0
- package/src/playwright.ts +8 -0
- package/src/rest.ts +2 -0
- package/src/shared/api/http-server/index.ts +2 -0
- package/src/shared/api/http-server/listen.ts +71 -0
- package/src/shared/api/playwright/index.ts +17 -0
- package/src/shared/api/playwright/ports.ts +150 -0
- package/src/shared/api/stream-server/index.ts +7 -0
- package/src/shared/api/stream-server/stream-server.ts +254 -0
- package/src/shared/lib/async/arrivals.ts +91 -0
- package/src/shared/lib/async/async-queue.ts +101 -0
- package/src/shared/lib/async/deferred.ts +38 -0
- package/src/shared/lib/async/index.ts +11 -0
- package/src/shared/lib/async/run-all.ts +19 -0
- package/src/shared/lib/bytes/bytes.ts +53 -0
- package/src/shared/lib/bytes/index.ts +9 -0
- package/src/shared/lib/clock/clock.ts +114 -0
- package/src/shared/lib/clock/index.ts +2 -0
- package/src/shared/lib/cookies/index.ts +2 -0
- package/src/shared/lib/cookies/set-cookie.ts +105 -0
- package/src/shared/lib/envelope/envelope.ts +133 -0
- package/src/shared/lib/envelope/index.ts +9 -0
- package/src/shared/lib/errors/index.ts +5 -0
- package/src/shared/lib/errors/wirestage-error.ts +50 -0
- package/src/shared/lib/id/id.ts +29 -0
- package/src/shared/lib/id/index.ts +1 -0
- package/src/shared/lib/logger/index.ts +12 -0
- package/src/shared/lib/logger/logger.ts +126 -0
- package/src/shared/lib/match/index.ts +6 -0
- package/src/shared/lib/match/url-matcher.ts +107 -0
- package/src/sse.ts +2 -0
- package/src/webrtc.ts +2 -0
- package/src/websocket.ts +2 -0
- package/src/widgets/stage/index.ts +9 -0
- package/src/widgets/stage/lib/attached-context.ts +10 -0
- package/src/widgets/stage/lib/create-stage.ts +307 -0
- package/src/widgets/stage/lib/http-router.ts +954 -0
- package/src/widgets/stage/lib/page-host.ts +375 -0
- package/src/widgets/stage/lib/page-runtime.ts +314 -0
- package/src/widgets/stage/lib/reads.ts +128 -0
- package/src/widgets/stage/lib/response-stream.ts +139 -0
- package/src/widgets/stage/lib/socket-router.ts +300 -0
- package/src/widgets/stage/model/stage.ts +110 -0
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { gunzipSync } from "node:zlib";
|
|
2
|
+
import { fromBinary, fromJsonString, } from "@bufbuild/protobuf";
|
|
3
|
+
import { Code } from "@connectrpc/connect";
|
|
4
|
+
import { codeFromString, codeFromHttpStatus as connectCodeFromHttpStatus, } from "@connectrpc/connect/protocol-connect";
|
|
5
|
+
import { codeFromHttpStatus as grpcCodeFromHttpStatus } from "@connectrpc/connect/protocol-grpc";
|
|
6
|
+
import { concatBytes, fromBase64, utf8, } from "../../../shared/lib/bytes/index.js";
|
|
7
|
+
import { decodeEnvelopes, EnvelopeFlag, parseTrailerBlock, } from "../../../shared/lib/envelope/index.js";
|
|
8
|
+
/**
|
|
9
|
+
* Read the format off a request, the way a Connect server negotiates it.
|
|
10
|
+
* Undefined means "not an RPC this plugin understands" — a rule then falls
|
|
11
|
+
* through instead of mangling, say, a REST call that shares the path prefix.
|
|
12
|
+
*/
|
|
13
|
+
export function detectFormat(request) {
|
|
14
|
+
const contentType = (request.headers["content-type"] ?? "")
|
|
15
|
+
.split(";")[0]
|
|
16
|
+
?.trim()
|
|
17
|
+
.toLowerCase();
|
|
18
|
+
if (contentType?.startsWith("application/grpc-web-text"))
|
|
19
|
+
return {
|
|
20
|
+
protocol: "grpc-web",
|
|
21
|
+
binary: !contentType.endsWith("+json"),
|
|
22
|
+
base64: true,
|
|
23
|
+
enveloped: true,
|
|
24
|
+
};
|
|
25
|
+
if (contentType?.startsWith("application/grpc-web"))
|
|
26
|
+
return {
|
|
27
|
+
protocol: "grpc-web",
|
|
28
|
+
binary: !contentType.endsWith("+json"),
|
|
29
|
+
base64: false,
|
|
30
|
+
enveloped: true,
|
|
31
|
+
};
|
|
32
|
+
if (contentType?.startsWith("application/grpc"))
|
|
33
|
+
return {
|
|
34
|
+
protocol: "grpc",
|
|
35
|
+
binary: !contentType.endsWith("+json"),
|
|
36
|
+
base64: false,
|
|
37
|
+
enveloped: true,
|
|
38
|
+
};
|
|
39
|
+
if (contentType?.startsWith("application/connect+"))
|
|
40
|
+
return {
|
|
41
|
+
protocol: "connect",
|
|
42
|
+
binary: contentType === "application/connect+proto",
|
|
43
|
+
base64: false,
|
|
44
|
+
enveloped: true,
|
|
45
|
+
};
|
|
46
|
+
if (contentType === "application/proto" || contentType === "application/json")
|
|
47
|
+
return {
|
|
48
|
+
protocol: "connect",
|
|
49
|
+
binary: contentType === "application/proto",
|
|
50
|
+
base64: false,
|
|
51
|
+
enveloped: false,
|
|
52
|
+
};
|
|
53
|
+
// Connect's GET form for side-effect-free methods carries the message in
|
|
54
|
+
// the query string and sends no content type at all.
|
|
55
|
+
if (request.method === "GET" &&
|
|
56
|
+
request.url.searchParams.get("connect") === "v1")
|
|
57
|
+
return {
|
|
58
|
+
protocol: "connect",
|
|
59
|
+
binary: request.url.searchParams.get("encoding") !== "json",
|
|
60
|
+
base64: false,
|
|
61
|
+
enveloped: false,
|
|
62
|
+
};
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
const OK = { code: 0, message: "" };
|
|
66
|
+
/** The request's messages, from its body or (Connect GET) its query. */
|
|
67
|
+
export function decodeRequestBody(format, request) {
|
|
68
|
+
if (!format.enveloped) {
|
|
69
|
+
const query = request.url.searchParams;
|
|
70
|
+
if (query.get("connect") === "v1") {
|
|
71
|
+
const message = query.get("message") ?? "";
|
|
72
|
+
return [
|
|
73
|
+
query.get("base64") === "1"
|
|
74
|
+
? fromBase64(message.replaceAll("-", "+").replaceAll("_", "/"))
|
|
75
|
+
: new TextEncoder().encode(message),
|
|
76
|
+
];
|
|
77
|
+
}
|
|
78
|
+
return [request.body()];
|
|
79
|
+
}
|
|
80
|
+
const body = format.base64
|
|
81
|
+
? fromBase64Stream(request.body())
|
|
82
|
+
: request.body();
|
|
83
|
+
return dataEnvelopes(body, request.headers[format.protocol === "connect"
|
|
84
|
+
? "connect-content-encoding"
|
|
85
|
+
: "grpc-encoding"]);
|
|
86
|
+
}
|
|
87
|
+
/** Messages and status from a response the real backend sent. */
|
|
88
|
+
export function decodeResponseBody(format, response) {
|
|
89
|
+
const headers = response.headers;
|
|
90
|
+
const raw = response.body ?? new Uint8Array(0);
|
|
91
|
+
if (!format.enveloped) {
|
|
92
|
+
if (response.status !== 200)
|
|
93
|
+
return { messages: [], status: connectError(raw, response.status) };
|
|
94
|
+
// A 200 that is not a message is something on the way — a proxy's
|
|
95
|
+
// sign-in page, say — and a Connect client reports it as an error.
|
|
96
|
+
const contentType = headers["content-type"] ?? "";
|
|
97
|
+
if (!/^application\/(proto|json)\b/i.test(contentType))
|
|
98
|
+
return {
|
|
99
|
+
messages: [],
|
|
100
|
+
status: {
|
|
101
|
+
code: Code.Unknown,
|
|
102
|
+
message: `unexpected content type "${contentType}"`,
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
return { messages: [raw], status: OK };
|
|
106
|
+
}
|
|
107
|
+
const body = format.base64 ? fromBase64Stream(raw) : raw;
|
|
108
|
+
const { envelopes } = decodeEnvelopes(body);
|
|
109
|
+
const encoding = headers[format.protocol === "connect"
|
|
110
|
+
? "connect-content-encoding"
|
|
111
|
+
: "grpc-encoding"];
|
|
112
|
+
const messages = [];
|
|
113
|
+
let status;
|
|
114
|
+
for (const envelope of envelopes) {
|
|
115
|
+
if (format.protocol === "connect" &&
|
|
116
|
+
envelope.flags & EnvelopeFlag.endStream)
|
|
117
|
+
status = endStream(inflate(envelope.flags, envelope.data, encoding));
|
|
118
|
+
else if (envelope.flags & EnvelopeFlag.trailer)
|
|
119
|
+
status = grpcStatus(parseTrailerBlock(envelope.data));
|
|
120
|
+
else
|
|
121
|
+
messages.push(inflate(envelope.flags, envelope.data, encoding));
|
|
122
|
+
}
|
|
123
|
+
// A trailers-only response carries the status in the headers instead.
|
|
124
|
+
if (status === undefined && headers["grpc-status"] !== undefined)
|
|
125
|
+
status = grpcStatus(headers);
|
|
126
|
+
// No status anywhere and not a 200: a gateway answered, not the server.
|
|
127
|
+
// The client maps the HTTP status to a code, and so does the record.
|
|
128
|
+
if (status === undefined && response.status !== 200)
|
|
129
|
+
status = {
|
|
130
|
+
code: format.protocol === "connect"
|
|
131
|
+
? connectCodeFromHttpStatus(response.status)
|
|
132
|
+
: grpcCodeFromHttpStatus(response.status),
|
|
133
|
+
message: `HTTP ${response.status}`,
|
|
134
|
+
};
|
|
135
|
+
return { messages, status };
|
|
136
|
+
}
|
|
137
|
+
/** Parse a message payload with the request's format. */
|
|
138
|
+
export function parseMessage(schema, bytes, binary, jsonOptions) {
|
|
139
|
+
return binary
|
|
140
|
+
? fromBinary(schema, bytes)
|
|
141
|
+
: fromJsonString(schema, utf8(bytes), {
|
|
142
|
+
ignoreUnknownFields: true,
|
|
143
|
+
...jsonOptions,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Connect's `{ "code": "not_found", "message": "..." }` error body. A body
|
|
148
|
+
* that is not one came from something on the way, and the HTTP status is all
|
|
149
|
+
* there is to go by — which is how a Connect client reads it too.
|
|
150
|
+
*/
|
|
151
|
+
export function connectError(body, httpStatus) {
|
|
152
|
+
try {
|
|
153
|
+
const status = errorStatus(JSON.parse(utf8(body)));
|
|
154
|
+
if (status !== undefined)
|
|
155
|
+
return status;
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
// Not JSON at all.
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
code: connectCodeFromHttpStatus(httpStatus),
|
|
162
|
+
message: `HTTP ${httpStatus}`,
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
/** The status in a Connect error object; undefined when it names no code. */
|
|
166
|
+
function errorStatus(value) {
|
|
167
|
+
const error = (typeof value === "object" && value !== null ? value : {});
|
|
168
|
+
const code = typeof error.code === "string" ? codeFromString(error.code) : undefined;
|
|
169
|
+
if (code === undefined)
|
|
170
|
+
return undefined;
|
|
171
|
+
return {
|
|
172
|
+
code,
|
|
173
|
+
message: typeof error.message === "string" ? error.message : "",
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
function grpcStatus(fields) {
|
|
177
|
+
const code = Number(fields["grpc-status"]);
|
|
178
|
+
return {
|
|
179
|
+
code: Number.isInteger(code) ? code : Code.Unknown,
|
|
180
|
+
message: safeDecodeURIComponent(fields["grpc-message"] ?? ""),
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
/** Connect's end-of-stream JSON: `{}` for OK, `{ "error": {...} }` otherwise. */
|
|
184
|
+
function endStream(data) {
|
|
185
|
+
try {
|
|
186
|
+
const parsed = JSON.parse(utf8(data));
|
|
187
|
+
if (parsed.error === undefined)
|
|
188
|
+
return OK;
|
|
189
|
+
return (errorStatus(parsed.error) ?? {
|
|
190
|
+
code: Code.Unknown,
|
|
191
|
+
message: "end-of-stream error with no code",
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
catch {
|
|
195
|
+
return { code: Code.Unknown, message: "malformed end-of-stream message" };
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* gRPC-web-text: base64, but not one base64 string. A server encodes each
|
|
200
|
+
* chunk it flushes on its own, padding included, so a stream is several
|
|
201
|
+
* encodings end to end, and decoding it as one stops at the first padding.
|
|
202
|
+
*/
|
|
203
|
+
function fromBase64Stream(body) {
|
|
204
|
+
const parts = utf8(body).match(/[^=]+=*/g) ?? [];
|
|
205
|
+
return concatBytes(parts.map((part) => fromBase64(part)));
|
|
206
|
+
}
|
|
207
|
+
function dataEnvelopes(body, encoding) {
|
|
208
|
+
return decodeEnvelopes(body)
|
|
209
|
+
.envelopes.filter((e) => !(e.flags & EnvelopeFlag.trailer) &&
|
|
210
|
+
!(e.flags & EnvelopeFlag.endStream))
|
|
211
|
+
.map((e) => inflate(e.flags, e.data, encoding));
|
|
212
|
+
}
|
|
213
|
+
/** Decompress a compressed envelope when the encoding is gzip; otherwise as is. */
|
|
214
|
+
function inflate(flags, data, encoding) {
|
|
215
|
+
if (!(flags & EnvelopeFlag.compressed) || encoding !== "gzip")
|
|
216
|
+
return data;
|
|
217
|
+
return new Uint8Array(gunzipSync(data));
|
|
218
|
+
}
|
|
219
|
+
/** gRPC percent-encodes `grpc-message`; a malformed escape must not throw. */
|
|
220
|
+
function safeDecodeURIComponent(value) {
|
|
221
|
+
try {
|
|
222
|
+
return decodeURIComponent(value);
|
|
223
|
+
}
|
|
224
|
+
catch {
|
|
225
|
+
return value;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=protocol.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../../../src/features/connect/lib/protocol.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { DescService } from "@bufbuild/protobuf";
|
|
2
|
+
import type { StubHandle } from "../model/types.js";
|
|
3
|
+
import type { RpcRules } from "./rules.js";
|
|
4
|
+
/**
|
|
5
|
+
* Record and decode a service's calls without answering them: the request
|
|
6
|
+
* as it leaves, the real backend's messages and status as they come back,
|
|
7
|
+
* or the fault when the connection fails.
|
|
8
|
+
*
|
|
9
|
+
* A call a stub answers is recorded by that stub. Where this rule sits among
|
|
10
|
+
* the stubs does not matter: a request is one exchange however many rules
|
|
11
|
+
* see it, so it lands once either way.
|
|
12
|
+
*/
|
|
13
|
+
export declare function recordService(rules: RpcRules, service: DescService): Promise<StubHandle>;
|
|
14
|
+
//# sourceMappingURL=record.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record.d.ts","sourceRoot":"","sources":["../../../../src/features/connect/lib/record.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AAGtD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAE3C;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAClC,KAAK,EAAE,QAAQ,EACf,OAAO,EAAE,WAAW,GAClB,OAAO,CAAC,UAAU,CAAC,CA4BrB"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { endpointOf } from "./recorder.js";
|
|
2
|
+
/**
|
|
3
|
+
* Record and decode a service's calls without answering them: the request
|
|
4
|
+
* as it leaves, the real backend's messages and status as they come back,
|
|
5
|
+
* or the fault when the connection fails.
|
|
6
|
+
*
|
|
7
|
+
* A call a stub answers is recorded by that stub. Where this rule sits among
|
|
8
|
+
* the stubs does not matter: a request is one exchange however many rules
|
|
9
|
+
* see it, so it lands once either way.
|
|
10
|
+
*/
|
|
11
|
+
export async function recordService(rules, service) {
|
|
12
|
+
const added = [];
|
|
13
|
+
for (const method of service.methods) {
|
|
14
|
+
// A page cannot call the others; there is nothing of theirs to record.
|
|
15
|
+
if (method.methodKind !== "unary" &&
|
|
16
|
+
method.methodKind !== "server_streaming")
|
|
17
|
+
continue;
|
|
18
|
+
added.push(await rules.add({
|
|
19
|
+
method,
|
|
20
|
+
label: `record ${endpointOf(method)}`,
|
|
21
|
+
options: {},
|
|
22
|
+
anyProtocol: true,
|
|
23
|
+
observe: true,
|
|
24
|
+
respond: () => ({ type: "fallback" }),
|
|
25
|
+
}));
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
get hits() {
|
|
29
|
+
return added.reduce((sum, rule) => sum + rule.hits, 0);
|
|
30
|
+
},
|
|
31
|
+
async remove() {
|
|
32
|
+
await Promise.all(added.map((rule) => rule.remove()));
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
//# sourceMappingURL=record.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"record.js","sourceRoot":"","sources":["../../../../src/features/connect/lib/record.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAG3C;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAClC,KAAe,EACf,OAAoB;IAEpB,MAAM,KAAK,GAAqB,EAAE,CAAC;IACnC,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACtC,uEAAuE;QACvE,IACC,MAAM,CAAC,UAAU,KAAK,OAAO;YAC7B,MAAM,CAAC,UAAU,KAAK,kBAAkB;YAExC,SAAS;QACV,KAAK,CAAC,IAAI,CACT,MAAM,KAAK,CAAC,GAAG,CAAC;YACf,MAAM;YACN,KAAK,EAAE,UAAU,UAAU,CAAC,MAAM,CAAC,EAAE;YACrC,OAAO,EAAE,EAAE;YACX,WAAW,EAAE,IAAI;YACjB,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,UAAU,EAAE,CAAC;SACrC,CAAC,CACF,CAAC;IACH,CAAC;IACD,OAAO;QACN,IAAI,IAAI;YACP,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,IAAI,EAAE,EAAE,CAAC,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACxD,CAAC;QACD,KAAK,CAAC,MAAM;YACX,MAAM,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC;QACvD,CAAC;KACD,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { type DescMethod } from "@bufbuild/protobuf";
|
|
2
|
+
import { type HandlerContext } from "@connectrpc/connect";
|
|
3
|
+
import type { FrameSource, Timeline } from "../../../entities/frame/index.js";
|
|
4
|
+
import type { RpcProtocol } from "../model/types.js";
|
|
5
|
+
import type { RpcStatus } from "./protocol.js";
|
|
6
|
+
/** What is known about one call, by whoever records its frames. */
|
|
7
|
+
export interface CallInfo {
|
|
8
|
+
readonly correlation: string;
|
|
9
|
+
/** Who makes the call: the page, the test's drive client, an outside client. */
|
|
10
|
+
readonly from: FrameSource;
|
|
11
|
+
/** Who answers it: a stub, the real network, a served fake. */
|
|
12
|
+
readonly answeredBy: FrameSource;
|
|
13
|
+
readonly rpcProtocol: RpcProtocol | undefined;
|
|
14
|
+
readonly page?: string | undefined;
|
|
15
|
+
readonly context?: string | undefined;
|
|
16
|
+
/**
|
|
17
|
+
* The request side is already on the timeline: the rule that took the
|
|
18
|
+
* request recorded it before deciding how to answer.
|
|
19
|
+
*/
|
|
20
|
+
readonly requestRecorded?: boolean;
|
|
21
|
+
/** Set on live streams: resets the underlying connection. */
|
|
22
|
+
cut?: () => void;
|
|
23
|
+
/** Set on live streams: settles once the response is over. */
|
|
24
|
+
over?: Promise<unknown>;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* How a call's identity reaches the implementation. Connect threads context
|
|
28
|
+
* values from the server adapter into `HandlerContext.values`, which keeps the
|
|
29
|
+
* recording wrapper free of globals and safe under concurrent calls.
|
|
30
|
+
*/
|
|
31
|
+
export declare const kCall: import("@connectrpc/connect").ContextKey<CallInfo>;
|
|
32
|
+
export declare const endpointOf: (method: DescMethod) => string;
|
|
33
|
+
export interface Recorder {
|
|
34
|
+
/** A request-side message: the first is the `request` frame. */
|
|
35
|
+
out(call: CallInfo, method: DescMethod, message: unknown, first: boolean): void;
|
|
36
|
+
/** A response-side message. */
|
|
37
|
+
in(call: CallInfo, method: DescMethod, message: unknown): void;
|
|
38
|
+
/** The call ended: OK when `error` is undefined. */
|
|
39
|
+
status(call: CallInfo, method: DescMethod, error?: unknown): void;
|
|
40
|
+
/** A status read off the wire (passthrough). */
|
|
41
|
+
statusOf(call: CallInfo, method: DescMethod, status: RpcStatus): void;
|
|
42
|
+
/**
|
|
43
|
+
* The call ended without a status: an abort, a cut, a dropped connection.
|
|
44
|
+
* `by` is who caused it, when that is not who was answering.
|
|
45
|
+
*/
|
|
46
|
+
fault(call: CallInfo, method: DescMethod, reason: string, detail?: {
|
|
47
|
+
readonly error?: string | undefined;
|
|
48
|
+
readonly by?: FrameSource;
|
|
49
|
+
}): void;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Writes RPC frames. Every RPC, however it was answered, lands as the same
|
|
53
|
+
* shape: a `request` frame from whoever called, `message` frames each way,
|
|
54
|
+
* and one closing frame — a `response` with the status, or a `fault` when
|
|
55
|
+
* there was none — so `calls()` reassembles stubbed, passed-through and
|
|
56
|
+
* served calls the same way.
|
|
57
|
+
*
|
|
58
|
+
* A call ends once. A stream the test cut is over at the cut, whatever the
|
|
59
|
+
* implementation goes on to return; the first ending is the one recorded.
|
|
60
|
+
*/
|
|
61
|
+
export declare function createRecorder(timeline: Timeline, protocol: string): Recorder;
|
|
62
|
+
/**
|
|
63
|
+
* The call a handler is serving. An unidentified one is recorded as
|
|
64
|
+
* anonymous — each as a call of its own, so one ending does not end the next.
|
|
65
|
+
*/
|
|
66
|
+
export declare function callOf(context: HandlerContext): CallInfo;
|
|
67
|
+
/** Wrap an iterable so `tap` sees every value as the consumer takes it. */
|
|
68
|
+
export declare function tapIterable<T>(source: AsyncIterable<T>, tap: (value: T, index: number) => void): AsyncGenerator<T>;
|
|
69
|
+
type AnyImpl = (input: never, context: HandlerContext) => unknown;
|
|
70
|
+
/**
|
|
71
|
+
* Wrap an implementation of any of the four method kinds so every message
|
|
72
|
+
* and the final status are recorded. The implementation itself is untouched:
|
|
73
|
+
* it sees the same requests, and the client sees the same responses.
|
|
74
|
+
*/
|
|
75
|
+
export declare function recordingImpl(method: DescMethod, impl: AnyImpl, recorder: Recorder): AnyImpl;
|
|
76
|
+
export {};
|
|
77
|
+
//# sourceMappingURL=recorder.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recorder.d.ts","sourceRoot":"","sources":["../../../../src/features/connect/lib/recorder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { create, isMessage, toBinary, } from "@bufbuild/protobuf";
|
|
2
|
+
import { Code, ConnectError, createContextKey, } from "@connectrpc/connect";
|
|
3
|
+
/** A call nobody identified; the key's default, so a lookup never misses. */
|
|
4
|
+
const ANONYMOUS = Object.freeze({
|
|
5
|
+
correlation: "anonymous",
|
|
6
|
+
from: "page",
|
|
7
|
+
answeredBy: "stub",
|
|
8
|
+
rpcProtocol: undefined,
|
|
9
|
+
});
|
|
10
|
+
/**
|
|
11
|
+
* How a call's identity reaches the implementation. Connect threads context
|
|
12
|
+
* values from the server adapter into `HandlerContext.values`, which keeps the
|
|
13
|
+
* recording wrapper free of globals and safe under concurrent calls.
|
|
14
|
+
*/
|
|
15
|
+
export const kCall = createContextKey(ANONYMOUS, {
|
|
16
|
+
description: "wirestage call",
|
|
17
|
+
});
|
|
18
|
+
export const endpointOf = (method) => `${method.parent.typeName}/${method.name}`;
|
|
19
|
+
/**
|
|
20
|
+
* Writes RPC frames. Every RPC, however it was answered, lands as the same
|
|
21
|
+
* shape: a `request` frame from whoever called, `message` frames each way,
|
|
22
|
+
* and one closing frame — a `response` with the status, or a `fault` when
|
|
23
|
+
* there was none — so `calls()` reassembles stubbed, passed-through and
|
|
24
|
+
* served calls the same way.
|
|
25
|
+
*
|
|
26
|
+
* A call ends once. A stream the test cut is over at the cut, whatever the
|
|
27
|
+
* implementation goes on to return; the first ending is the one recorded.
|
|
28
|
+
*/
|
|
29
|
+
export function createRecorder(timeline, protocol) {
|
|
30
|
+
const ended = new WeakSet();
|
|
31
|
+
const base = (call, method) => ({
|
|
32
|
+
protocol,
|
|
33
|
+
endpoint: endpointOf(method),
|
|
34
|
+
correlation: call.correlation,
|
|
35
|
+
...(call.page === undefined ? {} : { page: call.page }),
|
|
36
|
+
...(call.context === undefined ? {} : { context: call.context }),
|
|
37
|
+
});
|
|
38
|
+
const asMessage = (schema, value) => (isMessage(value, schema)
|
|
39
|
+
? value
|
|
40
|
+
: create(schema, value));
|
|
41
|
+
const close = (call, method, status, extra = {}) => {
|
|
42
|
+
if (ended.has(call))
|
|
43
|
+
return;
|
|
44
|
+
ended.add(call);
|
|
45
|
+
timeline.append({
|
|
46
|
+
...base(call, method),
|
|
47
|
+
kind: "response",
|
|
48
|
+
direction: "in",
|
|
49
|
+
source: call.answeredBy,
|
|
50
|
+
meta: {
|
|
51
|
+
rpcProtocol: call.rpcProtocol,
|
|
52
|
+
code: status.code,
|
|
53
|
+
message: status.message,
|
|
54
|
+
...extra,
|
|
55
|
+
},
|
|
56
|
+
});
|
|
57
|
+
};
|
|
58
|
+
return {
|
|
59
|
+
out(call, method, message, first) {
|
|
60
|
+
const value = asMessage(method.input, message);
|
|
61
|
+
timeline.append({
|
|
62
|
+
...base(call, method),
|
|
63
|
+
kind: first ? "request" : "message",
|
|
64
|
+
direction: "out",
|
|
65
|
+
source: call.from,
|
|
66
|
+
value,
|
|
67
|
+
data: () => toBinary(method.input, value),
|
|
68
|
+
meta: { rpcProtocol: call.rpcProtocol },
|
|
69
|
+
});
|
|
70
|
+
},
|
|
71
|
+
in(call, method, message) {
|
|
72
|
+
if (ended.has(call))
|
|
73
|
+
return;
|
|
74
|
+
const value = asMessage(method.output, message);
|
|
75
|
+
timeline.append({
|
|
76
|
+
...base(call, method),
|
|
77
|
+
kind: "message",
|
|
78
|
+
direction: "in",
|
|
79
|
+
source: call.answeredBy,
|
|
80
|
+
value,
|
|
81
|
+
data: () => toBinary(method.output, value),
|
|
82
|
+
meta: { rpcProtocol: call.rpcProtocol },
|
|
83
|
+
});
|
|
84
|
+
},
|
|
85
|
+
status(call, method, error) {
|
|
86
|
+
if (error === undefined) {
|
|
87
|
+
close(call, method, { code: 0, message: "" });
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (error instanceof ConnectError) {
|
|
91
|
+
close(call, method, { code: error.code, message: error.rawMessage });
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
// Anything else reaches the page as Connect's own "internal error".
|
|
95
|
+
// The frame records that, and keeps what was really thrown where
|
|
96
|
+
// the test can read it and the page cannot.
|
|
97
|
+
close(call, method, { code: Code.Internal, message: "internal error" }, { thrown: String(error) });
|
|
98
|
+
},
|
|
99
|
+
statusOf: (call, method, status) => close(call, method, status),
|
|
100
|
+
fault(call, method, reason, detail = {}) {
|
|
101
|
+
if (ended.has(call))
|
|
102
|
+
return;
|
|
103
|
+
ended.add(call);
|
|
104
|
+
timeline.append({
|
|
105
|
+
...base(call, method),
|
|
106
|
+
kind: "fault",
|
|
107
|
+
direction: "none",
|
|
108
|
+
source: detail.by ?? call.answeredBy,
|
|
109
|
+
meta: {
|
|
110
|
+
rpcProtocol: call.rpcProtocol,
|
|
111
|
+
reason,
|
|
112
|
+
...(detail.error === undefined ? {} : { error: detail.error }),
|
|
113
|
+
},
|
|
114
|
+
});
|
|
115
|
+
},
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* The call a handler is serving. An unidentified one is recorded as
|
|
120
|
+
* anonymous — each as a call of its own, so one ending does not end the next.
|
|
121
|
+
*/
|
|
122
|
+
export function callOf(context) {
|
|
123
|
+
const call = context.values.get(kCall);
|
|
124
|
+
return call === ANONYMOUS ? { ...ANONYMOUS } : call;
|
|
125
|
+
}
|
|
126
|
+
/** Wrap an iterable so `tap` sees every value as the consumer takes it. */
|
|
127
|
+
export async function* tapIterable(source, tap) {
|
|
128
|
+
let index = 0;
|
|
129
|
+
for await (const value of source) {
|
|
130
|
+
tap(value, index++);
|
|
131
|
+
yield value;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Wrap an implementation of any of the four method kinds so every message
|
|
136
|
+
* and the final status are recorded. The implementation itself is untouched:
|
|
137
|
+
* it sees the same requests, and the client sees the same responses.
|
|
138
|
+
*/
|
|
139
|
+
export function recordingImpl(method, impl, recorder) {
|
|
140
|
+
const run = impl;
|
|
141
|
+
/** The request side, unless the rule that took the request recorded it. */
|
|
142
|
+
const request = (call, message, first) => {
|
|
143
|
+
if (!call.requestRecorded)
|
|
144
|
+
recorder.out(call, method, message, first);
|
|
145
|
+
};
|
|
146
|
+
switch (method.methodKind) {
|
|
147
|
+
case "unary":
|
|
148
|
+
return async (input, context) => {
|
|
149
|
+
const call = callOf(context);
|
|
150
|
+
request(call, input, true);
|
|
151
|
+
try {
|
|
152
|
+
const response = await run(input, context);
|
|
153
|
+
recorder.in(call, method, response);
|
|
154
|
+
recorder.status(call, method);
|
|
155
|
+
return response;
|
|
156
|
+
}
|
|
157
|
+
catch (error) {
|
|
158
|
+
recorder.status(call, method, error);
|
|
159
|
+
throw error;
|
|
160
|
+
}
|
|
161
|
+
};
|
|
162
|
+
case "server_streaming":
|
|
163
|
+
return async function* (input, context) {
|
|
164
|
+
const call = callOf(context);
|
|
165
|
+
request(call, input, true);
|
|
166
|
+
try {
|
|
167
|
+
for await (const response of run(input, context)) {
|
|
168
|
+
recorder.in(call, method, response);
|
|
169
|
+
yield response;
|
|
170
|
+
}
|
|
171
|
+
recorder.status(call, method);
|
|
172
|
+
}
|
|
173
|
+
catch (error) {
|
|
174
|
+
recorder.status(call, method, error);
|
|
175
|
+
throw error;
|
|
176
|
+
}
|
|
177
|
+
};
|
|
178
|
+
case "client_streaming":
|
|
179
|
+
return async (requests, context) => {
|
|
180
|
+
const call = callOf(context);
|
|
181
|
+
try {
|
|
182
|
+
const response = await run(tapIterable(requests, (m, i) => request(call, m, i === 0)), context);
|
|
183
|
+
recorder.in(call, method, response);
|
|
184
|
+
recorder.status(call, method);
|
|
185
|
+
return response;
|
|
186
|
+
}
|
|
187
|
+
catch (error) {
|
|
188
|
+
recorder.status(call, method, error);
|
|
189
|
+
throw error;
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
case "bidi_streaming":
|
|
193
|
+
return async function* (requests, context) {
|
|
194
|
+
const call = callOf(context);
|
|
195
|
+
try {
|
|
196
|
+
for await (const response of run(tapIterable(requests, (m, i) => request(call, m, i === 0)), context)) {
|
|
197
|
+
recorder.in(call, method, response);
|
|
198
|
+
yield response;
|
|
199
|
+
}
|
|
200
|
+
recorder.status(call, method);
|
|
201
|
+
}
|
|
202
|
+
catch (error) {
|
|
203
|
+
recorder.status(call, method, error);
|
|
204
|
+
throw error;
|
|
205
|
+
}
|
|
206
|
+
};
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=recorder.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"recorder.js","sourceRoot":"","sources":["../../../../src/features/connect/lib/recorder.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { DescMessage, DescMethod } from "@bufbuild/protobuf";
|
|
2
|
+
import { type HandlerContext } from "@connectrpc/connect";
|
|
3
|
+
import type { UniversalHandler } from "@connectrpc/connect/protocol";
|
|
4
|
+
import type { HttpOutcome, HttpRequestView, HttpRuleHandle, PluginContext } from "../../../entities/plugin/index.js";
|
|
5
|
+
import type { ConnectOptions, HoldOptions } from "../model/types.js";
|
|
6
|
+
import { type CallInfo, type Recorder } from "./recorder.js";
|
|
7
|
+
export type AnyImpl = (input: never, context: HandlerContext) => unknown;
|
|
8
|
+
/** One method's rule, as each kind of stub describes it. */
|
|
9
|
+
export interface RuleSpec<I extends DescMessage> {
|
|
10
|
+
readonly method: DescMethod;
|
|
11
|
+
readonly label: string;
|
|
12
|
+
readonly options: HoldOptions<I> & {
|
|
13
|
+
readonly delayMs?: number | undefined;
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Take calls in any RPC format, not only the protocols stubs answer: for
|
|
17
|
+
* a rule that watches and answers nothing.
|
|
18
|
+
*/
|
|
19
|
+
readonly anyProtocol?: boolean;
|
|
20
|
+
/** Hear how a call this rule let through ended, and record it. */
|
|
21
|
+
readonly observe?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* Decide the call. Its request is already recorded, and `messages` are
|
|
24
|
+
* the request's messages decoded (none when they would not decode).
|
|
25
|
+
*/
|
|
26
|
+
respond(view: HttpRequestView, messages: readonly unknown[]): HttpOutcome | Promise<HttpOutcome>;
|
|
27
|
+
}
|
|
28
|
+
export interface RpcRules {
|
|
29
|
+
/**
|
|
30
|
+
* Add one method's rule. Every stub goes through here, so every stub
|
|
31
|
+
* means the same by "a call to this method": the path, the protocols the
|
|
32
|
+
* plugin answers, the content type, `match` on the decoded request,
|
|
33
|
+
* `times`, the request on the timeline before the decision, `delayMs`.
|
|
34
|
+
*/
|
|
35
|
+
add<I extends DescMessage>(spec: RuleSpec<I>): Promise<HttpRuleHandle>;
|
|
36
|
+
/**
|
|
37
|
+
* Connect's own server-side handler for one method: what makes a stub's
|
|
38
|
+
* bytes exactly a Connect server's. Built once per stub, not per call.
|
|
39
|
+
*/
|
|
40
|
+
handler(method: DescMethod, impl: AnyImpl): UniversalHandler;
|
|
41
|
+
/** Answer a call through a handler. */
|
|
42
|
+
answer(handler: UniversalHandler, method: DescMethod, view: HttpRequestView): Promise<HttpOutcome>;
|
|
43
|
+
/** The call a request is, as a stub answers it. */
|
|
44
|
+
callOf(view: HttpRequestView): CallInfo;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* How an RPC method becomes an HTTP rule, and how its traffic is recorded.
|
|
48
|
+
* The one place that knows both, shared by every stub of the plugin.
|
|
49
|
+
*/
|
|
50
|
+
export declare function createRpcRules(context: PluginContext, options: ConnectOptions, recorder: Recorder, protocol: string): RpcRules;
|
|
51
|
+
//# sourceMappingURL=rules.d.ts.map
|