diff --git a/apps/rath-service/README.md b/apps/rath-service/README.md deleted file mode 100644 index ccfb69c6d..000000000 --- a/apps/rath-service/README.md +++ /dev/null @@ -1,3 +0,0 @@ -## WIP RATH Service :construction: - -designed for RATH's server side persistent storage. \ No newline at end of file diff --git a/apps/rath-service/api/datasource.go b/apps/rath-service/api/datasource.go deleted file mode 100644 index 6e28d82d6..000000000 --- a/apps/rath-service/api/datasource.go +++ /dev/null @@ -1,20 +0,0 @@ -package api - -import ( - "rath-service/global" - "rath-service/models" - "rath-service/services" - - "github.com/gin-gonic/gin" -) - -func CreateDataSource(ctx *gin.Context) { - var ds models.IDataSource - ctx.Bind(&ds) - result := global.RATH_DB.Create(&ds) - if result.Error != nil { - services.SendErrorResponse(ctx, result.Error.Error()) - return - } - services.SendSuccessResponse(ctx, ds.ID) -} diff --git a/apps/rath-service/global/common.go b/apps/rath-service/global/common.go deleted file mode 100644 index 88d8b759b..000000000 --- a/apps/rath-service/global/common.go +++ /dev/null @@ -1,5 +0,0 @@ -package global - -import "gorm.io/gorm" - -var RATH_DB *gorm.DB diff --git a/apps/rath-service/go.mod b/apps/rath-service/go.mod deleted file mode 100644 index 3ddd0a7f4..000000000 --- a/apps/rath-service/go.mod +++ /dev/null @@ -1,33 +0,0 @@ -module rath-service - -go 1.18 - -require ( - github.com/gin-gonic/gin v1.8.1 - gorm.io/driver/sqlite v1.3.6 - gorm.io/gorm v1.23.8 -) - -require ( - github.com/gin-contrib/sse v0.1.0 // indirect - github.com/go-playground/locales v0.14.0 // indirect - github.com/go-playground/universal-translator v0.18.0 // indirect - github.com/go-playground/validator/v10 v10.11.0 // indirect - github.com/goccy/go-json v0.9.11 // indirect - github.com/jinzhu/inflection v1.0.0 // indirect - github.com/jinzhu/now v1.1.5 // indirect - github.com/json-iterator/go v1.1.12 // indirect - github.com/leodido/go-urn v1.2.1 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect - github.com/mattn/go-sqlite3 v1.14.15 // indirect - github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect - github.com/modern-go/reflect2 v1.0.2 // indirect - github.com/pelletier/go-toml/v2 v2.0.3 // indirect - github.com/ugorji/go/codec v1.2.7 // indirect - golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 // indirect - golang.org/x/net v0.0.0-20220812174116-3211cb980234 // indirect - golang.org/x/sys v0.0.0-20220818161305-2296e01440c6 // indirect - golang.org/x/text v0.3.8 // indirect - google.golang.org/protobuf v1.28.1 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect -) diff --git a/apps/rath-service/go.sum b/apps/rath-service/go.sum deleted file mode 100644 index eb1d6ba14..000000000 --- a/apps/rath-service/go.sum +++ /dev/null @@ -1,108 +0,0 @@ -github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= -github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE= -github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= -github.com/gin-gonic/gin v1.8.1 h1:4+fr/el88TOO3ewCmQr8cx/CtZ/umlIRIs5M4NTNjf8= -github.com/gin-gonic/gin v1.8.1/go.mod h1:ji8BvRH1azfM+SYow9zQ6SZMvR8qOMZHmsCuWR9tTTk= -github.com/go-playground/assert/v2 v2.0.1 h1:MsBgLAaY856+nPRTKrp3/OZK38U/wa0CcBYNjji3q3A= -github.com/go-playground/assert/v2 v2.0.1/go.mod h1:VDjEfimB/XKnb+ZQfWdccd7VUvScMdVu0Titje2rxJ4= -github.com/go-playground/locales v0.14.0 h1:u50s323jtVGugKlcYeyzC0etD1HifMjqmJqb8WugfUU= -github.com/go-playground/locales v0.14.0/go.mod h1:sawfccIbzZTqEDETgFXqTho0QybSa7l++s0DH+LDiLs= -github.com/go-playground/universal-translator v0.18.0 h1:82dyy6p4OuJq4/CByFNOn/jYrnRPArHwAcmLoJZxyho= -github.com/go-playground/universal-translator v0.18.0/go.mod h1:UvRDBj+xPUEGrFYl+lu/H90nyDXpg0fqeB/AQUGNTVA= -github.com/go-playground/validator/v10 v10.11.0 h1:0W+xRM511GY47Yy3bZUbJVitCNg2BOGlCyvTqsp/xIw= -github.com/go-playground/validator/v10 v10.11.0/go.mod h1:i+3WkQ1FvaUjjxh1kSvIA4dMGDBiPU55YFDl0WbKdWU= -github.com/goccy/go-json v0.9.11 h1:/pAaQDLHEoCq/5FFmSKBswWmK6H0e8g4159Kc/X/nqk= -github.com/goccy/go-json v0.9.11/go.mod h1:6MelG93GURQebXPDq3khkgXZkazVtN9CRI+MGFi0w8I= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/google/go-cmp v0.5.5 h1:Khx7svrCpmxxtHBq5j2mp/xVjsi8hQMfNLvJFAlrGgU= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/gofuzz v1.0.0/go.mod h1:dBl0BpW6vV/+mYPU4Po3pmUjxk6FQPldtuIdl/M65Eg= -github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD/E= -github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= -github.com/jinzhu/now v1.1.4/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= -github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= -github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= -github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= -github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= -github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.0 h1:WgNl7dwNpEZ6jJ9k1snq4pZsg7DOEN8hP9Xw0Tsjwk0= -github.com/kr/pretty v0.3.0/go.mod h1:640gp4NfQd8pI5XOwp5fnNeVWj67G7CFk/SaSQn7NBk= -github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= -github.com/leodido/go-urn v1.2.1 h1:BqpAaACuzVSgi/VLzGZIobT2z4v53pjosyNd9Yv6n/w= -github.com/leodido/go-urn v1.2.1/go.mod h1:zt4jvISO2HfUBqxjfIshjdMTYS56ZS/qv49ictyFfxY= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-sqlite3 v1.14.12/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= -github.com/mattn/go-sqlite3 v1.14.15 h1:vfoHhTN1af61xCRSWzFIWzx2YskyMTwHLrExkBOjvxI= -github.com/mattn/go-sqlite3 v1.14.15/go.mod h1:2eHXhiwb8IkHr+BDWZGa96P6+rkvnG63S2DGjv9HUNg= -github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg= -github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= -github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9Gz0M= -github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= -github.com/pelletier/go-toml/v2 v2.0.3 h1:h9JoA60e1dVEOpp0PFwJSmt1Htu057NUq9/bUwaO61s= -github.com/pelletier/go-toml/v2 v2.0.3/go.mod h1:OMHamSCAODeSsVrwwvcJOaoN0LIUIaFVNZzmWyNfXas= -github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= -github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= -github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.6.1/go.mod h1:xXDCJY+GAPziupqXw64V24skbSoqbTEfhy4qGm1nDQc= -github.com/rogpeppe/go-internal v1.8.0 h1:FCbCCtXNOY3UtUuHUYaghJg4y7Fd14rXifAYUAtL9R8= -github.com/rogpeppe/go-internal v1.8.0/go.mod h1:WmiCO8CzOY8rg0OYDC4/i/2WRWAB6poM+XZ2dLUbcbE= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/ugorji/go v1.2.7/go.mod h1:nF9osbDWLy6bDVv/Rtoh6QgnvNDpmCalQV5urGCCS6M= -github.com/ugorji/go/codec v1.2.7 h1:YPXUKf7fYbp/y8xloBqZOw2qaVggbfwMlI8WM3wZUJ0= -github.com/ugorji/go/codec v1.2.7/go.mod h1:WGN1fab3R1fzQlVQTkfxVtIBhWDRqOviHU95kRgeqEY= -golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8 h1:GIAS/yBem/gq2MUqgNIzUHW7cJMmx3TGZOrnyYaNQ6c= -golang.org/x/crypto v0.0.0-20220817201139-bc19a97f63c8/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220812174116-3211cb980234 h1:RDqmgfe7SvlMWoqC3xwQ2blLO3fcWcxMa3eBLRdRW7E= -golang.org/x/net v0.0.0-20220812174116-3211cb980234/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20210806184541-e5e7981a1069/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220818161305-2296e01440c6 h1:Sx/u41w+OwrInGdEckYmEuU5gHoGSL4QbDz3S9s6j4U= -golang.org/x/sys v0.0.0-20220818161305-2296e01440c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= -golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.3.8 h1:nAL+RVCQ9uMn3vJZbV+MRnydTJFPf8qqY42YiA6MrqY= -golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543 h1:E7g+9GITq07hpfrRu66IVDexMakfv52eLZ2CXBWiKr4= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.28.1 h1:d0NfwRgPtno5B1Wa6L2DAG+KivqkdutMf1UhdNx175w= -google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= -gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gorm.io/driver/sqlite v1.3.6 h1:Fi8xNYCUplOqWiPa3/GuCeowRNBRGTf62DEmhMDHeQQ= -gorm.io/driver/sqlite v1.3.6/go.mod h1:Sg1/pvnKtbQ7jLXxfZa+jSHvoX8hoZA8cn4xllOMTgE= -gorm.io/gorm v1.23.4/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= -gorm.io/gorm v1.23.8 h1:h8sGJ+biDgBA1AD1Ha9gFCx7h8npU7AsLdlkX0n2TpE= -gorm.io/gorm v1.23.8/go.mod h1:l2lP/RyAtc1ynaTjFksBde/O8v9oOGIApu2/xRitmZk= diff --git a/apps/rath-service/initialize/database.go b/apps/rath-service/initialize/database.go deleted file mode 100644 index 898ce26cc..000000000 --- a/apps/rath-service/initialize/database.go +++ /dev/null @@ -1,19 +0,0 @@ -package initialize - -import ( - "rath-service/models" - - "gorm.io/driver/sqlite" - "gorm.io/gorm" -) - -func InitDB() *gorm.DB { - db, err := gorm.Open(sqlite.Open("test.db"), &gorm.Config{}) - if err != nil { - panic("failed to connect database") - } - db.AutoMigrate( - &models.IDataSource{}, - ) - return db -} diff --git a/apps/rath-service/main.go b/apps/rath-service/main.go deleted file mode 100644 index 005d5e4da..000000000 --- a/apps/rath-service/main.go +++ /dev/null @@ -1,19 +0,0 @@ -package main - -import ( - "rath-service/api" - "rath-service/global" - "rath-service/initialize" - - "github.com/gin-gonic/gin" -) - -func main() { - app := gin.New() - global.RATH_DB = initialize.InitDB() - apiGroup := app.Group("/api") - { - apiGroup.GET("/datasource/create", api.CreateDataSource) - } - app.Run(":2019") -} diff --git a/apps/rath-service/models/dataset.go b/apps/rath-service/models/dataset.go deleted file mode 100644 index b8e7f4869..000000000 --- a/apps/rath-service/models/dataset.go +++ /dev/null @@ -1,8 +0,0 @@ -package models - -import "gorm.io/gorm" - -type Dataset struct { - gorm.Model - -} diff --git a/apps/rath-service/models/datasource.go b/apps/rath-service/models/datasource.go deleted file mode 100644 index 71c39f280..000000000 --- a/apps/rath-service/models/datasource.go +++ /dev/null @@ -1,10 +0,0 @@ -package models - -import "gorm.io/gorm" - -type IDataSource struct { - gorm.Model - Name string - SourceType string - URI string -} diff --git a/apps/rath-service/services/response.go b/apps/rath-service/services/response.go deleted file mode 100644 index 31a890cda..000000000 --- a/apps/rath-service/services/response.go +++ /dev/null @@ -1,26 +0,0 @@ -package services - -import "github.com/gin-gonic/gin" - -// 触发服务器内部错误时,使用。会伴随500的状态码 -func SendErrorResponse(ctx *gin.Context, message string) { - ctx.JSON(500, gin.H{ - "success": false, - "message": message, - }) -} - -// 用户参数不规范时使用,本身没有触发服务器内部错误,返回状态码200 -func SendFailResponse(ctx *gin.Context, message string) { - ctx.JSON(200, gin.H{ - "success": false, - "message": message, - }) -} - -func SendSuccessResponse(ctx *gin.Context, payload interface{}) { - ctx.JSON(200, gin.H{ - "success": true, - "data": payload, - }) -} diff --git a/packages/rath-client/package.json b/packages/rath-client/package.json index ede39f2c1..fe9d55f96 100644 --- a/packages/rath-client/package.json +++ b/packages/rath-client/package.json @@ -10,7 +10,6 @@ }, "dependencies": { "@antv/g6": "^4.8.4", - "@babel/parser": "^7.19.6", "@fluentui/font-icons-mdl2": "^8.5.4", "@fluentui/react": "^8.94.4", "@fluentui/react-components": "^9.19.0", diff --git a/packages/rath-client/public/locales/en-US.json b/packages/rath-client/public/locales/en-US.json index 97cee0b3e..f83b07ea3 100644 --- a/packages/rath-client/public/locales/en-US.json +++ b/packages/rath-client/public/locales/en-US.json @@ -359,15 +359,11 @@ }, "extend": { "title": "Extend Information", - "manual": "Customized computation", "editor": "Editor", "autoExtend": "More fields can be generated from { count } existing fields to enhance analyze and exploration.", "notDecided": "{ count } fields has not been decided.", "findThem": "Find Next", "checkThem": "Check", - "empty": "No column exported.", - "apply": "Apply", - "cancel": "Cancel", "auto": "transforms", "suggestion": { "regex_selection": "Pattern discovery & extraction | Extract patterns from text fields and generate new fields matching extracted pattern.", @@ -553,49 +549,6 @@ "create": "Create" } }, - "latiao": { - "maybe": { - "keyword": "keyword", - "operator": "operator", - "fid": "field" - }, - "keyword": { - "out": "Append field to data." - }, - "op": { - "$set": "Transforms a field to ordinals as a new column.", - "$vec": "Transforms a field to calculative numbers as a new column.", - "$text": "Transforms a field to strings as a new column.", - "$bool": "Transforms a field to 0 or 1 as a new column.", - "$id": "Generates an automatically incrementing id field, starting from 1.", - "$order": "Returns rank index of the data sorted on the target numeric field, starting from 1.", - "$dict": "Returns rank index of the data sorted on the target string field, starting from 1.", - "$isNaN": "Transforms numbers to string \"1\" if the number is NaN, otherwise string \"0\" as a new column.", - "$isZero": "Transforms numbers to string \"1\" if the number is zero, otherwise string \"0\" as a new column.", - "$toDate": "Transforms a field to a set of operative Date objects, which could be sliced on time units.", - "$isValidDate": "Transforms Date objects to string \"1\" if the Date object is valid, otherwise string \"0\" as a new column.", - "$normalize": "Normalizes a field as a new column.", - "$inset": "Scales a field to range -1 ~ +1 as a new column.", - "$bound": "Scales a field to range 0 ~ 1 as a new column.", - "$log": "Projects a field by x -> log(x) (the base is default to E) as a new column.", - "$log2": "Projects a field by x -> log[2](x) as a new column.", - "$log1p": "Projects a field by x -> log(x + 1) as a new column.", - "$log10": "Projects a field by x -> log[10](x) as a new column.", - "$map": "Maps each value to a new value of the same type as a new column.", - "$test": "Maps each value to a 0 (false) or 1 (true) as a new column.", - "$ReLU": "Projects a field by x -> max(0, x) as a new column.", - "$match": "Finds the matched parts of each text content using Regular Expression as a new column.", - "$replace": "Replaces the matched parts of each text content with a given string using Regular Expression as a new column.", - "$concat": "Merge two or more text contents of all the fields as a new column.", - "$sigmoid": "Projects a field by x -> (1 + e^-x)^-1 as a new column.", - "$boxClip": "Maps overflowing values (due to boxplot) to the domain as a new column.", - "$meanClip": "Maps overflowing values (due to the given domain) to the mean of all the other values as a new column.", - "$nearestClip": "Maps overflowing values (due to the given domain) to the domain as a new column.", - "$zeroFill": "Maps Infinite or NaN to 0 as a new column.", - "$meanFill": "Maps Infinite or NaN to the mean of all the other values as a new column.", - "$partition": "Separates each value by boolean expression into two new column." - } - }, "causal_direction": { "_": "Type of Link", "none": "irrelevant to", diff --git a/packages/rath-client/public/locales/zh-CN.json b/packages/rath-client/public/locales/zh-CN.json index 5be810fce..c819df6f8 100644 --- a/packages/rath-client/public/locales/zh-CN.json +++ b/packages/rath-client/public/locales/zh-CN.json @@ -325,15 +325,11 @@ }, "extend": { "title": "扩展信息", - "manual": "自定义计算", "editor": "编辑器", "autoExtend": "{ count } 个字段可以自动扩展生成新的字段以增强分析和探索。", "notDecided": "{ count } 个自动扩展的字段待确认。", "findThem": "下一个", "checkThem": "筛选", - "empty": "没有导出的列。", - "apply": "扩展", - "cancel": "取消", "auto": "转换", "suggestion": { "regex_selection": "模式发现&提取|将选中的字段作为模式,发现数据集中所有匹配的相似模式并提取出来。", @@ -519,49 +515,6 @@ "create": "创建" } }, - "latiao": { - "maybe": { - "keyword": "关键字", - "operator": "算子", - "fid": "字段" - }, - "keyword": { - "out": "扩充这个字段。" - }, - "op": { - "$set": "将一列转换至序数作为新的字段。", - "$vec": "将一列转换至可计算数值作为新的字段。", - "$text": "将一列转换至字符字面量作为新的字段。", - "$bool": "将一列转换至 0 或 1 作为新的字段。", - "$id": "生成一列从 1 起自增的 ID。", - "$order": "计算数据按目标字段数学排序后的位次,从 1 开始。", - "$dict": "计算数据按目标字段字典排序后的位次,从 1 开始。", - "$isNaN": "将一列中是 NaN 的数字记为字符 \"1\" ,其他记为字符 \"0\" 作为新的字段。", - "$isZero": "将一列中是 0 的数字记为字符 \"1\" ,其他记为字符 \"0\" 作为新的字段。", - "$toDate": "将一个字段识别为可沿时间单位切面的 Date 对象作为新的字段。", - "$isValidDate": "将一列中是有效 Date 对象的记为字符 \"1\" ,其他记为字符 \"0\" 作为新的字段。", - "$normalize": "标准化一个列作为新的字段。", - "$inset": "将一个列线性映射到 -1 ~ +1 区间作为新的字段。", - "$bound": "将一个列线性映射到 0 ~ 1 区间作为新的字段。", - "$log": "以对数(默认为自然对数)映射变换到一个新的字段。", - "$log2": "以 x -> log[2](x) 映射变换到一个新的字段。", - "$log1p": "以 x -> log(x + 1) 映射变换到一个新的字段。", - "$log10": "以 x -> log[10](x) 映射变换到一个新的字段。", - "$map": "构造一个同等类型的映射变换到一个新的字段。", - "$test": "构造一个二元映射变换到 0(非真)或 1(真)作为一个新的字段。", - "$ReLU": "以 x -> max(0, x) 映射变换到一个新的字段。", - "$match": "使用正则表达式提取出字段中的匹配部分作为新的字段。", - "$replace": "使用正则表达式替换字段中的匹配部分后作为新的字段。", - "$concat": "连接若干列文本作为新的字段。", - "$sigmoid": "以 x -> (1 + e^-x)^-1 映射变换到一个新的字段。", - "$boxClip": "基于箱线图统计,将异常值收束到正常分布范围的上下界作为新的字段。", - "$meanClip": "指定一个范围,将超出这个范围的值修正到范围内所有值的均值作为新的字段。", - "$nearestClip": "指定一个范围,将超出这个范围的值修正到对应的上下界作为新的字段。", - "$zeroFill": "将无穷或错误数值转换至 0 作为新的字段。", - "$meanFill": "将无穷或错误数值转换其他所有值的均值作为新的字段。", - "$partition": "构造一个二元映射将字段按规则拆解到两个新的字段。" - } - }, "causal_direction": { "_": "连接类型", "none": "无关", diff --git a/packages/rath-client/src/components/latiaoConsole/autocompletable.tsx b/packages/rath-client/src/components/latiaoConsole/autocompletable.tsx deleted file mode 100644 index 869612c42..000000000 --- a/packages/rath-client/src/components/latiaoConsole/autocompletable.tsx +++ /dev/null @@ -1,192 +0,0 @@ -import { observer } from 'mobx-react-lite'; -import { useEffect, useMemo } from 'react'; -import intl from 'react-intl-universal'; -import styled from 'styled-components'; -import { getOperatorList } from '../../latiao/program/operator'; -import { useGlobalStore } from '../../store'; -import type { InputMaybe } from './modal'; - - -const Container = styled.div` - overflow: hidden scroll; - padding: 0.2em 0 1em; - height: 6em; - border: 1px solid #8888; - border-top: none; - display: flex; - flex-direction: column; - - > * { - width: 100%; - flex-grow: 0; - flex-shrink: 0; - cursor: pointer; - user-select: none; - font-size: 0.9rem; - line-height: 1.2em; - padding: 0.2em 1em; - display: flex; - flex-direction: row; - &.highlight { - background-color: rgba(0, 120, 212, 0.12); - } - :hover { - background-color: rgba(0, 120, 212, 0.3); - } - - > span { - flex-grow: 0; - flex-shrink: 0; - color: rgb(0, 120, 212); - font-size: 0.6rem; - width: 6em; - padding: 0 0.4em; - text-align: center; - } - > div { - flex-grow: 1; - flex-shrink: 1; - } - } -`; - -export interface LaTiaoACProps { - editingText: string; - setOptions: (list: InputMaybe[]) => void; - maybeIdx: number; - setMaybeIdx: (idx: number) => void; - submit: (content: string) => void; -} - -const LaTiaoAC = observer(({ editingText, setOptions, maybeIdx, setMaybeIdx, submit }) => { - const { dataSourceStore } = useGlobalStore(); - const { fields: mutFields } = dataSourceStore; - - const inputMaybe = useMemo(() => { - if (editingText.length === 0) { - // 只推算子 - const ops = getOperatorList(); - - const maybe = ops.reduce( - (list, op) => { - if (list.find(o => o.name === op.name)) { - return list; - } - - return [...list, op]; - }, [] - ).map(op => ({ - type: 'operator' as const, - content: op.name, - description: intl.get(`latiao.op.${op.name}`) || '', - })).sort(); // 字典序 - - return maybe.find(op => op.content === editingText) ? [] : maybe; - } - - const pattern = new RegExp(`^${editingText.split('').map(c => `.*${c}`).join('')}.*$`, 'i'); - - const maybe: InputMaybe[] = []; - - if ('out'.match(pattern)) { - maybe.push({ - type: 'keyword', - content: 'out', - description: intl.get('latiao.keyword.out') || '', - }); - } - - const fields = mutFields.filter(f => ( - f.fid.match(pattern) || f.name?.match(pattern) - )); - - maybe.push(...fields.map(f => ({ - type: 'fid' as const, - content: `_${f.fid}`, - description: f.name ?? f.fid, - }))); - - // 文本越长说明匹配比例越低 - maybe.sort((a, b) => a.content.length - b.content.length); - - if (editingText.startsWith('$')) { - // 优先推算子 - const ops = getOperatorList().filter(op => op.name.slice(1).match(new RegExp(`^${editingText.slice(1).split('').map(c => `.*${c}`).join('')}.*$`, 'i'))); - - maybe.splice( - 0, - 0, - ...ops.reduce( - (list, op) => { - if (list.find(o => o.name === op.name)) { - return list; - } - - return [...list, op]; - }, [] - ).map(op => ({ - type: 'operator' as const, - content: op.name, - description: intl.get(`latiao.op.${op.name}`) || '', - })).sort((a, b) => a.content.length - b.content.length) - ); - } - - return maybe.find(m => m.content === editingText) ? [] : maybe; - }, [editingText, mutFields]); - - useEffect(() => { - setOptions(inputMaybe); - }, [inputMaybe, setOptions]); - - useEffect(() => { - setMaybeIdx(0); - }, [inputMaybe, setMaybeIdx]); - - return ( - - {inputMaybe.map((maybe, i) => ( -
{ - submit(maybe.content); - setMaybeIdx(0); - } - } - ref={e => { - if (e && i === maybeIdx) { - e.scrollIntoView({ - behavior: 'smooth', - block: 'nearest', - }); - } - }} - > - - {intl.get(`latiao.maybe.${maybe.type}`)} - -
-
-                            {maybe.content}
-                        
- {maybe.description && ( - - {maybe.description} - - )} -
- {i === maybeIdx && ( - - {'[Tab]'} - - )} -
- ))} -
- ); -}); - - -export default LaTiaoAC; diff --git a/packages/rath-client/src/components/latiaoConsole/editor.tsx b/packages/rath-client/src/components/latiaoConsole/editor.tsx deleted file mode 100644 index 209ae9b20..000000000 --- a/packages/rath-client/src/components/latiaoConsole/editor.tsx +++ /dev/null @@ -1,251 +0,0 @@ -import { TextField } from '@fluentui/react'; -import { observer } from 'mobx-react-lite'; -import { forwardRef, useEffect, useMemo, useRef, useState } from 'react'; -import intl from 'react-intl-universal'; -import { debounceTime, Subject } from 'rxjs'; -import styled from 'styled-components'; -import { IRow, IFieldMeta } from '../../interfaces'; -import { rich } from '../../latiao/ide-helper'; -import createProgram, { resolveFields } from '../../latiao/program'; -import { Static } from '../../latiao/program/types'; -import { computeFieldMetaService } from '../../services'; -import { useGlobalStore } from '../../store'; - - -const Container = styled.div` - display: flex; - flex-direction: column; - overflow: hidden auto; - --font-family: "Segoe UI", "Segoe UI Web (West European)", "Segoe UI", -apple-system, BlinkMacSystemFont, Roboto, "Helvetica Neue", sans-serif; - --font-size: 0.95rem; - --letter-spacing: 0.4px; - --font-weight: 600; - --line-height: 1.5em; - --padding: 0.8em 1em 1.5em; - - > * { - width: 100%; - flex-grow: 0; - flex-shrink: 0; - overflow: hidden; - } - & label { - font-size: 13px; - margin-bottom: 0.4em; - } - & textarea { - color: transparent; - caret-color: #444; - font-family: var(--font-family); - font-size: var(--font-size); - font-weight: var(--font-weight); - letter-spacing: var(--letter-spacing); - line-height: var(--line-height); - padding: var(--padding); - white-space: pre-line; - line-break: anywhere; - } - > .content { - position: fixed; - pointer-events: none; - overflow: hidden; - - > pre { - color: #444; - width: 100%; - height: 100%; - font-family: var(--font-family); - font-size: var(--font-size); - font-weight: var(--font-weight); - letter-spacing: var(--letter-spacing); - line-height: var(--line-height); - padding: var(--padding); - background-color: transparent; - overflow: hidden; - resize: none; - white-space: break-spaces; - line-break: anywhere; - } - } -`; - -export interface LaTiaoEditorProps { - code: string; - setCode: (code: string) => void; - position: { - x: number; y: number; w: number; h: number; H: number; offset: number - }; - autocomplete: () => void; - moveHintCursorPrev: () => void; - moveHintCursorNext: () => void; - setPreview: (fields: Static, data: Static | undefined) => void; - setErrMsg: (msg: [string, [number, number]]) => void; -} - -const LaTiaoEditor = observer(forwardRef(({ - code, setCode, position, autocomplete, moveHintCursorPrev, moveHintCursorNext, setPreview, setErrMsg, -}, ref) => { - const { dataSourceStore } = useGlobalStore(); - const { rawDataMetaInfo, extData, fields: mutFields } = dataSourceStore; - const [rawData, setRawData] = useState([]); - - useEffect(() => { - if (rawDataMetaInfo.versionCode > -1) { - dataSourceStore.rawDataStorage.getAll().then(setRawData); - } - }, [rawDataMetaInfo.versionCode, dataSourceStore.rawDataStorage]); - - const mergedData = useMemo(() => { - return rawData.map((row, i) => Object.fromEntries( - mutFields.map<[string, string | number]>(({ fid }) => { - const col = extData.get(fid); - return [fid, col ? col.data[i] : row[fid]]; - }) - )); - }, [rawData, extData, mutFields]); - - const auto$ = useMemo(() => new Subject(), []); - const serviceRef = useRef>(); - - const program = useMemo(() => { - const fields = mutFields.map[1][0]>(f => { - return { - fid: `_${f.fid}`, - name: f.name ?? f.fid, - mode: typeof mergedData[0]?.[f.fid] === 'string' ? 'text' : ({ - nominal: 'text', - ordinal: 'set', - quantitative: 'vec', - temporal: 'vec', - } as const)[f.semanticType], - out: f.name ?? f.fid, - }; - }); - - const p = createProgram( - mergedData.map(row => Object.fromEntries(Object.entries(row).map(([k, v]) => [`_${k}`, v]))), - fields, - (fieldArr, data) => { - const fields = fieldArr.map(f => ({ - ...f, - fid: f.fid.slice(1), - })); - setErrMsg(['', [-1, -1]]); - - const rows: IRow[] = data[0].map(d => ({ - [fields[0].fid]: d, - })); - - data.slice(1).forEach((col, i) => { - const fid = fields[i + 1].fid; - - col.forEach((d, k) => { - rows[k][fid] = d; - }); - }); - - const f = resolveFields(fields); - - setPreview([], rows); - - const s = computeFieldMetaService({ - dataSource: rows, - fields: f, - }); - - serviceRef.current = s; - - s.then(meta => { - if (serviceRef.current === s) { - setPreview( - meta.map((f, i) => ({ - ...f, - extInfo: fields[i].extInfo, - })), - rows - ); - } - }); - }, - ); - - p.onError(err => { - setPreview([], undefined); - setErrMsg([err.message, err.loc ? err.loc[0] : [-1, -1]]); - }); - - return p; - }, [mergedData, mutFields, setErrMsg, setPreview]); - - useEffect(() => { - auto$.next(code); - }, [code, auto$]); - - useEffect(() => { - setPreview([], undefined); - - const subscription = auto$.pipe( - debounceTime(300) - ).subscribe(source => { - program.run(source); - }); - - return () => subscription.unsubscribe(); - }, [auto$, program, setPreview]); - - return ( - - setCode(data ?? '')} - multiline - autoAdjustHeight - resizable={false} - style={{ - minHeight: '15vmin', - maxHeight: '30vh', - }} - styles={{ - fieldGroup: { - border: '1px solid #8888', - }, - }} - onKeyDown={e => { - if (e.key === 'Tab') { - autocomplete(); - e.preventDefault(); - } else if (e.key === 'ArrowDown') { - moveHintCursorNext(); - } else if (e.key === 'ArrowUp') { - moveHintCursorPrev(); - } - }} - /> -
-
-                    {rich(code, mutFields.map(f => ({
-                        ...f,
-                        fid: `_${f.fid}`,
-                    })))}
-                
-
-
- ); -})); - - -export default LaTiaoEditor; diff --git a/packages/rath-client/src/components/latiaoConsole/index.tsx b/packages/rath-client/src/components/latiaoConsole/index.tsx deleted file mode 100644 index 3e95eeae5..000000000 --- a/packages/rath-client/src/components/latiaoConsole/index.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import { CommandButton } from '@fluentui/react'; -import { observer } from 'mobx-react-lite'; -import { Fragment, useState } from 'react'; -import intl from 'react-intl-universal'; -import { useGlobalStore } from '../../store'; -import LaTiaoModal from './modal'; - - -const LaTiaoConsole = observer(() => { - const { dataSourceStore } = useGlobalStore(); - const { rawDataMetaInfo } = dataSourceStore; - const [open, setOpen] = useState(false); - - return ( - - rawDataMetaInfo.length && setOpen(true)} - /> - {open && ( - setOpen(false)} /> - )} - - ); -}); - - -export default LaTiaoConsole; diff --git a/packages/rath-client/src/components/latiaoConsole/modal.tsx b/packages/rath-client/src/components/latiaoConsole/modal.tsx deleted file mode 100644 index b62013b39..000000000 --- a/packages/rath-client/src/components/latiaoConsole/modal.tsx +++ /dev/null @@ -1,258 +0,0 @@ -import { observer } from 'mobx-react-lite'; -import { useCallback, useEffect, useRef, useState } from 'react'; -import intl from 'react-intl-universal'; -import styled from 'styled-components'; -import type { IRow, IFieldMeta } from '../../interfaces'; -import type { Static } from '../../latiao/program/types'; -import LaTiaoEditor from './editor'; -import LaTiaoAC from './autocompletable'; -import LaTiaoPreview from './preview'; - - -const Mask = styled.div` - position: fixed; - top: 0; - left: 0; - width: 100vw; - height: 100vh; - display: flex; - align-items: center; - justify-content: center; - background-color: #8884; - z-index: 10000; -`; - -const Container = styled.div` - min-height: 10vh; - background-color: #fff; - box-shadow: 0 0 16px #8884; - overflow: hidden; - display: flex; - flex-direction: row; - > div { - padding: 1em; - display: flex; - flex-direction: column; - width: 30vw; - > * { - width: 100%; - flex-grow: 0; - flex-shrink: 0; - overflow: hidden; - } - > header { - margin-bottom: 0.6em; - } - > pre { - white-space: pre-line; - overflow: hidden auto; - border: 1px solid #c81; - padding: 0.6em 1em 1.4em; - - &.err-msg { - margin: 1em 0; - height: 8em; - font-size: 0.8rem; - line-height: 1.5em; - color: #c22; - } - } - } -`; - -export type InputMaybe = { - type: 'keyword' | 'operator' | 'fid'; - content: string; - description?: string; -}; - -export interface LaTiaoModalProps { - close: () => void; -} - -const LaTiaoModal = observer(({ close }) => { - const [code, setCode] = useState(''); - const [editing, setEditing] = useState<{ pos: [number, number], text: string }>({ - pos: [0, 0], - text: '', - }); - const [errMsg, setErrMsg] = useState<[string, [number, number]]>(['', [-1, -1]]); - - useEffect(() => { - const textarea = editorRef.current?.querySelector('textarea'); - const nowFocusing = document.querySelector(':focus'); - - if (textarea && textarea !== nowFocusing) { - textarea.focus(); - } - }, [code]); - - const [inputMaybe, setInputMaybe] = useState([]); - - const resultRef = useRef>(); - const [preview, setPreview] = useState>([]); - - useEffect(() => { - const textarea = editorRef.current?.querySelector('textarea'); - - if (code && textarea && textarea.selectionStart === textarea.selectionEnd) { - const beforeCursor = /[$\w]+$/.exec(code.slice(0, textarea.selectionStart))?.[0] ?? ''; - const afterCursor = /^[$\w]+/.exec(code.slice(textarea.selectionStart))?.[0] ?? ''; - - setEditing({ - pos: [ - textarea.selectionStart - beforeCursor.length, - textarea.selectionStart + afterCursor.length, - ], - text: `${beforeCursor}${afterCursor}`, - }); - } - }, [code]); - - const [position, setPosition] = useState<{ - x: number; y: number; w: number; h: number; H: number; offset: number - }>({ x: 0, y: 0, w: 0, h: 0, H: 0, offset: 0 }); - - const editorRef = useRef(null); - const cursorPosRef = useRef(); - - useEffect(() => { - if (cursorPosRef.current) { - const textarea = editorRef.current?.querySelector('textarea'); - - if (textarea) { - textarea.setSelectionRange(cursorPosRef.current, null); - // textarea.selectionStart = cursorPosRef.current; - // textarea.selectionEnd = cursorPosRef.current; - } - - cursorPosRef.current = undefined; - } - }, []); - - useEffect(() => { - const textarea = editorRef.current?.querySelector('textarea'); - - setPreview([]); - - if (textarea) { - const observer = new ResizeObserver(() => { - const rect = textarea.getBoundingClientRect(); - - setPosition(p => ({ - ...p, - x: rect.x, - y: rect.y, - w: rect.width, - h: rect.height, - H: textarea.scrollHeight, - })); - }); - - observer.observe(textarea); - - const handleScroll = () => { - setPosition(p => ({ - ...p, - offset: textarea.scrollTop, - H: textarea.scrollHeight, - })); - }; - - textarea.addEventListener('scroll', handleScroll); - - return () => { - observer.disconnect(); - textarea.removeEventListener('scroll', handleScroll); - }; - } - }, []); - - const submitMaybe = useCallback((data: string) => { - const textarea = editorRef.current?.querySelector('textarea'); - - if (textarea) { - cursorPosRef.current = textarea.selectionEnd; - - setCode( - `${ - code.slice(0, editing.pos[0]) - }${data}${ - code.slice(editing.pos[1]) - }` - ); - } - }, [code, editing]); - - const [maybeIdx, setMaybeIdx] = useState(0); - - const autocomplete = useCallback(() => { - const target = inputMaybe[maybeIdx]; - - if (target) { - submitMaybe(target.content); - setMaybeIdx(0); - } - }, [inputMaybe, maybeIdx, submitMaybe]); - - const moveHintCursorPrev = useCallback(() => { - setMaybeIdx(maybeIdx => (maybeIdx + inputMaybe.length - 1) % inputMaybe.length); - }, [inputMaybe]); - - const moveHintCursorNext = useCallback(() => { - setMaybeIdx(maybeIdx => (maybeIdx + 1) % inputMaybe.length); - }, [inputMaybe]); - - const clearInput = useCallback(() => { - setCode(''); - setErrMsg(['', [-1, -1]]); - resultRef.current = undefined; - }, []); - - const updatePreview = useCallback((fields: Static, data: Static | undefined) => { - setPreview(fields); - resultRef.current = data; - }, []); - - return ( - close()}> - e.stopPropagation()}> -
-
- {intl.get('dataSource.extend.manual')} -
- - -
-                        {errMsg[0]}
-                    
-
- -
-
- ); -}); - - -export default LaTiaoModal; diff --git a/packages/rath-client/src/components/latiaoConsole/preview.tsx b/packages/rath-client/src/components/latiaoConsole/preview.tsx deleted file mode 100644 index 8930605a4..000000000 --- a/packages/rath-client/src/components/latiaoConsole/preview.tsx +++ /dev/null @@ -1,139 +0,0 @@ -import { DefaultButton, PrimaryButton } from '@fluentui/react'; -import { observer } from 'mobx-react-lite'; -import intl from 'react-intl-universal'; -import styled from 'styled-components'; -import type { IRow, IFieldMeta, IExtField } from '../../interfaces'; -import type { Static } from '../../latiao/program/types'; -import { useGlobalStore } from '../../store'; -import DistributionChart from '../../pages/dataSource/metaView/distChart'; - - -const Container = styled.div` - > .preview { - flex-grow: 1; - flex-shrink: 1; - border: 1px solid #8882; - margin: 1em 0; - height: 400px; - overflow: hidden scroll; - display: flex; - flex-direction: column; - align-items: center; - - > div { - margin: 1em 0; - padding: 1em 2em; - border: 1px solid; - - > header { - font-size: 0.9rem; - display: flex; - flex-direction: column; - align-items: center; - } - } - & + div { - display: flex; - flex-direction: row; - align-items: center; - justify-content: center; - > * { - margin-inline: 1em; - } - } - } -`; - -export interface LaTiaoPreviewProps { - preview: Static; - result: Static | undefined; - close: () => void; - clearInput: () => void; -} - -const LaTiaoPreview = observer(({ preview, result, close, clearInput }) => { - const { dataSourceStore } = useGlobalStore(); - const { rawDataMetaInfo } = dataSourceStore; - - return ( - -
- {preview.length === 0 ? ( -

- {intl.get('dataSource.extend.empty')} -

- ) : ( - <> - {preview.map(meta => ( -
-
- {meta.name ? ( - <> - {meta.name} - - {`(${meta.fid})`} - - - ) : meta.fid} -
- -
- ))} - - )} -
-
- { - if (preview.length === 0 || !result) { - return; - } - if (result.length !== rawDataMetaInfo.length) { - console.error( - 'Lengths do not match:', - result.length, - rawDataMetaInfo.length, - ); - - return; - } - - // dataSourceStore.mergeExtended(resultRef.current, preview); - dataSourceStore.addExtFieldsFromRows( - result, - preview.map(f => ({ - ...f, - extInfo: f.extInfo ? { - extOpt: f.extInfo.extOpt, - extInfo: f.extInfo.extInfo, - extFrom: f.extInfo.extFrom.map(s => s.slice(1)), // 里面为了防止 fid 作为保留字前面加了一个下划线所以这里记得去掉 - } : undefined, - stage: 'settled', - }) as IExtField), - ); - close(); - clearInput(); - }} - > - {intl.get('dataSource.extend.apply')} - - close()}> - {intl.get('dataSource.extend.cancel')} - -
-
- ); -}); - - -export default LaTiaoPreview; diff --git a/packages/rath-client/src/interfaces.ts b/packages/rath-client/src/interfaces.ts index b3bf84fbb..031c64d47 100644 --- a/packages/rath-client/src/interfaces.ts +++ b/packages/rath-client/src/interfaces.ts @@ -18,7 +18,7 @@ export type IGeoRole = 'longitude' | 'latitude' | 'none'; export type FieldExtOptType = ( | 'dateTimeExpand' - | `LaTiao.$${string}` + | `CC.${string}` ); /** Detailed information of a extended field. */ @@ -37,14 +37,14 @@ export interface IFieldExtInfoBaseDateTime extends IFieldExtInfoBase { extInfo: DateTimeInfoType; } -interface IFieldExtInfoBaseLaTiao extends IFieldExtInfoBase { - extOpt: `LaTiao.$${string}` | 'dateTimeExpand'; +interface IFieldExtInfoBaseCustomComputation extends IFieldExtInfoBase { + extOpt: `CC.${string}`; extInfo: any; } type FieldExtInfoBase = ( | IFieldExtInfoBaseDateTime - | IFieldExtInfoBaseLaTiao + | IFieldExtInfoBaseCustomComputation ); export type FieldExtSuggestion = { diff --git a/packages/rath-client/src/latiao/ide-helper/index.tsx b/packages/rath-client/src/latiao/ide-helper/index.tsx deleted file mode 100644 index a088c6b65..000000000 --- a/packages/rath-client/src/latiao/ide-helper/index.tsx +++ /dev/null @@ -1,151 +0,0 @@ -import { Fragment } from 'react'; -import { IRawField } from '../../interfaces'; -import '../program/implement/index'; -import { getOperatorList } from '../program/operator'; -import { validNameRegExp } from '../program/parse'; - - -const color = (token: string, prev: string | null, fields: readonly IRawField[]): JSX.Element => { - if (token === 'out') { - return ( - - {token} - - ); - } else if (token.match(/^ +$/)) { - return ( - - {new Array<0>(token.length).fill(0).map((_, i) => ( - - {' '} - - ))} - - ); - } else if (token.match(/^('[^']*')|("[^"]*")$/)) { - return ( - - {token} - - ); - } else if (['(', ')', ',', '.', ';'].includes(token)) { - return ( - - {token} - - ); - } else if (/^[*+-/]$/.test(token)) { - return ( - - {token} - - ); - } else if (token.startsWith('$')) { - if (getOperatorList().find(op => op.name === token)) { - return ( - - {token} - - ); - } - - return ( - - {token} - - ); - } else if (prev === 'out') { - if (validNameRegExp.test(token)) { - return ( - - {token} - - ); - } - - return ( - - {token} - - ); - } else if (fields.find(f => f.fid === token)) { - return ( - - {token} - - ); - } else if (token.match(/\s*/)) { - return ( - - {token} - - ); - } - - return ( - - {token} - - ); -}; - -export const rich = (source: string, fields: readonly IRawField[]): JSX.Element => { - const tokens: JSX.Element[] = []; - - let temp = source; - let prev: string | null = null; - - while (temp) { - const next = /^(\s+|('[^']*')|("[^"]*")|[*+-/]|[$\w]+|\(|\)|,|\.)/.exec(temp)?.[0]; - - if (next) { - tokens.push(color(next, prev, fields)); - temp = temp.slice(next.length); - prev = next.match(/^\s+$/) ? prev : next; - } else { - tokens.push(color(temp, prev, fields)); - break; - } - } - - return ( - <> - {tokens.map((t, i) => ( - - {t} - - ))} - - ); -}; diff --git a/packages/rath-client/src/latiao/program/error.ts b/packages/rath-client/src/latiao/program/error.ts deleted file mode 100644 index 54c241ef2..000000000 --- a/packages/rath-client/src/latiao/program/error.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { prefix } from "./parse"; - - -export const loc = (location: Record<'start' | 'end', { line: number; column: number; }> | undefined): ( - [[number, number], [number, number]] | undefined -) => { - if (location) { - const l: [[number, number], [number, number]] = [ - [location.start.line - (prefix.split('\n').length - 1), location.start.column], - [location.end.line - (prefix.split('\n').length - 1), location.end.column], - ]; - - if (l.flat().some(d => d < 0)) { - return undefined; - } - - return l; - } - - return undefined; -}; - -export class LaTiaoError extends Error { - - override name = 'LaTiao Error'; - - loc: [[number, number], [number, number]] | undefined; - - constructor(msg: string, source?: { loc?: Record<'start' | 'end', { line: number; column: number }> | null }) { - const location = loc(source?.loc ?? undefined); - super( - `${msg}${ - location ? ` - at ${location[0][0]},${location[0][1]}:${location[1][0]},${location[1][1]}` : '' - }` - ); - this.loc = loc(source?.loc ?? undefined); - } - -} - -export class LaTiaoParseError extends LaTiaoError { - - override name = 'LaTiao Parse Error'; - -} - -export class LaTiaoSyntaxError extends LaTiaoError { - - override name = 'LaTiao Syntax Error'; - -} - -export class LaTiaoNameError extends LaTiaoError { - - override name = 'LaTiao Name Error'; - -} - -export class LaTiaoTypeError extends LaTiaoError { - - override name = 'LaTiao Type Error'; - -} - -export class LaTiaoRuntimeError extends LaTiaoError { - - override name = 'LaTiao Runtime Error'; - -} diff --git a/packages/rath-client/src/latiao/program/exec.ts b/packages/rath-client/src/latiao/program/exec.ts deleted file mode 100644 index 177ab3eb3..000000000 --- a/packages/rath-client/src/latiao/program/exec.ts +++ /dev/null @@ -1,67 +0,0 @@ -import { $DateToField } from './implement/date-slice'; -import { getOperator } from './operator'; -import type { DateToken, FieldListToken, FieldToken, OpToken, Token } from './token'; -import type { LaTiaoProgramContext, Static } from './types'; - - -const execOp = async (op: OpToken, context: LaTiaoProgramContext, exp: (fid: string) => void): Promise> => { - const opt = getOperator(op); - const args: Static>[] = []; - - for await (const arg of op.args) { - if (arg.type === 'OP') { - args.push(await execOp(arg, context, exp)); - } else { - args.push(arg); - } - } - - // @ts-expect-error `args` is already validated - const res = await opt.exec(context, args); - - if (op.output.startsWith('RATH.FIELD::') && op.exports !== false) { - if (op.exports.length) { - (res as FieldToken).name = op.exports; - } - - (res as FieldToken).out = (res as FieldToken).name; - - exp((res as FieldToken).fid); - } else if (op.output === '$DATE' && op.exports !== false) { - const field = $DateToField(res as DateToken); - - if (op.exports.length) { - field.name = op.exports; - } - - field.out = field.name; - - exp(field.fid); - } else if (op.output === 'RATH.FIELD_LIST' && op.exports !== false) { - const { tuple } = res as FieldListToken; - - if (op.exports.length) { - tuple.forEach(field => field.name = `${op.exports}.${field.name}`); - } - - tuple.forEach(field => { - field.out = field.name; - exp(field.fid); - }); - } - - return res; -}; - -const exec = async (ast: OpToken[], context: LaTiaoProgramContext): Promise => { - const expArr = new Set(); - - for await (const op of ast) { - await execOp(op, context, fid => expArr.add(fid)); - } - - return [...expArr]; -}; - - -export default exec; diff --git a/packages/rath-client/src/latiao/program/implement/$binary.ts b/packages/rath-client/src/latiao/program/implement/$binary.ts deleted file mode 100644 index 22547ed04..000000000 --- a/packages/rath-client/src/latiao/program/implement/$binary.ts +++ /dev/null @@ -1,437 +0,0 @@ -import { nanoid } from 'nanoid'; -import { subscribeOperator } from '../operator'; -import { resolveDependencies } from '../parse'; -import type { FieldToken } from '../token'; - - -// ADD + - -subscribeOperator({ - name: '$__add', - secret: true, - args: ['RATH.FIELD::vec', 'RATH.FIELD::vec'], - returns: 'RATH.FIELD::vec', - exec: async (context, [a, b]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${a.name || a.fid} + ${b.name || b.fid}`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$add', - extFrom: resolveDependencies([a.fid, b.fid], context), - extInfo: '', - }, - out: false, - }; - - const [col1, col2] = await context.cols([a, b]); - - context.write(field, new Array<0>(context.rowCount).fill(0).map((_, i) => col1[i] + col2[i])); - - return field; - }, -}); - -subscribeOperator<['RATH.FIELD::vec', 'JS.number'], 'RATH.FIELD::vec'>({ - name: '$__add', - secret: true, - args: ['RATH.FIELD::vec', 'JS.number'], - returns: 'RATH.FIELD::vec', - exec: async (context, [a, { value: num }]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${a.name || a.fid} + ${num}`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$add', - extFrom: resolveDependencies([a.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(a) as number[]; - - context.write(field, col.map(d => d + num)); - - return field; - }, -}); - -subscribeOperator<['JS.number', 'RATH.FIELD::vec'], 'RATH.FIELD::vec'>({ - name: '$__add', - secret: true, - args: ['JS.number', 'RATH.FIELD::vec'], - returns: 'RATH.FIELD::vec', - exec: async (context, [{ value: num }, a]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${a.name || a.fid} + ${num}`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$add', - extFrom: resolveDependencies([a.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(a) as number[]; - - context.write(field, col.map(d => d + num)); - - return field; - }, -}); - -subscribeOperator<['JS.number', 'JS.number'], 'RATH.FIELD::vec'>({ - name: '$__add', - secret: true, - args: ['JS.number', 'JS.number'], - returns: 'RATH.FIELD::vec', - exec: async (context, [{ value: a }, { value: b }]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${a} + ${b}`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$add', - extFrom: [], - extInfo: '', - }, - out: false, - }; - - context.write(field, new Array<0>(context.rowCount).fill(0).map(_ => a + b)); - - return field; - }, -}); - -// MINUS - - -subscribeOperator({ - name: '$__minus', - secret: true, - args: ['RATH.FIELD::vec', 'RATH.FIELD::vec'], - returns: 'RATH.FIELD::vec', - exec: async (context, [a, b]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${a.name || a.fid} - ${b.name || b.fid}`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$minus', - extFrom: resolveDependencies([a.fid, b.fid], context), - extInfo: '', - }, - out: false, - }; - - const [col1, col2] = await context.cols([a, b]); - - context.write(field, new Array<0>(context.rowCount).fill(0).map((_, i) => col1[i] - col2[i])); - - return field; - }, -}); - -subscribeOperator<['RATH.FIELD::vec', 'JS.number'], 'RATH.FIELD::vec'>({ - name: '$__minus', - secret: true, - args: ['RATH.FIELD::vec', 'JS.number'], - returns: 'RATH.FIELD::vec', - exec: async (context, [a, { value: num }]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${a.name || a.fid} - ${num}`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$minus', - extFrom: resolveDependencies([a.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(a) as number[]; - - context.write(field, col.map(d => d - num)); - - return field; - }, -}); - -subscribeOperator<['JS.number', 'RATH.FIELD::vec'], 'RATH.FIELD::vec'>({ - name: '$__minus', - secret: true, - args: ['JS.number', 'RATH.FIELD::vec'], - returns: 'RATH.FIELD::vec', - exec: async (context, [{ value: num }, a]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${a.name || a.fid} - ${num}`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$minus', - extFrom: resolveDependencies([a.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(a) as number[]; - - context.write(field, col.map(d => d - num)); - - return field; - }, -}); - -subscribeOperator<['JS.number', 'JS.number'], 'RATH.FIELD::vec'>({ - name: '$__minus', - secret: true, - args: ['JS.number', 'JS.number'], - returns: 'RATH.FIELD::vec', - exec: async (context, [{ value: a }, { value: b }]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${a} - ${b}`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$minus', - extFrom: [], - extInfo: '', - }, - out: false, - }; - - context.write(field, new Array<0>(context.rowCount).fill(0).map(_ => a - b)); - - return field; - }, -}); - -// MULTIPLY * - -subscribeOperator({ - name: '$__multiply', - secret: true, - args: ['RATH.FIELD::vec', 'RATH.FIELD::vec'], - returns: 'RATH.FIELD::vec', - exec: async (context, [a, b]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${a.name || a.fid} * ${b.name || b.fid}`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$multiply', - extFrom: resolveDependencies([a.fid, b.fid], context), - extInfo: '', - }, - out: false, - }; - - const [col1, col2] = await context.cols([a, b]); - - context.write(field, new Array<0>(context.rowCount).fill(0).map((_, i) => col1[i] * col2[i])); - - return field; - }, -}); - -subscribeOperator<['RATH.FIELD::vec', 'JS.number'], 'RATH.FIELD::vec'>({ - name: '$__multiply', - secret: true, - args: ['RATH.FIELD::vec', 'JS.number'], - returns: 'RATH.FIELD::vec', - exec: async (context, [a, { value: num }]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${a.name || a.fid} * ${num}`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$multiply', - extFrom: resolveDependencies([a.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(a) as number[]; - - context.write(field, col.map(d => d * num)); - - return field; - }, -}); - -subscribeOperator<['JS.number', 'RATH.FIELD::vec'], 'RATH.FIELD::vec'>({ - name: '$__multiply', - secret: true, - args: ['JS.number', 'RATH.FIELD::vec'], - returns: 'RATH.FIELD::vec', - exec: async (context, [{ value: num }, a]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${a.name || a.fid} * ${num}`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$multiply', - extFrom: resolveDependencies([a.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(a) as number[]; - - context.write(field, col.map(d => d * num)); - - return field; - }, -}); - -subscribeOperator<['JS.number', 'JS.number'], 'RATH.FIELD::vec'>({ - name: '$__multiply', - secret: true, - args: ['JS.number', 'JS.number'], - returns: 'RATH.FIELD::vec', - exec: async (context, [{ value: a }, { value: b }]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${a} * ${b}`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$multiply', - extFrom: [], - extInfo: '', - }, - out: false, - }; - - context.write(field, new Array<0>(context.rowCount).fill(0).map(_ => a * b)); - - return field; - }, -}); - -// DIVIDE / - -subscribeOperator({ - name: '$__divide', - secret: true, - args: ['RATH.FIELD::vec', 'RATH.FIELD::vec'], - returns: 'RATH.FIELD::vec', - exec: async (context, [a, b]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${a.name || a.fid} / ${b.name || b.fid}`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$divide', - extFrom: resolveDependencies([a.fid, b.fid], context), - extInfo: '', - }, - out: false, - }; - - const [col1, col2] = await context.cols([a, b]); - - context.write(field, new Array<0>(context.rowCount).fill(0).map((_, i) => col1[i] / col2[i])); - - return field; - }, -}); - -subscribeOperator<['RATH.FIELD::vec', 'JS.number'], 'RATH.FIELD::vec'>({ - name: '$__divide', - secret: true, - args: ['RATH.FIELD::vec', 'JS.number'], - returns: 'RATH.FIELD::vec', - exec: async (context, [a, { value: num }]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${a.name || a.fid} / ${num}`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$divide', - extFrom: resolveDependencies([a.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(a) as number[]; - - context.write(field, col.map(d => d / num)); - - return field; - }, -}); - -subscribeOperator<['JS.number', 'RATH.FIELD::vec'], 'RATH.FIELD::vec'>({ - name: '$__divide', - secret: true, - args: ['JS.number', 'RATH.FIELD::vec'], - returns: 'RATH.FIELD::vec', - exec: async (context, [{ value: num }, a]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${a.name || a.fid} / ${num}`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$divide', - extFrom: resolveDependencies([a.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(a) as number[]; - - context.write(field, col.map(d => d / num)); - - return field; - }, -}); - -subscribeOperator<['JS.number', 'JS.number'], 'RATH.FIELD::vec'>({ - name: '$__divide', - secret: true, - args: ['JS.number', 'JS.number'], - returns: 'RATH.FIELD::vec', - exec: async (context, [{ value: a }, { value: b }]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${a} / ${b}`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$divide', - extFrom: [], - extInfo: '', - }, - out: false, - }; - - context.write(field, new Array<0>(context.rowCount).fill(0).map(_ => a / b)); - - return field; - }, -}); diff --git a/packages/rath-client/src/latiao/program/implement/$bool.ts b/packages/rath-client/src/latiao/program/implement/$bool.ts deleted file mode 100644 index a4c62cbeb..000000000 --- a/packages/rath-client/src/latiao/program/implement/$bool.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { nanoid } from 'nanoid'; -import { subscribeOperator } from '../operator'; -import { resolveDependencies } from '../parse'; -import type { FieldToken } from '../token'; - - -subscribeOperator({ - name: '$bool', - args: ['RATH.FIELD::vec'], - returns: 'RATH.FIELD::bool', - exec: async (context, [source]) => { - const field: FieldToken<'bool'> = { - type: 'RATH.FIELD::bool', - fid: nanoid(), - name: source.name, - mode: 'bool', - extInfo: { - extOpt: 'LaTiao.$bool', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source); - - context.write(field, col.map(d => d ? 1 : 0)); - - return field; - }, -}); - -subscribeOperator({ - name: '$bool', - args: ['RATH.FIELD::set'], - returns: 'RATH.FIELD::bool', - exec: async (context, [source]) => { - const field: FieldToken<'bool'> = { - type: 'RATH.FIELD::bool', - fid: nanoid(), - name: source.name, - mode: 'bool', - extInfo: { - extOpt: 'LaTiao.$bool', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source); - - context.write(field, col.map(d => d ? 1 : 0)); - - return field; - }, -}); - -subscribeOperator({ - name: '$bool', - args: ['RATH.FIELD::text'], - returns: 'RATH.FIELD::bool', - exec: async (context, [source]) => { - const field: FieldToken<'bool'> = { - type: 'RATH.FIELD::bool', - fid: nanoid(), - name: source.name, - mode: 'bool', - extInfo: { - extOpt: 'LaTiao.$bool', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source); - - context.write(field, col.map(d => d ? 1 : 0)); - - return field; - }, -}); diff --git a/packages/rath-client/src/latiao/program/implement/$clean.ts b/packages/rath-client/src/latiao/program/implement/$clean.ts deleted file mode 100644 index 5d94ab9ee..000000000 --- a/packages/rath-client/src/latiao/program/implement/$clean.ts +++ /dev/null @@ -1,167 +0,0 @@ -import { nanoid } from 'nanoid'; -import { subscribeOperator } from '../operator'; -import { resolveDependencies } from '../parse'; -import type { FieldToken } from '../token'; - - -subscribeOperator({ - name: '$zeroFill', - args: ['RATH.FIELD::vec'], - returns: 'RATH.FIELD::vec', - exec: async (context, [source]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `Cleaned ${source.name} (zero fill)`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$zeroFill', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source) as number[]; - - context.write(field, col.map(d => Number.isFinite(d) ? d : 0)); - - return field; - }, -}); - -subscribeOperator({ - name: '$meanFill', - args: ['RATH.FIELD::vec'], - returns: 'RATH.FIELD::vec', - exec: async (context, [source]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `Cleaned ${source.name} (mean fill)`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$meanFill', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source) as number[]; - const validNum = col.filter(d => Number.isFinite(d)); - const mean = validNum.reduce((sum, d) => sum + d, 0) / validNum.length; - - context.write(field, col.map(d => Number.isFinite(d) ? d : mean)); - - return field; - }, -}); - -subscribeOperator<['RATH.FIELD::vec', 'JS.number', 'JS.number'], 'RATH.FIELD::vec'>({ - name: '$nearestClip', - args: ['RATH.FIELD::vec', 'JS.number', 'JS.number'], - returns: 'RATH.FIELD::vec', - exec: async (context, [source, { value: min }, { value: max }]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `Cleaned ${source.name} (${min} ~ ${max} nearest)`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$nearestClip', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source) as number[]; - - context.write(field, col.map(d => Number.isFinite(d) ? ( - Math.max(min, Math.min(max, d)) - ) : d)); - - return field; - }, -}); - -subscribeOperator<['RATH.FIELD::vec', 'JS.number', 'JS.number'], 'RATH.FIELD::vec'>({ - name: '$meanClip', - args: ['RATH.FIELD::vec', 'JS.number', 'JS.number'], - returns: 'RATH.FIELD::vec', - exec: async (context, [source, { value: min }, { value: max }]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `Cleaned ${source.name} (${min} ~ ${max} mean)`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$meanClip', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source) as number[]; - const validNum = col.filter(d => Number.isFinite(d)); - const mean = validNum.reduce((sum, d) => sum + d, 0) / validNum.length; - - context.write(field, col.map(d => Number.isFinite(d) ? ( - d >= min && d <= max ? d : mean - ) : d)); - - return field; - }, -}); - -subscribeOperator<['RATH.FIELD::vec'], 'RATH.FIELD::vec'>({ - name: '$boxClip', - args: ['RATH.FIELD::vec'], - returns: 'RATH.FIELD::vec', - exec: async (context, [source]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `Cleaned ${source.name} (boxClip)`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$boxClip', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source) as number[]; - const validNum = col.filter(d => Number.isFinite(d)); - - const ranks: number[] = []; - - validNum.map((d, i) => ({ - value: d, - index: i, - })).sort((a, b) => a.value - b.value).forEach(((d, i) => { - ranks[i] = validNum[d.index]; - })); - - const validCount = validNum.length; - - const Q1l = ranks[Math.floor(validCount / 4)]; - const Q1r = ranks[Math.ceil(validCount / 4)]; - const Q1 = Q1l * 0.75 + Q1r * 0.25; - const Q3l = ranks[Math.floor(validCount * 3 / 4)]; - const Q3r = ranks[Math.ceil(validCount * 3 / 4)]; - const Q3 = Q3l * 0.25 + Q3r * 0.75; - const IQR = Q3 - Q1; - const min = Q1 - 1.5 * IQR; - const max = Q3 + 1.5 * IQR; - - context.write(field, col.map(d => Number.isFinite(d) ? ( - Math.max(min, Math.min(max, d)) - ) : d)); - - return field; - }, -}); diff --git a/packages/rath-client/src/latiao/program/implement/$concat.ts b/packages/rath-client/src/latiao/program/implement/$concat.ts deleted file mode 100644 index 5f3ca3886..000000000 --- a/packages/rath-client/src/latiao/program/implement/$concat.ts +++ /dev/null @@ -1,75 +0,0 @@ -import { nanoid } from 'nanoid'; -import { subscribeOperator } from '../operator'; -import { resolveDependencies } from '../parse'; -import type { FieldToken } from '../token'; - - -subscribeOperator<[], 'RATH.FIELD::text', 'RATH.FIELD::text'>({ - name: '$concat', - args: [], - trailing: 'RATH.FIELD::text', - returns: 'RATH.FIELD::text', - exec: async (context, fields) => { - const field: FieldToken<'text'> = { - type: 'RATH.FIELD::text', - fid: nanoid(), - name: `Concat {${fields.map(f => f.name).join(',')}}`, - mode: 'text', - extInfo: { - extOpt: 'LaTiao.$concat', - extFrom: resolveDependencies(fields.map(f => f.fid), context), - extInfo: '', - }, - out: false, - }; - - // @ts-expect-error 这里推断有误 - const cols = await context.cols<'collection'[]>(fields as FieldToken<'collection'>[]) as string[][]; - - const concat: string[] = []; - - for (let i = 0; i < context.rowCount; i += 1) { - const content = cols.map(col => col[i]).join(','); - concat.push(content); - } - - context.write(field, concat); - - return field; - }, -}); - -subscribeOperator<['JS.string'], 'RATH.FIELD::text', 'RATH.FIELD::text'>({ - name: '$concat', - args: ['JS.string'], - trailing: 'RATH.FIELD::text', - returns: 'RATH.FIELD::text', - exec: async (context, [separator, ...fields]) => { - const field: FieldToken<'text'> = { - type: 'RATH.FIELD::text', - fid: nanoid(), - name: `Concat {${fields.map(f => f.name).join(separator.value)}}`, - mode: 'text', - extInfo: { - extOpt: 'LaTiao.$concat', - extFrom: resolveDependencies(fields.map(f => f.fid), context), - extInfo: '', - }, - out: false, - }; - - // @ts-expect-error 这里推断有误 - const cols = await context.cols<'text'[]>(fields as FieldToken<'text'>[]) as string[][]; - - const concat: string[] = []; - - for (let i = 0; i < context.rowCount; i += 1) { - const content = cols.map(col => col[i]).join(separator.value); - concat.push(content); - } - - context.write(field, concat); - - return field; - }, -}); diff --git a/packages/rath-client/src/latiao/program/implement/$id.ts b/packages/rath-client/src/latiao/program/implement/$id.ts deleted file mode 100644 index 04eea5af1..000000000 --- a/packages/rath-client/src/latiao/program/implement/$id.ts +++ /dev/null @@ -1,28 +0,0 @@ -import { nanoid } from 'nanoid'; -import { subscribeOperator } from '../operator'; -import type { FieldToken } from '../token'; - - -subscribeOperator({ - name: '$id', - args: [], - returns: 'RATH.FIELD::set', - exec: async context => { - const field: FieldToken<'set'> = { - type: 'RATH.FIELD::set', - fid: nanoid(), - name: 'Data ID', - mode: 'set', - extInfo: { - extOpt: 'LaTiao.$id', - extFrom: [], - extInfo: '', - }, - out: false, - }; - - context.write(field, new Array<0>(context.rowCount).fill(0).map((_, i) => i + 1)); - - return field; - }, -}); diff --git a/packages/rath-client/src/latiao/program/implement/$isNaN.ts b/packages/rath-client/src/latiao/program/implement/$isNaN.ts deleted file mode 100644 index 7fbd4e594..000000000 --- a/packages/rath-client/src/latiao/program/implement/$isNaN.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { nanoid } from 'nanoid'; -import { subscribeOperator } from '../operator'; -import { resolveDependencies } from '../parse'; -import type { FieldToken } from '../token'; - - -subscribeOperator({ - name: '$isNaN', - args: ['RATH.FIELD::set'], - returns: 'RATH.FIELD::bool', - exec: async (context, [source]) => { - const field: FieldToken<'bool'> = { - type: 'RATH.FIELD::bool', - fid: nanoid(), - name: `${source.name} is NaN`, - mode: 'bool', - extInfo: { - extOpt: 'LaTiao.$isNaN', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source); - - context.write(field, col.map(d => Number.isNaN(d) ? 1 : 0)); - - return field; - }, -}); - -subscribeOperator({ - name: '$isNaN', - args: ['RATH.FIELD::vec'], - returns: 'RATH.FIELD::bool', - exec: async (context, [source]) => { - const field: FieldToken<'bool'> = { - type: 'RATH.FIELD::bool', - fid: nanoid(), - name: `${source.name} is NaN`, - mode: 'bool', - extInfo: { - extOpt: 'LaTiao.$isNaN', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source); - - context.write(field, col.map(d => Number.isNaN(d) ? 1 : 0)); - - return field; - }, -}); diff --git a/packages/rath-client/src/latiao/program/implement/$isZero.ts b/packages/rath-client/src/latiao/program/implement/$isZero.ts deleted file mode 100644 index 0225ff54f..000000000 --- a/packages/rath-client/src/latiao/program/implement/$isZero.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { nanoid } from 'nanoid'; -import { subscribeOperator } from '../operator'; -import { resolveDependencies } from '../parse'; -import type { FieldToken } from '../token'; - - -subscribeOperator({ - name: '$isZero', - args: ['RATH.FIELD::set'], - returns: 'RATH.FIELD::bool', - exec: async (context, [source]) => { - const field: FieldToken<'bool'> = { - type: 'RATH.FIELD::bool', - fid: nanoid(), - name: `${source.name} is Zero`, - mode: 'bool', - extInfo: { - extOpt: 'LaTiao.$isZero', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source); - - context.write(field, col.map(d => d === 0 ? 1 : 0)); - - return field; - }, -}); - -subscribeOperator({ - name: '$isZero', - args: ['RATH.FIELD::vec'], - returns: 'RATH.FIELD::bool', - exec: async (context, [source]) => { - const field: FieldToken<'bool'> = { - type: 'RATH.FIELD::bool', - fid: nanoid(), - name: `${source.name} is Zero`, - mode: 'bool', - extInfo: { - extOpt: 'LaTiao.$isZero', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source); - - context.write(field, col.map(d => d === 0 ? 1 : 0)); - - return field; - }, -}); diff --git a/packages/rath-client/src/latiao/program/implement/$log.ts b/packages/rath-client/src/latiao/program/implement/$log.ts deleted file mode 100644 index 1d3123589..000000000 --- a/packages/rath-client/src/latiao/program/implement/$log.ts +++ /dev/null @@ -1,135 +0,0 @@ -import { nanoid } from 'nanoid'; -import { subscribeOperator } from '../operator'; -import { resolveDependencies } from '../parse'; -import type { FieldToken } from '../token'; - - -subscribeOperator({ - name: '$log', - args: ['RATH.FIELD::vec'], - returns: 'RATH.FIELD::vec', - exec: async (context, [source]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `log(${source.name})`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$log', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source) as number[]; - - context.write(field, col.map(d => Math.log(d || NaN))); - - return field; - }, -}); - -subscribeOperator({ - name: '$log1p', - args: ['RATH.FIELD::vec'], - returns: 'RATH.FIELD::vec', - exec: async (context, [source]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `log1p(${source.name})`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$log', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source) as number[]; - - context.write(field, col.map(d => Math.log((1 + d) || NaN))); - - return field; - }, -}); - -subscribeOperator<['RATH.FIELD::vec', 'JS.number'], 'RATH.FIELD::vec'>({ - name: '$log', - args: ['RATH.FIELD::vec', 'JS.number'], - returns: 'RATH.FIELD::vec', - exec: async (context, [source, { value: base }]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `log ${base} (${source.name})`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$log', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source) as number[]; - - context.write(field, col.map(d => Math.log(d) / Math.log(base || NaN))); - - return field; - }, -}); - -subscribeOperator({ - name: '$log2', - args: ['RATH.FIELD::vec'], - returns: 'RATH.FIELD::vec', - exec: async (context, [source]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `log2(${source.name})`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$log2', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source) as number[]; - - context.write(field, col.map(d => Math.log2(d || NaN))); - - return field; - }, -}); - -subscribeOperator({ - name: '$log10', - args: ['RATH.FIELD::vec'], - returns: 'RATH.FIELD::vec', - exec: async (context, [source]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `log10(${source.name})`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$log10', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source) as number[]; - - context.write(field, col.map(d => Math.log10(d || NaN))); - - return field; - }, -}); diff --git a/packages/rath-client/src/latiao/program/implement/$map.ts b/packages/rath-client/src/latiao/program/implement/$map.ts deleted file mode 100644 index 3cfa8afac..000000000 --- a/packages/rath-client/src/latiao/program/implement/$map.ts +++ /dev/null @@ -1,102 +0,0 @@ -/* eslint-disable no-new-func */ -import { nanoid } from 'nanoid'; -import { subscribeOperator } from '../operator'; -import { resolveDependencies } from '../parse'; -import type { FieldToken } from '../token'; - - -subscribeOperator<['RATH.FIELD::vec', 'JS.string'], 'RATH.FIELD::vec'>({ - name: '$map', - args: ['RATH.FIELD::vec', 'JS.string'], - returns: 'RATH.FIELD::vec', - exec: async (context, [source, { value: projectSource }]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${source.name} mapped by ${projectSource}`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$map', - extFrom: resolveDependencies([source.fid], context), - extInfo: { - projector: projectSource, - }, - }, - out: false, - }; - - const origin = await context.col(source) as number[]; - const project = new Function('d', 'i', `return ${projectSource}`) as (d: number, i: number) => any; - - context.write(field, origin.map((d, i) => { - const t = project(d, i); - return typeof t === 'number' ? t : NaN; - })); - - return field; - }, -}); - -subscribeOperator<['RATH.FIELD::set', 'JS.string'], 'RATH.FIELD::set'>({ - name: '$map', - args: ['RATH.FIELD::set', 'JS.string'], - returns: 'RATH.FIELD::set', - exec: async (context, [source, { value: projectSource }]) => { - const field: FieldToken<'set'> = { - type: 'RATH.FIELD::set', - fid: nanoid(), - name: `${source.name} mapped by ${projectSource}`, - mode: 'set', - extInfo: { - extOpt: 'LaTiao.$map', - extFrom: resolveDependencies([source.fid], context), - extInfo: { - projector: projectSource, - }, - }, - out: false, - }; - - const origin = await context.col(source) as number[]; - const project = new Function('d', 'i', `return ${projectSource}`) as (d: number, i: number) => any; - - context.write(field, origin.map((d, i) => { - const t = project(d, i); - return typeof t === 'number' ? t : NaN; - })); - - return field; - }, -}); - -subscribeOperator<['RATH.FIELD::text', 'JS.string'], 'RATH.FIELD::text'>({ - name: '$map', - args: ['RATH.FIELD::text', 'JS.string'], - returns: 'RATH.FIELD::text', - exec: async (context, [source, { value: projectSource }]) => { - const field: FieldToken<'text'> = { - type: 'RATH.FIELD::text', - fid: nanoid(), - name: `${source.name} mapped by ${projectSource}`, - mode: 'text', - extInfo: { - extOpt: 'LaTiao.$map', - extFrom: resolveDependencies([source.fid], context), - extInfo: { - projector: projectSource, - }, - }, - out: false, - }; - - const origin = await context.col(source) as string[]; - const project = new Function('d', 'i', `return ${projectSource}`) as (d: string, i: number) => any; - - context.write(field, origin.map((d, i) => { - const t = project(d, i); - return typeof t === 'string' ? t : ''; - })); - - return field; - }, -}); diff --git a/packages/rath-client/src/latiao/program/implement/$normalize.ts b/packages/rath-client/src/latiao/program/implement/$normalize.ts deleted file mode 100644 index 7ed1fdd04..000000000 --- a/packages/rath-client/src/latiao/program/implement/$normalize.ts +++ /dev/null @@ -1,154 +0,0 @@ -import { nanoid } from 'nanoid'; -import { subscribeOperator } from '../operator'; -import { resolveDependencies } from '../parse'; -import type { FieldToken } from '../token'; - - -subscribeOperator({ - name: '$inset', - args: ['RATH.FIELD::vec'], - returns: 'RATH.FIELD::vec', - exec: async (context, [source]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${source.name} Scaled to -1 ~ +1`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$inset', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source) as number[]; - - const validNum = col.filter(d => Number.isFinite(d)); - - const [min, max] = validNum.reduce<[number, number]>(([_min, _max], d) => [ - Math.min(_min, d), - Math.max(_max, d), - ], [Infinity, -Infinity]); - - context.write(field, col.map(d => (d - min) / (max - min) * 2 - 1)); - - return field; - }, -}); - -subscribeOperator({ - name: '$bound', - args: ['RATH.FIELD::vec'], - returns: 'RATH.FIELD::vec', - exec: async (context, [source]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${source.name} Scaled to 0 ~ 1`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$bound', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source) as number[]; - - const validNum = col.filter(d => Number.isFinite(d)); - - const [min, max] = validNum.reduce<[number, number]>(([_min, _max], d) => [ - Math.min(_min, d), - Math.max(_max, d), - ], [Infinity, -Infinity]); - - context.write(field, col.map(d => (d - min) / (max - min))); - - return field; - }, -}); - -subscribeOperator({ - name: '$normalize', - args: ['RATH.FIELD::vec'], - returns: 'RATH.FIELD::vec', - exec: async (context, [source]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `Normalized ${source.name}`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$normalize', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source) as number[]; - - const validNum = col.filter(d => Number.isFinite(d)); - - const mean = validNum.reduce((sum, d) => sum + d, 0) / validNum.length; - const sd = (validNum.reduce((m, d) => m + ((d - mean) ** 2), 0) / validNum.length) ** 0.5; - - context.write(field, col.map(d => (d - mean) / sd)); - - return field; - }, -}); - -subscribeOperator({ - name: '$ReLU', - args: ['RATH.FIELD::vec'], - returns: 'RATH.FIELD::vec', - exec: async (context, [source]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `ReLU(${source.name})`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$ReLU', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source) as number[]; - - context.write(field, col.map(d => Math.max(0, d))); - - return field; - }, -}); - -subscribeOperator({ - name: '$sigmoid', - args: ['RATH.FIELD::vec'], - returns: 'RATH.FIELD::vec', - exec: async (context, [source]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `S(${source.name})`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$sigmoid', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source) as number[]; - - context.write(field, col.map(d => 1 / (1 + Math.exp(- 1 * d)))); - - return field; - }, -}); diff --git a/packages/rath-client/src/latiao/program/implement/$order.ts b/packages/rath-client/src/latiao/program/implement/$order.ts deleted file mode 100644 index ed63b0217..000000000 --- a/packages/rath-client/src/latiao/program/implement/$order.ts +++ /dev/null @@ -1,116 +0,0 @@ -import { nanoid } from 'nanoid'; -import { subscribeOperator } from '../operator'; -import { resolveDependencies } from '../parse'; -import type { FieldToken } from '../token'; - - -subscribeOperator<['RATH.FIELD::set']>({ - name: '$order', - args: ['RATH.FIELD::set'], - returns: 'RATH.FIELD::set', - exec: async (context, [source]) => { - const field: FieldToken<'set'> = { - type: 'RATH.FIELD::set', - fid: nanoid(), - name: `Order of ${source.name}`, - mode: 'set', - extInfo: { - extOpt: 'LaTiao.$order', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = (await context.col(context.resolveColId(source.fid))) as number[]; - - const sorted = col.map((d, i) => ({ - value: d, - index: i, - })).sort((a, b) => a.value - b.value); - - const order = new Map(); - - sorted.forEach(({ index }, i) => { - order.set(index, i + 1); - }); - - context.write(field, new Array<0>(context.rowCount).fill(0).map((_, i) => order.get(i) as number)); - - return field; - }, -}); - -subscribeOperator<['RATH.FIELD::vec']>({ - name: '$order', - args: ['RATH.FIELD::vec'], - returns: 'RATH.FIELD::set', - exec: async (context, [source]) => { - const field: FieldToken<'set'> = { - type: 'RATH.FIELD::set', - fid: nanoid(), - name: `Order of ${source.name}`, - mode: 'set', - extInfo: { - extOpt: 'LaTiao.$order', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = (await context.col(context.resolveColId(source.fid))) as number[]; - - const sorted = col.map((d, i) => ({ - value: d, - index: i, - })).sort((a, b) => a.value - b.value); - - const order = new Map(); - - sorted.forEach(({ index }, i) => { - order.set(index, i + 1); - }); - - context.write(field, new Array<0>(context.rowCount).fill(0).map((_, i) => order.get(i) as number)); - - return field; - }, -}); - -subscribeOperator<['RATH.FIELD::text']>({ - name: '$dict', - args: ['RATH.FIELD::text'], - returns: 'RATH.FIELD::set', - exec: async (context, [source]) => { - const field: FieldToken<'set'> = { - type: 'RATH.FIELD::set', - fid: nanoid(), - name: `Order of ${source.name}`, - mode: 'set', - extInfo: { - extOpt: 'LaTiao.$order', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = (await context.col(context.resolveColId(source.fid))) as string[]; - - const sorted = col.map((d, i) => ({ - value: d, - index: i, - })).sort((a, b) => a.value.localeCompare(b.value)); - - const order = new Map(); - - sorted.forEach(({ index }, i) => { - order.set(index, i + 1); - }); - - context.write(field, new Array<0>(context.rowCount).fill(0).map((_, i) => order.get(i) as number)); - - return field; - }, -}); diff --git a/packages/rath-client/src/latiao/program/implement/$partition.ts b/packages/rath-client/src/latiao/program/implement/$partition.ts deleted file mode 100644 index 2693c93e4..000000000 --- a/packages/rath-client/src/latiao/program/implement/$partition.ts +++ /dev/null @@ -1,162 +0,0 @@ -/* eslint-disable no-new-func */ -import { nanoid } from 'nanoid'; -import { subscribeOperator } from '../operator'; -import { resolveDependencies } from '../parse'; -import type { FieldListToken, FieldToken } from '../token'; - - -subscribeOperator<['RATH.FIELD::vec', 'JS.string'], 'RATH.FIELD_LIST'>({ - name: '$partition', - args: ['RATH.FIELD::vec', 'JS.string'], - returns: 'RATH.FIELD_LIST', - exec: async (context, [source, { value: predicateSource }]) => { - const fieldTrue: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${source.name} where ${predicateSource}`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$partition', - extFrom: resolveDependencies([source.fid], context), - extInfo: { - predictor: predicateSource, - value: true, - }, - }, - out: false, - }; - - const fieldFalse: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${source.name} where not ${predicateSource}`, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$partition', - extFrom: resolveDependencies([source.fid], context), - extInfo: { - predictor: predicateSource, - value: true, - }, - }, - out: false, - }; - - const fields: FieldListToken = { - type: 'RATH.FIELD_LIST', - tuple: [fieldTrue, fieldFalse], - }; - - const origin = await context.col(source) as number[]; - const predicate = new Function('d', `return ${predicateSource}`) as (d: number) => boolean; - - context.write(fieldTrue, origin.map(d => predicate(d) ? d : NaN)); - context.write(fieldFalse, origin.map(d => predicate(d) ? NaN : d)); - - return fields; - }, -}); - -subscribeOperator<['RATH.FIELD::set', 'JS.string'], 'RATH.FIELD_LIST'>({ - name: '$partition', - args: ['RATH.FIELD::set', 'JS.string'], - returns: 'RATH.FIELD_LIST', - exec: async (context, [source, { value: predicateSource }]) => { - const fieldTrue: FieldToken<'set'> = { - type: 'RATH.FIELD::set', - fid: nanoid(), - name: `${source.name} where ${predicateSource}`, - mode: 'set', - extInfo: { - extOpt: 'LaTiao.$partition', - extFrom: resolveDependencies([source.fid], context), - extInfo: { - predictor: predicateSource, - value: true, - }, - }, - out: false, - }; - - const fieldFalse: FieldToken<'set'> = { - type: 'RATH.FIELD::set', - fid: nanoid(), - name: `${source.name} where not ${predicateSource}`, - mode: 'set', - extInfo: { - extOpt: 'LaTiao.$partition', - extFrom: resolveDependencies([source.fid], context), - extInfo: { - predictor: predicateSource, - value: true, - }, - }, - out: false, - }; - - const fields: FieldListToken = { - type: 'RATH.FIELD_LIST', - tuple: [fieldTrue, fieldFalse], - }; - - const origin = await context.col(source) as number[]; - const predicate = new Function('d', `return ${predicateSource}`) as (d: number) => boolean; - - context.write(fieldTrue, origin.map(d => predicate(d) ? d : NaN)); - context.write(fieldFalse, origin.map(d => predicate(d) ? NaN : d)); - - return fields; - }, -}); - -subscribeOperator<['RATH.FIELD::text', 'JS.string'], 'RATH.FIELD_LIST'>({ - name: '$partition', - args: ['RATH.FIELD::text', 'JS.string'], - returns: 'RATH.FIELD_LIST', - exec: async (context, [source, { value: predicateSource }]) => { - const fieldTrue: FieldToken<'text'> = { - type: 'RATH.FIELD::text', - fid: nanoid(), - name: `${source.name} where ${predicateSource}`, - mode: 'text', - extInfo: { - extOpt: 'LaTiao.$partition', - extFrom: resolveDependencies([source.fid], context), - extInfo: { - predictor: predicateSource, - value: true, - }, - }, - out: false, - }; - - const fieldFalse: FieldToken<'text'> = { - type: 'RATH.FIELD::text', - fid: nanoid(), - name: `${source.name} where not ${predicateSource}`, - mode: 'text', - extInfo: { - extOpt: 'LaTiao.$partition', - extFrom: resolveDependencies([source.fid], context), - extInfo: { - predictor: predicateSource, - value: true, - }, - }, - out: false, - }; - - const fields: FieldListToken = { - type: 'RATH.FIELD_LIST', - tuple: [fieldTrue, fieldFalse], - }; - - const origin = await context.col(source) as string[]; - const predicate = new Function('d', `return ${predicateSource}`) as (d: string) => boolean; - - context.write(fieldTrue, origin.map(d => predicate(d) ? d : '')); - context.write(fieldFalse, origin.map(d => predicate(d) ? '' : d)); - - return fields; - }, -}); diff --git a/packages/rath-client/src/latiao/program/implement/$set.ts b/packages/rath-client/src/latiao/program/implement/$set.ts deleted file mode 100644 index 3c823424a..000000000 --- a/packages/rath-client/src/latiao/program/implement/$set.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { nanoid } from 'nanoid'; -import { subscribeOperator } from '../operator'; -import { resolveDependencies } from '../parse'; -import type { FieldToken } from '../token'; - - -subscribeOperator({ - name: '$set', - args: ['RATH.FIELD::bool'], - returns: 'RATH.FIELD::set', - exec: async (context, [source]) => { - const field: FieldToken<'set'> = { - type: 'RATH.FIELD::set', - fid: nanoid(), - name: source.name, - mode: 'set', - extInfo: { - extOpt: 'LaTiao.$set', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source); - - context.write(field, col.map(d => Number(d))); - - return field; - }, -}); - -subscribeOperator({ - name: '$set', - args: ['RATH.FIELD::text'], - returns: 'RATH.FIELD::set', - exec: async (context, [source]) => { - const field: FieldToken<'set'> = { - type: 'RATH.FIELD::set', - fid: nanoid(), - name: source.name, - mode: 'set', - extInfo: { - extOpt: 'LaTiao.$set', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source); - - context.write(field, col.map(d => Number(d))); - - return field; - }, -}); - -subscribeOperator({ - name: '$set', - args: ['RATH.FIELD::vec'], - returns: 'RATH.FIELD::set', - exec: async (context, [source]) => { - const field: FieldToken<'set'> = { - type: 'RATH.FIELD::set', - fid: nanoid(), - name: source.name, - mode: 'set', - extInfo: { - extOpt: 'LaTiao.$set', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source) as number[]; - - context.write(field, [...col]); - - return field; - }, -}); diff --git a/packages/rath-client/src/latiao/program/implement/$test.ts b/packages/rath-client/src/latiao/program/implement/$test.ts deleted file mode 100644 index fdae7c054..000000000 --- a/packages/rath-client/src/latiao/program/implement/$test.ts +++ /dev/null @@ -1,99 +0,0 @@ -/* eslint-disable no-new-func */ -import { nanoid } from 'nanoid'; -import { subscribeOperator } from '../operator'; -import { resolveDependencies } from '../parse'; -import type { FieldToken } from '../token'; - - -subscribeOperator<['RATH.FIELD::vec', 'JS.string'], 'RATH.FIELD::bool'>({ - name: '$test', - args: ['RATH.FIELD::vec', 'JS.string'], - returns: 'RATH.FIELD::bool', - exec: async (context, [source, { value: projectSource }]) => { - const field: FieldToken<'bool'> = { - type: 'RATH.FIELD::bool', - fid: nanoid(), - name: `${source.name} tested by ${projectSource}`, - mode: 'bool', - extInfo: { - extOpt: 'LaTiao.$test', - extFrom: resolveDependencies([source.fid], context), - extInfo: { - projector: projectSource, - }, - }, - out: false, - }; - - const origin = await context.col(source) as number[]; - const project = new Function('d', 'i', `return Boolean(${projectSource}) ? 1 : 0`) as (d: number, i: number) => 0 | 1; - - context.write(field, origin.map((d, i) => { - return project(d, i); - })); - - return field; - }, -}); - -subscribeOperator<['RATH.FIELD::set', 'JS.string'], 'RATH.FIELD::bool'>({ - name: '$test', - args: ['RATH.FIELD::set', 'JS.string'], - returns: 'RATH.FIELD::bool', - exec: async (context, [source, { value: projectSource }]) => { - const field: FieldToken<'bool'> = { - type: 'RATH.FIELD::bool', - fid: nanoid(), - name: `${source.name} tested by ${projectSource}`, - mode: 'bool', - extInfo: { - extOpt: 'LaTiao.$test', - extFrom: resolveDependencies([source.fid], context), - extInfo: { - projector: projectSource, - }, - }, - out: false, - }; - - const origin = await context.col(source) as number[]; - const project = new Function('d', 'i', `return Boolean(${projectSource}) ? 1 : 0`) as (d: number, i: number) => 0 | 1; - - context.write(field, origin.map((d, i) => { - return project(d, i); - })); - - return field; - }, -}); - -subscribeOperator<['RATH.FIELD::text', 'JS.string'], 'RATH.FIELD::bool'>({ - name: '$test', - args: ['RATH.FIELD::text', 'JS.string'], - returns: 'RATH.FIELD::bool', - exec: async (context, [source, { value: projectSource }]) => { - const field: FieldToken<'bool'> = { - type: 'RATH.FIELD::bool', - fid: nanoid(), - name: `${source.name} tested by ${projectSource}`, - mode: 'bool', - extInfo: { - extOpt: 'LaTiao.$test', - extFrom: resolveDependencies([source.fid], context), - extInfo: { - projector: projectSource, - }, - }, - out: false, - }; - - const origin = await context.col(source) as string[]; - const project = new Function('d', 'i', `return Boolean(${projectSource}) ? 1 : 0`) as (d: string, i: number) => 0 | 1; - - context.write(field, origin.map((d, i) => { - return project(d, i); - })); - - return field; - }, -}); diff --git a/packages/rath-client/src/latiao/program/implement/$text.ts b/packages/rath-client/src/latiao/program/implement/$text.ts deleted file mode 100644 index b311a5995..000000000 --- a/packages/rath-client/src/latiao/program/implement/$text.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { nanoid } from 'nanoid'; -import { subscribeOperator } from '../operator'; -import { resolveDependencies } from '../parse'; -import type { FieldToken } from '../token'; - - -subscribeOperator({ - name: '$nominal', - args: ['RATH.FIELD::bool'], - returns: 'RATH.FIELD::text', - exec: async (context, [source]) => { - const field: FieldToken<'text'> = { - type: 'RATH.FIELD::text', - fid: nanoid(), - name: source.name, - mode: 'text', - extInfo: { - extOpt: 'LaTiao.$text', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source); - - context.write(field, col.map(d => String(d))); - - return field; - }, -}); - -subscribeOperator({ - name: '$nominal', - args: ['RATH.FIELD::set'], - returns: 'RATH.FIELD::text', - exec: async (context, [source]) => { - const field: FieldToken<'text'> = { - type: 'RATH.FIELD::text', - fid: nanoid(), - name: source.name, - mode: 'text', - extInfo: { - extOpt: 'LaTiao.$text', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source); - - context.write(field, col.map(d => String(d))); - - return field; - }, -}); - -subscribeOperator({ - name: '$nominal', - args: ['RATH.FIELD::vec'], - returns: 'RATH.FIELD::text', - exec: async (context, [source]) => { - const field: FieldToken<'text'> = { - type: 'RATH.FIELD::text', - fid: nanoid(), - name: source.name, - mode: 'text', - extInfo: { - extOpt: 'LaTiao.$text', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source); - - context.write(field, col.map(d => String(d))); - - return field; - }, -}); diff --git a/packages/rath-client/src/latiao/program/implement/$toDate.ts b/packages/rath-client/src/latiao/program/implement/$toDate.ts deleted file mode 100644 index ff5c89e1f..000000000 --- a/packages/rath-client/src/latiao/program/implement/$toDate.ts +++ /dev/null @@ -1,264 +0,0 @@ -import { nanoid } from 'nanoid'; -import dayjs from 'dayjs'; -import type { IFieldExtInfoBaseDateTime } from '../../../interfaces'; -import { subscribeOperator } from '../operator'; -import { resolveDependencies } from '../parse'; -import type { DateObjectDimension, DateToken, FieldListToken, FieldToken } from '../token'; -import { $DateToField } from './date-slice'; - - -const parseDateTime = (col: readonly string[] | readonly number[]): number[] => { - return col.map(d => dayjs(d).toDate().getTime()); -}; - -subscribeOperator({ - name: '$toDate', - args: ['RATH.FIELD::set'], - returns: '$DATE', - exec: async (context, [source]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `DateTime (${source.fid})`, - mode: 'vec', - out: false, - extInfo: { - extOpt: 'dateTimeExpand', - extFrom: [source.fid], - extInfo: 'utime', - }, - }; - - const col = await context.col(source); - - const utime = parseDateTime(col); - - context.write(field, utime); - - const date: DateToken = { - type: '$DATE', - source: field, - dimensions: 'all', - exports: false, - }; - - return date; - }, -}); - -subscribeOperator({ - name: '$toDate', - args: ['RATH.FIELD::vec'], - returns: '$DATE', - exec: async (context, [source]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `DateTime (${source.fid})`, - mode: 'vec', - out: false, - extInfo: { - extOpt: 'dateTimeExpand', - extFrom: [source.fid], - extInfo: 'utime', - }, - }; - - const col = await context.col(source); - - const utime = parseDateTime(col); - - context.write(field, utime); - - const date: DateToken = { - type: '$DATE', - source: field, - dimensions: 'all', - exports: false, - }; - - return date; - }, -}); - -subscribeOperator({ - name: '$toDate', - args: ['RATH.FIELD::text'], - returns: '$DATE', - exec: async (context, [source]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `DateTime (${source.fid})`, - mode: 'vec', - out: false, - extInfo: { - extOpt: 'dateTimeExpand', - extFrom: [source.fid], - extInfo: 'utime', - }, - }; - - const col = await context.col(source); - - const utime = parseDateTime(col); - - context.write(field, utime); - - const date: DateToken = { - type: '$DATE', - source: field, - dimensions: 'all', - exports: false, - }; - - return date; - }, -}); - -subscribeOperator({ - name: '$toDate', - args: ['$DATE'], - returns: '$DATE', - exec: async (context, [source]) => { - const base = source.source; - - const date: DateToken = { - type: '$DATE', - source: base, - dimensions: 'all', - exports: false, - }; - - return date; - }, -}); - -subscribeOperator({ - name: '$isValidDate', - args: ['$DATE'], - returns: 'RATH.FIELD::bool', - exec: async (context, [date]) => { - const data = $DateToField(date); - - const field: FieldToken<'bool'> = { - type: 'RATH.FIELD::bool', - fid: nanoid(), - name: `${(date.exports ?? date.source.name) || (date.source.name || date.source.fid)} is Valid Date`, - mode: 'bool', - extInfo: { - extOpt: 'LaTiao.$isValidDate', - extFrom: resolveDependencies([data.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(data); - - const dt = parseDateTime(col); - - context.write(field, dt.map(d => Number.isFinite(d) && d >= 0 ? 1 : 0)); - - return field; - }, -}); - -subscribeOperator<['$DATE', 'JS.string'], 'RATH.FIELD_LIST'>({ - name: '$__sliceDate', - secret: true, - args: ['$DATE', 'JS.string'], - returns: 'RATH.FIELD_LIST', - exec: async (context, [date, slicer]) => { - const source = $DateToField(date); - const utime = await context.col(source); - const dims = slicer.value.split('') as DateObjectDimension[]; - - const fields: FieldListToken = { - type: 'RATH.FIELD_LIST', - tuple: [], - }; - - for await (const dim of dims) { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${dim} | ${source.name}`, - mode: 'vec', - extInfo: { - extOpt: 'dateTimeExpand', - extFrom: resolveDependencies([source.fid], context), - extInfo: ({ - Y: '$y', - M: '$M', - W: '$W', - D: '$D', - h: '$H', - m: '$m', - s: '$s', - } as const)[dim], - } as IFieldExtInfoBaseDateTime, - out: false, - }; - - context.write(field, utime.map(d => new Date(d)[({ - Y: 'getFullYear', - M: 'getMonth', - W: 'getDay', - D: 'getDate', - h: 'getHours', - m: 'getMinutes', - s: 'getSeconds', - } as const)[dim]]() + (dim === 'M' ? 1 : 0))); - - fields.tuple.push(field); - } - - return fields; - }, -}); - -subscribeOperator<['$DATE', 'JS.string'], 'RATH.FIELD::vec'>({ - name: '$__projDate', - secret: true, - args: ['$DATE', 'JS.string'], - returns: 'RATH.FIELD::vec', - exec: async (context, [date, slicer]) => { - const source = $DateToField(date); - const utime = await context.col(source); - const [dim] = slicer.value.split('') as DateObjectDimension[]; - - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: `${dim} | ${source.name}`, - mode: 'vec', - extInfo: { - extOpt: 'dateTimeExpand', - extFrom: resolveDependencies([source.fid], context), - extInfo: ({ - Y: '$y', - M: '$M', - W: '$W', - D: '$D', - h: '$H', - m: '$m', - s: '$s', - } as const)[dim], - } as IFieldExtInfoBaseDateTime, - out: false, - }; - - context.write(field, utime.map(d => new Date(d)[({ - Y: 'getFullYear', - M: 'getMonth', - W: 'getDay', - D: 'getDate', - h: 'getHours', - m: 'getMinutes', - s: 'getSeconds', - } as const)[dim]]() + (dim === 'M' ? 1 : 0))); - - return field; - }, -}); diff --git a/packages/rath-client/src/latiao/program/implement/$vec.ts b/packages/rath-client/src/latiao/program/implement/$vec.ts deleted file mode 100644 index d19fd358a..000000000 --- a/packages/rath-client/src/latiao/program/implement/$vec.ts +++ /dev/null @@ -1,83 +0,0 @@ -import { nanoid } from 'nanoid'; -import { subscribeOperator } from '../operator'; -import { resolveDependencies } from '../parse'; -import type { FieldToken } from '../token'; - - -subscribeOperator({ - name: '$vec', - args: ['RATH.FIELD::bool'], - returns: 'RATH.FIELD::vec', - exec: async (context, [source]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: source.name, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$vec', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source); - - context.write(field, col.map(d => d)); - - return field; - }, -}); - -subscribeOperator({ - name: '$vec', - args: ['RATH.FIELD::text'], - returns: 'RATH.FIELD::vec', - exec: async (context, [source]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: source.name, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$vec', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source); - - context.write(field, col.map(d => Number(d))); - - return field; - }, -}); - -subscribeOperator({ - name: '$vec', - args: ['RATH.FIELD::set'], - returns: 'RATH.FIELD::vec', - exec: async (context, [source]) => { - const field: FieldToken<'vec'> = { - type: 'RATH.FIELD::vec', - fid: nanoid(), - name: source.name, - mode: 'vec', - extInfo: { - extOpt: 'LaTiao.$vec', - extFrom: resolveDependencies([source.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(source) as number[]; - - context.write(field, [...col]); - - return field; - }, -}); diff --git a/packages/rath-client/src/latiao/program/implement/date-slice.ts b/packages/rath-client/src/latiao/program/implement/date-slice.ts deleted file mode 100644 index d45f95d12..000000000 --- a/packages/rath-client/src/latiao/program/implement/date-slice.ts +++ /dev/null @@ -1,27 +0,0 @@ -import { LaTiaoTypeError } from '../error'; -import type { DateObjectDimension, DateToken, FieldToken } from '../token'; - - -export const $DateToField = (date: DateToken): FieldToken => { - return date.source; -}; - -export const validDateSlice = (key: string): DateObjectDimension[] => { - if (!key.match(/^[YMWDhms]+$/)) { - throw new LaTiaoTypeError(`"${key}" is not a valid Date slice.`); - } - - const set = new Set(); - const list: DateObjectDimension[] = []; - - for (const char of key) { - if (set.has(char as DateObjectDimension)) { - throw new LaTiaoTypeError(`Duplicated dimension "${char}".`); - } - - set.add(char as DateObjectDimension); - list.push(char as DateObjectDimension); - } - - return list; -}; diff --git a/packages/rath-client/src/latiao/program/implement/index.ts b/packages/rath-client/src/latiao/program/implement/index.ts deleted file mode 100644 index d9d1e1e71..000000000 --- a/packages/rath-client/src/latiao/program/implement/index.ts +++ /dev/null @@ -1,19 +0,0 @@ -// setup -import './$set'; -import './$vec'; -import './$text'; -import './$bool'; -import './$binary'; -import './$id'; -import './$order'; -import './$isNaN'; -import './$isZero'; -import './$normalize'; -import './$concat'; -import './$log'; -import './$clean'; -import './regex'; -import './$partition'; -import './$map'; -import './$test'; -import './$toDate'; diff --git a/packages/rath-client/src/latiao/program/implement/regex.ts b/packages/rath-client/src/latiao/program/implement/regex.ts deleted file mode 100644 index be69e736f..000000000 --- a/packages/rath-client/src/latiao/program/implement/regex.ts +++ /dev/null @@ -1,61 +0,0 @@ -import { nanoid } from 'nanoid'; -import { subscribeOperator } from '../operator'; -import { resolveDependencies } from '../parse'; -import type { FieldToken } from '../token'; - - -subscribeOperator<['RATH.FIELD::text', 'JS.string'], 'RATH.FIELD::text'>({ - name: '$match', - args: ['RATH.FIELD::text', 'JS.string'], - returns: 'RATH.FIELD::text', - exec: async (context, [f, pattern]) => { - const field: FieldToken<'text'> = { - type: 'RATH.FIELD::text', - fid: nanoid(), - name: `Pattern matched {${f.name}}`, - mode: 'text', - extInfo: { - extOpt: 'LaTiao.$match', - extFrom: resolveDependencies([f.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(f) as string[]; - - const matched = col.map(str => new RegExp(pattern.value).exec(str)?.[0] ?? ''); - - context.write(field, matched); - - return field; - }, -}); - -subscribeOperator<['RATH.FIELD::text', 'JS.string', 'JS.string'], 'RATH.FIELD::text'>({ - name: '$replace', - args: ['RATH.FIELD::text', 'JS.string', 'JS.string'], - returns: 'RATH.FIELD::text', - exec: async (context, [f, pattern, newStr]) => { - const field: FieldToken<'text'> = { - type: 'RATH.FIELD::text', - fid: nanoid(), - name: `Pattern replaced {${f.name}}`, - mode: 'text', - extInfo: { - extOpt: 'LaTiao.$replace', - extFrom: resolveDependencies([f.fid], context), - extInfo: '', - }, - out: false, - }; - - const col = await context.col(f) as string[]; - - const replaced = col.map(str => str.replaceAll(new RegExp(pattern.value, 'g'), newStr.value)) - - context.write(field, replaced); - - return field; - }, -}); diff --git a/packages/rath-client/src/latiao/program/index.ts b/packages/rath-client/src/latiao/program/index.ts deleted file mode 100644 index 719fc40db..000000000 --- a/packages/rath-client/src/latiao/program/index.ts +++ /dev/null @@ -1,130 +0,0 @@ -import type { IRow } from 'visual-insights'; -import type { IRawField } from '../../interfaces'; -import { workerService } from '../../services/base'; -import { LaTiaoError } from './error'; -import type { FieldToken, FieldType } from './token'; -// @ts-ignore -import LTWorker from './program.worker?worker'; - -import type { - CreateLaTiaoProgramProps, - CreateLaTiaoProgramResult, - DestroyLaTiaoProgramProps, - ExecuteLaTiaoProgramProps, - ExecuteLaTiaoProgramResult, - ILaTiaoColumn, - Static, -} from './types'; - - -// @ts-ignore -const programWorker = new LTWorker() as Worker; - -export type Program = { - run: (source: string) => Promise; - onError: (handler: (err: LaTiaoError) => void) => void; - destroy: () => void; -}; - -export const createProgram = ( - data: Readonly, - fields: Omit[], - load: (fields: Static, data: Static<(number[] | string[])[]>) => void, -): Program => { - let programId: number | undefined = undefined; - let errHandler: (err: LaTiaoError) => void = err => { - throw err; - }; - - const program: Program = { - run: async source => { - if (programId === undefined) { - throw new Error('Program is not loaded yet.'); - } - try { - const result = await workerService(programWorker, { - task: 'execute', - programId, - source, - }); - if (result.success) { - load(result.data.enter, result.data.columns); - return 0; - } else { - throw new LaTiaoError(result.message); - } - } catch (error) { - if (error instanceof LaTiaoError) { - errHandler(error); - return -1; - } - throw error; - } - }, - onError: handler => { - errHandler = handler; - }, - destroy: () => { - if (programId === undefined) { - throw new Error('Program is not loaded yet.'); - } - workerService(programWorker, { - task: 'destroyProgram', - programId, - }); - }, - }; - - const columns: ILaTiaoColumn[] = []; - - for (const f of fields) { - const header: CreateLaTiaoProgramProps['data'][number]['info'] = { - token: { - ...f, - type: `RATH.FIELD::${f.mode}`, - }, - }; - const col = data.map(row => (f.mode === 'text' ? String : f.mode === 'bool' ? ((d: any) => d ? 1 : 0) : Number)(row[f.fid])) as number[] | string[] | (0 | 1)[]; - columns.push({ - info: header, - data: col, - }); - } - - try { - workerService(programWorker, { - task: 'createProgram', - data: columns, - }).then(result => { - if (result.success) { - programId = result.data.programId; - } else { - throw new Error(result.message); - } - }); - } catch (error) { - console.error(error); - } - - return program; -}; - -export const resolveFields = (tokens: Static): IRawField[] => { - return tokens.map(token => ({ - fid: token.fid, - name: token.name, - analyticType: token.extInfo?.extOpt === 'dateTimeExpand' ? 'dimension' : token.mode === 'vec' ? 'measure' : 'dimension', - semanticType: token.extInfo?.extOpt === 'dateTimeExpand' ? ( - token.extInfo.extInfo === 'utime' ? 'temporal' : token.extInfo.extInfo === '$y' ? 'quantitative' : 'ordinal' - ) : ({ - bool: 'nominal', - vec: 'quantitative', - set: 'ordinal', - text: 'nominal', - } as const)[token.mode], - geoRole: 'none', - })); -}; - - -export default createProgram; diff --git a/packages/rath-client/src/latiao/program/operator.ts b/packages/rath-client/src/latiao/program/operator.ts deleted file mode 100644 index 6c167d6cc..000000000 --- a/packages/rath-client/src/latiao/program/operator.ts +++ /dev/null @@ -1,93 +0,0 @@ -import { LaTiaoError, LaTiaoNameError, LaTiaoTypeError } from './error'; -import type { TokenType, Token, OpToken, FieldToken, FieldType } from './token'; -import type { LaTiaoProgramContext } from './types'; - - -export type OperatorName = `$${string}`; - -type MapParameter = ( - T extends `RATH.FIELD::${infer P}` ? P extends FieldType ? FieldToken

: FieldToken : Token & { type: T } -); - -type MapParameters = { - [index in keyof A]: MapParameter; -}; - -type MapReturnType = Token & { type: R }; - -export type Operator< - A extends Exclude[] = Exclude[], - R extends Exclude = Exclude, - M extends Exclude | null = Exclude | null, - P extends MapParameters = MapParameters, - S extends MapReturnType = MapReturnType, -> = { - name: OperatorName; - args: Readonly; - returns: R; - /** @default false */ - secret?: boolean; - trailing?: M; - exec: ( - context: LaTiaoProgramContext, - args: M extends Exclude ? [...P, ...MapParameters] : P, - ) => Promise; -}; - -const operators: Operator[] = []; - -export const subscribeOperator = < - A extends Exclude[] = Exclude[], - R extends Exclude = Exclude, - M extends Exclude | null = null, - P extends MapParameters = MapParameters, - S extends MapReturnType = MapReturnType, ->(op: Operator): void => { - operators.push(op as unknown as Operator); -}; - -export const getOperator = (op: Omit, loc?: ConstructorParameters[1]): Readonly => { - const overloads = operators.filter(o => o.name === op.op); - - if (overloads.length === 0) { - throw new LaTiaoNameError(`"${op.op}" is not an operator.`, loc); - } - - const input = op.args.map(arg => arg.type === 'OP' ? arg.output : arg.type); - - for (const overload of overloads) { - if (overload.trailing) { - if (!input.slice(0, overload.args.length).every((type, i) => type === overload.args[i])) { - continue; - } - if (!input.slice(overload.args.length).every(type => type === overload.trailing)) { - continue; - } - - return overload; - } - - if (overload.args.length !== op.args.length) { - continue; - } - - if (!overload.args.every((arg, i) => arg === input[i])) { - continue; - } - - return overload; - } - - throw new LaTiaoTypeError( - `No overload of ${op.op} matches arguments: [${input.join(', ')}]\nPossible overloads: ${ - overloads.map((o, i) => `\n [${i + 1}] ${op.op}(${o.args.join(', ')}${ - o.trailing ? `${o.args.length ? ', ' : ''}...${o.trailing}` : '' - })`).join('') - }`, - loc - ); -}; - -export const getOperatorList = () => { - return operators.filter(op => !op.secret) as readonly Readonly[]; -}; diff --git a/packages/rath-client/src/latiao/program/parse.ts b/packages/rath-client/src/latiao/program/parse.ts deleted file mode 100644 index 92e55f737..000000000 --- a/packages/rath-client/src/latiao/program/parse.ts +++ /dev/null @@ -1,388 +0,0 @@ -import { parse as p } from '@babel/parser'; -import { validDateSlice } from './implement/date-slice'; -import { LaTiaoSyntaxError, LaTiaoTypeError } from './error'; -import { getOperator } from './operator'; -import type { OpToken, Token, TokenType } from './token'; -import type { LaTiaoProgramContext, Static } from './types'; - - -export type ASTExpression = (ReturnType['program']['body'][0] & { - type: 'ExpressionStatement'; -})['expression']; - -export type ASTNode = {}; - -export const prefix = `/* LaTiao 100 */ - -function main() { -`; - -export const suffix = ` -} -`; - -export const validNameRegExp = /^[^$\s,.;:'"`+\-~!?<>@#%^&*/\\|]+$/; - -const translate = (source: string): string => { - return `${prefix}${ - source.replaceAll( - /\b(out)\b(\s+(?[^$\s,.;:'"`+\-~!?<>@#%^&*/\\|]+))?/g, - (_a0, _a1, _a2, _a3, _a4, _a5, { id }: { id: string | undefined }) => { - if (id && !validNameRegExp.test(id)) { - throw new LaTiaoSyntaxError(`"${id}" is not a valid field id.`); - } - - return `$${id ?? ''} = `; - } - ) - }${suffix}`; -}; - -const resolveMemberExp = (exp: ASTExpression & { type: 'MemberExpression' }): (ASTExpression & { type: 'MemberExpression' })[] => { - if ( - exp.object.type === 'CallExpression' - && exp.object.callee.type === 'Identifier' - && exp.object.callee.name === '$toDate' - && exp.property.type === 'Identifier' - ) { - validDateSlice(exp.property.name); - - return [exp]; - } - - throw new LaTiaoTypeError( - 'Left value does not support slice.', - exp, - ); -}; - -const findEntry = (res: ReturnType) => { - const body = res.program.body[0]; - - if (body.type === 'FunctionDeclaration' && body.id?.name === 'main' && body.body.body.length === 1) { - const statement = body.body.body[0]; - - if (statement.type !== 'ExpressionStatement') { - return []; - } - - const expression = statement.expression; - - switch (expression.type) { - case 'CallExpression': { - return [expression]; - } - case 'BinaryExpression': { - return [expression]; - } - case 'AssignmentExpression': { - return [expression]; - } - case 'MemberExpression': { - return resolveMemberExp(expression); - } - case 'SequenceExpression': { - if (expression.expressions.every(exp => ['CallExpression', 'AssignmentExpression'].includes(exp.type))) { - return expression.expressions as (typeof expression & { type: 'CallExpression' | 'AssignmentExpression' })[]; - } - - return []; - } - default: { - return []; - } - } - } - - return []; -}; - -export type Statement = ReturnType['program']['body'][0]; -export type ExportExpression = ReturnType[0] & { type: 'AssignmentExpression' }; -export type CallExpression = ReturnType[0] & { type: 'CallExpression' }; -export type SliceExpression = ReturnType[0] & { type: 'MemberExpression' }; -export type BinOpExpression = ReturnType[0] & { type: 'BinaryExpression' }; - -const resolveNode = (exp: CallExpression['arguments'][0], context: LaTiaoProgramContext, out: () => void): Static => { - switch (exp.type) { - case 'Identifier': { - const { name } = exp; - const field = context.resolveColId(name); - - return field; - } - case 'CallExpression': { - return resolveCall(exp, context, out); - } - case 'AssignmentExpression': { - return resolveExport(exp, context, out); - } - case 'MemberExpression': { - return resolveSlice(exp, context, out); - } - case 'StringLiteral': { - return { - type: 'JS.string', - value: exp.value, - }; - } - case 'NumericLiteral': { - return { - type: 'JS.number', - value: exp.value, - }; - } - case 'BinaryExpression': { - return resolveBinOp(exp, context, out); - } - default: { - throw new LaTiaoSyntaxError( - 'Unexpected token.', - exp, - ); - } - } -}; - -const resolveExport = (exp: ExportExpression, context: LaTiaoProgramContext, out: () => void): OpToken => { - if (exp.operator !== '=' || exp.left.type !== 'Identifier' || !exp.left.name.startsWith('$')) { - throw new LaTiaoSyntaxError('Failed to parse', exp); - } - - const name = exp.left.name.replace(/^\$/, ''); - - if (name && !validNameRegExp.test(name)) { - throw new LaTiaoSyntaxError(`"${name}" is not a valid field id.`); - } - - if (exp.right.type === 'MemberExpression') { - const op = resolveSlice(exp.right, context, out); - - out(); - - return { - ...op, - exports: name, - }; - } else if (exp.right.type === 'BinaryExpression') { - const op = resolveBinOp(exp.right, context, out); - - out(); - - return { - ...op, - exports: name, - }; - } - - if (exp.right.type !== 'CallExpression' || exp.right.callee.type !== 'Identifier') { - throw new LaTiaoSyntaxError( - 'Expect operator here.', - exp, - ); - } - - const op = resolveCall(exp.right, context, out); - - out(); - - return { - ...op, - exports: name, - }; -}; - -const resolveSlice = (exp: SliceExpression, context: LaTiaoProgramContext, out: () => void): OpToken => { - const targetOp = exp.object.type === 'AssignmentExpression' ? resolveExport(exp.object, context, out) - : exp.object.type === 'CallExpression' ? resolveCall(exp.object, context, out) - : null; - - if (!targetOp) { - throw new LaTiaoTypeError( - 'Left value does not support slice.', - exp, - ); - } - - const target = getOperator(targetOp); - - if (target.returns === '$DATE') { - if (exp.property.type !== 'Identifier' || !exp.property.name) { - throw new LaTiaoTypeError( - 'Invalid slice call.', - exp, - ); - } - - const sliceKey = exp.property.name; - - validDateSlice(sliceKey); - - const op: OpToken = { - type: 'OP', - op: sliceKey.length === 1 ? '$__projDate' : '$__sliceDate', - args: [targetOp, { - type: 'JS.string', - value: sliceKey, - }], - output: sliceKey.length === 1 ? 'RATH.FIELD::vec' : 'RATH.FIELD_LIST', - exports: false, - }; - - return op; - } - - throw new LaTiaoTypeError( - 'Left value does not support slice.', - exp, - ); -}; - -const resolveBinOp = (exp: BinOpExpression, context: LaTiaoProgramContext, out: () => void): OpToken => { - if (exp.left.type === 'PrivateName') { - throw new LaTiaoSyntaxError( - 'Unexpected token.', - exp, - ); - } - - const left = resolveNode(exp.left, context, out); - const right = resolveNode(exp.right, context, out); - - switch (exp.operator) { - case '+': { - return { - type: 'OP', - op: '$__add', - args: [left, right], - output: 'RATH.FIELD::vec', - exports: false, - }; - } - case '-': { - return { - type: 'OP', - op: '$__minus', - args: [left, right], - output: 'RATH.FIELD::vec', - exports: false, - }; - } - case '*': { - return { - type: 'OP', - op: '$__multiply', - args: [left, right], - output: 'RATH.FIELD::vec', - exports: false, - }; - } - case '/': { - return { - type: 'OP', - op: '$__divide', - args: [left, right], - output: 'RATH.FIELD::vec', - exports: false, - }; - } - default: { - throw new LaTiaoSyntaxError( - `Invalid syntax: ${exp.operator}.`, - exp, - ); - } - } -}; - -const resolveCall = (exp: CallExpression, context: LaTiaoProgramContext, out: () => void): OpToken => { - const opName = exp.callee.type === 'Identifier' ? exp.callee.name : null; - - if (!opName || !opName.startsWith('$')) { - throw new LaTiaoSyntaxError( - 'Expect operator here.', - exp, - ); - } - - const args: Static = exp.arguments.map(arg => { - return resolveNode(arg, context, out); - }); - - const op: OpToken = { - type: 'OP', - op: opName as `$${string}`, - args, - output: '' as Exclude, - exports: false, - }; - - const opr = getOperator(op); - - op.output = opr.returns; - - return op; -}; - -export const resolveDependencies = (sources: readonly string[], context: LaTiaoProgramContext): string[] => { - return sources.reduce((list, source) => { - const field = context.resolveColId(source); - - if (field.out !== false) { - list.push(source); - } else if (field.extInfo) { - list.push(...resolveDependencies(field.extInfo.extFrom, context)); - } - - return list; - }, []); -}; - -const parse = (source: string, context: LaTiaoProgramContext): OpToken[] => { - let expCount = 0; - - let res = undefined as unknown as ReturnType; - - try { - res = p(translate(source)); - } catch (error) { - throw new LaTiaoSyntaxError( - 'Failed to parse.', - ); - } - - const body = findEntry(res); - - if (body.length === 0) { - throw new LaTiaoSyntaxError( - 'Expect one sentence.', - res, - ); - } - - const root = body.map( - t => ( - t.type === 'AssignmentExpression' ? resolveExport( - t, context, () => expCount += 1 - ) : t.type === 'MemberExpression' ? resolveSlice( - t, context, () => expCount += 1 - ) : t.type === 'BinaryExpression' ? resolveBinOp( - t, context, () => expCount += 1 - ) : resolveCall( - t, context, () => expCount += 1 - ) - ) - ); - - if (expCount === 0) { - throw new LaTiaoSyntaxError( - 'Expression should includes at least one "out" flag to export columns.', - res, - ); - } - - return root; -}; - - -export default parse; diff --git a/packages/rath-client/src/latiao/program/program.worker.ts b/packages/rath-client/src/latiao/program/program.worker.ts deleted file mode 100644 index e44dc8238..000000000 --- a/packages/rath-client/src/latiao/program/program.worker.ts +++ /dev/null @@ -1,188 +0,0 @@ -/* eslint-disable no-restricted-globals */ -import { LaTiaoError, LaTiaoNameError } from "./error"; -import './operator'; -import './implement/index'; -import parse from "./parse"; -import exec from './exec'; -import type { FieldToken, FieldType } from "./token"; -import type { LaTiaoProgramContext, CreateLaTiaoProgramProps, CreateLaTiaoProgramResult, ILaTiaoColumn, LaTiaoErrorLocation, Static, ExecuteLaTiaoProgramResult, LaTiaoProgramProps } from "./types"; - - -const programStores = new Map(); -let programCount = 0; - -const createProgram = (data: CreateLaTiaoProgramProps['data']): ( - | { success: true; data: CreateLaTiaoProgramResult } - | { success: false; message: string } -) => { - try { - const programId = programCount++; - - const originData = data; - const tempData: ILaTiaoColumn[] = []; - const rowCount = data[0]?.data.length ?? 0; - - const resolveColId = (colId: string, loc: LaTiaoErrorLocation): Static => { - const fieldAsOrigin = originData.find(col => col.info.token.fid === colId); - if (fieldAsOrigin) { - return fieldAsOrigin.info.token; - } - const fieldAsTemp = tempData.find(col => col.info.token.fid === colId); - if (fieldAsTemp) { - return fieldAsTemp.info.token; - } - throw new LaTiaoNameError(`Cannot find column "${colId}"`, loc); - }; - - const col = (async < - T extends FieldType = FieldType, - D extends T extends 'collection' ? string[] : number[] = T extends 'collection' ? string[] : number[], - >(field: Static>, loc?: LaTiaoErrorLocation): Promise> => { - const { fid: colId } = field; - const fieldAsOrigin = originData.find(col => col.info.token.fid === colId); - if (fieldAsOrigin) { - return fieldAsOrigin.data as Static; - } - const fieldAsTemp = tempData.find(col => col.info.token.fid === colId); - if (fieldAsTemp) { - return fieldAsTemp.data as Static; - } - throw new LaTiaoNameError(`Cannot find column "${colId}"`, loc); - }) as LaTiaoProgramContext['col']; - - const cols = async < - T extends FieldType[] = FieldType[], - D extends { - [index in keyof T]: T extends 'collection' ? string[] : number[] - } = { - [index in keyof T]: T extends 'collection' ? string[] : number[] - }, - >(fields: Static<{ [index in keyof T]: FieldToken }>, loc?: LaTiaoErrorLocation): Promise> => { - const res = await Promise.all(fields.map(f => context.col(f, loc))); - return res as Static; - }; - - const write = (< - T extends FieldType = FieldType, - D extends T extends 'collection' ? string[] : T extends 'bool' ? (0 | 1)[] : number[] = T extends 'collection' ? string[] : T extends 'bool' ? (0 | 1)[] : number[], - >( - field: FieldToken, - data: D, - ): void => { - if ([...originData, ...tempData].find(col => col.info.token.fid === field.fid)) { - throw new LaTiaoNameError(`Column ${field.fid} already existed.`); - } - tempData.push({ - info: { token: field }, - data, - }); - }) as LaTiaoProgramContext['write']; - - let reportError = (err: LaTiaoError): void => { - throw err; - }; - - const context: LaTiaoProgramContext = { - programId, - originData, - tempData: [], - rowCount, - resolveColId, - col, - cols, - write, - reportError, - }; - - programStores.set(programId, context); - - const res: CreateLaTiaoProgramResult = { - programId, - }; - - return { - success: true, - data: res, - }; - } catch (error) { - return { - success: false, - message: `${error}` - }; - } -}; - -const execute = async (programId: number, source: string): Promise<( - | { success: true; data: ExecuteLaTiaoProgramResult } - | { success: false; message: string } -)> => { - try { - const context = programStores.get(programId); - if (!context) { - throw new Error(`Program id not found: ${programId}`); - } - const ast = parse(source, context); - - const expArr = await exec(ast, context); - - const enter = expArr.map(fid => context.resolveColId(fid)); - const data = await context.cols(enter); - - return { - success: true, - data: { data: [], enter, columns: data }, - }; - } catch (error) { - return { - success: false, - message: `${error}` - }; - } -}; - -const destroyProgram = (programId: number): ( - | { success: true; data: true } - | { success: false; message: string } -) => { - try { - if (programStores.delete(programId)) { - return { success: true, data: true }; - } - throw new Error(`Program id not found: ${programId}`); - } catch (error) { - return { - success: false, - message: `${error}` - }; - } -}; - -const router = async (e: MessageEvent) => { - const { data } = e; - - switch (data.task) { - case 'createProgram': { - return self.postMessage( - createProgram(data.data) - ); - } - case 'execute': { - return self.postMessage( - await execute(data.programId, data.source) - ); - } - case 'destroyProgram': { - return self.postMessage( - destroyProgram(data.programId) - ); - } - default: { - return self.postMessage({ - success: false, - message: `${new Error(`Unknown task: ${(data as any).task}.`)}`, - }); - } - } -}; - -self.addEventListener('message', router, false); diff --git a/packages/rath-client/src/latiao/program/token.ts b/packages/rath-client/src/latiao/program/token.ts deleted file mode 100644 index d2084ad6e..000000000 --- a/packages/rath-client/src/latiao/program/token.ts +++ /dev/null @@ -1,76 +0,0 @@ -import type { IFieldMeta } from '../../interfaces'; -import type { OperatorName } from './operator'; -import type { Static } from './types'; - - -export type DateObjectDimension = 'Y' | 'M' | 'W' | 'D' | 'h' | 'm' | 's'; - -export type FieldType = ( - | 'bool' // numeric, 0 (false) or 1 (true) - | 'vec' // number set supporting operation - | 'set' // number set not supporting operation - | 'text' // string set -); - -export type TokenType = ( - | 'OP' - | 'JS.string' - | 'JS.number' - | `RATH.FIELD::${FieldType}` - | 'RATH.FIELD_LIST' - | '$DATE' -); - -interface IToken { - type: TokenType; -} - -export interface OpToken extends IToken { - type: 'OP'; - op: OperatorName; - args: Static; - output: Exclude; - exports: false | string; -} - -export interface StringToken extends IToken { - type: 'JS.string'; - value: string; -} - -export interface NumberToken extends IToken { - type: 'JS.number'; - value: number; -} - -export interface FieldToken extends IToken { - type: `RATH.FIELD::${T}`; - fid: string; - name: string; - mode: T; - extInfo?: IFieldMeta['extInfo']; - out: false | string; -} - -export interface FieldListToken extends IToken { - type: 'RATH.FIELD_LIST'; - tuple: { - [index in keyof T]: FieldToken; - }; -} - -export interface DateToken extends IToken { - type: '$DATE'; - source: FieldToken; - dimensions: 'all' | DateObjectDimension[]; - exports: false | string; -} - -export type Token = ( - | OpToken - | StringToken - | NumberToken - | FieldToken - | FieldListToken - | DateToken -); diff --git a/packages/rath-client/src/latiao/program/types.ts b/packages/rath-client/src/latiao/program/types.ts deleted file mode 100644 index 3a0c4b988..000000000 --- a/packages/rath-client/src/latiao/program/types.ts +++ /dev/null @@ -1,89 +0,0 @@ -import type { LaTiaoError } from "./error"; -import type { FieldToken, FieldType } from "./token"; - - -export type Static = T extends Record ? { - readonly [index in keyof T]: Static; -} : T; - -type LaTiaoJSType = { - bool: 0 | 1; - vec: number; - set: number; - text: string; -}[T]; - -type LaTiaoColumnData = Static[]>; - -export interface ILaTiaoColumnInfo { - token: FieldToken; -} - -export interface ILaTiaoColumn { - info: Static>; - data: Static>; -} - -export type CreateLaTiaoProgramProps = { - task: 'createProgram'; - data: Static[]>; -}; - -export type ExecuteLaTiaoProgramProps = { - task: 'execute'; - programId: number; - source: string; -}; - -export type DestroyLaTiaoProgramProps = { - task: 'destroyProgram'; - programId: number; -}; - -export type LaTiaoProgramProps = ( - | CreateLaTiaoProgramProps - | ExecuteLaTiaoProgramProps - | DestroyLaTiaoProgramProps -); - -export interface CreateLaTiaoProgramResult { - programId: number; -} - -export interface ExecuteLaTiaoProgramResult { - data: Static[]>; - /** @deprecated */ - enter: Static[]>; - /** @deprecated */ - columns: Static<(number[] | string[])[]>; -} - -export type LaTiaoErrorLocation = ConstructorParameters[1]; - -export type LaTiaoProgramContext = { - readonly programId: number; - readonly originData: CreateLaTiaoProgramProps['data']; - tempData: CreateLaTiaoProgramProps['data']; - readonly rowCount: number; - readonly resolveColId: (colId: string, loc?: LaTiaoErrorLocation) => Static; - readonly col: < - T extends FieldType = FieldType, - D extends T extends 'text' ? string[] : T extends 'bool' ? (0 | 1)[] : number[] = T extends 'text' ? string[] : T extends 'bool' ? (0 | 1)[] : number[], - >(field: Static>, loc?: LaTiaoErrorLocation) => Promise>; - readonly cols: < - T extends FieldType[] = FieldType[], - D extends { - [index in keyof T]: T extends 'text' ? string[] : T extends 'bool' ? (0 | 1)[] : number[] - } = { - [index in keyof T]: T extends 'text' ? string[] : T extends 'bool' ? (0 | 1)[] : number[] - }, - >(fields: Static<{ [index in keyof T]: FieldToken }>, loc?: LaTiaoErrorLocation) => Promise>; - readonly write: < - T extends FieldType = FieldType, - D extends T extends 'text' ? string[] : T extends 'bool' ? (0 | 1)[] : number[] = T extends 'text' ? string[] : T extends 'bool' ? (0 | 1)[] : number[], - >( - field: FieldToken, - data: D, - ) => void; - reportError: (err: LaTiaoError) => void; -}; diff --git a/packages/rath-client/src/pages/causal/datasetPanel.tsx b/packages/rath-client/src/pages/causal/datasetPanel.tsx index 8dd36e372..cdb6652f4 100644 --- a/packages/rath-client/src/pages/causal/datasetPanel.tsx +++ b/packages/rath-client/src/pages/causal/datasetPanel.tsx @@ -1,6 +1,5 @@ import { Checkbox, - CommandButton, DetailsList, IColumn, Label, @@ -15,9 +14,7 @@ import produce from 'immer'; import intl from 'react-intl-universal' import { useGlobalStore } from '../../store'; import FilterCreationPill from '../../components/fieldPill/filterCreationPill'; -// import LaTiaoConsole from '../../components/latiaoConsole/index'; import type { IFieldMeta } from '../../interfaces'; -import LaTiaoModal from '../../components/latiaoConsole/modal'; import { FilterCell } from './filters'; @@ -64,7 +61,7 @@ const SelectedKey = 'selected'; const DatasetPanel: FC = () => { const { dataSourceStore, causalStore } = useGlobalStore(); - const { cleanedData, showCustomizeComputationModal } = dataSourceStore; + const { cleanedData } = dataSourceStore; const { fields, allFields, filteredDataSize, sampleRate, sampleSize, filters } = causalStore.dataset; @@ -238,22 +235,6 @@ const DatasetPanel: FC = () => { return ( <> - - - { - dataSourceStore.togleShowCustomizeComputationModal(true); - }} - /> - {showCustomizeComputationModal && ( - { - dataSourceStore.togleShowCustomizeComputationModal(false); - }} /> - )} - {/* */} -

-
{intl.get('dataSource.extend.manual')}
-
- setCode(data ?? '')} - multiline - autoAdjustHeight - resizable={false} - style={{ - minHeight: '15vmin', - maxHeight: '30vh', - }} - styles={{ - fieldGroup: { - border: '1px solid #8888', - }, - }} - onKeyDown={(e) => { - if (e.key === 'Tab') { - const target = inputMaybe[maybeIdx]; - - if (target) { - submitMaybe(target.content); - setMaybeIdx(0); - } - - e.preventDefault(); - } else if (e.key === 'ArrowDown') { - setMaybeIdx((maybeIdx + 1) % inputMaybe.length); - } else if (e.key === 'ArrowUp') { - setMaybeIdx((maybeIdx + inputMaybe.length - 1) % inputMaybe.length); - } - }} - /> -
-
-                                {rich(
-                                    code,
-                                    fields.map((f) => ({
-                                        ...f,
-                                        fid: `_${f.fid}`,
-                                    }))
-                                )}
-                            
-
-
-
- {inputMaybe.map((maybe, i) => ( -
{ - submitMaybe(maybe.content); - setMaybeIdx(0); - }} - ref={(e) => { - if (e && i === maybeIdx) { - e.scrollIntoView({ - behavior: 'smooth', - block: 'nearest', - }); - } - }} - > - {intl.get(`latiao.maybe.${maybe.type}`)} -
-
{maybe.content}
- {maybe.description && {maybe.description}} -
- {i === maybeIdx && {'[Tab]'}} -
- ))} -
-
{errMsg[0]}
-
-
-
- {preview.length === 0 ? ( -

{intl.get('dataSource.extend.empty')}

- ) : ( - <> - {preview.map((meta) => ( -
-
- {meta.name ? ( - <> - {meta.name} - {`(${meta.fid})`} - - ) : ( - meta.fid - )} -
- -
- ))} - - )} -
-
- { - if (preview.length === 0 || !resultRef.current) { - return; - } - // if (resultRef.current.length !== rawData.length) { - // console.error('Lengths do not match:', resultRef.current[0].length, rawData.length); - - // return; - // } - // dataSourceStore.addExtFieldsFromRows( - // resultRef.current, - // preview.map( - // (f) => - // ({ - // ...f, - // extInfo: f.extInfo - // ? { - // extOpt: f.extInfo.extOpt, - // extInfo: f.extInfo.extInfo, - // extFrom: f.extInfo.extFrom.map((s) => s.slice(1)), // 里面为了防止 fid 作为保留字前面加了一个下划线所以这里记得去掉 - // } - // : undefined, - // stage: 'settled', - // } as IExtField) - // ) - // ); - // onClose(); - // setCode(''); - // resultRef.current = undefined; - }} - > - {intl.get('dataSource.extend.apply')} - - {intl.get('dataSource.extend.cancel')} -
-
- - - ); -}; - -export default ComputationConsole; diff --git a/packages/rath-client/src/store/dataSourceStore.ts b/packages/rath-client/src/store/dataSourceStore.ts index df5c87f6a..4ecf4d148 100644 --- a/packages/rath-client/src/store/dataSourceStore.ts +++ b/packages/rath-client/src/store/dataSourceStore.ts @@ -108,7 +108,6 @@ export class DataSourceStore { private subscriptions: Subscription[] = []; private reactions: IReactionDisposer[] = [] public datasetId: string | null = null; - public showCustomizeComputationModal: boolean = false; public sourceType = DataSourceType.Unknown; constructor() { makeAutoObservable(this, { @@ -138,7 +137,6 @@ export class DataSourceStore { versionCode: -1, length: 0, } - this.showCustomizeComputationModal = false; this.extData = new Map>(); this.mutFields = []; this.extFields = []; @@ -418,9 +416,6 @@ export class DataSourceStore { public setDatasetId (id: string) { this.datasetId = id; } - public togleShowCustomizeComputationModal (show: boolean) { - this.showCustomizeComputationModal = show; - } public addFilter () { const sampleField = this.fieldMetas.find(f => f.semanticType === 'quantitative'); this.filters = [] @@ -673,7 +668,7 @@ export class DataSourceStore { } if (f.semanticType === 'quantitative') { const alreadyExpandedAsOutlier = Boolean(this.allFields.find( - which => which.extInfo?.extFrom.includes(f.fid) && which.extInfo.extOpt === 'LaTiao.$outlier' + which => which.extInfo?.extFrom.includes(f.fid) && which.extInfo.extOpt === 'CC.outlier' )); if (!alreadyExpandedAsOutlier && this.canExpandAsOutlier(f.fid)) { suggestions.push({ @@ -687,7 +682,7 @@ export class DataSourceStore { if (f.semanticType === 'nominal') { const mayHaveSentences = await this.canExpandAsWord(f.fid); const alreadyExpandedAsOneHot = Boolean(this.allFields.find( - which => which.extInfo?.extFrom.includes(f.fid) && which.extInfo.extOpt === 'LaTiao.$oneHot' + which => which.extInfo?.extFrom.includes(f.fid) && which.extInfo.extOpt === 'CC.oneHot' )); if (!alreadyExpandedAsOneHot) { suggestions.push({ @@ -697,7 +692,7 @@ export class DataSourceStore { }) } const alreadyExpandedAsWordTF = Boolean(this.allFields.find( - which => which.extInfo?.extFrom.includes(f.fid) && which.extInfo.extOpt === 'LaTiao.$wordTF' + which => which.extInfo?.extFrom.includes(f.fid) && which.extInfo.extOpt === 'CC.wordTF' )); if (!alreadyExpandedAsWordTF && mayHaveSentences) { suggestions.push({ @@ -707,7 +702,7 @@ export class DataSourceStore { }) } const alreadyExpandedAsWordTFIDF = Boolean(this.allFields.find( - which => which.extInfo?.extFrom.includes(f.fid) && which.extInfo.extOpt === 'LaTiao.$wordTFIDF' + which => which.extInfo?.extFrom.includes(f.fid) && which.extInfo.extOpt === 'CC.wordTFIDF' )); if (!alreadyExpandedAsWordTFIDF && mayHaveSentences) { suggestions.push({ @@ -717,7 +712,7 @@ export class DataSourceStore { }) } const alreadyExpandedAsReGroupByFreq = Boolean(this.allFields.find( - which => which.extInfo?.extFrom.includes(f.fid) && which.extInfo.extOpt === 'LaTiao.$reGroupByFreq' + which => which.extInfo?.extFrom.includes(f.fid) && which.extInfo.extOpt === 'CC.reGroupByFreq' )); if (!alreadyExpandedAsReGroupByFreq && this.canExpandAsReGroupByFreq(f.fid)) { suggestions.push({ @@ -763,7 +758,7 @@ export class DataSourceStore { return which.semanticType === 'temporal' && !which.extInfo; } public canExpandAsReGroupByFreq(fid: string) { - const which = fieldNotExtended(fid, this.mutFields, 'LaTiao.$reGroupByFreq'); + const which = fieldNotExtended(fid, this.mutFields, 'CC.reGroupByFreq'); if (typeof which === 'undefined') return; if (which.semanticType !== 'nominal') { return false; @@ -773,7 +768,7 @@ export class DataSourceStore { return meta.features.unique > 8; } public canExpandAsOutlier(fid: string) { - const which = fieldNotExtended(fid, this.mutFields, 'LaTiao.$outlierIForest'); + const which = fieldNotExtended(fid, this.mutFields, 'CC.outlierIForest'); if (typeof which === 'undefined') return; if (!(which.semanticType === 'quantitative' && !which.extInfo)) return false; const meta = this.fieldMetas.find(f => f.fid === fid); @@ -853,7 +848,7 @@ export class DataSourceStore { analyticType: 'dimension', extInfo: { extFrom: [fid], - extOpt: 'LaTiao.$wordTFIDF', + extOpt: 'CC.wordTFIDF', extInfo: {} }, geoRole: 'none' @@ -873,7 +868,7 @@ export class DataSourceStore { } } public clearTextPatternIfExist () { - const extRemainFields = this.extFields.filter(f => !(f.extInfo?.extOpt === 'LaTiao.$selection_pattern' && f.stage === 'preview')); + const extRemainFields = this.extFields.filter(f => !(f.extInfo?.extOpt === 'CC.selection_pattern' && f.stage === 'preview')); if (extRemainFields.length !== this.extFields.length) { this.extFields = extRemainFields; } @@ -893,7 +888,7 @@ export class DataSourceStore { analyticType: 'dimension', extInfo: { extFrom: [fid], - extOpt: 'LaTiao.$selection_pattern', + extOpt: 'CC.selection_pattern', extInfo: { pattern: pattern.toString(), } @@ -928,7 +923,7 @@ export class DataSourceStore { analyticType: 'dimension', extInfo: { extFrom: [fid], - extOpt: 'LaTiao.$regex', + extOpt: 'CC.regex', extInfo: { pattern: pattern.toString(), } @@ -972,7 +967,7 @@ export class DataSourceStore { analyticType: 'dimension', extInfo: { extFrom: [fid], - extOpt: 'LaTiao.$wordTF', + extOpt: 'CC.wordTF', extInfo: {} }, geoRole: 'none' @@ -1006,7 +1001,7 @@ export class DataSourceStore { analyticType: 'dimension', extInfo: { extFrom: [fid], - extOpt: 'LaTiao.$reGroupByFreq', + extOpt: 'CC.reGroupByFreq', extInfo: {} }, geoRole: 'none' @@ -1039,7 +1034,7 @@ export class DataSourceStore { analyticType: 'dimension', extInfo: { extFrom: [fid], - extOpt: 'LaTiao.$oneHot', + extOpt: 'CC.oneHot', extInfo: {} }, geoRole: 'none' @@ -1076,7 +1071,7 @@ export class DataSourceStore { analyticType: 'dimension', extInfo: { extFrom: [fid], - extOpt: 'LaTiao.$outlierIForest', + extOpt: 'CC.outlierIForest', extInfo: {} }, geoRole: 'none' diff --git a/yarn.lock b/yarn.lock index 77dc12f6b..909a16c1b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -810,11 +810,6 @@ resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.19.3.tgz#8dd36d17c53ff347f9e55c328710321b49479a9a" integrity sha512-pJ9xOlNWHiy9+FuFP09DEAFbAn4JskgRsVcc169w2xRBC3FRGuQEwjeIMMND9L2zc0iEhO/tGv4Zq+km+hxNpQ== -"@babel/parser@^7.19.6": - version "7.19.6" - resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.19.6.tgz#b923430cb94f58a7eae8facbffa9efd19130e7f8" - integrity sha512-h1IUp81s2JYJ3mRkdxJgs4UvmSsRvDrx5ICSJbPvtWYv5i1nTBGcBpnog+89rAFMwvvru6E5NUHdBe01UeSzYA== - "@babel/parser@^7.20.1", "@babel/parser@^7.20.2": version "7.20.3" resolved "https://registry.npmmirror.com/@babel/parser/-/parser-7.20.3.tgz#5358cf62e380cf69efcb87a7bb922ff88bfac6e2"