@crow-agent/server 0.0.0-stage → 0.2.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.
- package/README.md +108 -2
- package/dist/public-api.d.ts +5 -0
- package/dist/public-api.d.ts.map +1 -0
- package/dist/public-api.js +3 -0
- package/dist/public-api.js.map +1 -0
- package/dist/server-connection.d.ts +32 -0
- package/dist/server-connection.d.ts.map +1 -0
- package/dist/server-connection.js +5 -0
- package/dist/server-connection.js.map +1 -0
- package/dist/server-errors.d.ts +31 -0
- package/dist/server-errors.d.ts.map +1 -0
- package/dist/server-errors.js +41 -0
- package/dist/server-errors.js.map +1 -0
- package/dist/server-listener.d.ts +8 -0
- package/dist/server-listener.d.ts.map +1 -0
- package/dist/server-listener.js +2 -0
- package/dist/server-listener.js.map +1 -0
- package/dist/server-types.d.ts +52 -0
- package/dist/server-types.d.ts.map +1 -0
- package/dist/server-types.js +2 -0
- package/dist/server-types.js.map +1 -0
- package/dist/session-routing.d.ts +42 -0
- package/dist/session-routing.d.ts.map +1 -0
- package/dist/session-routing.js +300 -0
- package/dist/session-routing.js.map +1 -0
- package/dist/session-server.d.ts +14 -0
- package/dist/session-server.d.ts.map +1 -0
- package/dist/session-server.js +678 -0
- package/dist/session-server.js.map +1 -0
- package/dist/testing/public-api.d.ts +6 -0
- package/dist/testing/public-api.d.ts.map +1 -0
- package/dist/testing/public-api.js +4 -0
- package/dist/testing/public-api.js.map +1 -0
- package/dist/testing/test-client.d.ts +29 -0
- package/dist/testing/test-client.d.ts.map +1 -0
- package/dist/testing/test-client.js +196 -0
- package/dist/testing/test-client.js.map +1 -0
- package/dist/testing/test-host.d.ts +62 -0
- package/dist/testing/test-host.d.ts.map +1 -0
- package/dist/testing/test-host.js +241 -0
- package/dist/testing/test-host.js.map +1 -0
- package/dist/testing/test-server.d.ts +13 -0
- package/dist/testing/test-server.d.ts.map +1 -0
- package/dist/testing/test-server.js +17 -0
- package/dist/testing/test-server.js.map +1 -0
- package/dist/transports/unix/public-api.d.ts +5 -0
- package/dist/transports/unix/public-api.d.ts.map +1 -0
- package/dist/transports/unix/public-api.js +4 -0
- package/dist/transports/unix/public-api.js.map +1 -0
- package/dist/transports/unix/socket-address.d.ts +3 -0
- package/dist/transports/unix/socket-address.d.ts.map +1 -0
- package/dist/transports/unix/socket-address.js +11 -0
- package/dist/transports/unix/socket-address.js.map +1 -0
- package/dist/transports/unix/unix-listener.d.ts +18 -0
- package/dist/transports/unix/unix-listener.d.ts.map +1 -0
- package/dist/transports/unix/unix-listener.js +511 -0
- package/dist/transports/unix/unix-listener.js.map +1 -0
- package/dist/transports/unix/unix-preset.d.ts +7 -0
- package/dist/transports/unix/unix-preset.d.ts.map +1 -0
- package/dist/transports/unix/unix-preset.js +25 -0
- package/dist/transports/unix/unix-preset.js.map +1 -0
- package/dist/transports/unix/unix-types.d.ts +14 -0
- package/dist/transports/unix/unix-types.d.ts.map +1 -0
- package/dist/transports/unix/unix-types.js +2 -0
- package/dist/transports/unix/unix-types.js.map +1 -0
- package/package.json +53 -4
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"session-server.js","sourceRoot":"","sources":["../src/session-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAIN,kBAAkB,EAClB,yBAAyB,IAAI,gBAAgB,EAC7C,wBAAwB,IAAI,aAAa,EACzC,gBAAgB,EAChB,gCAAgC,IAAI,aAAa,GACjD,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,kBAAkB,EAGlB,YAAY,EACZ,eAAe,GACf,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAIN,oBAAoB,EACpB,wBAAwB,IAAI,oBAAoB,EAChD,mBAAmB,EACnB,UAAU,EACV,0BAA0B,EAC1B,gBAAgB,EAEhB,uBAAuB,GAOvB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAIN,oBAAoB,GACpB,MAAM,wBAAwB,CAAC;AAChC,OAAO,EACN,6BAA6B,IAAI,mBAAmB,EACpD,WAAW,EACX,gBAAgB,GAChB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EACN,aAAa,GACb,MAAM,sBAAsB,CAAC;AAO9B,MAAM,4BAA4B,GAAG,IAAI,CAAC;AAC1C,MAAM,UAAU,GAAG,UAAU,CAAC;AAC9B,MAAM,kBAAkB,GAAG,UAAU,CAAC;AAItC,MAAM,kBAAkB;IACd,cAAc,CAAS;IAChC,KAAK,CAAmE;IACxE,OAAO,GAAyC,EAAE,CAAC;IACnD,MAAM,GAAG,KAAK,CAAC;IACf,UAAU,GAAG,KAAK,CAAC;IAEnB,YACC,cAAsB,EACtB,IAAsE;QAEtE,IAAI,CAAC,cAAc,GAAG,cAAc,CAAC;QACrC,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,cAAsB,EAAE,MAAqB;QAC1D,MAAM,KAAK,GAAG,cAAc,KAAK,IAAI,CAAC,cAAc,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC;QACrE,IAAI,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC,CAAC;YAC9B,OAAO;QACR,CAAC;QACD,MAAM,IAAI,CAAC,KAAK,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IAC1C,CAAC;IAED,OAAO,CACN,MAA6B,EAC7B,QAA0D;QAE1D,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,MAAM,OAAO,GAAG,gDAAgD,CAAC;YACjE,MAAM,IAAI,uBAAuB,CAAC,OAAO,CAAC,CAAC;QAC5C,CAAC;QACD,MAAM,OAAO,GAAG,gBAAgB,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,OAAO,CAAC,cAAc,CAAC,aAAa,CAAC,MAAM,CAAC,CAAyB,CAAC;QACtF,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,CAAC;QAC3C,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,OAAO,OAAO,CAAC;IAChB,CAAC;IAED,KAAK,CAAC,KAAK;QACV,SAAS,CAAC;YACT,MAAM,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,CAAC;YACrC,IAAI,OAAO,KAAK,SAAS;gBAAE,MAAM;YACjC,MAAM,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,cAAc,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC;QACvD,CAAC;QACD,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC;IACpB,CAAC;IAED,QAAQ,CAAC,QAA0D,EAAE,SAAkB;QACtF,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,IAAI,CAAC,SAAS,CAAC;QAC5C,IAAI,KAAK;YAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;IACjD,CAAC;CACD;AAED,MAAM,OAAO,MAAM;IAGT,QAAQ,CAAS;IAC1B,mFAAmF;IAC1E,MAAM,CAAgB;IAE/B,QAAQ,CAAwB;IAChC,UAAU,CAA4B;IACtC,eAAe,CAAS;IACxB,mBAAmB,CAAS;IAC5B,yBAAyB,CAAwC;IACjE,QAAQ,CAAuC;IAC/C,YAAY,GAAG,IAAI,GAAG,EAAmB,CAAC;IAC1C,OAAO,CAA2B;IAClC,SAAS,GAAG,KAAK,CAAC;IAClB,UAAU,CAAiB;IAC3B,WAAW,GAAG,KAAK,CAAC;IACpB,WAAW,CAA4B;IACvC,aAAa,CAAc;IAC3B,UAAU,CAAiB;IAC3B,UAAU,GAAG,KAAK,CAAC;IAEnB,YACC,IAA2B,EAC3B,OAAsB;QAEtB,MAAM,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,CAAC;QACrC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,SAAS,CAAC;QACpC,MAAM,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;QAC7B,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAC;QACzB,IAAI,CAAC,eAAe,GAAG,MAAM,CAAC,cAAc,CAAC;QAC7C,IAAI,CAAC,mBAAmB,GAAG,MAAM,CAAC,kBAAkB,CAAC;QACrD,IAAI,CAAC,yBAAyB,GAAG,OAAO,CAAC,wBAAwB,CAAC;QAClE,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;QAChC,IAAI,CAAC,OAAO,GAAG,IAAI,aAAa,CAAC;YAChC,IAAI;YACJ,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,SAAS,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS;YAC/B,iBAAiB,EAAE,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,EAAE,CAClD,IAAI,CAAC,SAAS,CAAC,MAAyB,EAAE;gBACzC,IAAI,EAAE,YAAY;gBAClB,UAAU,EAAE,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,UAAU;aACxD,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC;YACzB,WAAW,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;SAC9C,CAAC,CAAC;QACH,IAAI,aAA0B,CAAC;QAC/B,IAAI,YAAuC,CAAC;QAC5C,IAAI,CAAC,MAAM,GAAG,IAAI,OAAO,CAAO,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACnD,aAAa,GAAG,OAAO,CAAC;YACxB,YAAY,GAAG,MAAM,CAAC;QACvB,CAAC,CAAC,CAAC;QACH,IAAI,CAAC,aAAa,GAAG,aAAa,CAAC;QACnC,IAAI,CAAC,WAAW,GAAG,YAAY,CAAC;QAChC,KAAK,IAAI,CAAC,MAAM,CAAC,IAAI,CACpB,GAAG,EAAE,CAAC,SAAS,EACf,GAAG,EAAE,CAAC,SAAS,CACf,CAAC;IACH,CAAC;IAED,KAAK;QACJ,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC,CAAC;QACnF,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,4BAA4B,CAAC,CAAC,CAAC;QAClG,IAAI,IAAI,CAAC,SAAS;YAAE,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC,CAAC;QACpF,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;QAC1B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,KAAK,CAAC,KAAK;QACV,MAAM,MAAM,GAAqB,EAAE,CAAC;QACpC,IAAI,CAAC;YACJ,KAAK,MAAM,QAAQ,IAAI,IAAI,CAAC,UAAU,EAAE,CAAC;gBACxC,MAAM,MAAM,GAAG,CAAC,UAA0B,EAAyB,EAAE,CAAC,IAAI,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;gBAC9F,MAAM,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;gBAC7B,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACvB,CAAC;YACD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;YACvB,OAAO,IAAI,CAAC;QACb,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;YACtB,MAAM,QAAQ,GAAc,EAAE,CAAC;YAC/B,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;YACvF,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;gBAClC,IAAI,QAAQ,CAAC,MAAM,KAAK,UAAU;oBAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACpE,CAAC;YACD,IAAI,CAAC;gBACJ,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;YACxB,CAAC;YAAC,OAAO,YAAY,EAAE,CAAC;gBACvB,QAAQ,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;YAC7B,CAAC;YACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBACzB,MAAM,OAAO,GAAG,IAAI,cAAc,CAAC,CAAC,KAAK,EAAE,GAAG,QAAQ,CAAC,EAAE,mCAAmC,CAAC,CAAC;gBAC9F,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;gBACnC,MAAM,OAAO,CAAC;YACf,CAAC;YACD,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC5B,MAAM,KAAK,CAAC;QACb,CAAC;gBAAS,CAAC;YACV,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC7B,CAAC;IACF,CAAC;IAED,MAAM,CACL,UAA0B;QAE1B,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;YACpB,KAAK,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;YACjC,MAAM,KAAK,GAA0B;gBACpC,MAAM,EAAE,GAAG,EAAE,GAAE,CAAC;gBAChB,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC;gBACjB,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC;aAC1C,CAAC;YACF,OAAO,KAAK,CAAC;QACd,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;QACnD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,CAAC,iBAAiB,EAAE,CAAC;QAEzB,OAAO;YACN,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,KAAK,CAAC;YAC7C,OAAO,EAAE,GAAG,EAAE,CAAC,IAAI,CAAC,oBAAoB,CAAC,KAAK,CAAC;YAC/C,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;gBAClB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;gBACvB,KAAK,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;YAChE,CAAC;SACD,CAAC;IACH,CAAC;IAED,mBAAmB,CAAC,UAA0B;QAC7C,IAAI,KAAuB,CAAC;QAC5B,MAAM,SAAS,GAAG,GAAS,EAAE;YAC5B,MAAM,KAAK,GAAkB,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC;YACvF,KAAK,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;QACjD,CAAC,CAAC;QACF,MAAM,KAAK,GAAG,UAAU,CAAC,SAAS,EAAE,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAC9D,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,MAAM,QAAQ,GAAG,IAAI,GAAG,EAAE,CAAC;QAC3B,MAAM,cAAc,GAAG,IAAI,GAAG,EAAE,CAAC;QACjC,KAAK,GAAG;YACP,UAAU;YACV,OAAO,EAAE,IAAI,oBAAoB,CAAC,EAAE,cAAc,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC;YAC3E,oBAAoB,EAAE,QAAQ;YAC9B,KAAK,EAAE,eAAe;YACtB,YAAY,EAAE,KAAK;YACnB,gBAAgB,EAAE,KAAK;YACvB,cAAc;SACd,CAAC;QACF,OAAO,KAAK,CAAC;IACd,CAAC;IAED,sBAAsB,CAAC,KAAsB;QAC5C,YAAY,CAAC,KAAK,CAAC,gBAAgB,CAAC,CAAC;IACtC,CAAC;IAED,aAAa,CAAC,KAAsB;QACnC,KAAK,CAAC,KAAK,GAAG,SAAS,CAAC;QACxB,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;IACpC,CAAC;IAED,KAAK,CAAC,KAAK;QACV,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC;QACjC,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,QAAQ,CAAC;QAC5C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC;QACtB,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,EAAE,CAAC;QACnC,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,OAAO,IAAI,CAAC;IACb,CAAC;IAED,KAAK,CAAC,cAAc;QACnB,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,CAAC;QACjC,IAAI,QAAQ,KAAK,SAAS;YAAE,MAAM,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC3D,MAAM,QAAQ,GAAc,EAAE,CAAC;QAC/B,MAAM,SAAS,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;QAChG,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;YAClC,IAAI,QAAQ,CAAC,MAAM,KAAK,UAAU;gBAAE,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QACpE,CAAC;QACD,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACxB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACtB,CAAC;QACD,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3B,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC5B,OAAO;QACR,CAAC;QACD,MAAM,CAAC,IAAI,CAAC,GAAG,QAAQ,CAAC;QACxB,MAAM,OAAO,GACZ,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,IAAI,YAAY,KAAK;YAC7C,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,IAAI,cAAc,CAAC,QAAQ,EAAE,wBAAwB,CAAC,CAAC;QAC3D,IAAI,CAAC,oBAAoB,CAAC,OAAO,CAAC,CAAC;QACnC,MAAM,OAAO,CAAC;IACf,CAAC;IAED,OAAO,CAAC,KAAsB,EAAE,KAAiB;QAChD,MAAM,QAAQ,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;QAC7C,IAAI,QAAQ;YAAE,OAAO;QACrB,IAAI,QAAqC,CAAC;QAC1C,IAAI,CAAC;YACJ,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC1C,QAAQ,GAAG,OAAO,CAAC;QACpB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,KAAK,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CAAC;QACxE,CAAC;QACD,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO;QACnC,KAAK,MAAM,OAAO,IAAI,QAAQ,EAAE,CAAC;YAChC,MAAM,IAAI,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;YACzC,IAAI,IAAI;gBAAE,OAAO;YACjB,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACpC,CAAC;IACF,CAAC;IAED,aAAa,CAAC,KAAsB,EAAE,OAAsB;QAC3D,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,KAAK,eAAe,CAAC;QACtD,IAAI,aAAa,EAAE,CAAC;YACnB,IAAI,CAAC,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACjC,OAAO;QACR,CAAC;QACD,MAAM,aAAa,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC;QAC/C,IAAI,aAAa,EAAE,CAAC;YACnB,MAAM,KAAK,GAAkB;gBAC5B,IAAI,EAAE,iBAAiB;gBACvB,OAAO,EAAE,0CAA0C;aACnD,CAAC;YACF,KAAK,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAChD,OAAO;QACR,CAAC;QACD,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,KAAK,OAAO,CAAC;QACtC,IAAI,KAAK,EAAE,CAAC;YACX,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YACxC,OAAO;QACR,CAAC;QACD,MAAM,WAAW,GAAG,KAAK,CAAC,KAAK,KAAK,aAAa,CAAC;QAClD,IAAI,CAAC,WAAW;YAAE,OAAO;QACzB,MAAM,EAAE,SAAS,EAAE,GAAG,KAAK,CAAC;QAC5B,IAAI,SAAS,KAAK,SAAS;YAAE,OAAO;QACpC,KAAK,SAAS,CAAC,IAAI,CAAC,GAAS,EAAE;YAC9B,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,KAAK,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC;YAC/D,IAAI,OAAO;gBAAE,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QACtD,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,WAAW,CAAC,KAAsB,EAAE,OAAsB;QACzD,MAAM,OAAO,GAAG,OAAO,CAAC,IAAI,KAAK,OAAO,CAAC;QACzC,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,MAAM,KAAK,GAAkB;gBAC5B,IAAI,EAAE,iBAAiB;gBACvB,OAAO,EAAE,0CAA0C;aACnD,CAAC;YACF,KAAK,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;YAChD,OAAO;QACR,CAAC;QACD,KAAK,CAAC,KAAK,GAAG,aAAa,CAAC;QAC5B,MAAM,SAAS,GAAG,IAAI,CAAC,kBAAkB,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAC1D,KAAK,CAAC,SAAS,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,KAAc,EAAE,EAAE,CACpD,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC,CACjE,CAAC;IACH,CAAC;IAED,kBAAkB,CAAC,KAAsB,EAAE,OAAsB;QAChE,IAAI,OAAO,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;YAC/B,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;YAClC,OAAO;QACR,CAAC;QACD,8DAA8D;QAC9D,KAAK,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,OAA0B,CAAC,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,KAAsB,EAAE,KAAkB;QAClE,MAAM,SAAS,GAAG,0BAA0B,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC5D,IAAI,CAAC,SAAS,EAAE,CAAC;YAChB,MAAM,MAAM,GAAG,gCAAgC,KAAK,CAAC,OAAO,cAAc,gBAAgB,EAAE,CAAC;YAC7F,MAAM,IAAI,CAAC,uBAAuB,CAAC,KAAK,EAAE;gBACzC,IAAI,EAAE,SAAS;gBACf,OAAO,EAAE,MAAM;aACf,CAAC,CAAC;YACH,OAAO;QACR,CAAC;QAED,MAAM,MAAM,GACX,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,KAAK,KAAK,aAAa,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;QACrG,IAAI,CAAC,MAAM;YAAE,OAAO;QACpB,MAAM,YAAY,GAA6B;YAC9C,aAAa,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,EAAE,SAAS,EAAE,OAAO,CAAC;YAC3F,aAAa,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,YAAY,CAAC,KAAK,EAAE,OAAO,CAAC;YACrE,qBAAqB,EAAE,CAAC,SAAS,EAAE,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,SAAS,EAAE,OAAO,CAAC;SAC7F,CAAC;QACF,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,QAAQ,CAAC,cAAc,CAAC,YAAY,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QAC7F,MAAM,WAAW,GAChB,CAAC,IAAI,CAAC,SAAS,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,KAAK,KAAK,aAAa,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,MAAM,CAAC;QACrG,IAAI,CAAC,WAAW,EAAE,CAAC;YAClB,MAAM,OAAO,GAAG,YAAY,CAAC;YAC7B,MAAM,QAAQ,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;YAChC,OAAO;QACR,CAAC;QACD,KAAK,CAAC,cAAc,GAAG,QAAQ,CAAC;QAChC,MAAM,QAAQ,GAAG;YAChB,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,gBAAgB;YACzB,QAAQ,EAAE,IAAI,CAAC,QAAQ;SACD,CAAC;QACxB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QACnD,MAAM,KAAK,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,YAAY,IAAI,KAAK,CAAC,KAAK,KAAK,aAAa,CAAC;QAC3E,IAAI,KAAK,EAAE,CAAC;YACX,KAAK,CAAC,KAAK,GAAG,OAAO,CAAC;YACtB,IAAI,CAAC,sBAAsB,CAAC,KAAK,CAAC,CAAC;QACpC,CAAC;IACF,CAAC;IAED,YAAY,CAAC,KAAsB,EAAE,QAAwB;QAC5D,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,QAAQ,CAAC;QAChC,MAAM,aAAa,GAAG,MAAM,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,CAAC;QACxD,IAAI,CAAC,aAAa;YAAE,OAAO;QAC3B,MAAM,MAAM,GAAG,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC5C,MAAM,OAAO,GAAG,MAAM,KAAK,SAAS,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC1E,IAAI,OAAO,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,IAAI,YAAY,CAAC,uBAAuB,EAAE,YAAY,CAAC,CAAC;YACvE,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;QACjC,CAAC;IACF,CAAC;IAED,KAAK,CAAC,aAAa,CAAC,KAAsB,EAAE,QAAyB;QACpE,MAAM,EAAE,GAAG,QAAQ,CAAC,EAAE,CAAC;QACvB,MAAM,SAAS,GAAG,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC/C,IAAI,SAAS,EAAE,CAAC;YACf,MAAM,KAAK,GAAG,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,8BAA8B,EAAE,CAAC;YACnF,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,EAAE,EAAE,KAAK,CAAC,CAAC;YAC3C,OAAO;QACR,CAAC;QACD,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;QAC9C,IAAI,IAAI,KAAK,SAAS;YAAE,OAAO;QAC/B,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAC/B,MAAM,MAAM,GAAG,EAAE,UAAU,EAAE,MAAM,EAAE,CAAC;QACtC,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAC;QACrC,MAAM,MAAM,GAAG,UAAU,CAAC,MAAM,CAAC;QACjC,MAAM,OAAO,GAAG,eAAe,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;QACtD,MAAM,OAAO,GAA+B,aAAa,CAAC,IAAI,CAAC,CAAC;QAChE,MAAM,YAAY,GACjB,OAAO,EAAE,IAAI,KAAK,WAAW;YAC5B,CAAC,CAAC,IAAI,kBAAkB,CAAC,OAAO,CAAC,cAAc,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,EAAE,CAC1E,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,cAAc,EAAE,MAAM,CAAC,CAClD;YACF,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,OAAO,GAAG,KAAK,EACpB,cAAsB,EACtB,MAAqB,EACL,EAAE;YAClB,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;gBAChC,MAAM,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,cAAc,EAAE,MAAM,CAAC,CAAC;gBACzD,OAAO;YACR,CAAC;YACD,MAAM,YAAY,CAAC,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;QACpD,CAAC,CAAC;QACF,IAAI,SAAS,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC;YACJ,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;YACzF,SAAS,GAAG,IAAI,CAAC;YACjB,IAAI,YAAY,KAAK,SAAS;gBAAE,MAAM,YAAY,CAAC,KAAK,EAAE,CAAC;QAC5D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,oBAAoB,EAAE,SAAS,CAAC,CAAC;YAC9D,MAAM,aAAa,GAAG,SAAS,CAAC;YAChC,IAAI,aAAa,EAAE,CAAC;gBACnB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;gBACvB,MAAM,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;gBACxC,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;gBAClB,OAAO;YACR,CAAC;YACD,MAAM,SAAS,GAAG,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC;YAC5C,MAAM,OAAO,GAAG,SAAS;gBACxB,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,OAAO,EAAE,uBAAuB,EAAE;gBACzD,CAAC,CAAC,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAC;YAChC,MAAM,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,EAAE,EAAE,OAAO,CAAC,CAAC;QAC9C,CAAC;gBAAS,CAAC;YACV,MAAM,OAAO,GAAG,KAAK,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YAC7C,IAAI,OAAO,KAAK,MAAM;gBAAE,KAAK,CAAC,cAAc,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QACzD,CAAC;IACF,CAAC;IAED,UAAU,CAAC,KAAsB,EAAE,QAAyB;QAC3D,IAAI,CAAC;YACJ,OAAO,gBAAgB,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QACxC,CAAC;QAAC,MAAM,CAAC;YACR,MAAM,KAAK,GAAG,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,sBAAsB,EAAE,CAAC;YAC3E,KAAK,IAAI,CAAC,aAAa,CAAC,KAAK,EAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,CAAC,CAAC;YACnD,OAAO,SAAS,CAAC;QAClB,CAAC;IACF,CAAC;IAED,KAAK,CAAC,aAAa,CAClB,KAAsB,EACtB,EAAU,EACV,KAAwC;QAExC,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE;YAC3B,IAAI,EAAE,UAAU;YAChB,EAAE;YACF,EAAE,EAAE,KAAK;YACT,KAAK;SACL,CAAC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,aAAa,CAClB,KAAsB,EACtB,QAAyB,EACzB,IAAiB,EACjB,OAAmC,EACnC,YAA4C,EAC5C,OAAyE,EACzE,OAAgB;QAEhB,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,QAAQ,KAAK,IAAI,CAAC,QAAQ,CAAC;QACjE,IAAI,CAAC,aAAa;YAAE,MAAM,IAAI,gBAAgB,EAAE,CAAC;QACjD,MAAM,qBAAqB,GAC1B,YAAY,KAAK,SAAS,IAAI,KAAK,CAAC,oBAAoB,CAAC,GAAG,CAAC,YAAY,CAAC,cAAc,CAAC,CAAC;QAC3F,IAAI,qBAAqB,EAAE,CAAC;YAC3B,MAAM,IAAI,uBAAuB,CAAC,kCAAkC,YAAY,CAAC,cAAc,EAAE,CAAC,CAAC;QACpG,CAAC;QACD,IAAI,MAAM,GAA0B,SAAS,CAAC;QAC9C,MAAM,aAAa,GAAG,WAAW,IAAI,QAAQ,CAAC,MAAM,CAAC;QACrD,IAAI,aAAa,EAAE,CAAC;YACnB,MAAM,GAAG,MAAM,IAAI,CAAC,OAAO,CAAC,kBAAkB,CAAC,IAAI,EAAE,QAAQ,CAAC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAChG,CAAC;aAAM,CAAC;YACP,MAAM,QAAQ,GAAG,KAAK,CAAC,cAAc,CAAC;YACtC,IAAI,QAAQ,KAAK,SAAS,EAAE,CAAC;gBAC5B,MAAM,OAAO,GAAG,0BAA0B,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;gBAC1E,MAAM,IAAI,uBAAuB,CAAC,OAAO,CAAC,CAAC;YAC5C,CAAC;YACD,MAAM,GAAG,MAAM,QAAQ,CAAC,aAAa,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;QAC/D,CAAC;QACD,IAAI,YAAY,KAAK,SAAS,EAAE,CAAC;YAChC,MAAM,GAAG,YAAY,CAAC,OAAO,CAAC,MAAM,EAAE,KAAK,CAAC,oBAAoB,CAAC,CAAC;QACnE,CAAC;aAAM,IAAI,OAAO,EAAE,IAAI,KAAK,aAAa,EAAE,CAAC;YAC5C,MAAM,EAAE,cAAc,EAAE,GAAG,OAAO,CAAC;YACnC,KAAK,CAAC,oBAAoB,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;QACnD,CAAC;QACD,IAAI,QAA0B,CAAC;QAC/B,IAAI,MAAM,KAAK,SAAS,EAAE,CAAC;YAC1B,QAAQ,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;QAC5D,CAAC;aAAM,CAAC;YACP,QAAQ,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,EAAE,EAAE,QAAQ,CAAC,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QACpE,CAAC;QACD,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,QAAQ,CAAC,CAAC;IACvC,CAAC;IAED,oBAAoB,CAAC,UAA2B;QAC/C,MAAM,OAAO,GAAG,UAAU,CAAC,YAAY,IAAI,UAAU,CAAC,KAAK,KAAK,SAAS,CAAC;QAC1E,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,IAAI,CAAC;gBACJ,MAAM,EAAE,OAAO,EAAE,GAAG,UAAU,CAAC;gBAC/B,OAAO,CAAC,GAAG,EAAE,CAAC;YACf,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBAChB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACxB,CAAC;QACF,CAAC;QACD,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,UAA2B;QAChC,MAAM,OAAO,GAAG,UAAU,CAAC,YAAY,CAAC;QACxC,IAAI,OAAO;YAAE,OAAO;QACpB,UAAU,CAAC,YAAY,GAAG,IAAI,CAAC;QAC/B,UAAU,CAAC,KAAK,GAAG,QAAQ,CAAC;QAC5B,IAAI,CAAC,sBAAsB,CAAC,UAAU,CAAC,CAAC;QACxC,KAAK,MAAM,MAAM,IAAI,UAAU,CAAC,cAAc,CAAC,MAAM,EAAE,EAAE,CAAC;YACzD,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,qBAAqB,CAAC,CAAC,CAAC;QAC3D,CAAC;QACD,UAAU,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAClC,UAAU,CAAC,oBAAoB,CAAC,KAAK,EAAE,CAAC;QACxC,MAAM,OAAO,GAAG,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;QACrD,IAAI,OAAO;YAAE,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACtC,MAAM,EAAE,cAAc,EAAE,GAAG,UAAU,CAAC;QACtC,OAAO,UAAU,CAAC,cAAc,CAAC;QACjC,MAAM,QAAQ,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,UAAU,EAAE,YAAY,CAAC,CAAC,CAAC;QACrE,IAAI,cAAc,KAAK,SAAS;YAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,cAAc,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACvG,MAAM,OAAO,GAAG,OAAO,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC;QAC7C,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE;YAC7B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC9B,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU;oBAAE,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;YAClE,CAAC;QACF,CAAC,CAAC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,cAAc,CACnB,UAA2B,EAC3B,cAAsB,EACtB,MAAqB;QAErB,MAAM,QAAQ,GAAG,UAAU,CAAC,oBAAoB,CAAC;QACjD,MAAM,YAAY,GAAG,QAAQ,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;QAClD,MAAM,OAAO,GAAG,YAAY,KAAK,SAAS,CAAC;QAC3C,IAAI,OAAO;YAAE,OAAO;QACpB,MAAM,OAAO,GAAG,YAAY,CAAC,YAAY,CAAC,MAAM,CAAyB,CAAC;QAC1E,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,EAAE;YAChC,IAAI,EAAE,gBAAgB;YACtB,cAAc;YACd,MAAM,EAAE,OAAO;SACf,CAAC,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,SAAS,CAAC,UAA2B,EAAE,OAAsB;QAClE,MAAM,QAAQ,GAAG,CAAC,UAAU,CAAC,YAAY,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,MAAM,CAAC;QAC3E,IAAI,CAAC,QAAQ;YAAE,OAAO,KAAK,CAAC;QAC5B,MAAM,KAAK,GAAG,IAAI,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QACrD,IAAI,KAAK,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QACtC,IAAI,CAAC;YACJ,MAAM,SAAS,GAAG,UAAU,CAAC,UAAU,CAAC;YACxC,MAAM,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC5B,OAAO,IAAI,CAAC;QACb,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACvB,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC;YAC7C,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;YACvB,OAAO,KAAK,CAAC;QACd,CAAC;IACF,CAAC;IAED,YAAY,CAAC,UAA2B,EAAE,OAAsB;QAC/D,IAAI,CAAC;YACJ,OAAO,mBAAmB,CAAC,OAAO,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC;QAC/E,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;YACvB,KAAK,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC;YAC/E,OAAO,SAAS,CAAC;QAClB,CAAC;IACF,CAAC;IAED,KAAK,CAAC,uBAAuB,CAAC,UAA2B,EAAE,KAAoB;QAC9E,MAAM,QAAQ,GAAG,UAAU,CAAC,YAAY,IAAI,UAAU,CAAC,KAAK,KAAK,SAAS,IAAI,UAAU,CAAC,KAAK,KAAK,QAAQ,CAAC;QAC5G,IAAI,QAAQ;YAAE,OAAO;QACrB,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QAC/B,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,aAAa,EAAE,KAAK,EAA6B,CAAC;QAC1E,IAAI,UAAkC,CAAC;QACvC,IAAI,CAAC;YACJ,UAAU,GAAG,mBAAmB,CAAC,OAAO,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,eAAe,EAAE,CAAC,CAAC;QACrF,CAAC;QAAC,OAAO,WAAW,EAAE,CAAC;YACtB,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,CAAC;QAC9B,CAAC;QACD,MAAM,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,UAAU,EAAE,UAAU,CAAC,CAAC;QACzD,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,SAAS;QACd,MAAM,WAAW,GAAG,CAAC,GAAG,IAAI,CAAC,YAAY,CAAC,CAAC;QAC3C,KAAK,MAAM,UAAU,IAAI,WAAW;YAAE,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;QACrE,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,CAAC,CAAC;QAC1F,MAAM,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QAC7B,KAAK,MAAM,UAAU,IAAI,WAAW;YAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC7D,MAAM,OAAO,GAAG,MAAM,OAAO,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,kBAAkB,CAAC,CAAC,CAAC,CAAC;QACnF,IAAI,CAAC,YAAY,CAAC,KAAK,EAAE,CAAC;QAC1B,mBAAmB,CAAC,OAAO,CAAC,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,UAA0B,EAAE,UAAuB;QACnE,MAAM,OAAO,GAAG,UAAU,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC;QAC7C,IAAI,CAAC;YACJ,MAAM,OAAO,CAAC;QACf,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;IACF,CAAC;IAED,gBAAgB,CAAC,KAAc;QAC9B,MAAM,YAAY,GAAG,KAAK,YAAY,WAAW,IAAI,KAAK,YAAY,kBAAkB,CAAC;QACzF,IAAI,YAAY,EAAE,CAAC;YAClB,MAAM,KAAK,GAAG,KAAyC,CAAC;YACxD,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;QACrD,CAAC;QACD,MAAM,OAAO,GAAG,KAAK,YAAY,uBAAuB,CAAC;QACzD,IAAI,OAAO,EAAE,CAAC;YACb,MAAM,OAAO,GAAI,KAAiC,CAAC,OAAO,CAAC;YAC3D,OAAO,EAAE,IAAI,EAAE,iBAAiB,EAAE,OAAO,EAAE,CAAC;QAC7C,CAAC;QACD,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACvB,OAAO,EAAE,IAAI,EAAE,gBAAgB,EAAE,OAAO,EAAE,mBAAmB,EAAE,CAAC;IACjE,CAAC;IAED,iBAAiB;QAChB,IAAI,CAAC;YACJ,IAAI,CAAC,yBAAyB,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAC1D,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YAChB,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACxB,CAAC;IACF,CAAC;IAED,UAAU,CAAC,KAAc;QACxB,MAAM,UAAU,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAC7E,IAAI,CAAC;YACJ,IAAI,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,CAAC;QAC7B,CAAC;QAAC,MAAM,CAAC;YACR,4DAA4D;QAC7D,CAAC;IACF,CAAC;IAED,oBAAoB,CAAC,KAAe;QACnC,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAC7B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,KAAK,KAAK,SAAS;YAAE,IAAI,CAAC,aAAa,EAAE,CAAC;;YACzC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC9B,CAAC;CACD;AAED,SAAS,UAAU,CAAC,IAAe,EAAE,KAAgB;IACpD,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,CAAC;IACpD,IAAI,CAAC,UAAU;QAAE,OAAO,KAAK,CAAC;IAC9B,MAAM,WAAW,GAAG,WAAW,IAAI,IAAI,CAAC;IACxC,MAAM,YAAY,GAAG,WAAW,IAAI,KAAK,CAAC;IAC1C,IAAI,CAAC,WAAW,IAAI,CAAC,YAAY;QAAE,OAAO,WAAW,KAAK,YAAY,CAAC;IACvE,OAAO,IAAI,CAAC,SAAS,KAAK,KAAK,CAAC,SAAS,IAAI,IAAI,CAAC,YAAY,KAAK,KAAK,CAAC,YAAY,CAAC;AACvF,CAAC;AAOD,SAAS,YAAY,CAAC,OAAsB;IAC3C,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACxD,IAAI,CAAC,cAAc;QAAE,MAAM,IAAI,SAAS,CAAC,mCAAmC,CAAC,CAAC;IAC9E,MAAM,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC7C,IAAI,CAAC,OAAO,EAAE,CAAC;QACd,MAAM,IAAI,SAAS,CAAC,+CAA+C,CAAC,CAAC;IACtE,CAAC;IACD,MAAM,cAAc,GAAG,OAAO,CAAC,cAAc,IAAI,oBAAoB,CAAC;IACtE,MAAM,eAAe,GAAG,MAAM,CAAC,aAAa,CAAC,cAAc,CAAC,IAAI,cAAc,GAAG,CAAC,IAAI,cAAc,IAAI,UAAU,CAAC;IACnH,IAAI,CAAC,eAAe,EAAE,CAAC;QACtB,MAAM,IAAI,SAAS,CAAC,0DAA0D,UAAU,EAAE,CAAC,CAAC;IAC7F,CAAC;IACD,MAAM,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,IAAI,4BAA4B,CAAC;IACtF,MAAM,YAAY,GACjB,MAAM,CAAC,aAAa,CAAC,kBAAkB,CAAC,IAAI,kBAAkB,GAAG,CAAC,IAAI,kBAAkB,IAAI,kBAAkB,CAAC;IAChH,IAAI,CAAC,YAAY,EAAE,CAAC;QACnB,MAAM,IAAI,SAAS,CAAC,8DAA8D,kBAAkB,EAAE,CAAC,CAAC;IACzG,CAAC;IACD,MAAM,MAAM,GAAiB,EAAE,cAAc,EAAE,kBAAkB,EAAE,CAAC;IACpE,OAAO,MAAM,CAAC;AACf,CAAC;AAED,SAAS,mBAAmB,CAAC,OAAwC;IACpE,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC9B,IAAI,MAAM,CAAC,MAAM,KAAK,UAAU;YAAE,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAChE,CAAC;IACD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC;QAAE,MAAM,QAAQ,CAAC,CAAC,CAAC,CAAC;IAC7C,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACzB,MAAM,IAAI,cAAc,CAAC,QAAQ,EAAE,iCAAiC,CAAC,CAAC;IACvE,CAAC;AACF,CAAC","sourcesContent":["import {\n\ttype JsonValue,\n\ttype ServiceCall,\n\ttype ServiceProviderUpdate as ServiceUpdate,\n\tRemoteServiceError,\n\tcreateServiceStateEncoder as makeStateEncoder,\n\tdecodeServiceControlCall as decodeControl,\n\tparseServiceCall,\n\tparseServiceSubscriptionSnapshot as parseSnapshot,\n} from \"@crow-agent/chord\";\nimport {\n\tBACKGROUND_CONTEXT,\n\ttype Context,\n\ttype SessionMetadata,\n\tTODO_CONTEXT,\n\twithAbortSignal,\n} from \"@crow-agent/agent-core\";\nimport {\n\ttype CancelEnvelope,\n\ttype ClientHello,\n\ttype ClientMessage,\n\tClientMessageDecoder,\n\tDEFAULT_MAX_FRAME_LENGTH as PROTOCOL_FRAME_LIMIT,\n\tencodeServerMessage,\n\tisServerId,\n\tisSupportedProtocolVersion,\n\tPROTOCOL_VERSION,\n\ttype ProtocolError,\n\tProtocolValidationError,\n\ttype RequestEnvelope,\n\ttype ResponseEnvelope,\n\ttype RpcTarget,\n\ttype ServerHello,\n\ttype ServerHelloError,\n\ttype ServerMessage,\n} from \"@crow-agent/protocol\";\nimport {\n\ttype ByteConnection,\n\ttype ByteConnectionHandler,\n\ttype ConnectionState,\n\tisTerminalConnection,\n} from \"./server-connection.ts\";\nimport {\n\tINTERNAL_SERVER_ERROR_MESSAGE as FALLBACK_ERROR_TEXT,\n\tServerError,\n\tWrongServerError,\n} from \"./server-errors.ts\";\nimport type {\n\tServerListener,\n} from \"./server-listener.ts\";\nimport {\n\tSessionRouter,\n} from \"./session-routing.ts\";\nimport type {\n\tRoutedServerPresentation,\n\tServerHost,\n\tServerOptions,\n} from \"./server-types.ts\";\n\nconst HANDSHAKE_TIMEOUT_DEFAULT_MS = 5000;\nconst UINT32_MAX = 0xffffffff;\nconst TIMER_DELAY_MAX_MS = 2147483647;\n\ntype ControlMessage = NonNullable<ReturnType<typeof decodeControl>>;\n\nclass ActiveSubscription {\n\treadonly subscriptionId: string;\n\t#emit: (subscriptionId: string, update: ServiceUpdate) => Promise<void>;\n\t#queued: { readonly update: ServiceUpdate }[] = [];\n\t#ready = false;\n\t#installed = false;\n\n\tconstructor(\n\t\tsubscriptionId: string,\n\t\temit: (subscriptionId: string, update: ServiceUpdate) => Promise<void>,\n\t) {\n\t\tthis.subscriptionId = subscriptionId;\n\t\tthis.#emit = emit;\n\t}\n\n\tasync publish(subscriptionId: string, update: ServiceUpdate): Promise<void> {\n\t\tconst early = subscriptionId === this.subscriptionId && !this.#ready;\n\t\tif (early) {\n\t\t\tthis.#queued.push({ update });\n\t\t\treturn;\n\t\t}\n\t\tawait this.#emit(subscriptionId, update);\n\t}\n\n\tinstall(\n\t\tresult: JsonValue | undefined,\n\t\tencoders: Map<string, ReturnType<typeof makeStateEncoder>>,\n\t): JsonValue {\n\t\tif (result === undefined) {\n\t\t\tconst missing = \"Service subscription did not return a snapshot\";\n\t\t\tthrow new ProtocolValidationError(missing);\n\t\t}\n\t\tconst encoder = makeStateEncoder();\n\t\tconst encoded = encoder.encodeSnapshot(parseSnapshot(result)) as unknown as JsonValue;\n\t\tencoders.set(this.subscriptionId, encoder);\n\t\tthis.#installed = true;\n\t\treturn encoded;\n\t}\n\n\tasync drain(): Promise<void> {\n\t\tfor (;;) {\n\t\t\tconst pending = this.#queued.shift();\n\t\t\tif (pending === undefined) break;\n\t\t\tawait this.#emit(this.subscriptionId, pending.update);\n\t\t}\n\t\tthis.#ready = true;\n\t}\n\n\trollback(encoders: Map<string, ReturnType<typeof makeStateEncoder>>, responded: boolean): void {\n\t\tconst stray = this.#installed && !responded;\n\t\tif (stray) encoders.delete(this.subscriptionId);\n\t}\n}\n\nexport class Server<\n\tTMetadata extends SessionMetadata = SessionMetadata,\n> {\n\treadonly serverId: string;\n\t/** Settles after shutdown; rejects if listener or routed-Session cleanup fails. */\n\treadonly closed: Promise<void>;\n\n\t#appHost: ServerHost<TMetadata>;\n\t#listeners: readonly ServerListener[];\n\t#maxFrameLength: number;\n\t#handshakeTimeoutMs: number;\n\t#onConnectionCountChanged: ((count: number) => void) | undefined;\n\t#onError: ((error: Error) => void) | undefined;\n\t#connections = new Set<ConnectionState>();\n\t#router: SessionRouter<TMetadata>;\n\t#draining = false;\n\t#closeTask?: Promise<void>;\n\t#closedDone = false;\n\t#failClosed!: (error: unknown) => void;\n\t#finishClosed!: () => void;\n\t#startTask?: Promise<this>;\n\t#isStarted = false;\n\n\tconstructor(\n\t\thost: ServerHost<TMetadata>,\n\t\toptions: ServerOptions,\n\t) {\n\t\tconst limits = checkOptions(options);\n\t\tthis.#appHost = host;\n\t\tthis.#listeners = options.listeners;\n\t\tconst { serverId } = options;\n\t\tthis.serverId = serverId;\n\t\tthis.#maxFrameLength = limits.maxFrameLength;\n\t\tthis.#handshakeTimeoutMs = limits.handshakeTimeoutMs;\n\t\tthis.#onConnectionCountChanged = options.onConnectionCountChanged;\n\t\tthis.#onError = options.onError;\n\t\tthis.#router = new SessionRouter({\n\t\t\thost,\n\t\t\tserverId: this.serverId,\n\t\t\tisClosing: () => this.#draining,\n\t\t\tpublishAttachment: (client, attachment, context) =>\n\t\t\t\tthis.#transmit(client as ConnectionState, {\n\t\t\t\t\ttype: \"attachment\",\n\t\t\t\t\tattachment: attachment === undefined ? null : attachment,\n\t\t\t\t}).then(() => undefined),\n\t\t\treportError: (error) => this.#noteError(error),\n\t\t});\n\t\tlet resolveClosed!: () => void;\n\t\tlet rejectClosed!: (error: unknown) => void;\n\t\tthis.closed = new Promise<void>((resolve, reject) => {\n\t\t\tresolveClosed = resolve;\n\t\t\trejectClosed = reject;\n\t\t});\n\t\tthis.#finishClosed = resolveClosed;\n\t\tthis.#failClosed = rejectClosed;\n\t\tvoid this.closed.then(\n\t\t\t() => undefined,\n\t\t\t() => undefined,\n\t\t);\n\t}\n\n\tstart(): Promise<this> {\n\t\tif (this.#isStarted) return Promise.reject(new Error(\"Server is already started\"));\n\t\tif (this.#startTask !== undefined) return Promise.reject(new Error(\"Server is already starting\"));\n\t\tif (this.#draining) return Promise.reject(new Error(\"Server is closing or closed\"));\n\t\tconst task = this.#boot();\n\t\tthis.#startTask = task;\n\t\treturn task;\n\t}\n\n\tasync #boot(): Promise<this> {\n\t\tconst online: ServerListener[] = [];\n\t\ttry {\n\t\t\tfor (const listener of this.#listeners) {\n\t\t\t\tconst accept = (connection: ByteConnection): ByteConnectionHandler => this.accept(connection);\n\t\t\t\tawait listener.start(accept);\n\t\t\t\tonline.push(listener);\n\t\t\t}\n\t\t\tthis.#isStarted = true;\n\t\t\treturn this;\n\t\t} catch (error) {\n\t\t\tthis.#draining = true;\n\t\t\tconst failures: unknown[] = [];\n\t\t\tconst shutdowns = await Promise.allSettled(online.map((listener) => listener.close()));\n\t\t\tfor (const shutdown of shutdowns) {\n\t\t\t\tif (shutdown.status === \"rejected\") failures.push(shutdown.reason);\n\t\t\t}\n\t\t\ttry {\n\t\t\t\tawait this.#tearDown();\n\t\t\t} catch (cleanupError) {\n\t\t\t\tfailures.push(cleanupError);\n\t\t\t}\n\t\t\tif (failures.length > 0) {\n\t\t\t\tconst failure = new AggregateError([error, ...failures], \"Server startup and cleanup failed\");\n\t\t\t\tthis.#settleClosedPromise(failure);\n\t\t\t\tthrow failure;\n\t\t\t}\n\t\t\tthis.#settleClosedPromise();\n\t\t\tthrow error;\n\t\t} finally {\n\t\t\tthis.#startTask = undefined;\n\t\t}\n\t}\n\n\taccept(\n\t\tconnection: ByteConnection,\n\t): ByteConnectionHandler {\n\t\tif (this.#draining) {\n\t\t\tvoid this.#terminate(connection);\n\t\t\tconst inert: ByteConnectionHandler = {\n\t\t\t\tonData: () => {},\n\t\t\t\tonClose: () => {},\n\t\t\t\tonError: (error) => this.#noteError(error),\n\t\t\t};\n\t\t\treturn inert;\n\t\t}\n\n\t\tconst state = this.#newConnectionState(connection);\n\t\tthis.#connections.add(state);\n\t\tthis.#emitCountChanged();\n\n\t\treturn {\n\t\t\tonData: (chunk) => this.#ingest(state, chunk),\n\t\t\tonClose: () => this.#noteTransportClosed(state),\n\t\t\tonError: (error) => {\n\t\t\t\tthis.#noteError(error);\n\t\t\t\tvoid this.#terminate(connection).then(() => this.#drop(state));\n\t\t\t},\n\t\t};\n\t}\n\n\t#newConnectionState(connection: ByteConnection): ConnectionState {\n\t\tlet state!: ConnectionState;\n\t\tconst onTimeout = (): void => {\n\t\t\tconst error: ProtocolError = { code: \"invalid_request\", message: \"Handshake timeout\" };\n\t\t\tvoid this.#abortWithProtocolError(state, error);\n\t\t};\n\t\tconst timer = setTimeout(onTimeout, this.#handshakeTimeoutMs);\n\t\ttimer.unref();\n\t\tconst encoders = new Map();\n\t\tconst activeRequests = new Map();\n\t\tstate = {\n\t\t\tconnection,\n\t\t\tdecoder: new ClientMessageDecoder({ maxFrameLength: this.#maxFrameLength }),\n\t\t\tserviceStateEncoders: encoders,\n\t\t\tstage: \"awaitingHello\",\n\t\t\tdisconnected: false,\n\t\t\thandshakeTimeout: timer,\n\t\t\tactiveRequests,\n\t\t};\n\t\treturn state;\n\t}\n\n\t#clearHandshakeTimeout(state: ConnectionState): void {\n\t\tclearTimeout(state.handshakeTimeout);\n\t}\n\n\t#beginClosing(state: ConnectionState): void {\n\t\tstate.stage = \"closing\";\n\t\tthis.#clearHandshakeTimeout(state);\n\t}\n\n\tasync close(): Promise<void> {\n\t\tconst existing = this.#closeTask;\n\t\tif (existing !== undefined) return existing;\n\t\tthis.#draining = true;\n\t\tconst task = this.#closeInternal();\n\t\tthis.#closeTask = task;\n\t\treturn task;\n\t}\n\n\tasync #closeInternal(): Promise<void> {\n\t\tconst starting = this.#startTask;\n\t\tif (starting !== undefined) await starting.catch(() => {});\n\t\tconst failures: unknown[] = [];\n\t\tconst shutdowns = await Promise.allSettled(this.#listeners.map((listener) => listener.close()));\n\t\tfor (const shutdown of shutdowns) {\n\t\t\tif (shutdown.status === \"rejected\") failures.push(shutdown.reason);\n\t\t}\n\t\ttry {\n\t\t\tawait this.#tearDown();\n\t\t} catch (error) {\n\t\t\tfailures.push(error);\n\t\t}\n\t\tthis.#isStarted = false;\n\t\tif (failures.length === 0) {\n\t\t\tthis.#settleClosedPromise();\n\t\t\treturn;\n\t\t}\n\t\tconst [only] = failures;\n\t\tconst failure =\n\t\t\tfailures.length === 1 && only instanceof Error\n\t\t\t\t? only\n\t\t\t\t: new AggregateError(failures, \"Server shutdown failed\");\n\t\tthis.#settleClosedPromise(failure);\n\t\tthrow failure;\n\t}\n\n\t#ingest(state: ConnectionState, chunk: Uint8Array): void {\n\t\tconst terminal = isTerminalConnection(state);\n\t\tif (terminal) return;\n\t\tlet messages: ClientMessage[] | undefined;\n\t\ttry {\n\t\t\tconst decoded = state.decoder.push(chunk);\n\t\t\tmessages = decoded;\n\t\t} catch (error) {\n\t\t\tvoid this.#abortWithProtocolError(state, this.#asProtocolError(error));\n\t\t}\n\t\tif (messages === undefined) return;\n\t\tfor (const message of messages) {\n\t\t\tconst done = isTerminalConnection(state);\n\t\t\tif (done) return;\n\t\t\tthis.#routeMessage(state, message);\n\t\t}\n\t}\n\n\t#routeMessage(state: ConnectionState, message: ClientMessage): void {\n\t\tconst awaitingHello = state.stage === \"awaitingHello\";\n\t\tif (awaitingHello) {\n\t\t\tthis.#routeHello(state, message);\n\t\t\treturn;\n\t\t}\n\t\tconst repeatedHello = message.type === \"hello\";\n\t\tif (repeatedHello) {\n\t\t\tconst error: ProtocolError = {\n\t\t\t\tcode: \"invalid_request\",\n\t\t\t\tmessage: \"hello is only valid as the first message\",\n\t\t\t};\n\t\t\tvoid this.#abortWithProtocolError(state, error);\n\t\t\treturn;\n\t\t}\n\t\tconst ready = state.stage === \"ready\";\n\t\tif (ready) {\n\t\t\tthis.#routeReadyMessage(state, message);\n\t\t\treturn;\n\t\t}\n\t\tconst handshaking = state.stage === \"handshaking\";\n\t\tif (!handshaking) return;\n\t\tconst { handshake } = state;\n\t\tif (handshake === undefined) return;\n\t\tvoid handshake.then((): void => {\n\t\t\tconst settled = state.stage === \"ready\" && !state.disconnected;\n\t\t\tif (settled) this.#routeReadyMessage(state, message);\n\t\t});\n\t}\n\n\t#routeHello(state: ConnectionState, message: ClientMessage): void {\n\t\tconst isHello = message.type === \"hello\";\n\t\tif (!isHello) {\n\t\t\tconst error: ProtocolError = {\n\t\t\t\tcode: \"invalid_request\",\n\t\t\t\tmessage: \"the first client message must be a hello\",\n\t\t\t};\n\t\t\tvoid this.#abortWithProtocolError(state, error);\n\t\t\treturn;\n\t\t}\n\t\tstate.stage = \"handshaking\";\n\t\tconst completed = this.#completeHandshake(state, message);\n\t\tstate.handshake = completed.catch((error: unknown) =>\n\t\t\tthis.#abortWithProtocolError(state, this.#asProtocolError(error)),\n\t\t);\n\t}\n\n\t#routeReadyMessage(state: ConnectionState, message: ClientMessage): void {\n\t\tif (message.type === \"cancel\") {\n\t\t\tthis.#applyCancel(state, message);\n\t\t\treturn;\n\t\t}\n\t\t// The caller excluded hello; only a request envelope remains.\n\t\tvoid this.#serveRequest(state, message as RequestEnvelope);\n\t}\n\n\tasync #completeHandshake(state: ConnectionState, hello: ClientHello): Promise<void> {\n\t\tconst supported = isSupportedProtocolVersion(hello.version);\n\t\tif (!supported) {\n\t\t\tconst detail = `Unsupported protocol version ${hello.version}; expected ${PROTOCOL_VERSION}`;\n\t\t\tawait this.#abortWithProtocolError(state, {\n\t\t\t\tcode: \"version\",\n\t\t\t\tmessage: detail,\n\t\t\t});\n\t\t\treturn;\n\t\t}\n\n\t\tconst viable =\n\t\t\t!this.#draining && !state.disconnected && state.stage === \"handshaking\" && !state.connection.closed;\n\t\tif (!viable) return;\n\t\tconst presentation: RoutedServerPresentation = {\n\t\t\tattachSession: (sessionId, context) => this.#router.attachClient(state, sessionId, context),\n\t\t\tdetachSession: (context) => this.#router.detachClient(state, context),\n\t\t\tprepareSessionRemoval: (sessionId, context) => this.#router.removeSession(sessionId, context),\n\t\t};\n\t\tconst services = await this.#appHost.serverServices.attachClient(presentation, TODO_CONTEXT);\n\t\tconst stillViable =\n\t\t\t!this.#draining && !state.disconnected && state.stage === \"handshaking\" && !state.connection.closed;\n\t\tif (!stillViable) {\n\t\t\tconst context = TODO_CONTEXT;\n\t\t\tawait services.release(context);\n\t\t\treturn;\n\t\t}\n\t\tstate.serverServices = services;\n\t\tconst greeting = {\n\t\t\ttype: \"hello\",\n\t\t\tversion: PROTOCOL_VERSION,\n\t\t\tserverId: this.serverId,\n\t\t} satisfies ServerHello;\n\t\tconst sent = await this.#transmit(state, greeting);\n\t\tconst ready = sent && !state.disconnected && state.stage === \"handshaking\";\n\t\tif (ready) {\n\t\t\tstate.stage = \"ready\";\n\t\t\tthis.#clearHandshakeTimeout(state);\n\t\t}\n\t}\n\n\t#applyCancel(state: ConnectionState, envelope: CancelEnvelope): void {\n\t\tconst { id, target } = envelope;\n\t\tconst addressedHere = target.serverId === this.serverId;\n\t\tif (!addressedHere) return;\n\t\tconst active = state.activeRequests.get(id);\n\t\tconst matches = active !== undefined && sameTarget(active.target, target);\n\t\tif (matches) {\n\t\t\tconst reason = new DOMException(\"RPC request cancelled\", \"AbortError\");\n\t\t\tactive.controller.abort(reason);\n\t\t}\n\t}\n\n\tasync #serveRequest(state: ConnectionState, envelope: RequestEnvelope): Promise<void> {\n\t\tconst id = envelope.id;\n\t\tconst duplicate = state.activeRequests.has(id);\n\t\tif (duplicate) {\n\t\t\tconst error = { code: \"invalid_request\", message: \"Request ID is already active\" };\n\t\t\tawait this.#respondError(state, id, error);\n\t\t\treturn;\n\t\t}\n\t\tconst call = this.#parseCall(state, envelope);\n\t\tif (call === undefined) return;\n\t\tconst controller = new AbortController();\n\t\tconst target = envelope.target;\n\t\tconst active = { controller, target };\n\t\tstate.activeRequests.set(id, active);\n\t\tconst signal = controller.signal;\n\t\tconst context = withAbortSignal(signal, TODO_CONTEXT);\n\t\tconst control: ControlMessage | undefined = decodeControl(call);\n\t\tconst subscription =\n\t\t\tcontrol?.type === \"subscribe\"\n\t\t\t\t? new ActiveSubscription(control.subscriptionId, (subscriptionId, update) =>\n\t\t\t\t\t\tthis.#publishUpdate(state, subscriptionId, update),\n\t\t\t\t\t)\n\t\t\t\t: undefined;\n\t\tconst publish = async (\n\t\t\tsubscriptionId: string,\n\t\t\tupdate: ServiceUpdate,\n\t\t): Promise<void> => {\n\t\t\tif (subscription === undefined) {\n\t\t\t\tawait this.#publishUpdate(state, subscriptionId, update);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tawait subscription.publish(subscriptionId, update);\n\t\t};\n\t\tlet responded = false;\n\t\ttry {\n\t\t\tawait this.#invokeRouted(state, envelope, call, control, subscription, publish, context);\n\t\t\tresponded = true;\n\t\t\tif (subscription !== undefined) await subscription.drain();\n\t\t} catch (error) {\n\t\t\tsubscription?.rollback(state.serviceStateEncoders, responded);\n\t\t\tconst afterResponse = responded;\n\t\t\tif (afterResponse) {\n\t\t\t\tthis.#noteError(error);\n\t\t\t\tawait this.#terminate(state.connection);\n\t\t\t\tthis.#drop(state);\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst cancelled = controller.signal.aborted;\n\t\t\tconst failure = cancelled\n\t\t\t\t? { code: \"cancelled\", message: \"RPC request cancelled\" }\n\t\t\t\t: this.#asProtocolError(error);\n\t\t\tawait this.#respondError(state, id, failure);\n\t\t} finally {\n\t\t\tconst current = state.activeRequests.get(id);\n\t\t\tif (current === active) state.activeRequests.delete(id);\n\t\t}\n\t}\n\n\t#parseCall(state: ConnectionState, envelope: RequestEnvelope): ServiceCall | undefined {\n\t\ttry {\n\t\t\treturn parseServiceCall(envelope.call);\n\t\t} catch {\n\t\t\tconst error = { code: \"invalid_request\", message: \"Invalid service call\" };\n\t\t\tvoid this.#respondError(state, envelope.id, error);\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tasync #respondError(\n\t\tstate: ConnectionState,\n\t\tid: string,\n\t\terror: { code: string; message: string },\n\t): Promise<void> {\n\t\tawait this.#transmit(state, {\n\t\t\ttype: \"response\",\n\t\t\tid,\n\t\t\tok: false,\n\t\t\terror,\n\t\t});\n\t}\n\n\tasync #invokeRouted(\n\t\tstate: ConnectionState,\n\t\tenvelope: RequestEnvelope,\n\t\tcall: ServiceCall,\n\t\tcontrol: ControlMessage | undefined,\n\t\tsubscription: ActiveSubscription | undefined,\n\t\tpublish: (subscriptionId: string, update: ServiceUpdate) => Promise<void>,\n\t\tcontext: Context,\n\t): Promise<void> {\n\t\tconst addressedHere = envelope.target.serverId === this.serverId;\n\t\tif (!addressedHere) throw new WrongServerError();\n\t\tconst duplicateSubscription =\n\t\t\tsubscription !== undefined && state.serviceStateEncoders.has(subscription.subscriptionId);\n\t\tif (duplicateSubscription) {\n\t\t\tthrow new ProtocolValidationError(`Duplicate service subscription ${subscription.subscriptionId}`);\n\t\t}\n\t\tlet result: JsonValue | undefined = undefined;\n\t\tconst sessionTarget = \"sessionId\" in envelope.target;\n\t\tif (sessionTarget) {\n\t\t\tresult = await this.#router.executeServiceCall(call, envelope.target, state, publish, context);\n\t\t} else {\n\t\t\tconst services = state.serverServices;\n\t\t\tif (services === undefined) {\n\t\t\t\tconst unknown = `Unknown service member ${call.serviceId}.${call.member}`;\n\t\t\t\tthrow new ProtocolValidationError(unknown);\n\t\t\t}\n\t\t\tresult = await services.invokeService(call, publish, context);\n\t\t}\n\t\tif (subscription !== undefined) {\n\t\t\tresult = subscription.install(result, state.serviceStateEncoders);\n\t\t} else if (control?.type === \"unsubscribe\") {\n\t\t\tconst { subscriptionId } = control;\n\t\t\tstate.serviceStateEncoders.delete(subscriptionId);\n\t\t}\n\t\tlet response: ResponseEnvelope;\n\t\tif (result === undefined) {\n\t\t\tresponse = { type: \"response\", id: envelope.id, ok: true };\n\t\t} else {\n\t\t\tresponse = { type: \"response\", id: envelope.id, ok: true, result };\n\t\t}\n\t\tawait this.#transmit(state, response);\n\t}\n\n\t#noteTransportClosed(connection: ConnectionState): void {\n\t\tconst orderly = connection.disconnected || connection.stage === \"closing\";\n\t\tif (!orderly) {\n\t\t\ttry {\n\t\t\t\tconst { decoder } = connection;\n\t\t\t\tdecoder.end();\n\t\t\t} catch (error) {\n\t\t\t\tthis.#noteError(error);\n\t\t\t}\n\t\t}\n\t\tthis.#drop(connection);\n\t}\n\n\t#drop(connection: ConnectionState): void {\n\t\tconst dropped = connection.disconnected;\n\t\tif (dropped) return;\n\t\tconnection.disconnected = true;\n\t\tconnection.stage = \"closed\";\n\t\tthis.#clearHandshakeTimeout(connection);\n\t\tfor (const active of connection.activeRequests.values()) {\n\t\t\tactive.controller.abort(new Error(\"Client disconnected\"));\n\t\t}\n\t\tconnection.activeRequests.clear();\n\t\tconnection.serviceStateEncoders.clear();\n\t\tconst removed = this.#connections.delete(connection);\n\t\tif (removed) this.#emitCountChanged();\n\t\tconst { serverServices } = connection;\n\t\tdelete connection.serverServices;\n\t\tconst releases = [this.#router.disconnect(connection, TODO_CONTEXT)];\n\t\tif (serverServices !== undefined) releases.push(Promise.resolve(serverServices.release(TODO_CONTEXT)));\n\t\tconst cleanup = Promise.allSettled(releases);\n\t\tvoid cleanup.then((results) => {\n\t\t\tfor (const result of results) {\n\t\t\t\tif (result.status === \"rejected\") this.#noteError(result.reason);\n\t\t\t}\n\t\t});\n\t}\n\n\tasync #publishUpdate(\n\t\tconnection: ConnectionState,\n\t\tsubscriptionId: string,\n\t\tupdate: ServiceUpdate,\n\t): Promise<void> {\n\t\tconst encoders = connection.serviceStateEncoders;\n\t\tconst stateEncoder = encoders.get(subscriptionId);\n\t\tconst missing = stateEncoder === undefined;\n\t\tif (missing) return;\n\t\tconst encoded = stateEncoder.encodeUpdate(update) as unknown as JsonValue;\n\t\tawait this.#transmit(connection, {\n\t\t\ttype: \"service_update\",\n\t\t\tsubscriptionId,\n\t\t\tupdate: encoded,\n\t\t});\n\t}\n\n\tasync #transmit(connection: ConnectionState, message: ServerMessage): Promise<boolean> {\n\t\tconst writable = !connection.disconnected && !connection.connection.closed;\n\t\tif (!writable) return false;\n\t\tconst frame = this.#encodeFrame(connection, message);\n\t\tif (frame === undefined) return false;\n\t\ttry {\n\t\t\tconst transport = connection.connection;\n\t\t\tawait transport.send(frame);\n\t\t\treturn true;\n\t\t} catch (error) {\n\t\t\tthis.#noteError(error);\n\t\t\tawait this.#terminate(connection.connection);\n\t\t\tthis.#drop(connection);\n\t\t\treturn false;\n\t\t}\n\t}\n\n\t#encodeFrame(connection: ConnectionState, message: ServerMessage): Uint8Array | undefined {\n\t\ttry {\n\t\t\treturn encodeServerMessage(message, { maxFrameLength: this.#maxFrameLength });\n\t\t} catch (error) {\n\t\t\tthis.#noteError(error);\n\t\t\tvoid this.#terminate(connection.connection).then(() => this.#drop(connection));\n\t\t\treturn undefined;\n\t\t}\n\t}\n\n\tasync #abortWithProtocolError(connection: ConnectionState, error: ProtocolError): Promise<void> {\n\t\tconst terminal = connection.disconnected || connection.stage === \"closing\" || connection.stage === \"closed\";\n\t\tif (terminal) return;\n\t\tthis.#beginClosing(connection);\n\t\tconst message = { type: \"hello_error\", error } satisfies ServerHelloError;\n\t\tlet finalFrame: Uint8Array | undefined;\n\t\ttry {\n\t\t\tfinalFrame = encodeServerMessage(message, { maxFrameLength: this.#maxFrameLength });\n\t\t} catch (encodeError) {\n\t\t\tthis.#noteError(encodeError);\n\t\t}\n\t\tawait this.#terminate(connection.connection, finalFrame);\n\t\tthis.#drop(connection);\n\t}\n\n\tasync #tearDown(): Promise<void> {\n\t\tconst connections = [...this.#connections];\n\t\tfor (const connection of connections) this.#beginClosing(connection);\n\t\tconst shutdowns = connections.map((connection) => this.#terminate(connection.connection));\n\t\tawait Promise.all(shutdowns);\n\t\tfor (const connection of connections) this.#drop(connection);\n\t\tconst cleanup = await Promise.allSettled([this.#router.close(BACKGROUND_CONTEXT)]);\n\t\tthis.#connections.clear();\n\t\tthrowTearDownErrors(cleanup);\n\t}\n\n\tasync #terminate(connection: ByteConnection, finalChunk?: Uint8Array): Promise<void> {\n\t\tconst closing = connection.close(finalChunk);\n\t\ttry {\n\t\t\tawait closing;\n\t\t} catch (error) {\n\t\t\tthis.#noteError(error);\n\t\t}\n\t}\n\n\t#asProtocolError(error: unknown): ProtocolError {\n\t\tconst serviceError = error instanceof ServerError || error instanceof RemoteServiceError;\n\t\tif (serviceError) {\n\t\t\tconst typed = error as ServerError | RemoteServiceError;\n\t\t\treturn { code: typed.code, message: typed.message };\n\t\t}\n\t\tconst invalid = error instanceof ProtocolValidationError;\n\t\tif (invalid) {\n\t\t\tconst message = (error as ProtocolValidationError).message;\n\t\t\treturn { code: \"invalid_request\", message };\n\t\t}\n\t\tthis.#noteError(error);\n\t\treturn { code: \"internal_error\", message: FALLBACK_ERROR_TEXT };\n\t}\n\n\t#emitCountChanged(): void {\n\t\ttry {\n\t\t\tthis.#onConnectionCountChanged?.(this.#connections.size);\n\t\t} catch (error) {\n\t\t\tthis.#noteError(error);\n\t\t}\n\t}\n\n\t#noteError(error: unknown): void {\n\t\tconst normalized = error instanceof Error ? error : new Error(String(error));\n\t\ttry {\n\t\t\tthis.#onError?.(normalized);\n\t\t} catch {\n\t\t\t// Observer failures stay local; server state is unaffected.\n\t\t}\n\t}\n\n\t#settleClosedPromise(error?: unknown): void {\n\t\tif (this.#closedDone) return;\n\t\tthis.#closedDone = true;\n\t\tif (error === undefined) this.#finishClosed();\n\t\telse this.#failClosed(error);\n\t}\n}\n\nfunction sameTarget(left: RpcTarget, right: RpcTarget): boolean {\n\tconst sameServer = left.serverId === right.serverId;\n\tif (!sameServer) return false;\n\tconst leftSession = \"sessionId\" in left;\n\tconst rightSession = \"sessionId\" in right;\n\tif (!leftSession || !rightSession) return leftSession === rightSession;\n\treturn left.sessionId === right.sessionId && left.attachmentId === right.attachmentId;\n}\n\ntype ServerLimits = {\n\tmaxFrameLength: number;\n\thandshakeTimeoutMs: number;\n};\n\nfunction checkOptions(options: ServerOptions): ServerLimits {\n\tconst listenersValid = Array.isArray(options.listeners);\n\tif (!listenersValid) throw new TypeError(\"Server listeners must be an array\");\n\tconst validId = isServerId(options.serverId);\n\tif (!validId) {\n\t\tthrow new TypeError(\"serverId must be a canonical lowercase UUIDv4\");\n\t}\n\tconst maxFrameLength = options.maxFrameLength ?? PROTOCOL_FRAME_LIMIT;\n\tconst frameLimitValid = Number.isSafeInteger(maxFrameLength) && maxFrameLength > 0 && maxFrameLength <= UINT32_MAX;\n\tif (!frameLimitValid) {\n\t\tthrow new TypeError(`Server maxFrameLength must be an integer between 1 and ${UINT32_MAX}`);\n\t}\n\tconst handshakeTimeoutMs = options.handshakeTimeoutMs ?? HANDSHAKE_TIMEOUT_DEFAULT_MS;\n\tconst timeoutValid =\n\t\tNumber.isSafeInteger(handshakeTimeoutMs) && handshakeTimeoutMs > 0 && handshakeTimeoutMs <= TIMER_DELAY_MAX_MS;\n\tif (!timeoutValid) {\n\t\tthrow new TypeError(`Server handshakeTimeoutMs must be an integer between 1 and ${TIMER_DELAY_MAX_MS}`);\n\t}\n\tconst limits: ServerLimits = { maxFrameLength, handshakeTimeoutMs };\n\treturn limits;\n}\n\nfunction throwTearDownErrors(cleanup: PromiseSettledResult<unknown>[]): void {\n\tconst failures: unknown[] = [];\n\tfor (const result of cleanup) {\n\t\tif (result.status === \"rejected\") failures.push(result.reason);\n\t}\n\tif (failures.length === 1) throw failures[0];\n\tif (failures.length > 1) {\n\t\tthrow new AggregateError(failures, \"Failed to close server Sessions\");\n\t}\n}\n"]}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type { WireChannel, } from "./test-client.ts";
|
|
2
|
+
export { connectUnixTestClient, ProtocolTestClient, } from "./test-client.ts";
|
|
3
|
+
export { createTestServerServices, Deferred, TestHarness, TestServerHost, } from "./test-host.ts";
|
|
4
|
+
export type { TestServer, TestServerOptions, } from "./test-server.ts";
|
|
5
|
+
export { createTestServer, } from "./test-server.ts";
|
|
6
|
+
//# sourceMappingURL=public-api.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-api.d.ts","sourceRoot":"","sources":["../../src/testing/public-api.ts"],"names":[],"mappings":"AAAA,YAAY,EACX,WAAW,GACX,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,qBAAqB,EACrB,kBAAkB,GAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,wBAAwB,EACxB,QAAQ,EACR,WAAW,EACX,cAAc,GACd,MAAM,gBAAgB,CAAC;AACxB,YAAY,EACX,UAAU,EACV,iBAAiB,GACjB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,gBAAgB,GAChB,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
export { connectUnixTestClient, ProtocolTestClient, } from "./test-client.js";
|
|
2
|
+
export { createTestServerServices, Deferred, TestHarness, TestServerHost, } from "./test-host.js";
|
|
3
|
+
export { createTestServer, } from "./test-server.js";
|
|
4
|
+
//# sourceMappingURL=public-api.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"public-api.js","sourceRoot":"","sources":["../../src/testing/public-api.ts"],"names":[],"mappings":"AAGA,OAAO,EACN,qBAAqB,EACrB,kBAAkB,GAClB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACN,wBAAwB,EACxB,QAAQ,EACR,WAAW,EACX,cAAc,GACd,MAAM,gBAAgB,CAAC;AAKxB,OAAO,EACN,gBAAgB,GAChB,MAAM,kBAAkB,CAAC","sourcesContent":["export type {\n\tWireChannel,\n} from \"./test-client.ts\";\nexport {\n\tconnectUnixTestClient,\n\tProtocolTestClient,\n} from \"./test-client.ts\";\nexport {\n\tcreateTestServerServices,\n\tDeferred,\n\tTestHarness,\n\tTestServerHost,\n} from \"./test-host.ts\";\nexport type {\n\tTestServer,\n\tTestServerOptions,\n} from \"./test-server.ts\";\nexport {\n\tcreateTestServer,\n} from \"./test-server.ts\";\n"]}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ServiceCall } from "@crow-agent/chord";
|
|
2
|
+
import { type ClientMessage, type ResponseEnvelope, type RpcTarget, type ServerMessage } from "@crow-agent/protocol";
|
|
3
|
+
export type WireChannel = {
|
|
4
|
+
send(chunk: Uint8Array): Promise<void>;
|
|
5
|
+
sendFragmented(chunk: Uint8Array, splitAt: number): Promise<void>;
|
|
6
|
+
close(): Promise<void>;
|
|
7
|
+
};
|
|
8
|
+
export declare class ProtocolTestClient {
|
|
9
|
+
#private;
|
|
10
|
+
constructor(channel: WireChannel);
|
|
11
|
+
get messages(): Array<ServerMessage>;
|
|
12
|
+
get closed(): boolean;
|
|
13
|
+
hello(version?: number): Promise<ServerMessage>;
|
|
14
|
+
requestService(target: RpcTarget, call: ServiceCall, id?: string): Promise<ResponseEnvelope>;
|
|
15
|
+
attach(serverId: string, sessionId: string): Promise<ResponseEnvelope>;
|
|
16
|
+
requestSessionService(serverId: string, sessionId: string, call: ServiceCall, id?: string): Promise<ResponseEnvelope>;
|
|
17
|
+
sendMessage(message: ClientMessage): Promise<void>;
|
|
18
|
+
sendBytes(chunk: Uint8Array): Promise<void>;
|
|
19
|
+
sendFragmentedMessage(message: ClientMessage, splitAt: number): Promise<void>;
|
|
20
|
+
next(predicate: (message: ServerMessage) => boolean): Promise<ServerMessage>;
|
|
21
|
+
nextFrom(index: number, predicate: (message: ServerMessage) => boolean): Promise<ServerMessage>;
|
|
22
|
+
waitForClose(): Promise<void>;
|
|
23
|
+
close(): Promise<void>;
|
|
24
|
+
receive(chunk: Uint8Array): void;
|
|
25
|
+
markClosed(): void;
|
|
26
|
+
fail(error: Error): void;
|
|
27
|
+
}
|
|
28
|
+
export declare function connectUnixTestClient(path: string): Promise<ProtocolTestClient>;
|
|
29
|
+
//# sourceMappingURL=test-client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-client.d.ts","sourceRoot":"","sources":["../../src/testing/test-client.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAEX,WAAW,EACX,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACN,KAAK,aAAa,EAGlB,KAAK,gBAAgB,EACrB,KAAK,SAAS,EACd,KAAK,aAAa,EAElB,MAAM,sBAAsB,CAAC;AAiB9B,MAAM,MAAM,WAAW,GAAG;IACzB,IAAI,CACH,KAAK,EAAE,UAAU,GACf,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,cAAc,CACb,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACvB,CAAC;AA6EF,qBAAa,kBAAkB;;IAW9B,YACC,OAAO,EAAE,WAAW,EAGpB;IAED,IAAI,QAAQ,IAAI,KAAK,CAAC,aAAa,CAAC,CAEnC;IAED,IAAI,MAAM,IAAI,OAAO,CAEpB;IAED,KAAK,CACJ,OAAO,GAAE,MAAyB,GAChC,OAAO,CAAC,aAAa,CAAC,CAOxB;IAEK,cAAc,CACnB,MAAM,EAAE,SAAS,EACjB,IAAI,EAAE,WAAW,EACjB,EAAE,CAAC,EAAE,MAAM,GACT,OAAO,CAAC,gBAAgB,CAAC,CAY3B;IAED,MAAM,CACL,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GACf,OAAO,CAAC,gBAAgB,CAAC,CAQ3B;IAED,qBAAqB,CACpB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,IAAI,EAAE,WAAW,EACjB,EAAE,CAAC,EAAE,MAAM,GACT,OAAO,CAAC,gBAAgB,CAAC,CAQ3B;IAED,WAAW,CACV,OAAO,EAAE,aAAa,GACpB,OAAO,CAAC,IAAI,CAAC,CAGf;IAED,SAAS,CACR,KAAK,EAAE,UAAU,GACf,OAAO,CAAC,IAAI,CAAC,CAEf;IAED,qBAAqB,CACpB,OAAO,EAAE,aAAa,EACtB,OAAO,EAAE,MAAM,GACb,OAAO,CAAC,IAAI,CAAC,CAGf;IAED,IAAI,CACH,SAAS,EAAE,CACV,OAAO,EAAE,aAAa,KAClB,OAAO,GACV,OAAO,CAAC,aAAa,CAAC,CAExB;IAED,QAAQ,CACP,KAAK,EAAE,MAAM,EACb,SAAS,EAAE,CACV,OAAO,EAAE,aAAa,KAClB,OAAO,GACV,OAAO,CAAC,aAAa,CAAC,CAExB;IAED,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAE5B;IAED,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAErB;IAED,OAAO,CACN,KAAK,EAAE,UAAU,GACf,IAAI,CAUN;IAED,UAAU,IAAI,IAAI,CAEjB;IAED,IAAI,CACH,KAAK,EAAE,KAAK,GACV,IAAI,CAEN;CACD;AAED,wBAAsB,qBAAqB,CAC1C,IAAI,EAAE,MAAM,GACV,OAAO,CAAC,kBAAkB,CAAC,CA4B7B"}
|
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
import { once, } from "node:events";
|
|
2
|
+
import { createConnection, } from "node:net";
|
|
3
|
+
import { encodeClientMessage, PROTOCOL_VERSION, ServerMessageDecoder, } from "@crow-agent/protocol";
|
|
4
|
+
import { Deferred, } from "./test-host.js";
|
|
5
|
+
/** Decodes inbound bytes, records messages, and wakes matching waiters. */
|
|
6
|
+
class InboundQueue {
|
|
7
|
+
seen = [];
|
|
8
|
+
#decoder = new ServerMessageDecoder();
|
|
9
|
+
#waiters = new Set();
|
|
10
|
+
#done = new Deferred();
|
|
11
|
+
#finished = false;
|
|
12
|
+
get finished() {
|
|
13
|
+
return this.#finished;
|
|
14
|
+
}
|
|
15
|
+
get donePromise() {
|
|
16
|
+
if (this.#finished)
|
|
17
|
+
return Promise.resolve();
|
|
18
|
+
return this.#done.promise;
|
|
19
|
+
}
|
|
20
|
+
waitFrom(index, test) {
|
|
21
|
+
const found = this.seen.slice(index).find(test);
|
|
22
|
+
if (found !== undefined)
|
|
23
|
+
return Promise.resolve(found);
|
|
24
|
+
if (this.#finished)
|
|
25
|
+
return Promise.reject(new Error("Wire client is closed"));
|
|
26
|
+
const pending = new Promise((resolve, reject) => {
|
|
27
|
+
this.#waiters.add({ test, resolve, reject });
|
|
28
|
+
});
|
|
29
|
+
return pending;
|
|
30
|
+
}
|
|
31
|
+
/** Feeds raw bytes through the decoder and returns whatever they carried. */
|
|
32
|
+
pushBytes(chunk) {
|
|
33
|
+
let decoded;
|
|
34
|
+
try {
|
|
35
|
+
decoded = this.#decoder.push(chunk);
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
const failure = error instanceof Error ? error : new Error(String(error));
|
|
39
|
+
this.rejectAll(failure);
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
for (const message of decoded)
|
|
43
|
+
this.deliver(message);
|
|
44
|
+
return decoded;
|
|
45
|
+
}
|
|
46
|
+
deliver(message) {
|
|
47
|
+
this.seen.push(message);
|
|
48
|
+
for (const waiter of Array.from(this.#waiters)) {
|
|
49
|
+
const matches = waiter.test(message);
|
|
50
|
+
if (!matches)
|
|
51
|
+
continue;
|
|
52
|
+
this.#waiters.delete(waiter);
|
|
53
|
+
waiter.resolve(message);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
rejectAll(error) {
|
|
57
|
+
for (const waiter of this.#waiters)
|
|
58
|
+
waiter.reject(error);
|
|
59
|
+
this.#waiters.clear();
|
|
60
|
+
}
|
|
61
|
+
finish() {
|
|
62
|
+
if (this.#finished)
|
|
63
|
+
return;
|
|
64
|
+
this.#finished = true;
|
|
65
|
+
this.#done.resolve(undefined);
|
|
66
|
+
this.rejectAll(new Error("Wire connection closed"));
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
export class ProtocolTestClient {
|
|
70
|
+
#channel;
|
|
71
|
+
#inbound = new InboundQueue();
|
|
72
|
+
#requestSequence = 0;
|
|
73
|
+
#attachment;
|
|
74
|
+
constructor(channel) {
|
|
75
|
+
this.#channel = channel;
|
|
76
|
+
}
|
|
77
|
+
get messages() {
|
|
78
|
+
return this.#inbound.seen;
|
|
79
|
+
}
|
|
80
|
+
get closed() {
|
|
81
|
+
return this.#inbound.finished;
|
|
82
|
+
}
|
|
83
|
+
hello(version = PROTOCOL_VERSION) {
|
|
84
|
+
const greeting = this.next((message) => message.type === "hello" || message.type === "hello_error");
|
|
85
|
+
const wireHello = { type: "hello", version };
|
|
86
|
+
void this.sendMessage(wireHello);
|
|
87
|
+
return greeting;
|
|
88
|
+
}
|
|
89
|
+
async requestService(target, call, id) {
|
|
90
|
+
const sequence = ++this.#requestSequence;
|
|
91
|
+
const requestId = id ?? `request-${sequence}`;
|
|
92
|
+
const isReply = (message) => message.type === "response" && message.id === requestId;
|
|
93
|
+
const response = this.next(isReply);
|
|
94
|
+
const wireCall = call;
|
|
95
|
+
const wireRequest = { type: "request", id: requestId, target, call: wireCall };
|
|
96
|
+
await this.sendMessage(wireRequest);
|
|
97
|
+
const envelope = await response;
|
|
98
|
+
return envelope;
|
|
99
|
+
}
|
|
100
|
+
attach(serverId, sessionId) {
|
|
101
|
+
const target = { serverId };
|
|
102
|
+
const call = {
|
|
103
|
+
serviceId: "crow.session-management",
|
|
104
|
+
member: "attach",
|
|
105
|
+
args: [sessionId],
|
|
106
|
+
};
|
|
107
|
+
return this.requestService(target, call);
|
|
108
|
+
}
|
|
109
|
+
requestSessionService(serverId, sessionId, call, id) {
|
|
110
|
+
const attachment = this.#attachment;
|
|
111
|
+
const usable = attachment !== undefined && attachment.sessionId === sessionId;
|
|
112
|
+
const target = usable
|
|
113
|
+
? { serverId, sessionId: attachment.sessionId, attachmentId: attachment.attachmentId }
|
|
114
|
+
: { serverId, sessionId, attachmentId: "missing-attachment" };
|
|
115
|
+
const response = this.requestService(target, call, id);
|
|
116
|
+
return response;
|
|
117
|
+
}
|
|
118
|
+
sendMessage(message) {
|
|
119
|
+
const encoded = encodeClientMessage(message);
|
|
120
|
+
return this.#channel.send(encoded);
|
|
121
|
+
}
|
|
122
|
+
sendBytes(chunk) {
|
|
123
|
+
return this.#channel.send(chunk);
|
|
124
|
+
}
|
|
125
|
+
sendFragmentedMessage(message, splitAt) {
|
|
126
|
+
const encoded = encodeClientMessage(message);
|
|
127
|
+
return this.#channel.sendFragmented(encoded, splitAt);
|
|
128
|
+
}
|
|
129
|
+
next(predicate) {
|
|
130
|
+
return this.#inbound.waitFrom(0, predicate);
|
|
131
|
+
}
|
|
132
|
+
nextFrom(index, predicate) {
|
|
133
|
+
return this.#inbound.waitFrom(index, predicate);
|
|
134
|
+
}
|
|
135
|
+
waitForClose() {
|
|
136
|
+
return this.#inbound.donePromise;
|
|
137
|
+
}
|
|
138
|
+
close() {
|
|
139
|
+
return this.#channel.close();
|
|
140
|
+
}
|
|
141
|
+
receive(chunk) {
|
|
142
|
+
const fresh = this.#inbound.pushBytes(chunk);
|
|
143
|
+
for (const message of fresh) {
|
|
144
|
+
if (message.type !== "attachment")
|
|
145
|
+
continue;
|
|
146
|
+
const attachment = message.attachment;
|
|
147
|
+
this.#attachment =
|
|
148
|
+
attachment === null
|
|
149
|
+
? undefined
|
|
150
|
+
: { sessionId: attachment.sessionId, attachmentId: attachment.attachmentId };
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
markClosed() {
|
|
154
|
+
this.#inbound.finish();
|
|
155
|
+
}
|
|
156
|
+
fail(error) {
|
|
157
|
+
this.#inbound.rejectAll(error);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
export async function connectUnixTestClient(path) {
|
|
161
|
+
const socket = createConnection(path);
|
|
162
|
+
await once(socket, "connect");
|
|
163
|
+
const transmit = (chunk) => writeSocket(socket, chunk);
|
|
164
|
+
const channel = {
|
|
165
|
+
send: transmit,
|
|
166
|
+
sendFragmented: async (chunk, splitAt) => {
|
|
167
|
+
await transmit(chunk.subarray(0, splitAt));
|
|
168
|
+
await transmit(chunk.subarray(splitAt));
|
|
169
|
+
},
|
|
170
|
+
close: async () => {
|
|
171
|
+
const gone = socket.destroyed;
|
|
172
|
+
if (gone)
|
|
173
|
+
return;
|
|
174
|
+
const onClose = once(socket, "close");
|
|
175
|
+
socket.destroy();
|
|
176
|
+
await onClose;
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
const client = new ProtocolTestClient(channel);
|
|
180
|
+
socket.on("data", (chunk) => {
|
|
181
|
+
const bytes = new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength);
|
|
182
|
+
client.receive(bytes);
|
|
183
|
+
});
|
|
184
|
+
socket.on("error", (cause) => client.fail(cause));
|
|
185
|
+
socket.once("close", () => {
|
|
186
|
+
client.markClosed();
|
|
187
|
+
});
|
|
188
|
+
return client;
|
|
189
|
+
}
|
|
190
|
+
function writeSocket(socket, chunk) {
|
|
191
|
+
return new Promise((resolve, reject) => {
|
|
192
|
+
const done = (error) => (error ? reject(error) : resolve());
|
|
193
|
+
socket.write(chunk, done);
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
//# sourceMappingURL=test-client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-client.js","sourceRoot":"","sources":["../../src/testing/test-client.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n\tonce,\n} from \"node:events\";\nimport {\n\tcreateConnection,\n\ttype Socket,\n} from \"node:net\";\nimport type {\n\tJsonValue,\n\tServiceCall,\n} from \"@crow-agent/chord\";\nimport {\n\ttype ClientMessage,\n\tencodeClientMessage,\n\tPROTOCOL_VERSION,\n\ttype ResponseEnvelope,\n\ttype RpcTarget,\n\ttype ServerMessage,\n\tServerMessageDecoder,\n} from \"@crow-agent/protocol\";\nimport {\n\tDeferred,\n} from \"./test-host.ts\";\n\ntype PendingWaiter = {\n\ttest: (\n\t\tmessage: ServerMessage,\n\t) => boolean;\n\tresolve: (\n\t\tmessage: ServerMessage,\n\t) => void;\n\treject: (\n\t\terror: Error,\n\t) => void;\n};\n\nexport type WireChannel = {\n\tsend(\n\t\tchunk: Uint8Array,\n\t): Promise<void>;\n\tsendFragmented(\n\t\tchunk: Uint8Array,\n\t\tsplitAt: number,\n\t): Promise<void>;\n\tclose(): Promise<void>;\n};\n\n/** Decodes inbound bytes, records messages, and wakes matching waiters. */\nclass InboundQueue {\n\treadonly seen: Array<ServerMessage> = [];\n\t#decoder = new ServerMessageDecoder();\n\t#waiters = new Set<PendingWaiter>();\n\t#done = new Deferred<void>();\n\t#finished = false;\n\n\tget finished(): boolean {\n\t\treturn this.#finished;\n\t}\n\n\tget donePromise(): Promise<void> {\n\t\tif (this.#finished) return Promise.resolve();\n\t\treturn this.#done.promise;\n\t}\n\n\twaitFrom(\n\t\tindex: number,\n\t\ttest: (\n\t\t\tmessage: ServerMessage,\n\t\t) => boolean,\n\t): Promise<ServerMessage> {\n\t\tconst found = this.seen.slice(index).find(test);\n\t\tif (found !== undefined) return Promise.resolve(found);\n\t\tif (this.#finished) return Promise.reject(new Error(\"Wire client is closed\"));\n\t\tconst pending = new Promise<ServerMessage>((resolve, reject) => {\n\t\t\tthis.#waiters.add({ test, resolve, reject });\n\t\t});\n\t\treturn pending;\n\t}\n\n\t/** Feeds raw bytes through the decoder and returns whatever they carried. */\n\tpushBytes(\n\t\tchunk: Uint8Array,\n\t): Array<ServerMessage> {\n\t\tlet decoded: Array<ServerMessage>;\n\t\ttry {\n\t\t\tdecoded = this.#decoder.push(chunk);\n\t\t} catch (error) {\n\t\t\tconst failure = error instanceof Error ? error : new Error(String(error));\n\t\t\tthis.rejectAll(failure);\n\t\t\treturn [];\n\t\t}\n\t\tfor (const message of decoded) this.deliver(message);\n\t\treturn decoded;\n\t}\n\n\tprivate deliver(\n\t\tmessage: ServerMessage,\n\t): void {\n\t\tthis.seen.push(message);\n\t\tfor (const waiter of Array.from(this.#waiters)) {\n\t\t\tconst matches = waiter.test(message);\n\t\t\tif (!matches) continue;\n\t\t\tthis.#waiters.delete(waiter);\n\t\t\twaiter.resolve(message);\n\t\t}\n\t}\n\n\trejectAll(\n\t\terror: Error,\n\t): void {\n\t\tfor (const waiter of this.#waiters) waiter.reject(error);\n\t\tthis.#waiters.clear();\n\t}\n\n\tfinish(): void {\n\t\tif (this.#finished) return;\n\t\tthis.#finished = true;\n\t\tthis.#done.resolve(undefined);\n\t\tthis.rejectAll(new Error(\"Wire connection closed\"));\n\t}\n}\n\nexport class ProtocolTestClient {\n\t#channel: WireChannel;\n\t#inbound = new InboundQueue();\n\t#requestSequence = 0;\n\t#attachment:\n\t\t| {\n\t\t\t\tsessionId: string;\n\t\t\t\tattachmentId: string;\n\t\t }\n\t\t| undefined;\n\n\tconstructor(\n\t\tchannel: WireChannel,\n\t) {\n\t\tthis.#channel = channel;\n\t}\n\n\tget messages(): Array<ServerMessage> {\n\t\treturn this.#inbound.seen;\n\t}\n\n\tget closed(): boolean {\n\t\treturn this.#inbound.finished;\n\t}\n\n\thello(\n\t\tversion: number = PROTOCOL_VERSION,\n\t): Promise<ServerMessage> {\n\t\tconst greeting = this.next(\n\t\t\t(message) => message.type === \"hello\" || message.type === \"hello_error\",\n\t\t);\n\t\tconst wireHello: ClientMessage = { type: \"hello\", version };\n\t\tvoid this.sendMessage(wireHello);\n\t\treturn greeting;\n\t}\n\n\tasync requestService(\n\t\ttarget: RpcTarget,\n\t\tcall: ServiceCall,\n\t\tid?: string,\n\t): Promise<ResponseEnvelope> {\n\t\tconst sequence = ++this.#requestSequence;\n\t\tconst requestId = id ?? `request-${sequence}`;\n\t\tconst isReply = (\n\t\t\tmessage: ServerMessage,\n\t\t): message is ResponseEnvelope => message.type === \"response\" && message.id === requestId;\n\t\tconst response = this.next(isReply);\n\t\tconst wireCall = call as unknown as JsonValue;\n\t\tconst wireRequest: ClientMessage = { type: \"request\", id: requestId, target, call: wireCall };\n\t\tawait this.sendMessage(wireRequest);\n\t\tconst envelope = await response;\n\t\treturn envelope as ResponseEnvelope;\n\t}\n\n\tattach(\n\t\tserverId: string,\n\t\tsessionId: string,\n\t): Promise<ResponseEnvelope> {\n\t\tconst target = { serverId };\n\t\tconst call = {\n\t\t\tserviceId: \"crow.session-management\",\n\t\t\tmember: \"attach\",\n\t\t\targs: [sessionId],\n\t\t};\n\t\treturn this.requestService(target, call);\n\t}\n\n\trequestSessionService(\n\t\tserverId: string,\n\t\tsessionId: string,\n\t\tcall: ServiceCall,\n\t\tid?: string,\n\t): Promise<ResponseEnvelope> {\n\t\tconst attachment = this.#attachment;\n\t\tconst usable = attachment !== undefined && attachment.sessionId === sessionId;\n\t\tconst target: RpcTarget = usable\n\t\t\t? { serverId, sessionId: attachment.sessionId, attachmentId: attachment.attachmentId }\n\t\t\t: { serverId, sessionId, attachmentId: \"missing-attachment\" };\n\t\tconst response = this.requestService(target, call, id);\n\t\treturn response;\n\t}\n\n\tsendMessage(\n\t\tmessage: ClientMessage,\n\t): Promise<void> {\n\t\tconst encoded = encodeClientMessage(message);\n\t\treturn this.#channel.send(encoded);\n\t}\n\n\tsendBytes(\n\t\tchunk: Uint8Array,\n\t): Promise<void> {\n\t\treturn this.#channel.send(chunk);\n\t}\n\n\tsendFragmentedMessage(\n\t\tmessage: ClientMessage,\n\t\tsplitAt: number,\n\t): Promise<void> {\n\t\tconst encoded = encodeClientMessage(message);\n\t\treturn this.#channel.sendFragmented(encoded, splitAt);\n\t}\n\n\tnext(\n\t\tpredicate: (\n\t\t\tmessage: ServerMessage,\n\t\t) => boolean,\n\t): Promise<ServerMessage> {\n\t\treturn this.#inbound.waitFrom(0, predicate);\n\t}\n\n\tnextFrom(\n\t\tindex: number,\n\t\tpredicate: (\n\t\t\tmessage: ServerMessage,\n\t\t) => boolean,\n\t): Promise<ServerMessage> {\n\t\treturn this.#inbound.waitFrom(index, predicate);\n\t}\n\n\twaitForClose(): Promise<void> {\n\t\treturn this.#inbound.donePromise;\n\t}\n\n\tclose(): Promise<void> {\n\t\treturn this.#channel.close();\n\t}\n\n\treceive(\n\t\tchunk: Uint8Array,\n\t): void {\n\t\tconst fresh = this.#inbound.pushBytes(chunk);\n\t\tfor (const message of fresh) {\n\t\t\tif (message.type !== \"attachment\") continue;\n\t\t\tconst attachment = message.attachment;\n\t\t\tthis.#attachment =\n\t\t\t\tattachment === null\n\t\t\t\t\t? undefined\n\t\t\t\t\t: { sessionId: attachment.sessionId, attachmentId: attachment.attachmentId };\n\t\t}\n\t}\n\n\tmarkClosed(): void {\n\t\tthis.#inbound.finish();\n\t}\n\n\tfail(\n\t\terror: Error,\n\t): void {\n\t\tthis.#inbound.rejectAll(error);\n\t}\n}\n\nexport async function connectUnixTestClient(\n\tpath: string,\n): Promise<ProtocolTestClient> {\n\tconst socket = createConnection(path);\n\tawait once(socket, \"connect\");\n\tconst transmit = (chunk: Uint8Array): Promise<void> => writeSocket(socket, chunk);\n\tconst channel: WireChannel = {\n\t\tsend: transmit,\n\t\tsendFragmented: async (chunk, splitAt) => {\n\t\t\tawait transmit(chunk.subarray(0, splitAt));\n\t\t\tawait transmit(chunk.subarray(splitAt));\n\t\t},\n\t\tclose: async () => {\n\t\t\tconst gone = socket.destroyed;\n\t\t\tif (gone) return;\n\t\t\tconst onClose = once(socket, \"close\");\n\t\t\tsocket.destroy();\n\t\t\tawait onClose;\n\t\t},\n\t};\n\tconst client = new ProtocolTestClient(channel);\n\tsocket.on(\"data\", (chunk: Buffer) => {\n\t\tconst bytes = new Uint8Array(chunk.buffer, chunk.byteOffset, chunk.byteLength);\n\t\tclient.receive(bytes);\n\t});\n\tsocket.on(\"error\", (cause) => client.fail(cause));\n\tsocket.once(\"close\", () => {\n\t\tclient.markClosed();\n\t});\n\treturn client;\n}\n\nfunction writeSocket(\n\tsocket: Socket,\n\tchunk: Uint8Array,\n): Promise<void> {\n\treturn new Promise<void>((resolve, reject) => {\n\t\tconst done = (error?: Error | null): void => (error ? reject(error) : resolve());\n\t\tsocket.write(chunk, done);\n\t});\n}\n"]}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { JsonValue, ServiceCall } from "@crow-agent/chord";
|
|
2
|
+
import type { Context, Session, SessionMetadata } from "@crow-agent/agent-core";
|
|
3
|
+
import { MemorySessionRepo } from "@crow-agent/agent-core";
|
|
4
|
+
import type { RoutedServerServiceHost, RoutedSessionHandle, ServerHost } from "../server-types.ts";
|
|
5
|
+
export declare class Deferred<T = void> {
|
|
6
|
+
#private;
|
|
7
|
+
constructor();
|
|
8
|
+
get promise(): Promise<T>;
|
|
9
|
+
resolve(value: T): void;
|
|
10
|
+
}
|
|
11
|
+
/** A manually-released checkpoint: `pass()` signals entry, then waits for `release`. */
|
|
12
|
+
declare class Gate {
|
|
13
|
+
readonly entered: Deferred<void>;
|
|
14
|
+
readonly release: Deferred<void>;
|
|
15
|
+
pass(): Promise<void>;
|
|
16
|
+
}
|
|
17
|
+
type HarnessAttachment = {
|
|
18
|
+
invokeService: (call: ServiceCall) => Promise<JsonValue | undefined>;
|
|
19
|
+
release: (context: Context) => void;
|
|
20
|
+
};
|
|
21
|
+
export declare class TestHarness {
|
|
22
|
+
#private;
|
|
23
|
+
readonly session: Session;
|
|
24
|
+
readonly serviceCalls: Array<ServiceCall>;
|
|
25
|
+
readonly closed: Deferred<void>;
|
|
26
|
+
attachedClients: number;
|
|
27
|
+
attachmentReleaseCount: number;
|
|
28
|
+
closeCount: number;
|
|
29
|
+
failAttachmentRelease: Error | undefined;
|
|
30
|
+
failClose: Error | undefined;
|
|
31
|
+
nextServiceError: Error | undefined;
|
|
32
|
+
nextServiceResult: JsonValue | undefined;
|
|
33
|
+
constructor(session: Session);
|
|
34
|
+
get terminated(): Promise<Error | undefined>;
|
|
35
|
+
attachClient(_context: Context): HarnessAttachment;
|
|
36
|
+
invokeService(call: ServiceCall): Promise<JsonValue | undefined>;
|
|
37
|
+
close(context: Context): Promise<void>;
|
|
38
|
+
terminate(error: Error): Promise<void>;
|
|
39
|
+
gateNextClose(): Gate;
|
|
40
|
+
gateNextServiceCall(): Gate;
|
|
41
|
+
private passGate;
|
|
42
|
+
private takeServiceResult;
|
|
43
|
+
}
|
|
44
|
+
export declare function createTestServerServices(): RoutedServerServiceHost;
|
|
45
|
+
export declare class TestServerHost implements ServerHost {
|
|
46
|
+
#private;
|
|
47
|
+
readonly serverServices: RoutedServerServiceHost;
|
|
48
|
+
readonly repo: MemorySessionRepo;
|
|
49
|
+
readonly harnesses: Map<string, Array<TestHarness>>;
|
|
50
|
+
openSessionCount: number;
|
|
51
|
+
nextOpenSessionError: Error | undefined;
|
|
52
|
+
nextHarnessCloseError: Error | undefined;
|
|
53
|
+
resolveSession(sessionId: string, context: Context): Promise<SessionMetadata>;
|
|
54
|
+
openSession(metadata: SessionMetadata, context: Context): Promise<RoutedSessionHandle>;
|
|
55
|
+
seed(id?: string, parentSessionId?: string): Promise<SessionMetadata>;
|
|
56
|
+
gateNextOpenSession(): Gate;
|
|
57
|
+
latestHarness(id: string): TestHarness;
|
|
58
|
+
private passGate;
|
|
59
|
+
private buildHarness;
|
|
60
|
+
}
|
|
61
|
+
export {};
|
|
62
|
+
//# sourceMappingURL=test-host.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"test-host.d.ts","sourceRoot":"","sources":["../../src/testing/test-host.ts"],"names":[],"mappings":"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"}
|