Compare commits
54 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| fd4cefe1f0 | |||
| 272c021665 | |||
| 72b909a50c | |||
| 139feb9e4f | |||
| c293ec2181 | |||
| 6ea0d12187 | |||
| 3ddfbb73a9 | |||
| 1c9d482310 | |||
| 843d53587c | |||
| c0db3919a6 | |||
| b0b835d6b9 | |||
| 775049ae5f | |||
| 69ccb9990f | |||
| a10e4ddb89 | |||
| 96e0105511 | |||
| 3bbd0a1d65 | |||
| 60ece94fce | |||
| a997d1d246 | |||
| d257175cdb | |||
| 8de8e8b2f0 | |||
| eeb67cebd3 | |||
| b6e1ca95ac | |||
| 97821f83e5 | |||
| 0d1bf11b21 | |||
| 8d3de4e50a | |||
| 5b70df7c9d | |||
| da2085ad32 | |||
| 48fddb5cbc | |||
| dff47a80f9 | |||
| 76c73aac03 | |||
| 0c981d943d | |||
| 481fef9f70 | |||
| b11dd456c0 | |||
| bc51f20e48 | |||
| e7c78cf40d | |||
| 5d2b46eb38 | |||
| a134bd44bd | |||
| 86224c1daf | |||
| b8339897f3 | |||
| 42b68d5bee | |||
| dcd88de1a5 | |||
| 6d327967b1 | |||
| 4e8b7faead | |||
| efd77937a2 | |||
| 9c9493eaa0 | |||
| f06fbce486 | |||
| c919f9585d | |||
| bfb7acd55b | |||
| e74d0a3301 | |||
| a4f450386c | |||
| 15a7f1c178 | |||
| 31727f3337 | |||
| cc52ef1bda | |||
| a1fcd86a74 |
+231
@@ -267,6 +267,237 @@ What is the main interface of this package?
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
read the following files:
|
||||||
|
- ./src/msghandler.jl
|
||||||
|
- ./test/test_julia_mix_payloads_sender.jl
|
||||||
|
- ./src/msghandler-csr.js
|
||||||
|
- ./README.md
|
||||||
|
I want to add:
|
||||||
|
1) sending jsontable and arrowtable Julia example to README.md
|
||||||
|
2) sending image and jsontable Javascript(browser) example to README.md
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
read the following files:
|
||||||
|
- ./README.md
|
||||||
|
- ./src/msghandler.jl
|
||||||
|
- ./test/test_julia_mix_payloads_sender.jl
|
||||||
|
- ./src/msghandler-csr.js
|
||||||
|
I want to:
|
||||||
|
1) add sending jsontable and arrowtable julia example in README.md
|
||||||
|
2) add sending jsontable and image Javascript example in README.md
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
I execute test/test_julia_mix_payloads_sender.jl and I get this error:
|
||||||
|
ERROR: LoadError: HTTP.ConnectError for url = `https://fileserver.yiem.cc/upload`: IOError: SSL_ERROR_SSL
|
||||||
|
Stacktrace:
|
||||||
|
[1] macro expansion
|
||||||
|
@ ~/.julia/packages/OpenSSL/2SUGA/src/ssl.jl:476 [inlined]
|
||||||
|
[2] macro expansion
|
||||||
|
@ ./lock.jl:376 [inlined]
|
||||||
|
[3] connect(ssl::OpenSSL.SSLStream; require_ssl_verification::Bool)
|
||||||
|
@ OpenSSL ~/.julia/packages/OpenSSL/2SUGA/src/ssl.jl:443
|
||||||
|
[4] connect
|
||||||
|
@ ~/.julia/packages/OpenSSL/2SUGA/src/ssl.jl:509 [inlined]
|
||||||
|
[5] #sslconnection#21
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/Connections.jl:595 [inlined]
|
||||||
|
[6] sslconnection
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/Connections.jl:585 [inlined]
|
||||||
|
[7] getconnection(::Type{OpenSSL.SSLStream}, host::SubString{String}, port::SubString{String}; kw::@Kwargs{require_ssl_verification::Bool, keepalive::Bool, readtimeout::Int64, iofunction::Nothing, decompress::Nothing, verbose::Int64, body_is_form::Bool})
|
||||||
|
@ HTTP.Connections ~/.julia/packages/HTTP/Y97L1/src/Connections.jl:582
|
||||||
|
[8] getconnection
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/Connections.jl:574 [inlined]
|
||||||
|
[9] #13
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/Connections.jl:463 [inlined]
|
||||||
|
[10] macro expansion
|
||||||
|
@ ~/.julia/packages/ConcurrentUtilities/hQBsU/src/try_with_timeout.jl:92 [inlined]
|
||||||
|
[11] (::ConcurrentUtilities.var"#try_with_timeout##2#try_with_timeout##3"{Any, Channel{Any}, HTTP.Connections.var"#13#14"{OpenSSL.SSLStream, Bool, Bool, @Kwargs{readtimeout::Int64, iofunction::Nothing, decompress::Nothing, verbose::Int64, body_is_form::Bool}, SubString{String}, SubString{String}}, Timer})()
|
||||||
|
@ ConcurrentUtilities ~/.julia/packages/ConcurrentUtilities/hQBsU/src/ConcurrentUtilities.jl:10
|
||||||
|
Stacktrace:
|
||||||
|
[1] (::HTTP.ConnectionRequest.var"#connections#connectionlayer##0"{HTTP.ConnectionRequest.var"#connections#1#connectionlayer##1"{HTTP.TimeoutRequest.var"#timeouts#timeoutlayer##0"{HTTP.TimeoutRequest.var"#timeouts#1#timeoutlayer##1"{HTTP.ExceptionRequest.var"#exceptions#exceptionlayer##0"{HTTP.ExceptionRequest.var"#exceptions#1#exceptionlayer##1"{typeof(HTTP.StreamRequest.streamlayer)}}}}}})(req::HTTP.Messages.Request; proxy::Nothing, socket_type::Type, socket_type_tls::Nothing, readtimeout::Int64, connect_timeout::Int64, logerrors::Bool, logtag::Nothing, closeimmediately::Bool, kw::@Kwargs{iofunction::Nothing, decompress::Nothing, verbose::Int64, body_is_form::Bool})
|
||||||
|
@ HTTP.ConnectionRequest ~/.julia/packages/HTTP/Y97L1/src/clientlayers/ConnectionRequest.jl:88
|
||||||
|
[2] connections
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/clientlayers/ConnectionRequest.jl:60 [inlined]
|
||||||
|
[3] (::Base.var"#46#47"{Base.var"#48#49"{ExponentialBackOff, HTTP.RetryRequest.var"#retrylayer##2#retrylayer##3"{Int64, typeof(HTTP.RetryRequest.FALSE), HTTP.Messages.Request, Base.RefValue{Int64}}, HTTP.ConnectionRequest.var"#connections#connectionlayer##0"{HTTP.ConnectionRequest.var"#connections#1#connectionlayer##1"{HTTP.TimeoutRequest.var"#timeouts#timeoutlayer##0"{HTTP.TimeoutRequest.var"#timeouts#1#timeoutlayer##1"{HTTP.ExceptionRequest.var"#exceptions#exceptionlayer##0"{HTTP.ExceptionRequest.var"#exceptions#1#exceptionlayer##1"{typeof(HTTP.StreamRequest.streamlayer)}}}}}}}})(args::HTTP.Messages.Request; kwargs::@Kwargs{iofunction::Nothing, decompress::Nothing, verbose::Int64, body_is_form::Bool})
|
||||||
|
@ Base ./error.jl:309
|
||||||
|
[4] (::HTTP.RetryRequest.var"#manageretries#retrylayer##0"{HTTP.RetryRequest.var"#manageretries#1#retrylayer##1"{HTTP.ConnectionRequest.var"#connections#connectionlayer##0"{HTTP.ConnectionRequest.var"#connections#1#connectionlayer##1"{HTTP.TimeoutRequest.var"#timeouts#timeoutlayer##0"{HTTP.TimeoutRequest.var"#timeouts#1#timeoutlayer##1"{HTTP.ExceptionRequest.var"#exceptions#exceptionlayer##0"{HTTP.ExceptionRequest.var"#exceptions#1#exceptionlayer##1"{typeof(HTTP.StreamRequest.streamlayer)}}}}}}}})(req::HTTP.Messages.Request; retry::Bool, retries::Int64, retry_delays::ExponentialBackOff, retry_check::Function, retry_non_idempotent::Bool, kw::@Kwargs{iofunction::Nothing, decompress::Nothing, verbose::Int64, body_is_form::Bool})
|
||||||
|
@ HTTP.RetryRequest ~/.julia/packages/HTTP/Y97L1/src/clientlayers/RetryRequest.jl:75
|
||||||
|
[5] manageretries
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/clientlayers/RetryRequest.jl:30 [inlined]
|
||||||
|
[6] (::HTTP.CookieRequest.var"#managecookies#cookielayer##0"{HTTP.CookieRequest.var"#managecookies#1#cookielayer##1"{HTTP.RetryRequest.var"#manageretries#retrylayer##0"{HTTP.RetryRequest.var"#manageretries#1#retrylayer##1"{HTTP.ConnectionRequest.var"#connections#connectionlayer##0"{HTTP.ConnectionRequest.var"#connections#1#connectionlayer##1"{HTTP.TimeoutRequest.var"#timeouts#timeoutlayer##0"{HTTP.TimeoutRequest.var"#timeouts#1#timeoutlayer##1"{HTTP.ExceptionRequest.var"#exceptions#exceptionlayer##0"{HTTP.ExceptionRequest.var"#exceptions#1#exceptionlayer##1"{typeof(HTTP.StreamRequest.streamlayer)}}}}}}}}}})(req::HTTP.Messages.Request; cookies::Bool, cookiejar::HTTP.Cookies.CookieJar, kw::@Kwargs{iofunction::Nothing, decompress::Nothing, verbose::Int64, body_is_form::Bool})
|
||||||
|
@ HTTP.CookieRequest ~/.julia/packages/HTTP/Y97L1/src/clientlayers/CookieRequest.jl:42
|
||||||
|
[7] managecookies
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/clientlayers/CookieRequest.jl:19 [inlined]
|
||||||
|
[8] (::HTTP.HeadersRequest.var"#defaultheaders#headerslayer##0"{HTTP.HeadersRequest.var"#defaultheaders#1#headerslayer##1"{HTTP.CookieRequest.var"#managecookies#cookielayer##0"{HTTP.CookieRequest.var"#managecookies#1#cookielayer##1"{HTTP.RetryRequest.var"#manageretries#retrylayer##0"{HTTP.RetryRequest.var"#manageretries#1#retrylayer##1"{HTTP.ConnectionRequest.var"#connections#connectionlayer##0"{HTTP.ConnectionRequest.var"#connections#1#connectionlayer##1"{HTTP.TimeoutRequest.var"#timeouts#timeoutlayer##0"{HTTP.TimeoutRequest.var"#timeouts#1#timeoutlayer##1"{HTTP.ExceptionRequest.var"#exceptions#exceptionlayer##0"{HTTP.ExceptionRequest.var"#exceptions#1#exceptionlayer##1"{typeof(HTTP.StreamRequest.streamlayer)}}}}}}}}}}}})(req::HTTP.Messages.Request; iofunction::Nothing, decompress::Nothing, basicauth::Bool, detect_content_type::Bool, canonicalize_headers::Bool, kw::@Kwargs{verbose::Int64, body_is_form::Bool})
|
||||||
|
@ HTTP.HeadersRequest ~/.julia/packages/HTTP/Y97L1/src/clientlayers/HeadersRequest.jl:71
|
||||||
|
[9] defaultheaders
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/clientlayers/HeadersRequest.jl:14 [inlined]
|
||||||
|
[10] (::HTTP.RedirectRequest.var"#redirects#redirectlayer##0"{HTTP.RedirectRequest.var"#redirects#1#redirectlayer##1"{HTTP.HeadersRequest.var"#defaultheaders#headerslayer##0"{HTTP.HeadersRequest.var"#defaultheaders#1#headerslayer##1"{HTTP.CookieRequest.var"#managecookies#cookielayer##0"{HTTP.CookieRequest.var"#managecookies#1#cookielayer##1"{HTTP.RetryRequest.var"#manageretries#retrylayer##0"{HTTP.RetryRequest.var"#manageretries#1#retrylayer##1"{HTTP.ConnectionRequest.var"#connections#connectionlayer##0"{HTTP.ConnectionRequest.var"#connections#1#connectionlayer##1"{HTTP.TimeoutRequest.var"#timeouts#timeoutlayer##0"{HTTP.TimeoutRequest.var"#timeouts#1#timeoutlayer##1"{HTTP.ExceptionRequest.var"#exceptions#exceptionlayer##0"{HTTP.ExceptionRequest.var"#exceptions#1#exceptionlayer##1"{typeof(HTTP.StreamRequest.streamlayer)}}}}}}}}}}}}}})(req::HTTP.Messages.Request; redirect::Bool, redirect_limit::Int64, redirect_method::Nothing, forwardheaders::Bool, response_stream::Nothing, kw::@Kwargs{verbose::Int64, body_is_form::Bool})
|
||||||
|
@ HTTP.RedirectRequest ~/.julia/packages/HTTP/Y97L1/src/clientlayers/RedirectRequest.jl:25
|
||||||
|
[11] redirects
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/clientlayers/RedirectRequest.jl:14 [inlined]
|
||||||
|
[12] (::HTTP.MessageRequest.var"#makerequest#messagelayer##0"{HTTP.MessageRequest.var"#makerequest#1#messagelayer##1"{HTTP.RedirectRequest.var"#redirects#redirectlayer##0"{HTTP.RedirectRequest.var"#redirects#1#redirectlayer##1"{HTTP.HeadersRequest.var"#defaultheaders#headerslayer##0"{HTTP.HeadersRequest.var"#defaultheaders#1#headerslayer##1"{HTTP.CookieRequest.var"#managecookies#cookielayer##0"{HTTP.CookieRequest.var"#managecookies#1#cookielayer##1"{HTTP.RetryRequest.var"#manageretries#retrylayer##0"{HTTP.RetryRequest.var"#manageretries#1#retrylayer##1"{HTTP.ConnectionRequest.var"#connections#connectionlayer##0"{HTTP.ConnectionRequest.var"#connections#1#connectionlayer##1"{HTTP.TimeoutRequest.var"#timeouts#timeoutlayer##0"{HTTP.TimeoutRequest.var"#timeouts#1#timeoutlayer##1"{HTTP.ExceptionRequest.var"#exceptions#exceptionlayer##0"{HTTP.ExceptionRequest.var"#exceptions#1#exceptionlayer##1"{typeof(HTTP.StreamRequest.streamlayer)}}}}}}}}}}}}}}}})(method::String, url::URIs.URI, headers::Vector{Pair{String, String}}, body::String; copyheaders::Bool, response_stream::Nothing, http_version::HTTP.Strings.HTTPVersion, verbose::Int64, kw::@Kwargs{body_is_form::Bool})
|
||||||
|
@ HTTP.MessageRequest ~/.julia/packages/HTTP/Y97L1/src/clientlayers/MessageRequest.jl:35
|
||||||
|
[13] makerequest
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/clientlayers/MessageRequest.jl:24 [inlined]
|
||||||
|
[14] request(stack::HTTP.MessageRequest.var"#makerequest#messagelayer##0"{HTTP.MessageRequest.var"#makerequest#1#messagelayer##1"{HTTP.RedirectRequest.var"#redirects#redirectlayer##0"{HTTP.RedirectRequest.var"#redirects#1#redirectlayer##1"{HTTP.HeadersRequest.var"#defaultheaders#headerslayer##0"{HTTP.HeadersRequest.var"#defaultheaders#1#headerslayer##1"{HTTP.CookieRequest.var"#managecookies#cookielayer##0"{HTTP.CookieRequest.var"#managecookies#1#cookielayer##1"{HTTP.RetryRequest.var"#manageretries#retrylayer##0"{HTTP.RetryRequest.var"#manageretries#1#retrylayer##1"{HTTP.ConnectionRequest.var"#connections#connectionlayer##0"{HTTP.ConnectionRequest.var"#connections#1#connectionlayer##1"{HTTP.TimeoutRequest.var"#timeouts#timeoutlayer##0"{HTTP.TimeoutRequest.var"#timeouts#1#timeoutlayer##1"{HTTP.ExceptionRequest.var"#exceptions#exceptionlayer##0"{HTTP.ExceptionRequest.var"#exceptions#1#exceptionlayer##1"{typeof(HTTP.StreamRequest.streamlayer)}}}}}}}}}}}}}}}}, method::String, url::String, h::Vector{Pair{String, String}}, b::String, q::Nothing; headers::Vector{Pair{String, String}}, body::String, query::Nothing, kw::@Kwargs{body_is_form::Bool})
|
||||||
|
@ HTTP ~/.julia/packages/HTTP/Y97L1/src/HTTP.jl:465
|
||||||
|
[15] #request#21
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/HTTP.jl:323 [inlined]
|
||||||
|
[16] request
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/HTTP.jl:321 [inlined]
|
||||||
|
[17] plik_upload_handler(fileserver_url::String, dataname::String, data::Vector{UInt8})
|
||||||
|
@ Main ~/docker-apps/sommpanion/msghandler/test/test_julia_mix_payloads_sender.jl:48
|
||||||
|
[18] smartpack(subject::String, data::Vector{Tuple{String, Any, String}}; broker_url::String, fileserver_url::String, fileserver_upload_handler::typeof(plik_upload_handler), size_threshold::Int64, correlation_id::String, msg_purpose::String, sender_name::String, receiver_name::String, receiver_id::String, reply_to::String, reply_to_msg_id::String, msg_id::String, sender_id::String)
|
||||||
|
@ Main.msghandler ~/docker-apps/sommpanion/msghandler/src/msghandler.jl:493
|
||||||
|
[19] test_mix_send()
|
||||||
|
@ Main ~/docker-apps/sommpanion/msghandler/test/test_julia_mix_payloads_sender.jl:208
|
||||||
|
[20] top-level scope
|
||||||
|
@ ~/docker-apps/sommpanion/msghandler/test/test_julia_mix_payloads_sender.jl:256
|
||||||
|
[21] include(mod::Module, _path::String)
|
||||||
|
@ Base ./Base.jl:306
|
||||||
|
[22] exec_options(opts::Base.JLOptions)
|
||||||
|
@ Base ./client.jl:317
|
||||||
|
[23] _start()
|
||||||
|
@ Base ./client.jl:550
|
||||||
|
in expression starting at /home/ton/docker-apps/sommpanion/msghandler/test/test_julia_mix_payloads_sender.jl:256
|
||||||
|
|
||||||
|
caused by: IOError: SSL_ERROR_SSL
|
||||||
|
Stacktrace:
|
||||||
|
[1] macro expansion
|
||||||
|
@ ~/.julia/packages/OpenSSL/2SUGA/src/ssl.jl:476 [inlined]
|
||||||
|
[2] macro expansion
|
||||||
|
@ ./lock.jl:376 [inlined]
|
||||||
|
[3] connect(ssl::OpenSSL.SSLStream; require_ssl_verification::Bool)
|
||||||
|
@ OpenSSL ~/.julia/packages/OpenSSL/2SUGA/src/ssl.jl:443
|
||||||
|
[4] connect
|
||||||
|
@ ~/.julia/packages/OpenSSL/2SUGA/src/ssl.jl:509 [inlined]
|
||||||
|
[5] #sslconnection#21
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/Connections.jl:595 [inlined]
|
||||||
|
[6] sslconnection
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/Connections.jl:585 [inlined]
|
||||||
|
[7] getconnection(::Type{OpenSSL.SSLStream}, host::SubString{String}, port::SubString{String}; kw::@Kwargs{require_ssl_verification::Bool, keepalive::Bool, readtimeout::Int64, iofunction::Nothing, decompress::Nothing, verbose::Int64, body_is_form::Bool})
|
||||||
|
@ HTTP.Connections ~/.julia/packages/HTTP/Y97L1/src/Connections.jl:582
|
||||||
|
[8] getconnection
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/Connections.jl:574 [inlined]
|
||||||
|
[9] #13
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/Connections.jl:463 [inlined]
|
||||||
|
[10] macro expansion
|
||||||
|
@ ~/.julia/packages/ConcurrentUtilities/hQBsU/src/try_with_timeout.jl:92 [inlined]
|
||||||
|
[11] (::ConcurrentUtilities.var"#try_with_timeout##2#try_with_timeout##3"{Any, Channel{Any}, HTTP.Connections.var"#13#14"{OpenSSL.SSLStream, Bool, Bool, @Kwargs{readtimeout::Int64, iofunction::Nothing, decompress::Nothing, verbose::Int64, body_is_form::Bool}, SubString{String}, SubString{String}}, Timer})()
|
||||||
|
@ ConcurrentUtilities ~/.julia/packages/ConcurrentUtilities/hQBsU/src/ConcurrentUtilities.jl:10
|
||||||
|
Stacktrace:
|
||||||
|
[1] try_yieldto(undo::typeof(Base.ensure_rescheduled))
|
||||||
|
@ Base ./task.jl:1157
|
||||||
|
[2] wait()
|
||||||
|
@ Base ./task.jl:1229
|
||||||
|
[3] wait(c::Base.GenericCondition{ReentrantLock}; first::Bool)
|
||||||
|
@ Base ./condition.jl:141
|
||||||
|
[4] wait
|
||||||
|
@ ./condition.jl:136 [inlined]
|
||||||
|
[5] take_unbuffered(c::Channel{Any})
|
||||||
|
@ Base ./channels.jl:549
|
||||||
|
[6] take!
|
||||||
|
@ ./channels.jl:526 [inlined]
|
||||||
|
[7] try_with_timeout(f::Function, timeout::Int64, ::Type{Any})
|
||||||
|
@ ConcurrentUtilities ~/.julia/packages/ConcurrentUtilities/hQBsU/src/try_with_timeout.jl:99
|
||||||
|
[8] try_with_timeout
|
||||||
|
@ ~/.julia/packages/ConcurrentUtilities/hQBsU/src/try_with_timeout.jl:77 [inlined]
|
||||||
|
[9] (::HTTP.Connections.var"#11#12"{OpenSSL.SSLStream, Int64, Int64, Bool, Bool, @Kwargs{readtimeout::Int64, iofunction::Nothing, decompress::Nothing, verbose::Int64, body_is_form::Bool}, SubString{String}, SubString{String}})()
|
||||||
|
@ HTTP.Connections ~/.julia/packages/HTTP/Y97L1/src/Connections.jl:460
|
||||||
|
[10] acquire(f::HTTP.Connections.var"#11#12"{OpenSSL.SSLStream, Int64, Int64, Bool, Bool, @Kwargs{readtimeout::Int64, iofunction::Nothing, decompress::Nothing, verbose::Int64, body_is_form::Bool}, SubString{String}, SubString{String}}, pool::ConcurrentUtilities.Pools.Pool{Tuple{AbstractString, AbstractString, Bool, Bool, Bool}, HTTP.Connections.Connection{OpenSSL.SSLStream}}, key::Tuple{SubString{String}, SubString{String}, Bool, Bool, Bool}; forcenew::Bool, isvalid::HTTP.Connections.var"#15#16"{Int64})
|
||||||
|
@ ConcurrentUtilities.Pools ~/.julia/packages/ConcurrentUtilities/hQBsU/src/pools.jl:159
|
||||||
|
[11] acquire
|
||||||
|
@ ~/.julia/packages/ConcurrentUtilities/hQBsU/src/pools.jl:140 [inlined]
|
||||||
|
[12] #newconnection#7
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/Connections.jl:455 [inlined]
|
||||||
|
[13] (::HTTP.ConnectionRequest.var"#connections#connectionlayer##0"{HTTP.ConnectionRequest.var"#connections#1#connectionlayer##1"{HTTP.TimeoutRequest.var"#timeouts#timeoutlayer##0"{HTTP.TimeoutRequest.var"#timeouts#1#timeoutlayer##1"{HTTP.ExceptionRequest.var"#exceptions#exceptionlayer##0"{HTTP.ExceptionRequest.var"#exceptions#1#exceptionlayer##1"{typeof(HTTP.StreamRequest.streamlayer)}}}}}})(req::HTTP.Messages.Request; proxy::Nothing, socket_type::Type, socket_type_tls::Nothing, readtimeout::Int64, connect_timeout::Int64, logerrors::Bool, logtag::Nothing, closeimmediately::Bool, kw::@Kwargs{iofunction::Nothing, decompress::Nothing, verbose::Int64, body_is_form::Bool})
|
||||||
|
@ HTTP.ConnectionRequest ~/.julia/packages/HTTP/Y97L1/src/clientlayers/ConnectionRequest.jl:82
|
||||||
|
[14] connections
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/clientlayers/ConnectionRequest.jl:60 [inlined]
|
||||||
|
[15] (::Base.var"#46#47"{Base.var"#48#49"{ExponentialBackOff, HTTP.RetryRequest.var"#retrylayer##2#retrylayer##3"{Int64, typeof(HTTP.RetryRequest.FALSE), HTTP.Messages.Request, Base.RefValue{Int64}}, HTTP.ConnectionRequest.var"#connections#connectionlayer##0"{HTTP.ConnectionRequest.var"#connections#1#connectionlayer##1"{HTTP.TimeoutRequest.var"#timeouts#timeoutlayer##0"{HTTP.TimeoutRequest.var"#timeouts#1#timeoutlayer##1"{HTTP.ExceptionRequest.var"#exceptions#exceptionlayer##0"{HTTP.ExceptionRequest.var"#exceptions#1#exceptionlayer##1"{typeof(HTTP.StreamRequest.streamlayer)}}}}}}}})(args::HTTP.Messages.Request; kwargs::@Kwargs{iofunction::Nothing, decompress::Nothing, verbose::Int64, body_is_form::Bool})
|
||||||
|
@ Base ./error.jl:309
|
||||||
|
[16] (::HTTP.RetryRequest.var"#manageretries#retrylayer##0"{HTTP.RetryRequest.var"#manageretries#1#retrylayer##1"{HTTP.ConnectionRequest.var"#connections#connectionlayer##0"{HTTP.ConnectionRequest.var"#connections#1#connectionlayer##1"{HTTP.TimeoutRequest.var"#timeouts#timeoutlayer##0"{HTTP.TimeoutRequest.var"#timeouts#1#timeoutlayer##1"{HTTP.ExceptionRequest.var"#exceptions#exceptionlayer##0"{HTTP.ExceptionRequest.var"#exceptions#1#exceptionlayer##1"{typeof(HTTP.StreamRequest.streamlayer)}}}}}}}})(req::HTTP.Messages.Request; retry::Bool, retries::Int64, retry_delays::ExponentialBackOff, retry_check::Function, retry_non_idempotent::Bool, kw::@Kwargs{iofunction::Nothing, decompress::Nothing, verbose::Int64, body_is_form::Bool})
|
||||||
|
@ HTTP.RetryRequest ~/.julia/packages/HTTP/Y97L1/src/clientlayers/RetryRequest.jl:75
|
||||||
|
[17] manageretries
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/clientlayers/RetryRequest.jl:30 [inlined]
|
||||||
|
[18] (::HTTP.CookieRequest.var"#managecookies#cookielayer##0"{HTTP.CookieRequest.var"#managecookies#1#cookielayer##1"{HTTP.RetryRequest.var"#manageretries#retrylayer##0"{HTTP.RetryRequest.var"#manageretries#1#retrylayer##1"{HTTP.ConnectionRequest.var"#connections#connectionlayer##0"{HTTP.ConnectionRequest.var"#connections#1#connectionlayer##1"{HTTP.TimeoutRequest.var"#timeouts#timeoutlayer##0"{HTTP.TimeoutRequest.var"#timeouts#1#timeoutlayer##1"{HTTP.ExceptionRequest.var"#exceptions#exceptionlayer##0"{HTTP.ExceptionRequest.var"#exceptions#1#exceptionlayer##1"{typeof(HTTP.StreamRequest.streamlayer)}}}}}}}}}})(req::HTTP.Messages.Request; cookies::Bool, cookiejar::HTTP.Cookies.CookieJar, kw::@Kwargs{iofunction::Nothing, decompress::Nothing, verbose::Int64, body_is_form::Bool})
|
||||||
|
@ HTTP.CookieRequest ~/.julia/packages/HTTP/Y97L1/src/clientlayers/CookieRequest.jl:42
|
||||||
|
[19] managecookies
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/clientlayers/CookieRequest.jl:19 [inlined]
|
||||||
|
[20] (::HTTP.HeadersRequest.var"#defaultheaders#headerslayer##0"{HTTP.HeadersRequest.var"#defaultheaders#1#headerslayer##1"{HTTP.CookieRequest.var"#managecookies#cookielayer##0"{HTTP.CookieRequest.var"#managecookies#1#cookielayer##1"{HTTP.RetryRequest.var"#manageretries#retrylayer##0"{HTTP.RetryRequest.var"#manageretries#1#retrylayer##1"{HTTP.ConnectionRequest.var"#connections#connectionlayer##0"{HTTP.ConnectionRequest.var"#connections#1#connectionlayer##1"{HTTP.TimeoutRequest.var"#timeouts#timeoutlayer##0"{HTTP.TimeoutRequest.var"#timeouts#1#timeoutlayer##1"{HTTP.ExceptionRequest.var"#exceptions#exceptionlayer##0"{HTTP.ExceptionRequest.var"#exceptions#1#exceptionlayer##1"{typeof(HTTP.StreamRequest.streamlayer)}}}}}}}}}}}})(req::HTTP.Messages.Request; iofunction::Nothing, decompress::Nothing, basicauth::Bool, detect_content_type::Bool, canonicalize_headers::Bool, kw::@Kwargs{verbose::Int64, body_is_form::Bool})
|
||||||
|
@ HTTP.HeadersRequest ~/.julia/packages/HTTP/Y97L1/src/clientlayers/HeadersRequest.jl:71
|
||||||
|
[21] defaultheaders
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/clientlayers/HeadersRequest.jl:14 [inlined]
|
||||||
|
[22] (::HTTP.RedirectRequest.var"#redirects#redirectlayer##0"{HTTP.RedirectRequest.var"#redirects#1#redirectlayer##1"{HTTP.HeadersRequest.var"#defaultheaders#headerslayer##0"{HTTP.HeadersRequest.var"#defaultheaders#1#headerslayer##1"{HTTP.CookieRequest.var"#managecookies#cookielayer##0"{HTTP.CookieRequest.var"#managecookies#1#cookielayer##1"{HTTP.RetryRequest.var"#manageretries#retrylayer##0"{HTTP.RetryRequest.var"#manageretries#1#retrylayer##1"{HTTP.ConnectionRequest.var"#connections#connectionlayer##0"{HTTP.ConnectionRequest.var"#connections#1#connectionlayer##1"{HTTP.TimeoutRequest.var"#timeouts#timeoutlayer##0"{HTTP.TimeoutRequest.var"#timeouts#1#timeoutlayer##1"{HTTP.ExceptionRequest.var"#exceptions#exceptionlayer##0"{HTTP.ExceptionRequest.var"#exceptions#1#exceptionlayer##1"{typeof(HTTP.StreamRequest.streamlayer)}}}}}}}}}}}}}})(req::HTTP.Messages.Request; redirect::Bool, redirect_limit::Int64, redirect_method::Nothing, forwardheaders::Bool, response_stream::Nothing, kw::@Kwargs{verbose::Int64, body_is_form::Bool})
|
||||||
|
@ HTTP.RedirectRequest ~/.julia/packages/HTTP/Y97L1/src/clientlayers/RedirectRequest.jl:25
|
||||||
|
[23] redirects
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/clientlayers/RedirectRequest.jl:14 [inlined]
|
||||||
|
[24] (::HTTP.MessageRequest.var"#makerequest#messagelayer##0"{HTTP.MessageRequest.var"#makerequest#1#messagelayer##1"{HTTP.RedirectRequest.var"#redirects#redirectlayer##0"{HTTP.RedirectRequest.var"#redirects#1#redirectlayer##1"{HTTP.HeadersRequest.var"#defaultheaders#headerslayer##0"{HTTP.HeadersRequest.var"#defaultheaders#1#headerslayer##1"{HTTP.CookieRequest.var"#managecookies#cookielayer##0"{HTTP.CookieRequest.var"#managecookies#1#cookielayer##1"{HTTP.RetryRequest.var"#manageretries#retrylayer##0"{HTTP.RetryRequest.var"#manageretries#1#retrylayer##1"{HTTP.ConnectionRequest.var"#connections#connectionlayer##0"{HTTP.ConnectionRequest.var"#connections#1#connectionlayer##1"{HTTP.TimeoutRequest.var"#timeouts#timeoutlayer##0"{HTTP.TimeoutRequest.var"#timeouts#1#timeoutlayer##1"{HTTP.ExceptionRequest.var"#exceptions#exceptionlayer##0"{HTTP.ExceptionRequest.var"#exceptions#1#exceptionlayer##1"{typeof(HTTP.StreamRequest.streamlayer)}}}}}}}}}}}}}}}})(method::String, url::URIs.URI, headers::Vector{Pair{String, String}}, body::String; copyheaders::Bool, response_stream::Nothing, http_version::HTTP.Strings.HTTPVersion, verbose::Int64, kw::@Kwargs{body_is_form::Bool})
|
||||||
|
@ HTTP.MessageRequest ~/.julia/packages/HTTP/Y97L1/src/clientlayers/MessageRequest.jl:35
|
||||||
|
[25] makerequest
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/clientlayers/MessageRequest.jl:24 [inlined]
|
||||||
|
[26] request(stack::HTTP.MessageRequest.var"#makerequest#messagelayer##0"{HTTP.MessageRequest.var"#makerequest#1#messagelayer##1"{HTTP.RedirectRequest.var"#redirects#redirectlayer##0"{HTTP.RedirectRequest.var"#redirects#1#redirectlayer##1"{HTTP.HeadersRequest.var"#defaultheaders#headerslayer##0"{HTTP.HeadersRequest.var"#defaultheaders#1#headerslayer##1"{HTTP.CookieRequest.var"#managecookies#cookielayer##0"{HTTP.CookieRequest.var"#managecookies#1#cookielayer##1"{HTTP.RetryRequest.var"#manageretries#retrylayer##0"{HTTP.RetryRequest.var"#manageretries#1#retrylayer##1"{HTTP.ConnectionRequest.var"#connections#connectionlayer##0"{HTTP.ConnectionRequest.var"#connections#1#connectionlayer##1"{HTTP.TimeoutRequest.var"#timeouts#timeoutlayer##0"{HTTP.TimeoutRequest.var"#timeouts#1#timeoutlayer##1"{HTTP.ExceptionRequest.var"#exceptions#exceptionlayer##0"{HTTP.ExceptionRequest.var"#exceptions#1#exceptionlayer##1"{typeof(HTTP.StreamRequest.streamlayer)}}}}}}}}}}}}}}}}, method::String, url::String, h::Vector{Pair{String, String}}, b::String, q::Nothing; headers::Vector{Pair{String, String}}, body::String, query::Nothing, kw::@Kwargs{body_is_form::Bool})
|
||||||
|
@ HTTP ~/.julia/packages/HTTP/Y97L1/src/HTTP.jl:465
|
||||||
|
[27] #request#21
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/HTTP.jl:323 [inlined]
|
||||||
|
[28] request
|
||||||
|
@ ~/.julia/packages/HTTP/Y97L1/src/HTTP.jl:321 [inlined]
|
||||||
|
[29] plik_upload_handler(fileserver_url::String, dataname::String, data::Vector{UInt8})
|
||||||
|
@ Main ~/docker-apps/sommpanion/msghandler/test/test_julia_mix_payloads_sender.jl:48
|
||||||
|
[30] smartpack(subject::String, data::Vector{Tuple{String, Any, String}}; broker_url::String, fileserver_url::String, fileserver_upload_handler::typeof(plik_upload_handler), size_threshold::Int64, correlation_id::String, msg_purpose::String, sender_name::String, receiver_name::String, receiver_id::String, reply_to::String, reply_to_msg_id::String, msg_id::String, sender_id::String)
|
||||||
|
@ Main.msghandler ~/docker-apps/sommpanion/msghandler/src/msghandler.jl:493
|
||||||
|
[31] test_mix_send()
|
||||||
|
@ Main ~/docker-apps/sommpanion/msghandler/test/test_julia_mix_payloads_sender.jl:208
|
||||||
|
[32] top-level scope
|
||||||
|
@ ~/docker-apps/sommpanion/msghandler/test/test_julia_mix_payloads_sender.jl:256
|
||||||
|
[33] include(mod::Module, _path::String)
|
||||||
|
@ Base ./Base.jl:306
|
||||||
|
[34] exec_options(opts::Base.JLOptions)
|
||||||
|
@ Base ./client.jl:317
|
||||||
|
[35] _start()
|
||||||
|
@ Base ./client.jl:550
|
||||||
|
---
|
||||||
|
This is my Caddyfile:
|
||||||
|
fileserver.mydomain.cc {
|
||||||
|
# 1. Handle OPTIONS preflight requests specifically
|
||||||
|
@options {
|
||||||
|
method OPTIONS
|
||||||
|
}
|
||||||
|
respond @options 204
|
||||||
|
|
||||||
|
# 2. Add CORS headers to all responses (including those from the proxy)
|
||||||
|
header {
|
||||||
|
Access-Control-Allow-Origin "*"
|
||||||
|
Access-Control-Allow-Methods "GET, HEAD, OPTIONS, POST, PUT, DELETE"
|
||||||
|
Access-Control-Allow-Headers "*"
|
||||||
|
Access-Control-Max-Age "86400"
|
||||||
|
}
|
||||||
|
|
||||||
|
# 3. Proxy to your Plik server
|
||||||
|
reverse_proxy 192.168.88.104:8080 {
|
||||||
|
header_up Host {http.request.host}
|
||||||
|
header_up X-Forwarded-For {http.request.remote}
|
||||||
|
header_up X-Forwarded-Proto {http.request.scheme}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
---
|
||||||
|
What do you think?
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+434
-117
@@ -1,8 +1,44 @@
|
|||||||
# This file is machine-generated - editing it directly is not advised
|
# This file is machine-generated - editing it directly is not advised
|
||||||
|
|
||||||
julia_version = "1.12.6"
|
julia_version = "1.12.7"
|
||||||
manifest_format = "2.0"
|
manifest_format = "2.0"
|
||||||
project_hash = "6757ef801c2fba25b1829ffc7ce99f19563e7dc4"
|
project_hash = "58b7a51dc4ee3f795ff0257a13ffaace09aa4e20"
|
||||||
|
|
||||||
|
[[deps.AWS]]
|
||||||
|
deps = ["Base64", "Compat", "Dates", "Downloads", "GitHub", "HTTP", "IniFile", "JSON", "MD5", "Mocking", "OrderedCollections", "Random", "SHA", "ScopedValues", "Sockets", "URIs", "UUIDs", "XMLDict"]
|
||||||
|
git-tree-sha1 = "842075b12a7f763c5f815a04037a99b6ac346df9"
|
||||||
|
uuid = "fbe9abb3-538b-5e4e-ba9e-bc94f4f92ebc"
|
||||||
|
version = "1.99.0"
|
||||||
|
|
||||||
|
[[deps.AWSS3]]
|
||||||
|
deps = ["AWS", "ArrowTypes", "Base64", "Compat", "Dates", "EzXML", "FilePathsBase", "HTTP", "MbedTLS", "Mocking", "OrderedCollections", "Retry", "SymDict", "URIs", "UUIDs", "XMLDict"]
|
||||||
|
git-tree-sha1 = "af99cea71364c8c4483405a6b03697d197ab4d3b"
|
||||||
|
uuid = "1c724243-ef5b-51ab-93f4-b0a88ac62a95"
|
||||||
|
version = "0.11.6"
|
||||||
|
|
||||||
|
[[deps.Accessors]]
|
||||||
|
deps = ["CompositionsBase", "ConstructionBase", "Dates", "InverseFunctions", "MacroTools"]
|
||||||
|
git-tree-sha1 = "7063ad1083578215c7c4bf410368150abe8d5524"
|
||||||
|
uuid = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697"
|
||||||
|
version = "0.1.45"
|
||||||
|
|
||||||
|
[deps.Accessors.extensions]
|
||||||
|
AxisKeysExt = "AxisKeys"
|
||||||
|
IntervalSetsExt = "IntervalSets"
|
||||||
|
LinearAlgebraExt = "LinearAlgebra"
|
||||||
|
StaticArraysExt = "StaticArrays"
|
||||||
|
StructArraysExt = "StructArrays"
|
||||||
|
TestExt = "Test"
|
||||||
|
UnitfulExt = "Unitful"
|
||||||
|
|
||||||
|
[deps.Accessors.weakdeps]
|
||||||
|
AxisKeys = "94b1ba4f-4ee9-5380-92f1-94cde586c3c5"
|
||||||
|
IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953"
|
||||||
|
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
|
||||||
|
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
|
||||||
|
StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a"
|
||||||
|
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
||||||
|
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
|
||||||
|
|
||||||
[[deps.AliasTables]]
|
[[deps.AliasTables]]
|
||||||
deps = ["PtrArrays", "Random"]
|
deps = ["PtrArrays", "Random"]
|
||||||
@@ -14,6 +50,12 @@ version = "1.1.3"
|
|||||||
uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"
|
uuid = "0dad84c5-d112-42e6-8d28-ef12dabb789f"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
|
|
||||||
|
[[deps.ArnoldiMethod]]
|
||||||
|
deps = ["LinearAlgebra", "Random", "StaticArrays"]
|
||||||
|
git-tree-sha1 = "d57bd3762d308bded22c3b82d033bff85f6195c6"
|
||||||
|
uuid = "ec485272-7323-5ecc-a04f-4719b315124d"
|
||||||
|
version = "0.4.0"
|
||||||
|
|
||||||
[[deps.Arrow]]
|
[[deps.Arrow]]
|
||||||
deps = ["ArrowTypes", "BitIntegers", "CodecLz4", "CodecZstd", "ConcurrentUtilities", "DataAPI", "Dates", "EnumX", "Mmap", "PooledArrays", "SentinelArrays", "StringViews", "Tables", "TimeZones", "TranscodingStreams", "UUIDs"]
|
deps = ["ArrowTypes", "BitIntegers", "CodecLz4", "CodecZstd", "ConcurrentUtilities", "DataAPI", "Dates", "EnumX", "Mmap", "PooledArrays", "SentinelArrays", "StringViews", "Tables", "TimeZones", "TranscodingStreams", "UUIDs"]
|
||||||
git-tree-sha1 = "4a69a3eadc1f7da78d950d1ef270c3a62c1f7e01"
|
git-tree-sha1 = "4a69a3eadc1f7da78d950d1ef270c3a62c1f7e01"
|
||||||
@@ -34,11 +76,6 @@ version = "1.11.0"
|
|||||||
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
|
uuid = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
|
||||||
[[deps.BitFlags]]
|
|
||||||
git-tree-sha1 = "0691e34b3bb8be9307330f88d1a3c3f25466c24d"
|
|
||||||
uuid = "d1d4a3ce-64b1-5f1a-9ba4-7e7e69966f35"
|
|
||||||
version = "0.1.9"
|
|
||||||
|
|
||||||
[[deps.BitIntegers]]
|
[[deps.BitIntegers]]
|
||||||
deps = ["Random"]
|
deps = ["Random"]
|
||||||
git-tree-sha1 = "091d591a060e43df1dd35faab3ca284925c48e46"
|
git-tree-sha1 = "091d591a060e43df1dd35faab3ca284925c48e46"
|
||||||
@@ -50,11 +87,20 @@ git-tree-sha1 = "6863c5b7fc997eadcabdbaf6c5f201dc30032643"
|
|||||||
uuid = "e1450e63-4bb3-523b-b2a4-4ffa8c0fd77d"
|
uuid = "e1450e63-4bb3-523b-b2a4-4ffa8c0fd77d"
|
||||||
version = "1.2.2"
|
version = "1.2.2"
|
||||||
|
|
||||||
|
[[deps.CEnum]]
|
||||||
|
git-tree-sha1 = "389ad5c84de1ae7cf0e28e381131c98ea87d54fc"
|
||||||
|
uuid = "fa961155-64e5-5f13-b03f-caf6b980ea82"
|
||||||
|
version = "0.5.0"
|
||||||
|
|
||||||
|
[[deps.CRC32c]]
|
||||||
|
uuid = "8bf52ea8-c179-5cab-976a-9e18b702a9bc"
|
||||||
|
version = "1.11.0"
|
||||||
|
|
||||||
[[deps.CSV]]
|
[[deps.CSV]]
|
||||||
deps = ["CodecZlib", "Dates", "FilePathsBase", "InlineStrings", "Mmap", "Parsers", "PooledArrays", "PrecompileTools", "SentinelArrays", "Tables", "Unicode", "WeakRefStrings", "WorkerUtilities"]
|
deps = ["CodecZlib", "Dates", "FilePathsBase", "InlineStrings", "Mmap", "Parsers", "PooledArrays", "PrecompileTools", "SentinelArrays", "Tables", "Unicode", "WeakRefStrings", "WorkerUtilities"]
|
||||||
git-tree-sha1 = "8d8e0b0f350b8e1c91420b5e64e5de774c2f0f4d"
|
git-tree-sha1 = "abed1e735dd4152f48c90cf0767e1790e25f332f"
|
||||||
uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
|
uuid = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"
|
||||||
version = "0.10.16"
|
version = "0.10.17"
|
||||||
|
|
||||||
[[deps.CodeTracking]]
|
[[deps.CodeTracking]]
|
||||||
deps = ["InteractiveUtils", "REPL", "UUIDs"]
|
deps = ["InteractiveUtils", "REPL", "UUIDs"]
|
||||||
@@ -76,9 +122,9 @@ version = "0.4.6"
|
|||||||
|
|
||||||
[[deps.CodecZlib]]
|
[[deps.CodecZlib]]
|
||||||
deps = ["TranscodingStreams", "Zlib_jll"]
|
deps = ["TranscodingStreams", "Zlib_jll"]
|
||||||
git-tree-sha1 = "962834c22b66e32aa10f7611c08c8ca4e20749a9"
|
git-tree-sha1 = "970758a3d591a2a5c2a907c53f2e2f8c1b1d3537"
|
||||||
uuid = "944b1d66-785c-5afd-91f1-9de20f533193"
|
uuid = "944b1d66-785c-5afd-91f1-9de20f533193"
|
||||||
version = "0.7.8"
|
version = "0.7.9"
|
||||||
|
|
||||||
[[deps.CodecZstd]]
|
[[deps.CodecZstd]]
|
||||||
deps = ["TranscodingStreams", "Zstd_jll"]
|
deps = ["TranscodingStreams", "Zstd_jll"]
|
||||||
@@ -86,6 +132,12 @@ git-tree-sha1 = "da54a6cd93c54950c15adf1d336cfd7d71f51a56"
|
|||||||
uuid = "6b39b394-51ab-5f42-8807-6242bab2b4c2"
|
uuid = "6b39b394-51ab-5f42-8807-6242bab2b4c2"
|
||||||
version = "0.8.7"
|
version = "0.8.7"
|
||||||
|
|
||||||
|
[[deps.CommonSolve]]
|
||||||
|
deps = ["PrecompileTools"]
|
||||||
|
git-tree-sha1 = "6c389fa857f6ca5a95474b52a52023fd77f24cb7"
|
||||||
|
uuid = "38540f10-b2f7-11e9-35d8-d573e4eb0ff2"
|
||||||
|
version = "0.2.14"
|
||||||
|
|
||||||
[[deps.Compat]]
|
[[deps.Compat]]
|
||||||
deps = ["TOML", "UUIDs"]
|
deps = ["TOML", "UUIDs"]
|
||||||
git-tree-sha1 = "9d8a54ce4b17aa5bdce0ea5c34bc5e7c340d16ad"
|
git-tree-sha1 = "9d8a54ce4b17aa5bdce0ea5c34bc5e7c340d16ad"
|
||||||
@@ -104,18 +156,47 @@ version = "0.1.1"
|
|||||||
[[deps.CompilerSupportLibraries_jll]]
|
[[deps.CompilerSupportLibraries_jll]]
|
||||||
deps = ["Artifacts", "Libdl"]
|
deps = ["Artifacts", "Libdl"]
|
||||||
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"
|
uuid = "e66e0078-7015-5450-92f7-15fbd957f2ae"
|
||||||
version = "1.3.0+1"
|
version = "1.3.1+2"
|
||||||
|
|
||||||
|
[[deps.CompositionsBase]]
|
||||||
|
git-tree-sha1 = "802bb88cd69dfd1509f6670416bd4434015693ad"
|
||||||
|
uuid = "a33af91c-f02d-484b-be07-31d278c5ca2b"
|
||||||
|
version = "0.1.2"
|
||||||
|
weakdeps = ["InverseFunctions"]
|
||||||
|
|
||||||
|
[deps.CompositionsBase.extensions]
|
||||||
|
CompositionsBaseInverseFunctionsExt = "InverseFunctions"
|
||||||
|
|
||||||
[[deps.ConcurrentUtilities]]
|
[[deps.ConcurrentUtilities]]
|
||||||
deps = ["Serialization", "Sockets"]
|
deps = ["Serialization", "Sockets"]
|
||||||
git-tree-sha1 = "21d088c496ea22914fe80906eb5bce65755e5ec8"
|
git-tree-sha1 = "3c9be947934c38475bafe822c6d61aaed17f0738"
|
||||||
uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb"
|
uuid = "f0e56b4a-5159-44fe-b623-3e5288b988bb"
|
||||||
version = "2.5.1"
|
version = "2.6.0"
|
||||||
|
|
||||||
|
[[deps.ConstructionBase]]
|
||||||
|
git-tree-sha1 = "b4b092499347b18a015186eae3042f72267106cb"
|
||||||
|
uuid = "187b0558-2788-49d3-abe0-74a17ed4e7c9"
|
||||||
|
version = "1.6.0"
|
||||||
|
|
||||||
|
[deps.ConstructionBase.extensions]
|
||||||
|
ConstructionBaseIntervalSetsExt = "IntervalSets"
|
||||||
|
ConstructionBaseLinearAlgebraExt = "LinearAlgebra"
|
||||||
|
ConstructionBaseStaticArraysExt = "StaticArrays"
|
||||||
|
|
||||||
|
[deps.ConstructionBase.weakdeps]
|
||||||
|
IntervalSets = "8197267c-284f-5f27-9208-e0e47529a953"
|
||||||
|
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
|
||||||
|
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
|
||||||
|
|
||||||
[[deps.Crayons]]
|
[[deps.Crayons]]
|
||||||
git-tree-sha1 = "249fe38abf76d48563e2f4556bebd215aa317e15"
|
git-tree-sha1 = "54b76cbb40d9a0f5368c880725b2f141da77c94f"
|
||||||
uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"
|
uuid = "a8cc5b0e-0ffa-5ad4-8c14-923d3ee1735f"
|
||||||
version = "4.1.1"
|
version = "4.2.0"
|
||||||
|
|
||||||
|
[[deps.DBInterface]]
|
||||||
|
git-tree-sha1 = "265d7f87f329c063cbde41920f9d00713a43cedd"
|
||||||
|
uuid = "a10d1c49-ce27-4219-8d33-6db1a4562965"
|
||||||
|
version = "2.7.0"
|
||||||
|
|
||||||
[[deps.DataAPI]]
|
[[deps.DataAPI]]
|
||||||
git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe"
|
git-tree-sha1 = "abe83f3a2f1b857aac70ef8b269080af17764bbe"
|
||||||
@@ -130,9 +211,9 @@ version = "1.8.2"
|
|||||||
|
|
||||||
[[deps.DataStructures]]
|
[[deps.DataStructures]]
|
||||||
deps = ["OrderedCollections"]
|
deps = ["OrderedCollections"]
|
||||||
git-tree-sha1 = "e86f4a2805f7f19bec5129bc9150c38208e5dc23"
|
git-tree-sha1 = "b0bc6d2cad1fed8b7fd59a1551a991cb3d2809e6"
|
||||||
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
|
uuid = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
|
||||||
version = "0.19.4"
|
version = "0.19.6"
|
||||||
|
|
||||||
[[deps.DataValueInterfaces]]
|
[[deps.DataValueInterfaces]]
|
||||||
git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6"
|
git-tree-sha1 = "bfc1187b79289637fa0ef6d4436ebdfe6905cbd6"
|
||||||
@@ -144,20 +225,46 @@ deps = ["Printf"]
|
|||||||
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"
|
uuid = "ade2ca70-3891-5945-98fb-dc099432e06a"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
|
||||||
|
[[deps.Decimals]]
|
||||||
|
git-tree-sha1 = "e98abef36d02a0ec385d68cd7dadbce9b28cbd88"
|
||||||
|
uuid = "abce61dc-4473-55a0-ba07-351d65e31d42"
|
||||||
|
version = "0.4.1"
|
||||||
|
|
||||||
|
[[deps.Distances]]
|
||||||
|
deps = ["LinearAlgebra", "Statistics", "StatsAPI"]
|
||||||
|
git-tree-sha1 = "c7e3a542b999843086e2f29dac96a618c105be1d"
|
||||||
|
uuid = "b4f34e82-e78d-54a5-968a-f98e89d6e8f7"
|
||||||
|
version = "0.10.12"
|
||||||
|
|
||||||
|
[deps.Distances.extensions]
|
||||||
|
DistancesChainRulesCoreExt = "ChainRulesCore"
|
||||||
|
DistancesSparseArraysExt = "SparseArrays"
|
||||||
|
|
||||||
|
[deps.Distances.weakdeps]
|
||||||
|
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
|
||||||
|
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
|
||||||
|
|
||||||
|
[[deps.Distributed]]
|
||||||
|
deps = ["Random", "Serialization", "Sockets"]
|
||||||
|
uuid = "8ba89e20-285c-5b6f-9357-94700520ee1b"
|
||||||
|
version = "1.11.0"
|
||||||
|
|
||||||
[[deps.Distributions]]
|
[[deps.Distributions]]
|
||||||
deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"]
|
deps = ["AliasTables", "FillArrays", "LinearAlgebra", "PDMats", "Printf", "QuadGK", "Random", "Roots", "SpecialFunctions", "Statistics", "StatsAPI", "StatsBase", "StatsFuns"]
|
||||||
git-tree-sha1 = "e421c1938fafab0165b04dc1a9dbe2a26272952c"
|
git-tree-sha1 = "a958ab3a40c755563f5e1405c0846cb0446bf19d"
|
||||||
uuid = "31c24e10-a181-5473-b8eb-7969acd0382f"
|
uuid = "31c24e10-a181-5473-b8eb-7969acd0382f"
|
||||||
version = "0.25.125"
|
version = "0.25.131"
|
||||||
|
|
||||||
[deps.Distributions.extensions]
|
[deps.Distributions.extensions]
|
||||||
DistributionsChainRulesCoreExt = "ChainRulesCore"
|
DistributionsChainRulesCoreExt = "ChainRulesCore"
|
||||||
DistributionsDensityInterfaceExt = "DensityInterface"
|
DistributionsDensityInterfaceExt = "DensityInterface"
|
||||||
|
DistributionsSparseConnectivityTracerExt = "SparseConnectivityTracer"
|
||||||
DistributionsTestExt = "Test"
|
DistributionsTestExt = "Test"
|
||||||
|
|
||||||
[deps.Distributions.weakdeps]
|
[deps.Distributions.weakdeps]
|
||||||
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
|
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
|
||||||
DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d"
|
DensityInterface = "b429d917-457f-4dbc-8f4c-0cc954292b1d"
|
||||||
|
SparseConnectivityTracer = "9f842d2f-2579-4b1d-911e-f412cf18a3f5"
|
||||||
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
||||||
|
|
||||||
[[deps.DocStringExtensions]]
|
[[deps.DocStringExtensions]]
|
||||||
@@ -175,16 +282,16 @@ git-tree-sha1 = "c49898e8438c828577f04b92fc9368c388ac783c"
|
|||||||
uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56"
|
uuid = "4e289a0a-7415-4d19-859d-a7e5c4648b56"
|
||||||
version = "1.0.7"
|
version = "1.0.7"
|
||||||
|
|
||||||
[[deps.ExceptionUnwrapping]]
|
[[deps.ExprTools]]
|
||||||
deps = ["Test"]
|
git-tree-sha1 = "d2e49e7efd29719d6f28b891b0e0e159daa9d2b4"
|
||||||
git-tree-sha1 = "d36f682e590a83d63d1c7dbd287573764682d12a"
|
uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04"
|
||||||
uuid = "460bff9d-24e4-43bc-9d9f-a8973cb893f4"
|
|
||||||
version = "0.1.11"
|
version = "0.1.11"
|
||||||
|
|
||||||
[[deps.ExprTools]]
|
[[deps.EzXML]]
|
||||||
git-tree-sha1 = "27415f162e6028e81c72b82ef756bf321213b6ec"
|
deps = ["Printf", "XML2_jll"]
|
||||||
uuid = "e2ba6199-217a-4e67-a87a-7c52f15ade04"
|
git-tree-sha1 = "7ea1aa5869e2626ccae84480e4f37185bc6f41d3"
|
||||||
version = "0.1.10"
|
uuid = "8f5d6c58-4d21-5cfd-889c-e3ad7ee6a615"
|
||||||
|
version = "1.2.3"
|
||||||
|
|
||||||
[[deps.FilePathsBase]]
|
[[deps.FilePathsBase]]
|
||||||
deps = ["Compat", "Dates"]
|
deps = ["Compat", "Dates"]
|
||||||
@@ -203,9 +310,10 @@ version = "1.11.0"
|
|||||||
|
|
||||||
[[deps.FillArrays]]
|
[[deps.FillArrays]]
|
||||||
deps = ["LinearAlgebra"]
|
deps = ["LinearAlgebra"]
|
||||||
git-tree-sha1 = "2f979084d1e13948a3352cf64a25df6bd3b4dca3"
|
git-tree-sha1 = "5bad39456d9f0166184fce2248783dd9862645c1"
|
||||||
uuid = "1a297f60-69ca-5386-bcde-b61e274b549b"
|
uuid = "1a297f60-69ca-5386-bcde-b61e274b549b"
|
||||||
version = "1.16.0"
|
version = "1.17.0"
|
||||||
|
weakdeps = ["PDMats", "SparseArrays", "StaticArrays", "Statistics"]
|
||||||
|
|
||||||
[deps.FillArrays.extensions]
|
[deps.FillArrays.extensions]
|
||||||
FillArraysPDMatsExt = "PDMats"
|
FillArraysPDMatsExt = "PDMats"
|
||||||
@@ -213,30 +321,47 @@ version = "1.16.0"
|
|||||||
FillArraysStaticArraysExt = "StaticArrays"
|
FillArraysStaticArraysExt = "StaticArrays"
|
||||||
FillArraysStatisticsExt = "Statistics"
|
FillArraysStatisticsExt = "Statistics"
|
||||||
|
|
||||||
[deps.FillArrays.weakdeps]
|
|
||||||
PDMats = "90014a1f-27ba-587c-ab20-58faa44d9150"
|
|
||||||
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
|
|
||||||
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
|
|
||||||
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
|
|
||||||
|
|
||||||
[[deps.Future]]
|
[[deps.Future]]
|
||||||
deps = ["Random"]
|
deps = ["Random"]
|
||||||
uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820"
|
uuid = "9fa8497b-333b-5362-9e8d-4d0656e87820"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
|
||||||
|
[[deps.Gamma]]
|
||||||
|
deps = ["LogExpFunctions"]
|
||||||
|
git-tree-sha1 = "becc397f7cfb06e343496ae6ffb04818a851da51"
|
||||||
|
uuid = "a0844989-3bd2-4988-8bea-c9407ab0941b"
|
||||||
|
version = "1.2.0"
|
||||||
|
|
||||||
[[deps.GeneralUtils]]
|
[[deps.GeneralUtils]]
|
||||||
deps = ["CSV", "DataFrames", "DataStructures", "Dates", "Distributions", "JSON", "NATS", "PrettyPrinting", "Random", "Revise", "SHA", "UUIDs"]
|
deps = ["AWS", "AWSS3", "CSV", "DataFrames", "DataStructures", "Dates", "Distributions", "Graphs", "HTTP", "JSON", "LibPQ", "NATS", "PrettyPrinting", "Random", "Revise", "SHA", "StringDistances", "UUIDs"]
|
||||||
git-tree-sha1 = "e28ca4df47d0c46d04716422bef6adb660f33dc3"
|
path = "../GeneralUtils"
|
||||||
repo-rev = "main"
|
|
||||||
repo-url = "https://git.yiem.cc/ton/GeneralUtils"
|
|
||||||
uuid = "c6c72f09-b708-4ac8-ac7c-2084d70108fe"
|
uuid = "c6c72f09-b708-4ac8-ac7c-2084d70108fe"
|
||||||
version = "0.3.1"
|
version = "0.6.1"
|
||||||
|
|
||||||
|
[[deps.GitHub]]
|
||||||
|
deps = ["Base64", "Dates", "HTTP", "JSON", "MbedTLS", "Sockets", "SodiumSeal", "URIs"]
|
||||||
|
git-tree-sha1 = "33de1bc5665494f0a9669fd6027e28180709d874"
|
||||||
|
uuid = "bc5e4493-9b4d-5f90-b8aa-2b2bcaad7a26"
|
||||||
|
version = "5.13.0"
|
||||||
|
|
||||||
|
[[deps.Graphs]]
|
||||||
|
deps = ["ArnoldiMethod", "DataStructures", "Inflate", "LinearAlgebra", "Random", "SimpleTraits", "SparseArrays", "Statistics"]
|
||||||
|
git-tree-sha1 = "7eb45fe833a5b7c51cf6d89c5a841d5967e44be3"
|
||||||
|
uuid = "86223c79-3864-5bf0-83f7-82e725a168b6"
|
||||||
|
version = "1.14.0"
|
||||||
|
|
||||||
|
[deps.Graphs.extensions]
|
||||||
|
GraphsSharedArraysExt = "SharedArrays"
|
||||||
|
|
||||||
|
[deps.Graphs.weakdeps]
|
||||||
|
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
|
||||||
|
SharedArrays = "1a1011a3-84de-559e-8e89-a11a2f7dc383"
|
||||||
|
|
||||||
[[deps.HTTP]]
|
[[deps.HTTP]]
|
||||||
deps = ["Base64", "CodecZlib", "ConcurrentUtilities", "Dates", "ExceptionUnwrapping", "Logging", "LoggingExtras", "MbedTLS", "NetworkOptions", "OpenSSL", "PrecompileTools", "Random", "SimpleBufferStream", "Sockets", "URIs", "UUIDs"]
|
deps = ["Base64", "CodecZlib", "Dates", "EnumX", "PrecompileTools", "Random", "Reseau", "SHA", "URIs", "UUIDs", "Zlib_jll"]
|
||||||
git-tree-sha1 = "51059d23c8bb67911a2e6fd5130229113735fc7e"
|
git-tree-sha1 = "d6e390d1515836237b837fb7b6fca7ba1d752db6"
|
||||||
uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3"
|
uuid = "cd3eb016-35fb-5094-929b-558a96fad6f3"
|
||||||
version = "1.11.0"
|
version = "2.6.5"
|
||||||
|
|
||||||
[[deps.HashArrayMappedTries]]
|
[[deps.HashArrayMappedTries]]
|
||||||
git-tree-sha1 = "2eaa69a7cab70a52b9687c8bf950a5a93ec895ae"
|
git-tree-sha1 = "2eaa69a7cab70a52b9687c8bf950a5a93ec895ae"
|
||||||
@@ -244,10 +369,32 @@ uuid = "076d061b-32b6-4027-95e0-9a2c6f6d7e74"
|
|||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
|
||||||
[[deps.HypergeometricFunctions]]
|
[[deps.HypergeometricFunctions]]
|
||||||
deps = ["LinearAlgebra", "OpenLibm_jll", "SpecialFunctions"]
|
deps = ["Gamma", "LinearAlgebra"]
|
||||||
git-tree-sha1 = "68c173f4f449de5b438ee67ed0c9c748dc31a2ec"
|
git-tree-sha1 = "31bb6c92405c084617facc1d7ed9eb6c402d061e"
|
||||||
uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a"
|
uuid = "34004b35-14d8-5ef3-9330-4cdb6864b03a"
|
||||||
version = "0.3.28"
|
version = "0.3.30"
|
||||||
|
|
||||||
|
[[deps.ICU_jll]]
|
||||||
|
deps = ["Artifacts", "JLLWrappers", "Libdl"]
|
||||||
|
git-tree-sha1 = "b3d8be712fbf9237935bde0ce9b5a736ae38fc34"
|
||||||
|
uuid = "a51ab1cf-af8e-5615-a023-bc2c838bba6b"
|
||||||
|
version = "76.2.0+0"
|
||||||
|
|
||||||
|
[[deps.Infinity]]
|
||||||
|
deps = ["Dates", "Random", "Requires"]
|
||||||
|
git-tree-sha1 = "cf8234411cbeb98676c173f930951ea29dca3b23"
|
||||||
|
uuid = "a303e19e-6eb4-11e9-3b09-cd9505f79100"
|
||||||
|
version = "0.2.4"
|
||||||
|
|
||||||
|
[[deps.Inflate]]
|
||||||
|
git-tree-sha1 = "d1b1b796e47d94588b3757fe84fbf65a5ec4a80d"
|
||||||
|
uuid = "d25df0c9-e2be-5dd7-82c8-3ad0b3e990b9"
|
||||||
|
version = "0.1.5"
|
||||||
|
|
||||||
|
[[deps.IniFile]]
|
||||||
|
git-tree-sha1 = "f550e6e32074c939295eb5ea6de31849ac2c9625"
|
||||||
|
uuid = "83e8ac13-25f8-5344-8a64-a9f2b223428f"
|
||||||
|
version = "0.5.1"
|
||||||
|
|
||||||
[[deps.InlineStrings]]
|
[[deps.InlineStrings]]
|
||||||
git-tree-sha1 = "8f3d257792a522b4601c24a577954b0a8cd7334d"
|
git-tree-sha1 = "8f3d257792a522b4601c24a577954b0a8cd7334d"
|
||||||
@@ -264,6 +411,22 @@ deps = ["Markdown"]
|
|||||||
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
|
uuid = "b77e0a4c-d291-57a0-90e8-8db25a27a240"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
|
||||||
|
[[deps.Intervals]]
|
||||||
|
deps = ["ArrowTypes", "Dates", "Printf", "RecipesBase", "Serialization", "TimeZones"]
|
||||||
|
git-tree-sha1 = "d6fe00b123e32ddd17231b35d69a6394e696fd5a"
|
||||||
|
uuid = "d8418881-c3e1-53bb-8760-2df7ec849ed5"
|
||||||
|
version = "1.11.0"
|
||||||
|
|
||||||
|
[[deps.InverseFunctions]]
|
||||||
|
git-tree-sha1 = "a779299d77cd080bf77b97535acecd73e1c5e5cb"
|
||||||
|
uuid = "3587e190-3f89-42d0-90ee-14403ec27112"
|
||||||
|
version = "0.1.17"
|
||||||
|
weakdeps = ["Dates", "Test"]
|
||||||
|
|
||||||
|
[deps.InverseFunctions.extensions]
|
||||||
|
InverseFunctionsDatesExt = "Dates"
|
||||||
|
InverseFunctionsTestExt = "Test"
|
||||||
|
|
||||||
[[deps.InvertedIndices]]
|
[[deps.InvertedIndices]]
|
||||||
git-tree-sha1 = "6da3c4316095de0f5ee2ebd875df8721e7e0bdbe"
|
git-tree-sha1 = "6da3c4316095de0f5ee2ebd875df8721e7e0bdbe"
|
||||||
uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f"
|
uuid = "41ab1584-1d38-5bbf-9106-f11c6c58b48f"
|
||||||
@@ -274,6 +437,11 @@ git-tree-sha1 = "b2d91fe939cae05960e760110b328288867b5758"
|
|||||||
uuid = "92d709cd-6900-40b7-9082-c6be49f344b6"
|
uuid = "92d709cd-6900-40b7-9082-c6be49f344b6"
|
||||||
version = "0.2.6"
|
version = "0.2.6"
|
||||||
|
|
||||||
|
[[deps.IterTools]]
|
||||||
|
git-tree-sha1 = "42d5f897009e7ff2cf88db414a389e5ed1bdd023"
|
||||||
|
uuid = "c8e1da08-722c-5040-9ed9-7db0dc04731e"
|
||||||
|
version = "1.10.0"
|
||||||
|
|
||||||
[[deps.IteratorInterfaceExtensions]]
|
[[deps.IteratorInterfaceExtensions]]
|
||||||
git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856"
|
git-tree-sha1 = "a3f24677c21f5bbe9d2a714f95dcd58337fb2856"
|
||||||
uuid = "82899510-4779-5014-852e-03e436cf321d"
|
uuid = "82899510-4779-5014-852e-03e436cf321d"
|
||||||
@@ -287,9 +455,9 @@ version = "1.8.0"
|
|||||||
|
|
||||||
[[deps.JSON]]
|
[[deps.JSON]]
|
||||||
deps = ["Dates", "Logging", "Parsers", "PrecompileTools", "StructUtils", "UUIDs", "Unicode"]
|
deps = ["Dates", "Logging", "Parsers", "PrecompileTools", "StructUtils", "UUIDs", "Unicode"]
|
||||||
git-tree-sha1 = "f76f7560267b840e492180f9899b472f30b88450"
|
git-tree-sha1 = "c7345ab1a7ca4dc8a02c9f6510da0d9857bbe513"
|
||||||
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
|
uuid = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
|
||||||
version = "1.6.0"
|
version = "1.7.1"
|
||||||
weakdeps = ["ArrowTypes"]
|
weakdeps = ["ArrowTypes"]
|
||||||
|
|
||||||
[deps.JSON.extensions]
|
[deps.JSON.extensions]
|
||||||
@@ -307,19 +475,30 @@ weakdeps = ["ArrowTypes"]
|
|||||||
|
|
||||||
[[deps.JuliaInterpreter]]
|
[[deps.JuliaInterpreter]]
|
||||||
deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"]
|
deps = ["CodeTracking", "InteractiveUtils", "Random", "UUIDs"]
|
||||||
git-tree-sha1 = "58927c485919bf17ea308d9d82156de1adf4b006"
|
git-tree-sha1 = "c3d401f110454b4ea24a76be33f6ee0d7d385103"
|
||||||
uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a"
|
uuid = "aa1ae85d-cabe-5617-a682-6adf51b2e16a"
|
||||||
version = "0.10.12"
|
version = "0.11.4"
|
||||||
|
|
||||||
[[deps.JuliaSyntaxHighlighting]]
|
[[deps.JuliaSyntaxHighlighting]]
|
||||||
deps = ["StyledStrings"]
|
deps = ["StyledStrings"]
|
||||||
uuid = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011"
|
uuid = "ac6e5ff7-fb65-4e79-a425-ec3bc9c03011"
|
||||||
version = "1.12.0"
|
version = "1.12.0"
|
||||||
|
|
||||||
|
[[deps.Kerberos_krb5_jll]]
|
||||||
|
deps = ["Artifacts", "JLLWrappers", "Libdl"]
|
||||||
|
git-tree-sha1 = "0f2899fdadaab4b8f57db558ba21bdb4fb52f1f0"
|
||||||
|
uuid = "b39eb1a6-c29a-53d7-8c32-632cd16f18da"
|
||||||
|
version = "1.21.3+0"
|
||||||
|
|
||||||
[[deps.LaTeXStrings]]
|
[[deps.LaTeXStrings]]
|
||||||
git-tree-sha1 = "dda21b8cbd6a6c40d9d02a73230f9d70fed6918c"
|
git-tree-sha1 = "f88f3ccef05a6a72a0cf0ed417c8fd68530f4ab2"
|
||||||
uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
|
uuid = "b964fa9f-0449-5b57-a5c2-d3ea65f4040f"
|
||||||
version = "1.4.0"
|
version = "1.4.1"
|
||||||
|
|
||||||
|
[[deps.LayerDicts]]
|
||||||
|
git-tree-sha1 = "6087ad3521d6278ebe5c27ae55e7bbb15ca312cb"
|
||||||
|
uuid = "6f188dcb-512c-564b-bc01-e0f76e72f166"
|
||||||
|
version = "1.0.0"
|
||||||
|
|
||||||
[[deps.LibCURL]]
|
[[deps.LibCURL]]
|
||||||
deps = ["LibCURL_jll", "MozillaCACerts_jll"]
|
deps = ["LibCURL_jll", "MozillaCACerts_jll"]
|
||||||
@@ -341,6 +520,18 @@ deps = ["Artifacts", "LibSSH2_jll", "Libdl", "OpenSSL_jll"]
|
|||||||
uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5"
|
uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5"
|
||||||
version = "1.9.0+0"
|
version = "1.9.0+0"
|
||||||
|
|
||||||
|
[[deps.LibPQ]]
|
||||||
|
deps = ["CEnum", "DBInterface", "Dates", "Decimals", "DocStringExtensions", "FileWatching", "Infinity", "Intervals", "IterTools", "LayerDicts", "LibPQ_jll", "Libdl", "Memento", "OffsetArrays", "SQLStrings", "Tables", "TimeZones", "UTCDateTimes"]
|
||||||
|
git-tree-sha1 = "3d227cd13cbf1e9a54d7748dab33e078da6f9168"
|
||||||
|
uuid = "194296ae-ab2e-5f79-8cd4-7183a0a5a0d1"
|
||||||
|
version = "1.18.0"
|
||||||
|
|
||||||
|
[[deps.LibPQ_jll]]
|
||||||
|
deps = ["Artifacts", "ICU_jll", "JLLWrappers", "Kerberos_krb5_jll", "Libdl", "OpenSSL_jll", "Zstd_jll"]
|
||||||
|
git-tree-sha1 = "c692057e05ba6da348bc45d5dab8c7a2c88da518"
|
||||||
|
uuid = "08be9ffa-1c94-5ee5-a977-46a84ec9b350"
|
||||||
|
version = "16.14.0+0"
|
||||||
|
|
||||||
[[deps.LibSSH2_jll]]
|
[[deps.LibSSH2_jll]]
|
||||||
deps = ["Artifacts", "Libdl", "OpenSSL_jll"]
|
deps = ["Artifacts", "Libdl", "OpenSSL_jll"]
|
||||||
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"
|
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"
|
||||||
@@ -350,6 +541,12 @@ version = "1.11.3+1"
|
|||||||
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
|
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
|
||||||
|
[[deps.Libiconv_jll]]
|
||||||
|
deps = ["Artifacts", "JLLWrappers", "Libdl"]
|
||||||
|
git-tree-sha1 = "be484f5c92fad0bd8acfef35fe017900b0b73809"
|
||||||
|
uuid = "94ce4f54-9a6c-5748-9c1c-f9c7231a4531"
|
||||||
|
version = "1.18.0+0"
|
||||||
|
|
||||||
[[deps.LinearAlgebra]]
|
[[deps.LinearAlgebra]]
|
||||||
deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"]
|
deps = ["Libdl", "OpenBLAS_jll", "libblastrampoline_jll"]
|
||||||
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
|
uuid = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
|
||||||
@@ -357,9 +554,9 @@ version = "1.12.0"
|
|||||||
|
|
||||||
[[deps.LogExpFunctions]]
|
[[deps.LogExpFunctions]]
|
||||||
deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"]
|
deps = ["DocStringExtensions", "IrrationalConstants", "LinearAlgebra"]
|
||||||
git-tree-sha1 = "13ca9e2586b89836fd20cccf56e57e2b9ae7f38f"
|
git-tree-sha1 = "bba2d9aa057d8f126415de240573e86a8f39d2a1"
|
||||||
uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
|
uuid = "2ab3a3ac-af41-5b50-aa03-7779005ae688"
|
||||||
version = "0.3.29"
|
version = "1.0.1"
|
||||||
|
|
||||||
[deps.LogExpFunctions.extensions]
|
[deps.LogExpFunctions.extensions]
|
||||||
LogExpFunctionsChainRulesCoreExt = "ChainRulesCore"
|
LogExpFunctionsChainRulesCoreExt = "ChainRulesCore"
|
||||||
@@ -375,17 +572,11 @@ version = "0.3.29"
|
|||||||
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"
|
uuid = "56ddb016-857b-54e1-b83d-db4d58db5568"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
|
||||||
[[deps.LoggingExtras]]
|
|
||||||
deps = ["Dates", "Logging"]
|
|
||||||
git-tree-sha1 = "f00544d95982ea270145636c181ceda21c4e2575"
|
|
||||||
uuid = "e6f89c97-d47a-5376-807f-9c37f3926c36"
|
|
||||||
version = "1.2.0"
|
|
||||||
|
|
||||||
[[deps.LoweredCodeUtils]]
|
[[deps.LoweredCodeUtils]]
|
||||||
deps = ["CodeTracking", "Compiler", "JuliaInterpreter"]
|
deps = ["CodeTracking", "Compiler", "JuliaInterpreter"]
|
||||||
git-tree-sha1 = "5d4278f755440f70648d80cc6225f51e78e94094"
|
git-tree-sha1 = "1d4c737ab26f51ceed52ab2019c09b7660eb7440"
|
||||||
uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b"
|
uuid = "6f1432cf-f94c-5a45-995e-cdbf5db27b0b"
|
||||||
version = "3.5.1"
|
version = "3.8.0"
|
||||||
|
|
||||||
[[deps.Lz4_jll]]
|
[[deps.Lz4_jll]]
|
||||||
deps = ["Artifacts", "JLLWrappers", "Libdl"]
|
deps = ["Artifacts", "JLLWrappers", "Libdl"]
|
||||||
@@ -393,6 +584,17 @@ git-tree-sha1 = "191686b1ac1ea9c89fc52e996ad15d1d241d1e33"
|
|||||||
uuid = "5ced341a-0733-55b8-9ab6-a4889d929147"
|
uuid = "5ced341a-0733-55b8-9ab6-a4889d929147"
|
||||||
version = "1.10.1+0"
|
version = "1.10.1+0"
|
||||||
|
|
||||||
|
[[deps.MD5]]
|
||||||
|
deps = ["Random", "SHA"]
|
||||||
|
git-tree-sha1 = "1576f756617d31eb397a4a517b68562fd28dc2b4"
|
||||||
|
uuid = "6ac74813-4b46-53a4-afec-0b5dc9d7885c"
|
||||||
|
version = "0.2.3"
|
||||||
|
|
||||||
|
[[deps.MacroTools]]
|
||||||
|
git-tree-sha1 = "1e0228a030642014fe5cfe68c2c0a818f9e3f522"
|
||||||
|
uuid = "1914dd2f-81c6-5fcd-8719-6d5c9610ff09"
|
||||||
|
version = "0.5.16"
|
||||||
|
|
||||||
[[deps.Markdown]]
|
[[deps.Markdown]]
|
||||||
deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"]
|
deps = ["Base64", "JuliaSyntaxHighlighting", "StyledStrings"]
|
||||||
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"
|
uuid = "d6f4376e-aef5-505a-96c1-9c027394607a"
|
||||||
@@ -410,6 +612,12 @@ git-tree-sha1 = "ff69a2b1330bcb730b9ac1ab7dd680176f5896b8"
|
|||||||
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"
|
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"
|
||||||
version = "2.28.1010+0"
|
version = "2.28.1010+0"
|
||||||
|
|
||||||
|
[[deps.Memento]]
|
||||||
|
deps = ["Dates", "Distributed", "Requires", "Serialization", "Sockets", "Test", "UUIDs"]
|
||||||
|
git-tree-sha1 = "e03a25cb3b6569623f8246d3d8b3faa7ce86f4ad"
|
||||||
|
uuid = "f28f55f0-a522-5efc-85c2-fe41dfb9b2d9"
|
||||||
|
version = "1.5.0"
|
||||||
|
|
||||||
[[deps.Missings]]
|
[[deps.Missings]]
|
||||||
deps = ["DataAPI"]
|
deps = ["DataAPI"]
|
||||||
git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d"
|
git-tree-sha1 = "ec4f7fbeab05d7747bdf98eb74d130a2a2ed298d"
|
||||||
@@ -438,14 +646,25 @@ version = "0.1.1"
|
|||||||
|
|
||||||
[[deps.NanoDates]]
|
[[deps.NanoDates]]
|
||||||
deps = ["Dates", "Parsers"]
|
deps = ["Dates", "Parsers"]
|
||||||
git-tree-sha1 = "850a0557ae5934f6e67ac0dc5ca13d0328422d1f"
|
git-tree-sha1 = "77c7e98ca39aefb481f9b97a2f4f5c5471c08a1d"
|
||||||
uuid = "46f1a544-deae-4307-8689-c12aa3c955c6"
|
uuid = "46f1a544-deae-4307-8689-c12aa3c955c6"
|
||||||
version = "1.0.3"
|
version = "1.1.0"
|
||||||
|
|
||||||
[[deps.NetworkOptions]]
|
[[deps.NetworkOptions]]
|
||||||
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"
|
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"
|
||||||
version = "1.3.0"
|
version = "1.3.0"
|
||||||
|
|
||||||
|
[[deps.OffsetArrays]]
|
||||||
|
git-tree-sha1 = "117432e406b5c023f665fa73dc26e79ec3630151"
|
||||||
|
uuid = "6fe1bfb0-de20-5000-8ca7-80f57d26f881"
|
||||||
|
version = "1.17.0"
|
||||||
|
|
||||||
|
[deps.OffsetArrays.extensions]
|
||||||
|
OffsetArraysAdaptExt = "Adapt"
|
||||||
|
|
||||||
|
[deps.OffsetArrays.weakdeps]
|
||||||
|
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
|
||||||
|
|
||||||
[[deps.OpenBLAS_jll]]
|
[[deps.OpenBLAS_jll]]
|
||||||
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"]
|
deps = ["Artifacts", "CompilerSupportLibraries_jll", "Libdl"]
|
||||||
uuid = "4536629a-c528-5b80-bd46-f80d51c5b363"
|
uuid = "4536629a-c528-5b80-bd46-f80d51c5b363"
|
||||||
@@ -456,16 +675,10 @@ deps = ["Artifacts", "Libdl"]
|
|||||||
uuid = "05823500-19ac-5b8b-9628-191a04bc5112"
|
uuid = "05823500-19ac-5b8b-9628-191a04bc5112"
|
||||||
version = "0.8.7+0"
|
version = "0.8.7+0"
|
||||||
|
|
||||||
[[deps.OpenSSL]]
|
|
||||||
deps = ["BitFlags", "Dates", "MozillaCACerts_jll", "NetworkOptions", "OpenSSL_jll", "Sockets"]
|
|
||||||
git-tree-sha1 = "1d1aaa7d449b58415f97d2839c318b70ffb525a0"
|
|
||||||
uuid = "4d8831e6-92b7-49fb-bdf8-b643e874388c"
|
|
||||||
version = "1.6.1"
|
|
||||||
|
|
||||||
[[deps.OpenSSL_jll]]
|
[[deps.OpenSSL_jll]]
|
||||||
deps = ["Artifacts", "Libdl"]
|
deps = ["Artifacts", "Libdl"]
|
||||||
uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95"
|
uuid = "458c3c95-2e84-50aa-8efc-19380b2a3a95"
|
||||||
version = "3.5.4+0"
|
version = "3.5.6+0"
|
||||||
|
|
||||||
[[deps.OpenSpecFun_jll]]
|
[[deps.OpenSpecFun_jll]]
|
||||||
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"]
|
deps = ["Artifacts", "CompilerSupportLibraries_jll", "JLLWrappers", "Libdl"]
|
||||||
@@ -474,15 +687,15 @@ uuid = "efe28fd5-8261-553b-a9e1-b2916fc3738e"
|
|||||||
version = "0.5.6+0"
|
version = "0.5.6+0"
|
||||||
|
|
||||||
[[deps.OrderedCollections]]
|
[[deps.OrderedCollections]]
|
||||||
git-tree-sha1 = "05868e21324cede2207c6f0f466b4bfef6d5e7ee"
|
git-tree-sha1 = "05f45c2e0de6259db764adbfd2f1dc6d3f8de13c"
|
||||||
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
|
uuid = "bac558e1-5e72-5ebc-8fee-abe8a469f55d"
|
||||||
version = "1.8.1"
|
version = "2.0.1"
|
||||||
|
|
||||||
[[deps.PDMats]]
|
[[deps.PDMats]]
|
||||||
deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"]
|
deps = ["LinearAlgebra", "SparseArrays", "SuiteSparse"]
|
||||||
git-tree-sha1 = "e4cff168707d441cd6bf3ff7e4832bdf34278e4a"
|
git-tree-sha1 = "123266c25174ef6c8d4718920abc206452cf8de6"
|
||||||
uuid = "90014a1f-27ba-587c-ab20-58faa44d9150"
|
uuid = "90014a1f-27ba-587c-ab20-58faa44d9150"
|
||||||
version = "0.11.37"
|
version = "0.11.41"
|
||||||
weakdeps = ["StatsBase"]
|
weakdeps = ["StatsBase"]
|
||||||
|
|
||||||
[deps.PDMats.extensions]
|
[deps.PDMats.extensions]
|
||||||
@@ -490,9 +703,9 @@ weakdeps = ["StatsBase"]
|
|||||||
|
|
||||||
[[deps.Parsers]]
|
[[deps.Parsers]]
|
||||||
deps = ["Dates", "PrecompileTools", "UUIDs"]
|
deps = ["Dates", "PrecompileTools", "UUIDs"]
|
||||||
git-tree-sha1 = "5d5e0a78e971354b1c7bff0655d11fdc1b0e12c8"
|
git-tree-sha1 = "3de8f5e6e90ebfa8d6d1f86997d6cdcd6a912ff3"
|
||||||
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
|
uuid = "69de0a69-1ddd-5017-9359-2bf0b02dc9f0"
|
||||||
version = "2.8.4"
|
version = "2.8.7"
|
||||||
|
|
||||||
[[deps.PooledArrays]]
|
[[deps.PooledArrays]]
|
||||||
deps = ["DataAPI", "Future"]
|
deps = ["DataAPI", "Future"]
|
||||||
@@ -513,21 +726,23 @@ uuid = "21216c6a-2e73-6563-6e65-726566657250"
|
|||||||
version = "1.5.2"
|
version = "1.5.2"
|
||||||
|
|
||||||
[[deps.PrettyPrinting]]
|
[[deps.PrettyPrinting]]
|
||||||
git-tree-sha1 = "142ee93724a9c5d04d78df7006670a93ed1b244e"
|
git-tree-sha1 = "0b7f4ad437e31c51cf5b91fb103579b04025170a"
|
||||||
uuid = "54e16d92-306c-5ea0-a30b-337be88ac337"
|
uuid = "54e16d92-306c-5ea0-a30b-337be88ac337"
|
||||||
version = "0.4.2"
|
version = "0.4.3"
|
||||||
|
|
||||||
[[deps.PrettyTables]]
|
[[deps.PrettyTables]]
|
||||||
deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "REPL", "Reexport", "StringManipulation", "Tables"]
|
deps = ["Crayons", "LaTeXStrings", "Markdown", "PrecompileTools", "Printf", "REPL", "Reexport", "StringManipulation", "Tables"]
|
||||||
git-tree-sha1 = "624de6279ab7d94fc9f672f0068107eb6619732c"
|
git-tree-sha1 = "1b8aa19f229b1cea7fc93874a52e49db6a854450"
|
||||||
uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
|
uuid = "08abe8d2-0d0c-5749-adfa-8a2ac140af0d"
|
||||||
version = "3.3.2"
|
version = "3.4.8"
|
||||||
|
|
||||||
[deps.PrettyTables.extensions]
|
[deps.PrettyTables.extensions]
|
||||||
|
PrettyTablesExcelExt = "XLSX"
|
||||||
PrettyTablesTypstryExt = "Typstry"
|
PrettyTablesTypstryExt = "Typstry"
|
||||||
|
|
||||||
[deps.PrettyTables.weakdeps]
|
[deps.PrettyTables.weakdeps]
|
||||||
Typstry = "f0ed7684-a786-439e-b1e3-3b82803b501e"
|
Typstry = "f0ed7684-a786-439e-b1e3-3b82803b501e"
|
||||||
|
XLSX = "fdbf4ff8-1666-58a4-91e7-1b58723a45e0"
|
||||||
|
|
||||||
[[deps.Printf]]
|
[[deps.Printf]]
|
||||||
deps = ["Unicode"]
|
deps = ["Unicode"]
|
||||||
@@ -561,23 +776,44 @@ deps = ["SHA"]
|
|||||||
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
|
uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
|
||||||
|
[[deps.RecipesBase]]
|
||||||
|
deps = ["PrecompileTools"]
|
||||||
|
git-tree-sha1 = "5c3d09cc4f31f5fc6af001c250bf1278733100ff"
|
||||||
|
uuid = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
|
||||||
|
version = "1.3.4"
|
||||||
|
|
||||||
[[deps.Reexport]]
|
[[deps.Reexport]]
|
||||||
git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b"
|
git-tree-sha1 = "45e428421666073eab6f2da5c9d310d99bb12f9b"
|
||||||
uuid = "189a3867-3050-52da-a836-e630ba90ab69"
|
uuid = "189a3867-3050-52da-a836-e630ba90ab69"
|
||||||
version = "1.2.2"
|
version = "1.2.2"
|
||||||
|
|
||||||
|
[[deps.Requires]]
|
||||||
|
deps = ["UUIDs"]
|
||||||
|
git-tree-sha1 = "62389eeff14780bfe55195b7204c0d8738436d64"
|
||||||
|
uuid = "ae029012-a4dd-5104-9daa-d747884805df"
|
||||||
|
version = "1.3.1"
|
||||||
|
|
||||||
|
[[deps.Reseau]]
|
||||||
|
deps = ["NetworkOptions", "OpenSSL_jll", "PrecompileTools", "Random", "SHA"]
|
||||||
|
git-tree-sha1 = "aaee74fab545e9af4b21d10c2203c93c636c4ae0"
|
||||||
|
uuid = "802f3686-a58f-41ce-bb0c-3c43c75bba36"
|
||||||
|
version = "1.4.1"
|
||||||
|
|
||||||
|
[[deps.Retry]]
|
||||||
|
git-tree-sha1 = "41ac127cd281bb33e42aba46a9d3b25cd35fc6d5"
|
||||||
|
uuid = "20febd7b-183b-5ae2-ac4a-720e7ce64774"
|
||||||
|
version = "0.4.1"
|
||||||
|
|
||||||
[[deps.Revise]]
|
[[deps.Revise]]
|
||||||
deps = ["CodeTracking", "FileWatching", "InteractiveUtils", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Preferences", "REPL", "UUIDs"]
|
deps = ["CRC32c", "CodeTracking", "FileWatching", "JuliaInterpreter", "LibGit2", "LoweredCodeUtils", "OrderedCollections", "Preferences", "REPL", "UUIDs"]
|
||||||
git-tree-sha1 = "d9383b639663d8220ac9c523927e38bc21cad16a"
|
git-tree-sha1 = "f6ad10ad2fa1063c2ae0f75d17d92d1d0cae4c77"
|
||||||
uuid = "295af30f-e4ad-537b-8983-00126c2a3abe"
|
uuid = "295af30f-e4ad-537b-8983-00126c2a3abe"
|
||||||
version = "3.14.3"
|
version = "3.16.5"
|
||||||
|
weakdeps = ["Distributed"]
|
||||||
|
|
||||||
[deps.Revise.extensions]
|
[deps.Revise.extensions]
|
||||||
DistributedExt = "Distributed"
|
DistributedExt = "Distributed"
|
||||||
|
|
||||||
[deps.Revise.weakdeps]
|
|
||||||
Distributed = "8ba89e20-285c-5b6f-9357-94700520ee1b"
|
|
||||||
|
|
||||||
[[deps.Rmath]]
|
[[deps.Rmath]]
|
||||||
deps = ["Random", "Rmath_jll"]
|
deps = ["Random", "Rmath_jll"]
|
||||||
git-tree-sha1 = "5b3d50eb374cea306873b371d3f8d3915a018f0b"
|
git-tree-sha1 = "5b3d50eb374cea306873b371d3f8d3915a018f0b"
|
||||||
@@ -586,14 +822,41 @@ version = "0.9.0"
|
|||||||
|
|
||||||
[[deps.Rmath_jll]]
|
[[deps.Rmath_jll]]
|
||||||
deps = ["Artifacts", "JLLWrappers", "Libdl"]
|
deps = ["Artifacts", "JLLWrappers", "Libdl"]
|
||||||
git-tree-sha1 = "58cdd8fb2201a6267e1db87ff148dd6c1dbd8ad8"
|
git-tree-sha1 = "6d40b2fe70437b01397d2a4d5b020008da4e7019"
|
||||||
uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f"
|
uuid = "f50d1b31-88e8-58de-be2c-1cc44531875f"
|
||||||
version = "0.5.1+0"
|
version = "0.5.2+0"
|
||||||
|
|
||||||
|
[[deps.Roots]]
|
||||||
|
deps = ["Accessors", "CommonSolve", "Printf"]
|
||||||
|
git-tree-sha1 = "13a9e0164267bb9ebc55c1c5d72fceea8f09555b"
|
||||||
|
uuid = "f2b01f46-fcfa-551c-844a-d8ac1e96c665"
|
||||||
|
version = "3.0.7"
|
||||||
|
|
||||||
|
[deps.Roots.extensions]
|
||||||
|
RootsChainRulesCoreExt = "ChainRulesCore"
|
||||||
|
RootsForwardDiffExt = "ForwardDiff"
|
||||||
|
RootsIntervalRootFindingExt = "IntervalRootFinding"
|
||||||
|
RootsSymPyExt = "SymPy"
|
||||||
|
RootsSymPyPythonCallExt = "SymPyPythonCall"
|
||||||
|
RootsUnitfulExt = "Unitful"
|
||||||
|
|
||||||
|
[deps.Roots.weakdeps]
|
||||||
|
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
|
||||||
|
ForwardDiff = "f6369f11-7733-5829-9624-2563aa707210"
|
||||||
|
IntervalRootFinding = "d2bf35a9-74e0-55ec-b149-d360ff49b807"
|
||||||
|
SymPy = "24249f21-da20-56a4-8eb1-6a02cf4ae2e6"
|
||||||
|
SymPyPythonCall = "bc8888f7-b21e-4b7c-a06a-5d9c9496438c"
|
||||||
|
Unitful = "1986cc42-f94f-5a68-af5c-568840ba703d"
|
||||||
|
|
||||||
[[deps.SHA]]
|
[[deps.SHA]]
|
||||||
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
|
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
|
||||||
version = "0.7.0"
|
version = "0.7.0"
|
||||||
|
|
||||||
|
[[deps.SQLStrings]]
|
||||||
|
git-tree-sha1 = "55de0530689832b1d3d43491ee6b67bd54d3323c"
|
||||||
|
uuid = "af517c2e-c243-48fa-aab8-efac3db270f5"
|
||||||
|
version = "0.1.0"
|
||||||
|
|
||||||
[[deps.ScopedValues]]
|
[[deps.ScopedValues]]
|
||||||
deps = ["HashArrayMappedTries", "Logging"]
|
deps = ["HashArrayMappedTries", "Logging"]
|
||||||
git-tree-sha1 = "67a144433c4ce877ee6d1ada69a124d6b1ecf7be"
|
git-tree-sha1 = "67a144433c4ce877ee6d1ada69a124d6b1ecf7be"
|
||||||
@@ -616,10 +879,11 @@ version = "1.4.10"
|
|||||||
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
|
uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b"
|
||||||
version = "1.11.0"
|
version = "1.11.0"
|
||||||
|
|
||||||
[[deps.SimpleBufferStream]]
|
[[deps.SimpleTraits]]
|
||||||
git-tree-sha1 = "f305871d2f381d21527c770d4788c06c097c9bc1"
|
deps = ["InteractiveUtils", "MacroTools"]
|
||||||
uuid = "777ac1f9-54b0-4bf8-805c-2214025038e7"
|
git-tree-sha1 = "7ddb0b49c109481b046972c0e4ab02b2127d6a75"
|
||||||
version = "1.2.0"
|
uuid = "699a6c99-e7fa-54fc-8d76-47d257e15c1d"
|
||||||
|
version = "0.9.6"
|
||||||
|
|
||||||
[[deps.Sockets]]
|
[[deps.Sockets]]
|
||||||
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"
|
uuid = "6462fe0b-24de-5631-8697-dd941f90decc"
|
||||||
@@ -631,11 +895,17 @@ git-tree-sha1 = "907703e0d50846f300650d7225bdcab145b7bca9"
|
|||||||
uuid = "4f5b5e99-b0ad-42cd-b47a-334e172ec8bd"
|
uuid = "4f5b5e99-b0ad-42cd-b47a-334e172ec8bd"
|
||||||
version = "1.1.2"
|
version = "1.1.2"
|
||||||
|
|
||||||
|
[[deps.SodiumSeal]]
|
||||||
|
deps = ["Base64", "Libdl", "libsodium_jll"]
|
||||||
|
git-tree-sha1 = "80cef67d2953e33935b41c6ab0a178b9987b1c99"
|
||||||
|
uuid = "2133526b-2bfb-4018-ac12-889fb3908a75"
|
||||||
|
version = "0.1.1"
|
||||||
|
|
||||||
[[deps.SortingAlgorithms]]
|
[[deps.SortingAlgorithms]]
|
||||||
deps = ["DataStructures"]
|
deps = ["DataStructures"]
|
||||||
git-tree-sha1 = "64d974c2e6fdf07f8155b5b2ca2ffa9069b608d9"
|
git-tree-sha1 = "13cd91cc9be159e3f4d95b857fa2aa383b53772a"
|
||||||
uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c"
|
uuid = "a2af1166-a08f-5f64-846c-94a0d3cef48c"
|
||||||
version = "1.2.2"
|
version = "1.2.3"
|
||||||
|
|
||||||
[[deps.SparseArrays]]
|
[[deps.SparseArrays]]
|
||||||
deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"]
|
deps = ["Libdl", "LinearAlgebra", "Random", "Serialization", "SuiteSparse_jll"]
|
||||||
@@ -644,9 +914,9 @@ version = "1.12.0"
|
|||||||
|
|
||||||
[[deps.SpecialFunctions]]
|
[[deps.SpecialFunctions]]
|
||||||
deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"]
|
deps = ["IrrationalConstants", "LogExpFunctions", "OpenLibm_jll", "OpenSpecFun_jll"]
|
||||||
git-tree-sha1 = "2700b235561b0335d5bef7097a111dc513b8655e"
|
git-tree-sha1 = "429071b23f4c9a13fb6582f807cc2ef454082408"
|
||||||
uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
|
uuid = "276daf66-3868-5448-9aa4-cd146d93841b"
|
||||||
version = "2.7.2"
|
version = "2.9.0"
|
||||||
|
|
||||||
[deps.SpecialFunctions.extensions]
|
[deps.SpecialFunctions.extensions]
|
||||||
SpecialFunctionsChainRulesCoreExt = "ChainRulesCore"
|
SpecialFunctionsChainRulesCoreExt = "ChainRulesCore"
|
||||||
@@ -654,6 +924,25 @@ version = "2.7.2"
|
|||||||
[deps.SpecialFunctions.weakdeps]
|
[deps.SpecialFunctions.weakdeps]
|
||||||
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
|
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
|
||||||
|
|
||||||
|
[[deps.StaticArrays]]
|
||||||
|
deps = ["LinearAlgebra", "PrecompileTools", "Random", "StaticArraysCore"]
|
||||||
|
git-tree-sha1 = "fac51faf3bb96e8bc0bf6f9f39ca4955652776bb"
|
||||||
|
uuid = "90137ffa-7385-5640-81b9-e52037218182"
|
||||||
|
version = "1.9.19"
|
||||||
|
|
||||||
|
[deps.StaticArrays.extensions]
|
||||||
|
StaticArraysChainRulesCoreExt = "ChainRulesCore"
|
||||||
|
StaticArraysStatisticsExt = "Statistics"
|
||||||
|
|
||||||
|
[deps.StaticArrays.weakdeps]
|
||||||
|
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
|
||||||
|
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
|
||||||
|
|
||||||
|
[[deps.StaticArraysCore]]
|
||||||
|
git-tree-sha1 = "6ab403037779dae8c514bad259f32a447262455a"
|
||||||
|
uuid = "1e83bf80-4336-4d27-bf5d-d5a4f845583c"
|
||||||
|
version = "1.4.4"
|
||||||
|
|
||||||
[[deps.Statistics]]
|
[[deps.Statistics]]
|
||||||
deps = ["LinearAlgebra"]
|
deps = ["LinearAlgebra"]
|
||||||
git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0"
|
git-tree-sha1 = "ae3bb1eb3bba077cd276bc5cfc337cc65c3075c0"
|
||||||
@@ -672,15 +961,15 @@ version = "1.8.0"
|
|||||||
|
|
||||||
[[deps.StatsBase]]
|
[[deps.StatsBase]]
|
||||||
deps = ["AliasTables", "DataAPI", "DataStructures", "IrrationalConstants", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"]
|
deps = ["AliasTables", "DataAPI", "DataStructures", "IrrationalConstants", "LinearAlgebra", "LogExpFunctions", "Missings", "Printf", "Random", "SortingAlgorithms", "SparseArrays", "Statistics", "StatsAPI"]
|
||||||
git-tree-sha1 = "aceda6f4e598d331548e04cc6b2124a6148138e3"
|
git-tree-sha1 = "adb9da019510162e67a4493fc235c23203d8b09e"
|
||||||
uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
|
uuid = "2913bbd2-ae8a-5f71-8c99-4fb6c76f3a91"
|
||||||
version = "0.34.10"
|
version = "0.34.13"
|
||||||
|
|
||||||
[[deps.StatsFuns]]
|
[[deps.StatsFuns]]
|
||||||
deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"]
|
deps = ["HypergeometricFunctions", "IrrationalConstants", "LogExpFunctions", "Reexport", "Rmath", "SpecialFunctions"]
|
||||||
git-tree-sha1 = "91f091a8716a6bb38417a6e6f274602a19aaa685"
|
git-tree-sha1 = "91a5737baed20ee31f3faea0e51f57461f6a689e"
|
||||||
uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
|
uuid = "4c63d2b9-4356-54db-8cca-17b64c39e42c"
|
||||||
version = "1.5.2"
|
version = "2.2.1"
|
||||||
|
|
||||||
[deps.StatsFuns.extensions]
|
[deps.StatsFuns.extensions]
|
||||||
StatsFunsChainRulesCoreExt = "ChainRulesCore"
|
StatsFunsChainRulesCoreExt = "ChainRulesCore"
|
||||||
@@ -690,11 +979,17 @@ version = "1.5.2"
|
|||||||
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
|
ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4"
|
||||||
InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112"
|
InverseFunctions = "3587e190-3f89-42d0-90ee-14403ec27112"
|
||||||
|
|
||||||
|
[[deps.StringDistances]]
|
||||||
|
deps = ["Distances", "StatsAPI"]
|
||||||
|
git-tree-sha1 = "456f343c7a6c8f52d8b501c0da2a05538ab1b907"
|
||||||
|
uuid = "88034a9c-02f8-509d-84a9-84ec65e18404"
|
||||||
|
version = "1.0.1"
|
||||||
|
|
||||||
[[deps.StringManipulation]]
|
[[deps.StringManipulation]]
|
||||||
deps = ["PrecompileTools"]
|
deps = ["PrecompileTools"]
|
||||||
git-tree-sha1 = "d05693d339e37d6ab134c5ab53c29fce5ee5d7d5"
|
git-tree-sha1 = "773065c6e0e903924a9d838259be74338422aef2"
|
||||||
uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e"
|
uuid = "892a3eda-7b42-436c-8928-eab12a02cf0e"
|
||||||
version = "0.4.4"
|
version = "0.5.0"
|
||||||
|
|
||||||
[[deps.StringViews]]
|
[[deps.StringViews]]
|
||||||
git-tree-sha1 = "f2dcb92855b31ad92fe8f079d4f75ac57c93e4b8"
|
git-tree-sha1 = "f2dcb92855b31ad92fe8f079d4f75ac57c93e4b8"
|
||||||
@@ -709,9 +1004,9 @@ version = "1.11.0"
|
|||||||
|
|
||||||
[[deps.StructUtils]]
|
[[deps.StructUtils]]
|
||||||
deps = ["Dates", "UUIDs"]
|
deps = ["Dates", "UUIDs"]
|
||||||
git-tree-sha1 = "82bee338d650aa515f31866c460cb7e3bcef90b8"
|
git-tree-sha1 = "2d0fc55c61321ba245c47be599570d11bac50303"
|
||||||
uuid = "ec057cc2-7a8d-4b58-b3b3-92acb9f63b42"
|
uuid = "ec057cc2-7a8d-4b58-b3b3-92acb9f63b42"
|
||||||
version = "2.8.2"
|
version = "2.8.5"
|
||||||
|
|
||||||
[deps.StructUtils.extensions]
|
[deps.StructUtils.extensions]
|
||||||
StructUtilsMeasurementsExt = ["Measurements"]
|
StructUtilsMeasurementsExt = ["Measurements"]
|
||||||
@@ -736,6 +1031,12 @@ deps = ["Artifacts", "Libdl", "libblastrampoline_jll"]
|
|||||||
uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c"
|
uuid = "bea87d4a-7f5b-5778-9afe-8cc45184846c"
|
||||||
version = "7.8.3+2"
|
version = "7.8.3+2"
|
||||||
|
|
||||||
|
[[deps.SymDict]]
|
||||||
|
deps = ["Test"]
|
||||||
|
git-tree-sha1 = "0108ccdaea3ef69d9680eeafc8d5ad198b896ec8"
|
||||||
|
uuid = "2da68c74-98d7-5633-99d6-8493888d7b1e"
|
||||||
|
version = "0.3.0"
|
||||||
|
|
||||||
[[deps.TOML]]
|
[[deps.TOML]]
|
||||||
deps = ["Dates"]
|
deps = ["Dates"]
|
||||||
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
|
uuid = "fa267f1f-6049-4f14-aa54-33bafae1ed76"
|
||||||
@@ -743,9 +1044,9 @@ version = "1.0.3"
|
|||||||
|
|
||||||
[[deps.TZJData]]
|
[[deps.TZJData]]
|
||||||
deps = ["Artifacts"]
|
deps = ["Artifacts"]
|
||||||
git-tree-sha1 = "72df96b3a595b7aab1e101eb07d2a435963a97e2"
|
git-tree-sha1 = "d3b30a9f29a898e21fb4bdf280101b7a12e1f39c"
|
||||||
uuid = "dc5dba14-91b3-4cab-a142-028a31da12f7"
|
uuid = "dc5dba14-91b3-4cab-a142-028a31da12f7"
|
||||||
version = "1.5.0+2025b"
|
version = "1.5.1+2025b"
|
||||||
|
|
||||||
[[deps.TableTraits]]
|
[[deps.TableTraits]]
|
||||||
deps = ["IteratorInterfaceExtensions"]
|
deps = ["IteratorInterfaceExtensions"]
|
||||||
@@ -755,9 +1056,9 @@ version = "1.0.1"
|
|||||||
|
|
||||||
[[deps.Tables]]
|
[[deps.Tables]]
|
||||||
deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"]
|
deps = ["DataAPI", "DataValueInterfaces", "IteratorInterfaceExtensions", "OrderedCollections", "TableTraits"]
|
||||||
git-tree-sha1 = "f2c1efbc8f3a609aadf318094f8fc5204bdaf344"
|
git-tree-sha1 = "a94d9bdda1b7bed0046cea645639ab3f62196fac"
|
||||||
uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
|
uuid = "bd369af6-aec1-5ad0-b16a-f7cc5008161c"
|
||||||
version = "1.12.1"
|
version = "1.14.0"
|
||||||
|
|
||||||
[[deps.Test]]
|
[[deps.Test]]
|
||||||
deps = ["InteractiveUtils", "Logging", "Random", "Serialization"]
|
deps = ["InteractiveUtils", "Logging", "Random", "Serialization"]
|
||||||
@@ -769,21 +1070,25 @@ deps = ["Artifacts", "Dates", "Downloads", "InlineStrings", "Mocking", "Printf",
|
|||||||
git-tree-sha1 = "d422301b2a1e294e3e4214061e44f338cafe18a2"
|
git-tree-sha1 = "d422301b2a1e294e3e4214061e44f338cafe18a2"
|
||||||
uuid = "f269a46b-ccf7-5d73-abea-4c690281aa53"
|
uuid = "f269a46b-ccf7-5d73-abea-4c690281aa53"
|
||||||
version = "1.22.2"
|
version = "1.22.2"
|
||||||
|
weakdeps = ["RecipesBase"]
|
||||||
|
|
||||||
[deps.TimeZones.extensions]
|
[deps.TimeZones.extensions]
|
||||||
TimeZonesRecipesBaseExt = "RecipesBase"
|
TimeZonesRecipesBaseExt = "RecipesBase"
|
||||||
|
|
||||||
[deps.TimeZones.weakdeps]
|
|
||||||
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
|
|
||||||
|
|
||||||
[[deps.TranscodingStreams]]
|
[[deps.TranscodingStreams]]
|
||||||
git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742"
|
git-tree-sha1 = "0c45878dcfdcfa8480052b6ab162cdd138781742"
|
||||||
uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa"
|
uuid = "3bb67fe8-82b1-5028-8e26-92a6c54297fa"
|
||||||
version = "0.11.3"
|
version = "0.11.3"
|
||||||
|
|
||||||
[[deps.URIs]]
|
[[deps.URIs]]
|
||||||
git-tree-sha1 = "bef26fb046d031353ef97a82e3fdb6afe7f21b1a"
|
git-tree-sha1 = "908fec9df6c5de98548ead82a468c95ccf6cd263"
|
||||||
uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4"
|
uuid = "5c2747f8-b7ea-4ff2-ba2e-563bfd36b1d4"
|
||||||
|
version = "1.7.0"
|
||||||
|
|
||||||
|
[[deps.UTCDateTimes]]
|
||||||
|
deps = ["Dates", "TimeZones"]
|
||||||
|
git-tree-sha1 = "4af3552bf0cf4a071bf3d14bd20023ea70f31b62"
|
||||||
|
uuid = "0f7cfa37-7abf-4834-b969-a8aa512401c2"
|
||||||
version = "1.6.1"
|
version = "1.6.1"
|
||||||
|
|
||||||
[[deps.UUIDs]]
|
[[deps.UUIDs]]
|
||||||
@@ -806,6 +1111,18 @@ git-tree-sha1 = "cd1659ba0d57b71a464a29e64dbc67cfe83d54e7"
|
|||||||
uuid = "76eceee3-57b5-4d4a-8e66-0e911cebbf60"
|
uuid = "76eceee3-57b5-4d4a-8e66-0e911cebbf60"
|
||||||
version = "1.6.1"
|
version = "1.6.1"
|
||||||
|
|
||||||
|
[[deps.XML2_jll]]
|
||||||
|
deps = ["Artifacts", "JLLWrappers", "Libdl", "Libiconv_jll", "Zlib_jll"]
|
||||||
|
git-tree-sha1 = "3f3315d89fc954a28f5b471bce698ed6e27481be"
|
||||||
|
uuid = "02c8fc9c-b97f-50b9-bbe4-9be30ff0a78a"
|
||||||
|
version = "2.15.3+0"
|
||||||
|
|
||||||
|
[[deps.XMLDict]]
|
||||||
|
deps = ["EzXML", "IterTools", "OrderedCollections"]
|
||||||
|
git-tree-sha1 = "8e8cdc9c93e1f442eba471b56db6f86ffeb1a33a"
|
||||||
|
uuid = "228000da-037f-5747-90a9-8195ccbf91a5"
|
||||||
|
version = "0.4.2"
|
||||||
|
|
||||||
[[deps.Zlib_jll]]
|
[[deps.Zlib_jll]]
|
||||||
deps = ["Libdl"]
|
deps = ["Libdl"]
|
||||||
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"
|
uuid = "83775a58-1f1d-513f-b197-d71354ab007a"
|
||||||
@@ -829,10 +1146,10 @@ uuid = "a9144af2-ca23-56d9-984f-0d03f7b5ccf8"
|
|||||||
version = "1.0.21+0"
|
version = "1.0.21+0"
|
||||||
|
|
||||||
[[deps.msghandler]]
|
[[deps.msghandler]]
|
||||||
deps = ["Arrow", "Base64", "DataFrames", "Dates", "HTTP", "JSON", "NATS", "PrettyPrinting", "Revise", "UUIDs"]
|
deps = ["Arrow", "Base64", "DataFrames", "Dates", "HTTP", "JSON", "NATS", "PrettyPrinting", "UUIDs"]
|
||||||
path = "."
|
path = "."
|
||||||
uuid = "f2724d33-f338-4a57-b9f8-1be882570d10"
|
uuid = "f2724d33-f338-4a57-b9f8-1be882570d10"
|
||||||
version = "0.5.6"
|
version = "1.4.0"
|
||||||
|
|
||||||
[[deps.nghttp2_jll]]
|
[[deps.nghttp2_jll]]
|
||||||
deps = ["Artifacts", "Libdl"]
|
deps = ["Artifacts", "Libdl"]
|
||||||
|
|||||||
+1
-3
@@ -1,6 +1,6 @@
|
|||||||
name = "msghandler"
|
name = "msghandler"
|
||||||
uuid = "f2724d33-f338-4a57-b9f8-1be882570d10"
|
uuid = "f2724d33-f338-4a57-b9f8-1be882570d10"
|
||||||
version = "0.5.6"
|
version = "1.4.0"
|
||||||
authors = ["narawat <narawat@gmail.com>"]
|
authors = ["narawat <narawat@gmail.com>"]
|
||||||
|
|
||||||
[deps]
|
[deps]
|
||||||
@@ -13,11 +13,9 @@ HTTP = "cd3eb016-35fb-5094-929b-558a96fad6f3"
|
|||||||
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
|
JSON = "682c06a0-de6a-54ab-a142-c8b1cf79cde6"
|
||||||
NATS = "55e73f9c-eeeb-467f-b4cc-a633fde63d2a"
|
NATS = "55e73f9c-eeeb-467f-b4cc-a633fde63d2a"
|
||||||
PrettyPrinting = "54e16d92-306c-5ea0-a30b-337be88ac337"
|
PrettyPrinting = "54e16d92-306c-5ea0-a30b-337be88ac337"
|
||||||
Revise = "295af30f-e4ad-537b-8983-00126c2a3abe"
|
|
||||||
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
|
UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
|
||||||
|
|
||||||
[compat]
|
[compat]
|
||||||
Base64 = "1.11.0"
|
Base64 = "1.11.0"
|
||||||
Dates = "1.11.0"
|
Dates = "1.11.0"
|
||||||
GeneralUtils = "0.3.1"
|
|
||||||
JSON = "1.4.0"
|
JSON = "1.4.0"
|
||||||
|
|||||||
+5
-26
@@ -526,36 +526,15 @@ async function smartunpack(msg, options = {}) {
|
|||||||
max_delay = 5000
|
max_delay = 5000
|
||||||
} = options;
|
} = options;
|
||||||
|
|
||||||
// Handle both raw JSON strings and transport message objects
|
let envJsonObj;
|
||||||
let payload;
|
|
||||||
if (typeof msg === 'string') {
|
// NATS's Javascript lib already return JSON object
|
||||||
payload = msg;
|
if (msg !== null && typeof msg === 'object') {
|
||||||
} else if (msg !== null && typeof msg === 'object') {
|
envJsonObj = msg;
|
||||||
if (msg.data !== undefined) {
|
|
||||||
payload = typeof msg.data === 'string' ? msg.data : new TextDecoder().decode(msg.data);
|
|
||||||
} else if (msg.payload !== undefined) {
|
|
||||||
payload = typeof msg.payload === 'string' ? msg.payload : new TextDecoder().decode(msg.payload);
|
|
||||||
} else {
|
|
||||||
throw new Error('Message has neither data nor payload property');
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Invalid message format: expected JSON string or message object');
|
throw new Error('Invalid message format: expected JSON string or message object');
|
||||||
}
|
}
|
||||||
|
|
||||||
logTrace('smartunpack', `smartunpack: raw payload length=${payload.length}`);
|
|
||||||
|
|
||||||
// Debug: Show first 200 chars of payload
|
|
||||||
const payloadPreview = payload.substring(0, 200);
|
|
||||||
logTrace('smartunpack', `smartunpack: payload preview: ${payloadPreview}`);
|
|
||||||
|
|
||||||
let envJsonObj;
|
|
||||||
try {
|
|
||||||
envJsonObj = JSON.parse(payload);
|
|
||||||
} catch (e) {
|
|
||||||
logTrace('smartunpack', `smartunpack: JSON parse failed: ${e.message}`);
|
|
||||||
throw e;
|
|
||||||
}
|
|
||||||
|
|
||||||
logTrace(envJsonObj.correlation_id, 'Processing received message');
|
logTrace(envJsonObj.correlation_id, 'Processing received message');
|
||||||
logTrace(envJsonObj.correlation_id, `smartunpack: envelope has ${envJsonObj.payloads.length} payloads`);
|
logTrace(envJsonObj.correlation_id, `smartunpack: envelope has ${envJsonObj.payloads.length} payloads`);
|
||||||
|
|
||||||
|
|||||||
+66
-98
@@ -369,7 +369,7 @@ Transport publishing must be performed by the caller.
|
|||||||
# Keyword Arguments:
|
# Keyword Arguments:
|
||||||
- `broker_url::String = DEFAULT_BROKER_URL` - URL of the broker
|
- `broker_url::String = DEFAULT_BROKER_URL` - URL of the broker
|
||||||
- `fileserver_url = DEFAULT_FILESERVER_URL` - URL of the HTTP file server for large payloads
|
- `fileserver_url = DEFAULT_FILESERVER_URL` - URL of the HTTP file server for large payloads
|
||||||
- `fileserver_upload_handler::Function = plik_oneshot_upload` - Function to handle fileserver uploads (must return Dict with "status", "uploadid", "fileid", "url" keys)
|
- `fileserver_upload_handler::Function = plik_oneshot_upload` - Custom upload handler with signature `handler(fileserver_url::String, dataname::String, data::Vector{UInt8})::Dict{String, Any}`. Must return a `Dict` with keys: `"status"` (Int/HTTP status code), `"uploadid"` (String), `"fileid"` (String), `"url"` (String - full download URL).
|
||||||
- `size_threshold::Int = DEFAULT_SIZE_THRESHOLD` - Threshold in bytes separating direct vs link transport
|
- `size_threshold::Int = DEFAULT_SIZE_THRESHOLD` - Threshold in bytes separating direct vs link transport
|
||||||
- `correlation_id::String = string(uuid4())` - Correlation ID for tracing (auto-generated UUID)
|
- `correlation_id::String = string(uuid4())` - Correlation ID for tracing (auto-generated UUID)
|
||||||
- `msg_purpose::String = "chat"` - Purpose of the message: "ACK", "NACK", "updateStatus", "shutdown", "chat", etc.
|
- `msg_purpose::String = "chat"` - Purpose of the message: "ACK", "NACK", "updateStatus", "shutdown", "chat", etc.
|
||||||
@@ -414,16 +414,25 @@ env, msg_json = smartpack("chat.subject", [
|
|||||||
("audio_clip", audio_data, "audio")
|
("audio_clip", audio_data, "audio")
|
||||||
])
|
])
|
||||||
|
|
||||||
# Publish the JSON string directly via your transport (manual publish)
|
# Custom fileserver upload handler (e.g., for AWS S3)
|
||||||
# conn = my_transport.connect(broker_url)
|
function my_custom_upload(fileserver_url::String, dataname::String, data::Vector{UInt8})::Dict{String, Any}
|
||||||
# my_transport.publish(conn, subject, env_json_str)
|
# Upload `data` to your file server at `fileserver_url`, using `dataname` as the file name
|
||||||
|
# Return a Dict with required keys:
|
||||||
|
# "status" - HTTP status code (e.g. 200)
|
||||||
|
# "uploadid" - String ID of the upload session
|
||||||
|
# "fileid" - String ID of the uploaded file
|
||||||
|
# "url" - Full download URL for the uploaded file
|
||||||
|
# Example return:
|
||||||
|
# Dict("status" => 200, "uploadid" => "abc123", "fileid" => "file456", "url" => "http://my-server.com/abc123/file456/myfile.bin")
|
||||||
|
throw(NotImplementedError("implement upload logic here"))
|
||||||
|
end
|
||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
function smartpack(
|
function smartpack(
|
||||||
subject::String, # smartunpack's subject
|
subject::String, # smartunpack's subject
|
||||||
data::AbstractArray{Tuple{String, T1, String}, 1}; # List of (dataname, data, type) tuples. Use Tuple{String, Any, String}[] for empty payloads
|
data::AbstractArray{Tuple{String, T1, String}, 1}; # List of (dataname, data, type) tuples. Use data = Tuple{String, Any, String}[] for empty payloads
|
||||||
broker_url::String = DEFAULT_BROKER_URL, # Broker URL
|
broker_url::String = DEFAULT_BROKER_URL, # Broker URL
|
||||||
fileserver_url = DEFAULT_FILESERVER_URL,
|
fileserver_url::String = DEFAULT_FILESERVER_URL,
|
||||||
fileserver_upload_handler::Function = plik_oneshot_upload, # a function to handle uploading data to specific HTTP fileserver
|
fileserver_upload_handler::Function = plik_oneshot_upload, # a function to handle uploading data to specific HTTP fileserver
|
||||||
size_threshold::Int = DEFAULT_SIZE_THRESHOLD,
|
size_threshold::Int = DEFAULT_SIZE_THRESHOLD,
|
||||||
|
|
||||||
@@ -446,25 +455,26 @@ function smartpack(
|
|||||||
)::Tuple{msg_envelope_v1, String} where {T1<:Any}
|
)::Tuple{msg_envelope_v1, String} where {T1<:Any}
|
||||||
|
|
||||||
# Log start of send operation
|
# Log start of send operation
|
||||||
log_trace(correlation_id, "Starting smartpack for subject: $subject")
|
# log_trace(correlation_id, "Starting smartpack for subject: $subject")
|
||||||
|
|
||||||
# Process each payload in the list
|
# Process each payload in the list
|
||||||
payloads = msg_payload_v1[]
|
payloads = msg_payload_v1[]
|
||||||
for (dataname, payload_data, payload_type) in data
|
for (dataname, payload_data, payload_type) in data
|
||||||
@show dataname typeof(payload_data)
|
# @show dataname typeof(payload_data)
|
||||||
|
# @info "msghandler smartpack() 1" @__LINE__
|
||||||
|
|
||||||
# Serialize data based on type
|
# Serialize data based on type. use bytes as medium for every datatype
|
||||||
payload_bytes = _serialize_data(payload_data, payload_type)
|
payload_bytes = _serialize_data(payload_data, payload_type)
|
||||||
|
# @info "msghandler smartpack() 2" @__LINE__
|
||||||
payload_size = length(payload_bytes) # Calculate payload size in bytes
|
payload_size = length(payload_bytes) # Calculate payload size in bytes
|
||||||
log_trace(correlation_id, "Serialized payload '$dataname' (payload_type: $payload_type) size: $payload_size bytes") # Log payload size
|
# log_trace(correlation_id, "Serialized payload '$dataname' (payload_type: $payload_type) size: $payload_size bytes") # Log payload size
|
||||||
|
|
||||||
# Decision: Direct vs Link
|
# Decision: Direct vs Link
|
||||||
if payload_size < size_threshold # Check if payload is small enough for direct transport
|
if payload_size < size_threshold # Check if payload is small enough for direct transport
|
||||||
# Direct path - Base64 encode and include in message envelope
|
# Direct path - Base64 encode and include in message envelope
|
||||||
payload_b64 = Base64.base64encode(payload_bytes) # Encode bytes as base64 string
|
payload_b64 = Base64.base64encode(payload_bytes) # Encode bytes as base64 string
|
||||||
log_trace(correlation_id, "Using direct transport for $payload_size bytes") # Log transport choice
|
# log_trace(correlation_id, "Using direct transport for $payload_size bytes") # Log transport choice
|
||||||
|
# @info "msghandler smartpack() 3" @__LINE__
|
||||||
# Determine encoding based on payload_type
|
# Determine encoding based on payload_type
|
||||||
encoding = "base64"
|
encoding = "base64"
|
||||||
if payload_type == "jsontable"
|
if payload_type == "jsontable"
|
||||||
@@ -486,8 +496,9 @@ function smartpack(
|
|||||||
)
|
)
|
||||||
push!(payloads, payload)
|
push!(payloads, payload)
|
||||||
else
|
else
|
||||||
|
# @info "msghandler smartpack() 4" @__LINE__
|
||||||
# Link path - Upload to HTTP server, include URL in message envelope
|
# Link path - Upload to HTTP server, include URL in message envelope
|
||||||
log_trace(correlation_id, "Using link transport, uploading to fileserver") # Log link transport choice
|
# log_trace(correlation_id, "Using link transport, uploading to fileserver") # Log link transport choice
|
||||||
|
|
||||||
# Upload to HTTP server
|
# Upload to HTTP server
|
||||||
response = fileserver_upload_handler(fileserver_url, dataname, payload_bytes)
|
response = fileserver_upload_handler(fileserver_url, dataname, payload_bytes)
|
||||||
@@ -497,7 +508,7 @@ function smartpack(
|
|||||||
end
|
end
|
||||||
|
|
||||||
url = response["url"] # URL for the uploaded data
|
url = response["url"] # URL for the uploaded data
|
||||||
log_trace(correlation_id, "Uploaded to URL: $url") # Log successful upload
|
# log_trace(correlation_id, "Uploaded to URL: $url") # Log successful upload
|
||||||
|
|
||||||
# Determine encoding based on payload_type
|
# Determine encoding based on payload_type
|
||||||
encoding = "none"
|
encoding = "none"
|
||||||
@@ -520,6 +531,7 @@ function smartpack(
|
|||||||
)
|
)
|
||||||
push!(payloads, payload)
|
push!(payloads, payload)
|
||||||
end
|
end
|
||||||
|
# @info "msghandler smartpack() 5" @__LINE__
|
||||||
end
|
end
|
||||||
|
|
||||||
# Create msg_envelope_v1 with all payloads
|
# Create msg_envelope_v1 with all payloads
|
||||||
@@ -549,7 +561,7 @@ function smartpack(
|
|||||||
# # Publish message to NATS using existing connection
|
# # Publish message to NATS using existing connection
|
||||||
# publish_message(NATS_connection, subject, env_json_str, correlation_id)
|
# publish_message(NATS_connection, subject, env_json_str, correlation_id)
|
||||||
# end
|
# end
|
||||||
|
# @info "msghandler smartpack() 6" @__LINE__
|
||||||
return (env, env_json_str)
|
return (env, env_json_str)
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -637,21 +649,22 @@ function _serialize_data(data::Any, payload_type::String)
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
if payload_type == "text" # Text data - convert to UTF-8 bytes
|
if payload_type == "text" # Text data - convert to UTF-8 bytes
|
||||||
if isa(data, String)
|
# @info "msghandler _serialize_data() 1" @__LINE__
|
||||||
data_bytes = Vector{UInt8}(data) # Convert string to UTF-8 bytes
|
data_bytes = Vector{UInt8}(string(data)) # Convert string to UTF-8 bytes
|
||||||
return data_bytes
|
return data_bytes
|
||||||
else
|
|
||||||
error("Text data must be a String")
|
|
||||||
end
|
|
||||||
elseif payload_type == "dictionary" # JSON data - serialize directly
|
elseif payload_type == "dictionary" # JSON data - serialize directly
|
||||||
|
# @info "msghandler _serialize_data() 2" @__LINE__
|
||||||
json_str = JSON.json(data) # Convert Julia data to JSON string
|
json_str = JSON.json(data) # Convert Julia data to JSON string
|
||||||
json_str_bytes = Vector{UInt8}(json_str) # Convert JSON string to bytes
|
json_str_bytes = Vector{UInt8}(json_str) # Convert JSON string to bytes
|
||||||
return json_str_bytes
|
return json_str_bytes
|
||||||
elseif payload_type == "arrowtable" # Arrow table data - convert to Arrow IPC stream
|
elseif payload_type == "arrowtable" # Arrow table data - convert to Arrow IPC stream
|
||||||
|
# @info "msghandler _serialize_data() 3" @__LINE__
|
||||||
io = IOBuffer() # Create in-memory buffer
|
io = IOBuffer() # Create in-memory buffer
|
||||||
Arrow.write(io, data) # Write data as Arrow IPC stream to buffer
|
Arrow.write(io, data) # Write data as Arrow IPC stream to buffer
|
||||||
return take!(io) # Return the buffer contents as bytes
|
return take!(io) # Return the buffer contents as bytes
|
||||||
elseif payload_type == "jsontable" # JSON table data - convert to JSON
|
elseif payload_type == "jsontable" # JSON table data - convert to JSON
|
||||||
|
# @info "msghandler _serialize_data() 4" @__LINE__
|
||||||
|
|
||||||
# data can be Vector{NamedTuple}, Vector{Dict}, or DataFrame
|
# data can be Vector{NamedTuple}, Vector{Dict}, or DataFrame
|
||||||
# If DataFrame, convert to Vector{Dict} first
|
# If DataFrame, convert to Vector{Dict} first
|
||||||
if isa(data, DataFrame)
|
if isa(data, DataFrame)
|
||||||
@@ -667,29 +680,35 @@ function _serialize_data(data::Any, payload_type::String)
|
|||||||
json_str = JSON.json(rows)
|
json_str = JSON.json(rows)
|
||||||
return Vector{UInt8}(json_str)
|
return Vector{UInt8}(json_str)
|
||||||
else
|
else
|
||||||
|
# @info "msghandler _serialize_data() 5" @__LINE__
|
||||||
|
|
||||||
# Already Vector{NamedTuple} or Vector{Dict}
|
# Already Vector{NamedTuple} or Vector{Dict}
|
||||||
json_str = JSON.json(data)
|
json_str = JSON.json(data)
|
||||||
return Vector{UInt8}(json_str)
|
return Vector{UInt8}(json_str)
|
||||||
end
|
end
|
||||||
elseif payload_type == "image" # Image data - treat as binary
|
elseif payload_type == "image" # Image data - treat as binary
|
||||||
|
# @info "msghandler _serialize_data() 6" @__LINE__
|
||||||
if isa(data, Vector{UInt8})
|
if isa(data, Vector{UInt8})
|
||||||
return data # Return binary data directly
|
return data # Return binary data directly
|
||||||
else
|
else
|
||||||
error("Image data must be Vector{UInt8}")
|
error("Image data must be Vector{UInt8}")
|
||||||
end
|
end
|
||||||
elseif payload_type == "audio" # Audio data - treat as binary
|
elseif payload_type == "audio" # Audio data - treat as binary
|
||||||
|
# @info "msghandler _serialize_data() 7" @__LINE__
|
||||||
if isa(data, Vector{UInt8})
|
if isa(data, Vector{UInt8})
|
||||||
return data # Return binary data directly
|
return data # Return binary data directly
|
||||||
else
|
else
|
||||||
error("Audio data must be Vector{UInt8}")
|
error("Audio data must be Vector{UInt8}")
|
||||||
end
|
end
|
||||||
elseif payload_type == "video" # Video data - treat as binary
|
elseif payload_type == "video" # Video data - treat as binary
|
||||||
|
# @info "msghandler _serialize_data() 8" @__LINE__
|
||||||
if isa(data, Vector{UInt8})
|
if isa(data, Vector{UInt8})
|
||||||
return data # Return binary data directly
|
return data # Return binary data directly
|
||||||
else
|
else
|
||||||
error("Video data must be Vector{UInt8}")
|
error("Video data must be Vector{UInt8}")
|
||||||
end
|
end
|
||||||
elseif payload_type == "binary" # Binary data - treat as binary
|
elseif payload_type == "binary" # Binary data - treat as binary
|
||||||
|
# @info "msghandler _serialize_data() 9" @__LINE__
|
||||||
if isa(data, IOBuffer) # Check if data is an IOBuffer
|
if isa(data, IOBuffer) # Check if data is an IOBuffer
|
||||||
return take!(data) # Return buffer contents as bytes
|
return take!(data) # Return buffer contents as bytes
|
||||||
elseif isa(data, Vector{UInt8}) # Check if data is already binary
|
elseif isa(data, Vector{UInt8}) # Check if data is already binary
|
||||||
@@ -698,80 +717,12 @@ function _serialize_data(data::Any, payload_type::String)
|
|||||||
error("Binary data must be binary (Vector{UInt8} or IOBuffer)")
|
error("Binary data must be binary (Vector{UInt8} or IOBuffer)")
|
||||||
end
|
end
|
||||||
else # Unknown type
|
else # Unknown type
|
||||||
|
# @info "msghandler _serialize_data() 10" @__LINE__
|
||||||
error("Unknown payload_type: $payload_type")
|
error("Unknown payload_type: $payload_type")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
# """ publish_message - Publish message via transport
|
|
||||||
# This function publishes a message via the transport with proper
|
|
||||||
# connection management and logging.
|
|
||||||
|
|
||||||
# # Arguments:
|
|
||||||
# - `broker_url::String` - Broker URL (e.g., "localhost:4222")
|
|
||||||
# - `subject::String` - Subject to publish to (e.g., "/agent/wine/api/v1/prompt")
|
|
||||||
# - `message::String` - JSON message to publish
|
|
||||||
# - `correlation_id::String` - Correlation ID for tracing and logging
|
|
||||||
|
|
||||||
# # Return:
|
|
||||||
# - `nothing` - This function performs publishing but returns nothing
|
|
||||||
|
|
||||||
# # Example
|
|
||||||
# ```jldoctest
|
|
||||||
# using NATS
|
|
||||||
|
|
||||||
# # Prepare JSON message
|
|
||||||
# message = "{\"correlation_id\":\"abc123\",\"payload\":\"test\"}"
|
|
||||||
|
|
||||||
# # Publish via transport
|
|
||||||
# publish_message("localhost:4222", "my.subject", message, "abc123")
|
|
||||||
# ```
|
|
||||||
# """
|
|
||||||
# function publish_message(broker_url::String, subject::String, message::String, correlation_id::String)
|
|
||||||
# conn = NATS.connect(broker_url) # Create NATS connection
|
|
||||||
# publish_message(conn, subject, message, correlation_id)
|
|
||||||
# end
|
|
||||||
|
|
||||||
# """ publish_message - Publish message via transport using pre-existing connection
|
|
||||||
# This function publishes a message via the transport using a pre-existing connection,
|
|
||||||
# avoiding the overhead of connection establishment.
|
|
||||||
|
|
||||||
# # Arguments:
|
|
||||||
# - `conn` - Pre-existing connection object with publish/close methods
|
|
||||||
# - `subject::String` - Subject to publish to (e.g., "/agent/wine/api/v1/prompt")
|
|
||||||
# - `message::String` - JSON message to publish
|
|
||||||
# - `correlation_id::String` - Correlation ID for tracing and logging
|
|
||||||
|
|
||||||
# # Return:
|
|
||||||
# - `nothing` - This function performs publishing but returns nothing
|
|
||||||
|
|
||||||
# # Example
|
|
||||||
# ```jldoctest
|
|
||||||
# using NATS
|
|
||||||
|
|
||||||
# # Prepare JSON message
|
|
||||||
# message = "{\"correlation_id\":\"abc123\",\"payload\":\"test\"}"
|
|
||||||
|
|
||||||
# # Create connection once and reuse for multiple publishes
|
|
||||||
# conn = NATS.connect("nats://localhost:4222")
|
|
||||||
# publish_message(conn, "my.subject", message, "abc123")
|
|
||||||
# # Connection is automatically drained after publish
|
|
||||||
# ```
|
|
||||||
|
|
||||||
# # Use Case:
|
|
||||||
# Use this version when you already have an established connection and want to publish
|
|
||||||
# multiple messages without the overhead of creating a new connection for each publish.
|
|
||||||
# """
|
|
||||||
# function publish_message(conn::NATS.Connection, subject::String, message::String, correlation_id::String)
|
|
||||||
# try
|
|
||||||
# NATS.publish(conn, subject, message) # Publish message to NATS
|
|
||||||
# log_trace(correlation_id, "Message published to $subject") # Log successful publish
|
|
||||||
# finally
|
|
||||||
# NATS.drain(conn) # Ensure connection is closed properly
|
|
||||||
# end
|
|
||||||
# end
|
|
||||||
|
|
||||||
|
|
||||||
""" smartunpack - Receive and process messages
|
""" smartunpack - Receive and process messages
|
||||||
This function processes incoming messages, handling both direct transport
|
This function processes incoming messages, handling both direct transport
|
||||||
(base64 decoded payloads) and link transport (URL-based payloads).
|
(base64 decoded payloads) and link transport (URL-based payloads).
|
||||||
@@ -789,7 +740,7 @@ A HTTP file server is required along with its download function.
|
|||||||
- `msg_json_str::String` - JSON string from the message payload (e.g., `String(msg.payload)`)
|
- `msg_json_str::String` - JSON string from the message payload (e.g., `String(msg.payload)`)
|
||||||
|
|
||||||
# Keyword Arguments:
|
# Keyword Arguments:
|
||||||
- `fileserver_download_handler::Function = _fetch_with_backoff` - Function to handle downloading data from file server URLs
|
- `fileserver_download_handler::Function = _fetch_with_backoff` - Custom download handler with signature `handler(url::String, max_retries::Int, base_delay::Int, max_delay::Int, correlation_id::String)::Vector{UInt8}`. Must accept the download URL, retry/backoff parameters, and correlation ID; return the fetched data as `Vector{UInt8}` bytes.
|
||||||
- `max_retries::Int = 5` - Maximum retry attempts for fetching URL
|
- `max_retries::Int = 5` - Maximum retry attempts for fetching URL
|
||||||
- `base_delay::Int = 100` - Initial delay for exponential backoff in ms
|
- `base_delay::Int = 100` - Initial delay for exponential backoff in ms
|
||||||
- `max_delay::Int = 5000` - Maximum delay for exponential backoff in ms
|
- `max_delay::Int = 5000` - Maximum delay for exponential backoff in ms
|
||||||
@@ -803,6 +754,23 @@ A HTTP file server is required along with its download function.
|
|||||||
msg_json_str = String(msg.payload)
|
msg_json_str = String(msg.payload)
|
||||||
env = smartunpack(msg_json_str; fileserver_download_handler=_fetch_with_backoff, max_retries=5, base_delay=100, max_delay=5000)
|
env = smartunpack(msg_json_str; fileserver_download_handler=_fetch_with_backoff, max_retries=5, base_delay=100, max_delay=5000)
|
||||||
# env["payloads"] = [("dataname1", data1, "type1"), ("dataname2", data2, "type2"), ...]
|
# env["payloads"] = [("dataname1", data1, "type1"), ("dataname2", data2, "type2"), ...]
|
||||||
|
|
||||||
|
# Custom fileserver download handler (e.g., for AWS S3 presigned URLs)
|
||||||
|
function my_custom_download(url::String, max_retries::Int, base_delay::Int, max_delay::Int, correlation_id::String)::Vector{UInt8}
|
||||||
|
# Fetch data from `url` with retry logic using exponential backoff
|
||||||
|
# Return the response body as Vector{UInt8} bytes
|
||||||
|
# Example:
|
||||||
|
# for attempt in 1:max_retries
|
||||||
|
# resp = HTTP.request("GET", url)
|
||||||
|
# if resp.status == 200
|
||||||
|
# return resp.body
|
||||||
|
# end
|
||||||
|
# end
|
||||||
|
throw(NotImplementedError("implement download logic here"))
|
||||||
|
end
|
||||||
|
|
||||||
|
# Use custom download handler
|
||||||
|
env = smartunpack(msg_json_str; fileserver_download_handler=my_custom_download)
|
||||||
```
|
```
|
||||||
"""
|
"""
|
||||||
function smartunpack(
|
function smartunpack(
|
||||||
@@ -815,7 +783,7 @@ function smartunpack(
|
|||||||
|
|
||||||
# Parse the JSON envelope
|
# Parse the JSON envelope
|
||||||
env_json_obj = JSON.parse(msg_json_str)
|
env_json_obj = JSON.parse(msg_json_str)
|
||||||
log_trace(env_json_obj["correlation_id"], "Processing received message") # Log message processing start
|
# log_trace(env_json_obj["correlation_id"], "Processing received message") # Log message processing start
|
||||||
|
|
||||||
# Process all payloads in the envelope
|
# Process all payloads in the envelope
|
||||||
payloads_list = Tuple{String, Any, String}[]
|
payloads_list = Tuple{String, Any, String}[]
|
||||||
@@ -829,12 +797,12 @@ function smartunpack(
|
|||||||
dataname = String(payload["dataname"])
|
dataname = String(payload["dataname"])
|
||||||
|
|
||||||
if transport == "direct" # Direct transport - payload is in the message
|
if transport == "direct" # Direct transport - payload is in the message
|
||||||
log_trace(env_json_obj["correlation_id"], "Direct transport - decoding payload '$dataname'") # Log direct transport handling
|
# log_trace(env_json_obj["correlation_id"], "Direct transport - decoding payload '$dataname'") # Log direct transport handling
|
||||||
|
|
||||||
# Extract base64 payload from the payload
|
# Extract base64 payload from the payload
|
||||||
payload_b64 = String(payload["data"])
|
payload_b64 = String(payload["data"])
|
||||||
|
|
||||||
# Decode Base64 payload
|
# Decode Base64 payload back into bytes (smartpack use bytes as medium for every datatype)
|
||||||
payload_bytes = Base64.base64decode(payload_b64) # Decode base64 payload to bytes
|
payload_bytes = Base64.base64decode(payload_b64) # Decode base64 payload to bytes
|
||||||
|
|
||||||
# Deserialize based on type
|
# Deserialize based on type
|
||||||
@@ -845,7 +813,7 @@ function smartunpack(
|
|||||||
elseif transport == "link" # Link transport - payload is at URL
|
elseif transport == "link" # Link transport - payload is at URL
|
||||||
# Extract download URL from the payload
|
# Extract download URL from the payload
|
||||||
url = String(payload["data"])
|
url = String(payload["data"])
|
||||||
log_trace(env_json_obj["correlation_id"], "Link transport - fetching '$dataname' from URL: $url") # Log link transport handling
|
# log_trace(env_json_obj["correlation_id"], "Link transport - fetching '$dataname' from URL: $url") # Log link transport handling
|
||||||
|
|
||||||
# Fetch with exponential backoff using the download handler
|
# Fetch with exponential backoff using the download handler
|
||||||
downloaded_data = fileserver_download_handler(url, max_retries, base_delay, max_delay, env_json_obj["correlation_id"])
|
downloaded_data = fileserver_download_handler(url, max_retries, base_delay, max_delay, env_json_obj["correlation_id"])
|
||||||
@@ -906,7 +874,7 @@ function _fetch_with_backoff(
|
|||||||
try
|
try
|
||||||
response = HTTP.request("GET", url) # Make HTTP GET request to URL
|
response = HTTP.request("GET", url) # Make HTTP GET request to URL
|
||||||
if response.status == 200 # Check if request was successful
|
if response.status == 200 # Check if request was successful
|
||||||
log_trace(correlation_id, "Successfully fetched data from $url on attempt $attempt") # Log success
|
# log_trace(correlation_id, "Successfully fetched data from $url on attempt $attempt") # Log success
|
||||||
return response.body # Return response body as bytes
|
return response.body # Return response body as bytes
|
||||||
else # Request failed
|
else # Request failed
|
||||||
error("Failed to fetch: $(response.status)") # Throw error for non-200 status
|
error("Failed to fetch: $(response.status)") # Throw error for non-200 status
|
||||||
@@ -1048,7 +1016,7 @@ function plik_oneshot_upload(file_server_url::String, dataname::String, data::Ve
|
|||||||
url_getUploadID = "$file_server_url/upload" # URL to get upload ID
|
url_getUploadID = "$file_server_url/upload" # URL to get upload ID
|
||||||
headers = ["Content-Type" => "application/json"]
|
headers = ["Content-Type" => "application/json"]
|
||||||
body = """{ "OneShot" : true }"""
|
body = """{ "OneShot" : true }"""
|
||||||
http_response = HTTP.request("POST", url_getUploadID, headers, body; body_is_form=false)
|
http_response = HTTP.request("POST", url_getUploadID, headers, body)
|
||||||
response_json = JSON.parse(http_response.body)
|
response_json = JSON.parse(http_response.body)
|
||||||
uploadid = response_json["id"]
|
uploadid = response_json["id"]
|
||||||
uploadtoken = response_json["uploadToken"]
|
uploadtoken = response_json["uploadToken"]
|
||||||
@@ -1125,7 +1093,7 @@ function plik_oneshot_upload(file_server_url::String, filepath::String)
|
|||||||
url_getUploadID = "$file_server_url/upload" # URL to get upload ID
|
url_getUploadID = "$file_server_url/upload" # URL to get upload ID
|
||||||
headers = ["Content-Type" => "application/json"]
|
headers = ["Content-Type" => "application/json"]
|
||||||
body = """{ "OneShot" : true }"""
|
body = """{ "OneShot" : true }"""
|
||||||
http_response = HTTP.request("POST", url_getUploadID, headers, body; body_is_form=false)
|
http_response = HTTP.request("POST", url_getUploadID, headers, body)
|
||||||
response_json = JSON.parse(http_response.body)
|
response_json = JSON.parse(http_response.body)
|
||||||
|
|
||||||
uploadid = response_json["id"]
|
uploadid = response_json["id"]
|
||||||
|
|||||||
@@ -0,0 +1,66 @@
|
|||||||
|
|
||||||
|
function plik_oneshot_upload(file_server_url::String, dataname::String, data::Vector{UInt8})
|
||||||
|
|
||||||
|
# ----------------------------------------- get upload id ---------------------------------------- #
|
||||||
|
# Equivalent curl command: curl -X POST -d '{ "OneShot" : true }' http://localhost:8080/upload
|
||||||
|
url_getUploadID = "$file_server_url/upload" # URL to get upload ID
|
||||||
|
headers = ["Content-Type" => "application/json"]
|
||||||
|
body = """{ "OneShot" : true }"""
|
||||||
|
http_response = HTTP.request("POST", url_getUploadID, headers, body)
|
||||||
|
response_json = JSON.parse(http_response.body)
|
||||||
|
uploadid = response_json["id"]
|
||||||
|
uploadtoken = response_json["uploadToken"]
|
||||||
|
|
||||||
|
# ------------------------------------------ upload file ----------------------------------------- #
|
||||||
|
# Equivalent curl command: curl -X POST --header "X-UploadToken: UPLOAD_TOKEN" -F "file=@PATH_TO_FILE" http://localhost:8080/file/UPLOAD_ID
|
||||||
|
file_multipart = HTTP.Multipart(dataname, IOBuffer(data), "application/octet-stream") # Plik won't accept raw bytes upload
|
||||||
|
url_upload = "$file_server_url/file/$uploadid"
|
||||||
|
headers = ["X-UploadToken" => uploadtoken]
|
||||||
|
|
||||||
|
# Create the multipart form data
|
||||||
|
form = HTTP.Form(Dict(
|
||||||
|
"file" => file_multipart
|
||||||
|
))
|
||||||
|
|
||||||
|
# Execute the POST request
|
||||||
|
http_response = nothing
|
||||||
|
try
|
||||||
|
http_response = HTTP.post(url_upload, headers, form)
|
||||||
|
catch e
|
||||||
|
@error "Request failed" exception=e
|
||||||
|
end
|
||||||
|
response_json = JSON.parse(http_response.body)
|
||||||
|
fileid = response_json["id"]
|
||||||
|
|
||||||
|
# url of the uploaded data e.g. "http://192.168.1.20:8080/file/3F62E/4AgGT/test.zip"
|
||||||
|
url = "$file_server_url/file/$uploadid/$fileid/$dataname"
|
||||||
|
|
||||||
|
return Dict("status" => http_response.status, "uploadid" => uploadid, "fileid" => fileid, "url" => url)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
using HTTP, JSON
|
||||||
|
|
||||||
|
file_server_url = "https://fileserver.yiem.cc"
|
||||||
|
dataname = "test.txt"
|
||||||
|
data = Vector{UInt8}("hello world")
|
||||||
|
|
||||||
|
# Upload to local plik server
|
||||||
|
result = plik_oneshot_upload(file_server_url, dataname, data)
|
||||||
|
println(result)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -6,7 +6,7 @@
|
|||||||
* any combination and any number of mixed content can be received correctly.
|
* any combination and any number of mixed content can be received correctly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const msghandler = require('../src/msghandler.js');
|
const msghandler = require('../src/msghandler-csr.js');
|
||||||
const nats = require('nats');
|
const nats = require('nats');
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
* any combination and any number of mixed content can be sent correctly.
|
* any combination and any number of mixed content can be sent correctly.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const msghandler = require('../src/msghandler.js');
|
const msghandler = require('../src/msghandler-csr.js').default;
|
||||||
const crypto = require('crypto');
|
const crypto = require('crypto');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|||||||
@@ -9,7 +9,7 @@
|
|||||||
using NATS, JSON, UUIDs, Dates, PrettyPrinting, DataFrames, Arrow, HTTP, Base64
|
using NATS, JSON, UUIDs, Dates, PrettyPrinting, DataFrames, Arrow, HTTP, Base64
|
||||||
|
|
||||||
# Include the bridge module
|
# Include the bridge module
|
||||||
include("../src/msghandler.jl")
|
include("/home/ton/docker-apps/sommpanion/msghandler/src/msghandler.jl")
|
||||||
using .msghandler
|
using .msghandler
|
||||||
|
|
||||||
# Configuration
|
# Configuration
|
||||||
@@ -39,7 +39,7 @@ function test_mix_receive()
|
|||||||
# Use msghandler.smartunpack to handle the data
|
# Use msghandler.smartunpack to handle the data
|
||||||
# API: smartunpack(msg, download_handler; max_retries, base_delay, max_delay)
|
# API: smartunpack(msg, download_handler; max_retries, base_delay, max_delay)
|
||||||
result = msghandler.smartunpack(
|
result = msghandler.smartunpack(
|
||||||
msg;
|
env_json_str;
|
||||||
max_retries = 5,
|
max_retries = 5,
|
||||||
base_delay = 100,
|
base_delay = 100,
|
||||||
max_delay = 5000
|
max_delay = 5000
|
||||||
|
|||||||
@@ -1,258 +1,632 @@
|
|||||||
#!/usr/bin/env julia
|
/**
|
||||||
# Test script for mixed-content message testing
|
* msghandler - Cross-Platform Bi-Directional Data Bridge
|
||||||
# Tests sending a mix of text, dictionary, arrowtable, jsontable, image, audio, video, and binary data
|
* Browser-Compatible Implementation (Client-Side Rendering)
|
||||||
# from Julia serviceA to Julia serviceB using msghandler.jl smartpack
|
*
|
||||||
#
|
* This module provides functionality for sending and receiving data across network boundaries
|
||||||
# This test demonstrates that any combination and any number of mixed content
|
* with support for both direct payload transport and URL-based transport for larger payloads.
|
||||||
# can be sent and received correctly.
|
*
|
||||||
#
|
* Supported payload types: "text", "dictionary", "jsontable", "image", "audio", "video", "binary"
|
||||||
# Key concept: DataFrames are the main table representation in Julia.
|
* Note: Browser version does NOT support Apache Arrow IPC (arrowtable) due to browser compatibility constraints.
|
||||||
# The msghandler.jl library handles serialization:
|
* Use "jsontable" for tabular data in browser applications.
|
||||||
# - For "arrowtable" type: DataFrame is serialized to Arrow IPC format
|
*
|
||||||
# - For "jsontable" type: DataFrame is converted to Vector{Dict} and then to JSON
|
* Browser requirements:
|
||||||
|
* - Modern browser with ES module support (or use module bundler)
|
||||||
|
* - Web Crypto API for UUID generation
|
||||||
|
* - Fetch API for HTTP requests
|
||||||
|
*
|
||||||
|
* Browser-compatible version uses:
|
||||||
|
* - Web Crypto API for UUID generation
|
||||||
|
* - Uint8Array instead of Buffer
|
||||||
|
* - fetch API for file server communication
|
||||||
|
*
|
||||||
|
* @module msghandlerCSR
|
||||||
|
*/
|
||||||
|
|
||||||
using NATS, JSON, UUIDs, Dates, PrettyPrinting, DataFrames, Arrow, HTTP, Base64
|
// Use native fetch available in browsers
|
||||||
|
|
||||||
# Include the bridge module
|
// ---------------------------------------------- Constants ---------------------------------------------- //
|
||||||
include("../src/msghandler.jl")
|
|
||||||
using .msghandler
|
|
||||||
|
|
||||||
# Configuration
|
/**
|
||||||
const SUBJECT = "/msghandler"
|
* Default size threshold for switching from direct to link transport (0.5MB)
|
||||||
const NATS_URL = "nats.yiem.cc"
|
*/
|
||||||
const FILESERVER_URL = "http://192.168.88.104:8080"
|
const DEFAULT_SIZE_THRESHOLD = 500_000;
|
||||||
|
|
||||||
# Create correlation ID for tracing
|
/**
|
||||||
correlation_id = string(uuid4())
|
* Default broker URL
|
||||||
|
*/
|
||||||
|
const DEFAULT_BROKER_URL = 'localhost:4222';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default HTTP file server URL for link transport
|
||||||
|
*/
|
||||||
|
const DEFAULT_FILESERVER_URL = 'http://localhost:8080';
|
||||||
|
|
||||||
# ------------------------------------------------------------------------------------------------ #
|
// ---------------------------------------------- Utility Functions ---------------------------------------------- //
|
||||||
# test mixed content transfer #
|
|
||||||
# ------------------------------------------------------------------------------------------------ #
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert Uint8Array to Base64 string
|
||||||
|
* @param {Uint8Array} data - Data to encode
|
||||||
|
* @returns {string} Base64 encoded string
|
||||||
|
*/
|
||||||
|
function bufferToBase64(data) {
|
||||||
|
const bytes = new Uint8Array(data);
|
||||||
|
const binary = String.fromCharCode(...bytes);
|
||||||
|
return btoa(binary);
|
||||||
|
}
|
||||||
|
|
||||||
# Helper: Log with correlation ID
|
/**
|
||||||
function log_trace(message)
|
* Convert Base64 string to Uint8Array
|
||||||
timestamp = Dates.now()
|
* @param {string} base64 - Base64 encoded string
|
||||||
println("[$timestamp] [Correlation: $correlation_id] $message")
|
* @returns {Uint8Array} Decoded binary data
|
||||||
end
|
*/
|
||||||
|
function base64ToBuffer(base64) {
|
||||||
|
const binary = atob(base64);
|
||||||
|
const len = binary.length;
|
||||||
|
const bytes = new Uint8Array(len);
|
||||||
|
for (let i = 0; i < len; i++) {
|
||||||
|
bytes[i] = binary.charCodeAt(i);
|
||||||
|
}
|
||||||
|
return bytes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate UUID v4 using Web Crypto API
|
||||||
|
* @returns {string} UUID string
|
||||||
|
*/
|
||||||
|
function uuidv4() {
|
||||||
|
const array = new Uint8Array(16);
|
||||||
|
crypto.getRandomValues(array);
|
||||||
|
array[6] = (array[6] & 0x0f) | 0x40;
|
||||||
|
array[8] = (array[8] & 0x3f) | 0x80;
|
||||||
|
return Array.from(array, (val) => val.toString(16).padStart(2, '0').toUpperCase()).join('');
|
||||||
|
}
|
||||||
|
|
||||||
# File upload handler for plik server
|
/**
|
||||||
function plik_upload_handler(fileserver_url::String, dataname::String, data::Vector{UInt8})::Dict{String, Any}
|
* Log a trace message with correlation ID and timestamp
|
||||||
# Get upload ID
|
* @param {string} correlationId - Correlation ID for tracing
|
||||||
url_getUploadID = "$fileserver_url/upload"
|
* @param {string} message - Message content to log
|
||||||
headers = ["Content-Type" => "application/json"]
|
*/
|
||||||
body = """{ "OneShot" : true }"""
|
function logTrace(correlationId, message) {
|
||||||
httpResponse = HTTP.request("POST", url_getUploadID, headers, body; body_is_form=false)
|
const timestamp = new Date().toISOString();
|
||||||
responseJson = JSON.parse(String(httpResponse.body))
|
console.log(`[${timestamp}] [Correlation: ${correlationId}] ${message}`);
|
||||||
uploadid = responseJson["id"]
|
}
|
||||||
uploadtoken = responseJson["uploadToken"]
|
|
||||||
|
|
||||||
# Upload file
|
// ---------------------------------------------- Serialization Functions ---------------------------------------------- //
|
||||||
file_multipart = HTTP.Multipart(dataname, IOBuffer(data), "application/octet-stream")
|
|
||||||
url_upload = "$fileserver_url/file/$uploadid"
|
|
||||||
headers = ["X-UploadToken" => uploadtoken]
|
|
||||||
|
|
||||||
form = HTTP.Form(Dict("file" => file_multipart))
|
/**
|
||||||
httpResponse = HTTP.post(url_upload, headers, form)
|
* Serialize data according to specified format
|
||||||
responseJson = JSON.parse(String(httpResponse.body))
|
* @param {any} data - Data to serialize
|
||||||
|
* @param {string} payloadType - Target format: "text", "dictionary", "jsontable", "image", "audio", "video", "binary"
|
||||||
|
* @returns {Uint8Array} Binary representation of the serialized data
|
||||||
|
*/
|
||||||
|
async function serializeData(data, payloadType) {
|
||||||
|
if (payloadType === 'text') {
|
||||||
|
if (typeof data === 'string') {
|
||||||
|
return new Uint8Array(new TextEncoder().encode(data));
|
||||||
|
} else {
|
||||||
|
throw new Error('Text data must be a string');
|
||||||
|
}
|
||||||
|
} else if (payloadType === 'dictionary') {
|
||||||
|
const jsonStr = JSON.stringify(data);
|
||||||
|
return new Uint8Array(new TextEncoder().encode(jsonStr));
|
||||||
|
} else if (payloadType === 'jsontable') {
|
||||||
|
// Serialize array of objects to JSON format
|
||||||
|
if (!Array.isArray(data)) {
|
||||||
|
throw new Error('JSON table data must be an array');
|
||||||
|
}
|
||||||
|
const jsonStr = JSON.stringify(data);
|
||||||
|
return new Uint8Array(new TextEncoder().encode(jsonStr));
|
||||||
|
} else if (payloadType === 'image') {
|
||||||
|
if (data instanceof Uint8Array || data instanceof ArrayBuffer || ArrayBuffer.isView(data)) {
|
||||||
|
return new Uint8Array(data);
|
||||||
|
} else {
|
||||||
|
throw new Error('Image data must be Uint8Array, ArrayBuffer, or ArrayBuffer view');
|
||||||
|
}
|
||||||
|
} else if (payloadType === 'audio') {
|
||||||
|
if (data instanceof Uint8Array || data instanceof ArrayBuffer || ArrayBuffer.isView(data)) {
|
||||||
|
return new Uint8Array(data);
|
||||||
|
} else {
|
||||||
|
throw new Error('Audio data must be Uint8Array, ArrayBuffer, or ArrayBuffer view');
|
||||||
|
}
|
||||||
|
} else if (payloadType === 'video') {
|
||||||
|
if (data instanceof Uint8Array || data instanceof ArrayBuffer || ArrayBuffer.isView(data)) {
|
||||||
|
return new Uint8Array(data);
|
||||||
|
} else {
|
||||||
|
throw new Error('Video data must be Uint8Array, ArrayBuffer, or ArrayBuffer view');
|
||||||
|
}
|
||||||
|
} else if (payloadType === 'binary') {
|
||||||
|
if (data instanceof Uint8Array || data instanceof ArrayBuffer || ArrayBuffer.isView(data)) {
|
||||||
|
return new Uint8Array(data);
|
||||||
|
} else {
|
||||||
|
throw new Error('Binary data must be Uint8Array, ArrayBuffer, or ArrayBuffer view');
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new Error(`Unknown payload_type: ${payloadType}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fileid = responseJson["id"]
|
/**
|
||||||
url = "$fileserver_url/file/$uploadid/$fileid/$dataname"
|
* Deserialize bytes to data based on type
|
||||||
|
* @param {Uint8Array|ArrayBuffer} data - Serialized data as bytes
|
||||||
|
* @param {string} payloadType - Data type
|
||||||
|
* @param {string} correlationId - Correlation ID for logging
|
||||||
|
* @returns {any} Deserialized data
|
||||||
|
*/
|
||||||
|
async function deserializeData(data, payloadType, correlationId) {
|
||||||
|
const buffer = data instanceof Uint8Array ? data : new Uint8Array(data);
|
||||||
|
|
||||||
return Dict("status" => httpResponse.status, "uploadid" => uploadid, "fileid" => fileid, "url" => url)
|
logTrace(correlationId, `deserializeData: type=${payloadType}, bufferLength=${buffer.length}`);
|
||||||
end
|
|
||||||
|
|
||||||
|
// Debug: Show first 20 bytes in hex for binary data
|
||||||
|
if (payloadType === 'jsontable' || payloadType === 'image' || payloadType === 'binary') {
|
||||||
|
const hexPreview = [];
|
||||||
|
for (let i = 0; i < Math.min(20, buffer.length); i++) {
|
||||||
|
hexPreview.push(buffer[i].toString(16).padStart(2, '0'));
|
||||||
|
}
|
||||||
|
logTrace(correlationId, `deserializeData: First 20 bytes (hex): ${hexPreview.join(' ')}`);
|
||||||
|
}
|
||||||
|
|
||||||
# Helper: Create sample data for each type
|
if (payloadType === 'text') {
|
||||||
function create_sample_data()
|
const result = new TextDecoder().decode(buffer);
|
||||||
# Text data (small - direct transport)
|
logTrace(correlationId, `deserializeData: text result length=${result.length}`);
|
||||||
text_data = "Hello! This is a test chat message. 🎉\nHow are you doing today? 😊"
|
return result;
|
||||||
|
} else if (payloadType === 'dictionary') {
|
||||||
|
const jsonStr = new TextDecoder().decode(buffer);
|
||||||
|
const result = JSON.parse(jsonStr);
|
||||||
|
logTrace(correlationId, `deserializeData: dictionary keys=${Object.keys(result).join(', ')}`);
|
||||||
|
return result;
|
||||||
|
} else if (payloadType === 'jsontable') {
|
||||||
|
const jsonStr = new TextDecoder().decode(buffer);
|
||||||
|
const result = JSON.parse(jsonStr);
|
||||||
|
logTrace(correlationId, `deserializeData: jsontable result length=${Array.isArray(result) ? result.length : 'N/A'}`);
|
||||||
|
return result;
|
||||||
|
} else if (payloadType === 'image') {
|
||||||
|
logTrace(correlationId, `deserializeData: image buffer length=${buffer.length}`);
|
||||||
|
return buffer;
|
||||||
|
} else if (payloadType === 'audio') {
|
||||||
|
logTrace(correlationId, `deserializeData: audio buffer length=${buffer.length}`);
|
||||||
|
return buffer;
|
||||||
|
} else if (payloadType === 'video') {
|
||||||
|
logTrace(correlationId, `deserializeData: video buffer length=${buffer.length}`);
|
||||||
|
return buffer;
|
||||||
|
} else if (payloadType === 'binary') {
|
||||||
|
logTrace(correlationId, `deserializeData: binary buffer length=${buffer.length}`);
|
||||||
|
return buffer;
|
||||||
|
} else {
|
||||||
|
throw new Error(`Unknown payload_type: ${payloadType}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Dictionary/JSON data (medium - could be direct or link)
|
// ---------------------------------------------- File Server Handlers ---------------------------------------------- //
|
||||||
dict_data = Dict(
|
|
||||||
"type" => "chat",
|
|
||||||
"sender" => "serviceA",
|
|
||||||
"receiver" => "serviceB",
|
|
||||||
"metadata" => Dict(
|
|
||||||
"timestamp" => string(Dates.now()),
|
|
||||||
"priority" => "high",
|
|
||||||
"tags" => ["urgent", "chat", "test"]
|
|
||||||
),
|
|
||||||
"content" => Dict(
|
|
||||||
"text" => "This is a JSON-formatted chat message with nested structure.",
|
|
||||||
"format" => "markdown",
|
|
||||||
"mentions" => ["user1", "user2"]
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Arrow table data (DataFrame - small - direct transport)
|
/**
|
||||||
# Uses Arrow IPC format for efficient binary serialization
|
* Upload data to plik server in one-shot mode
|
||||||
# msghandler.jl handles serialization: DataFrame -> Arrow IPC
|
* @param {string} fileServerUrl - Base URL of the plik server
|
||||||
arrow_table_small = DataFrame(
|
* @param {string} dataname - Name of the file being uploaded
|
||||||
id = 1:10,
|
* @param {Uint8Array} data - Raw byte data of the file content
|
||||||
name = ["Alice", "Bob", "Charlie", "Diana", "Eve", "Frank", "Grace", "Henry", "Ivy", "Jack"],
|
* @returns {Promise<{status: number, uploadid: string, fileid: string, url: string}>}
|
||||||
score = rand(50:100, 10),
|
*/
|
||||||
active = rand([true, false], 10)
|
async function plikOneshotUpload(fileServerUrl, dataname, data) {
|
||||||
)
|
const buffer = data instanceof Uint8Array ? data : new Uint8Array(data);
|
||||||
|
|
||||||
# Arrow table data (DataFrame - large - link transport)
|
// Get upload id
|
||||||
# ~1.5MB of Arrow data (200,000 rows) - should trigger link transport
|
const urlGetUploadID = `${fileServerUrl}/upload`;
|
||||||
# msghandler.jl handles serialization: DataFrame -> Arrow IPC
|
const headers = { 'Content-Type': 'application/json' };
|
||||||
arrow_table_large = DataFrame(
|
const body = JSON.stringify({ OneShot: true });
|
||||||
id = 1:2_000_000,
|
|
||||||
name = ["user_$i" for i in 1:2_000_000],
|
|
||||||
score = rand(50:100, 2_000_000),
|
|
||||||
active = rand([true, false], 2_000_000),
|
|
||||||
timestamp = [string(Dates.now()) for _ in 1:2_000_000]
|
|
||||||
)
|
|
||||||
|
|
||||||
# Json table data (DataFrame - small - direct transport)
|
const httpResponse = await fetch(urlGetUploadID, {
|
||||||
# Uses JSON format for human-readable tabular data
|
method: 'POST',
|
||||||
# msghandler.jl handles serialization: DataFrame -> Vector{Dict} -> JSON
|
headers,
|
||||||
json_table_small = DataFrame(
|
body
|
||||||
id = 1:10,
|
});
|
||||||
name = ["Alice", "Bob", "Charlie", "Diana", "Eve", "Frank", "Grace", "Henry", "Ivy", "Jack"],
|
|
||||||
score = rand(50:100, 10),
|
|
||||||
active = rand([true, false], 10)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Json table data (DataFrame - large - link transport)
|
const responseJson = await httpResponse.json();
|
||||||
# ~1.5MB of JSON data (150,000 rows) - should trigger link transport
|
const uploadid = responseJson.id;
|
||||||
# msghandler.jl handles serialization: DataFrame -> Vector{Dict} -> JSON
|
const uploadtoken = responseJson.uploadToken;
|
||||||
json_table_large = DataFrame(
|
|
||||||
id = 1:2_000_000,
|
|
||||||
name = ["user_$i" for i in 1:2_000_000],
|
|
||||||
score = rand(50:100, 2_000_000),
|
|
||||||
active = rand([true, false], 2_000_000)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Audio data (small binary - direct transport)
|
// Upload file
|
||||||
audio_data = UInt8[rand(1:255) for _ in 1:100]
|
const urlUpload = `${fileServerUrl}/file/${uploadid}`;
|
||||||
|
const form = new FormData();
|
||||||
|
const blob = new Blob([buffer], { type: 'application/octet-stream' });
|
||||||
|
form.append('file', blob, dataname);
|
||||||
|
|
||||||
# Audio data (large - link transport)
|
const uploadHeaders = {
|
||||||
# ~1.5MB of audio-like data
|
'X-UploadToken': uploadtoken
|
||||||
large_audio_data = UInt8[rand(1:255) for _ in 1:1_500_000]
|
};
|
||||||
|
|
||||||
# Video data (small binary - direct transport)
|
const uploadResponse = await fetch(urlUpload, {
|
||||||
video_data = UInt8[rand(1:255) for _ in 1:150]
|
method: 'POST',
|
||||||
|
headers: uploadHeaders,
|
||||||
|
body: form
|
||||||
|
});
|
||||||
|
|
||||||
# Video data (large - link transport)
|
const uploadJson = await uploadResponse.json();
|
||||||
# ~1.5MB of video-like data
|
const fileid = uploadJson.id;
|
||||||
large_video_data = UInt8[rand(1:255) for _ in 1:1_500_000]
|
|
||||||
|
|
||||||
# Binary data (small - direct transport)
|
const url = `${fileServerUrl}/file/${uploadid}/${fileid}/${dataname}`;
|
||||||
binary_data = UInt8[rand(1:255) for _ in 1:200]
|
|
||||||
|
|
||||||
# Binary data (large - link transport)
|
return {
|
||||||
# ~1.5MB of binary data
|
status: uploadResponse.status,
|
||||||
large_binary_data = UInt8[rand(1:255) for _ in 1:1_500_000]
|
uploadid,
|
||||||
|
fileid,
|
||||||
|
url
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
/**
|
||||||
text_data,
|
* Fetch data from URL with exponential backoff
|
||||||
dict_data,
|
* @param {string} url - URL to fetch from
|
||||||
arrow_table_small,
|
* @param {number} maxRetries - Maximum number of retry attempts
|
||||||
arrow_table_large,
|
* @param {number} baseDelay - Initial delay in milliseconds
|
||||||
json_table_small,
|
* @param {number} maxDelay - Maximum delay in milliseconds
|
||||||
json_table_large,
|
* @param {string} correlationId - Correlation ID for logging
|
||||||
audio_data,
|
* @returns {Promise<Uint8Array>} Fetched data as bytes
|
||||||
large_audio_data,
|
*/
|
||||||
video_data,
|
async function fetchWithBackoff(url, maxRetries, baseDelay, maxDelay, correlationId) {
|
||||||
large_video_data,
|
let delay = baseDelay;
|
||||||
binary_data,
|
|
||||||
large_binary_data
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
|
for (let attempt = 1; attempt <= maxRetries; attempt++) {
|
||||||
|
try {
|
||||||
|
const response = await fetch(url);
|
||||||
|
|
||||||
# Sender: Send mixed content via smartpack
|
if (response.status === 200) {
|
||||||
function test_mix_send()
|
logTrace(correlationId, `Successfully fetched data from ${url} on attempt ${attempt}`);
|
||||||
# Create sample data
|
const arrayBuffer = await response.arrayBuffer();
|
||||||
(text_data, dict_data, arrow_table_small, arrow_table_large, json_table_small, json_table_large, audio_data, large_audio_data, video_data, large_video_data, binary_data, large_binary_data) = create_sample_data()
|
return new Uint8Array(arrayBuffer);
|
||||||
|
} else {
|
||||||
|
throw new Error(`Failed to fetch: ${response.status}`);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
logTrace(correlationId, `Attempt ${attempt} failed: ${e.constructor.name} - ${e.message}`);
|
||||||
|
|
||||||
# Read image files from disk (following test_julia_file_sender.jl pattern)
|
if (attempt < maxRetries) {
|
||||||
# Small image - should use direct transport
|
await new Promise(resolve => setTimeout(resolve, delay));
|
||||||
file_path_small_image = "./test/small_image.jpg"
|
delay = Math.min(delay * 2, maxDelay);
|
||||||
file_data_small_image = read(file_path_small_image)
|
}
|
||||||
filename_small_image = basename(file_path_small_image)
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Large image - should use link transport
|
throw new Error(`Failed to fetch data after ${maxRetries} attempts`);
|
||||||
file_path_large_image = "./test/large_image.png"
|
}
|
||||||
file_data_large_image = read(file_path_large_image)
|
|
||||||
filename_large_image = basename(file_path_large_image)
|
|
||||||
|
|
||||||
# Create payloads list - mixed content with both small and large data
|
// ---------------------------------------------- Core Functions ---------------------------------------------- //
|
||||||
# Small data uses direct transport, large data uses link transport
|
|
||||||
# Key: Pass DataFrame directly and specify type as "arrowtable" or "jsontable"
|
|
||||||
# msghandler.jl handles the serialization internally
|
|
||||||
payloads = [
|
|
||||||
# Small data (direct transport) - text, dictionary, arrowtable, jsontable, small image
|
|
||||||
("chat_text", text_data, "text"),
|
|
||||||
("chat_json", dict_data, "dictionary"),
|
|
||||||
# ("arrow_table_small", arrow_table_small, "arrowtable"),
|
|
||||||
("json_table_small", json_table_small, "jsontable"),
|
|
||||||
(filename_small_image, file_data_small_image, "binary"),
|
|
||||||
|
|
||||||
# Large data (link transport) - large arrowtable, large jsontable, large image, large audio, large video, large binary
|
/**
|
||||||
# ("arrow_table_large", arrow_table_large, "arrowtable"),
|
* Build message envelope from payloads and metadata
|
||||||
("json_table_large", json_table_large, "jsontable"),
|
* @param {string} subject - Subject/topic
|
||||||
(filename_large_image, file_data_large_image, "binary"),
|
* @param {Array} payloads - Array of payload objects
|
||||||
("audio_clip_large", large_audio_data, "audio"),
|
* @param {Object} options - Envelope metadata options
|
||||||
("video_clip_large", large_video_data, "video"),
|
* @returns {Object} Envelope object
|
||||||
("binary_file_large", large_binary_data, "binary")
|
*/
|
||||||
]
|
function buildEnvelope(subject, payloads, options) {
|
||||||
|
return {
|
||||||
|
correlation_id: options.correlation_id,
|
||||||
|
msg_id: options.msg_id,
|
||||||
|
timestamp: new Date().toISOString(),
|
||||||
|
send_to: subject,
|
||||||
|
msg_purpose: options.msg_purpose,
|
||||||
|
sender_name: options.sender_name,
|
||||||
|
sender_id: options.sender_id,
|
||||||
|
receiver_name: options.receiver_name,
|
||||||
|
receiver_id: options.receiver_id,
|
||||||
|
reply_to: options.reply_to,
|
||||||
|
reply_to_msg_id: options.reply_to_msg_id,
|
||||||
|
broker_url: options.broker_url,
|
||||||
|
metadata: options.metadata || {},
|
||||||
|
payloads: payloads
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
# Use smartpack with mixed content
|
/**
|
||||||
sendinfo = msghandler.smartpack(
|
* Build payload object from serialized data
|
||||||
SUBJECT,
|
* @param {string} dataname - Name of the payload
|
||||||
payloads; # List of (dataname, data, type) tuples
|
* @param {string} payloadType - Type of the payload
|
||||||
broker_url = NATS_URL,
|
* @param {Uint8Array} payloadBytes - Serialized payload bytes
|
||||||
fileserver_url = FILESERVER_URL,
|
* @param {string} transport - Transport type ("direct" or "link")
|
||||||
fileserver_upload_handler = plik_upload_handler,
|
* @param {string} data - Data (base64 for direct, URL for link)
|
||||||
size_threshold = 1_000_000, # 1MB threshold
|
* @returns {Object} Payload object
|
||||||
correlation_id = correlation_id,
|
*/
|
||||||
msg_purpose = "chat",
|
function buildPayload(dataname, payloadType, payloadBytes, transport, data) {
|
||||||
sender_name = "mix_sender",
|
// Determine encoding based on payload type (matching Julia implementation)
|
||||||
receiver_name = "",
|
let encoding = 'base64';
|
||||||
receiver_id = "",
|
if (payloadType === 'jsontable') {
|
||||||
reply_to = "",
|
encoding = 'json';
|
||||||
reply_to_msg_id = "",
|
}
|
||||||
is_publish = true # Publish the message to NATS
|
|
||||||
)
|
|
||||||
|
|
||||||
env, env_json_str = sendinfo
|
return {
|
||||||
log_trace("Sent message with $(length(env.payloads)) payloads")
|
id: uuidv4(),
|
||||||
|
dataname,
|
||||||
|
payload_type: payloadType,
|
||||||
|
transport,
|
||||||
|
encoding,
|
||||||
|
size: payloadBytes.byteLength,
|
||||||
|
data,
|
||||||
|
metadata: transport === 'direct' ? { payload_bytes: payloadBytes.byteLength } : {}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
# Log transport type for each payload
|
/**
|
||||||
for (i, payload) in enumerate(env.payloads)
|
* Send data with automatic transport selection
|
||||||
log_trace("Payload $i ('$payload.dataname'):")
|
*
|
||||||
log_trace(" Transport: $(payload.transport)")
|
* This function intelligently routes data delivery based on payload size.
|
||||||
log_trace(" Type: $(payload.payload_type)")
|
* If the serialized payload is smaller than size_threshold, it encodes the data as Base64
|
||||||
log_trace(" Size: $(payload.size) bytes")
|
* into a "direct" payload. Otherwise, it uploads the data to a fileserver
|
||||||
log_trace(" Encoding: $(payload.encoding)")
|
* and creates a "link" payload with the URL.
|
||||||
|
*
|
||||||
|
* Transport publishing is the caller's responsibility. This function returns the
|
||||||
|
* envelope and its JSON string representation.
|
||||||
|
*
|
||||||
|
* @param {string} subject - Subject/topic to send the message to
|
||||||
|
* @param {Array} data - List of [dataname, data, type] tuples to send
|
||||||
|
* - type: "text", "dictionary", "jsontable", "image", "audio", "video", "binary"
|
||||||
|
* - Note: "arrowtable" is NOT supported in browser (use "jsontable" for tabular data)
|
||||||
|
* @param {Object} options - Optional configuration
|
||||||
|
* @param {string} [options.broker_url=DEFAULT_BROKER_URL] - Broker URL (for envelope metadata)
|
||||||
|
* @param {string} [options.fileserver_url=DEFAULT_FILESERVER_URL] - URL of the HTTP file server
|
||||||
|
* @param {Function} [options.fileserver_upload_handler=plikOneshotUpload] - Function to handle fileserver uploads
|
||||||
|
* @param {number} [options.size_threshold=DEFAULT_SIZE_THRESHOLD] - Threshold separating direct vs link transport
|
||||||
|
* @param {string} [options.correlation_id=uuidv4()] - Correlation ID for tracing
|
||||||
|
* @param {string} [options.msg_purpose="chat"] - Purpose of the message
|
||||||
|
* @param {string} [options.sender_name="msghandler"] - Name of the sender
|
||||||
|
* @param {string} [options.receiver_name=""] - Name of the receiver (empty means broadcast)
|
||||||
|
* @param {string} [options.receiver_id=""] - UUID of the receiver (empty means broadcast)
|
||||||
|
* @param {string} [options.reply_to=""] - Topic to reply to
|
||||||
|
* @param {string} [options.reply_to_msg_id=""] - Message ID this message is replying to
|
||||||
|
* @param {string} [options.msg_id=uuidv4()] - Message ID
|
||||||
|
* @param {string} [options.sender_id=uuidv4()] - Sender ID
|
||||||
|
* @returns {Promise<[Object, string]>} Tuple of [env, env_json_str]
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* // Send a single payload
|
||||||
|
* const [env, envJsonStr] = await msghandlerCSR.smartpack(
|
||||||
|
* "/test",
|
||||||
|
* [["dataname1", data1, "dictionary"]]
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* // Send multiple payloads (use jsontable instead of arrowtable for browser)
|
||||||
|
* const [env, envJsonStr] = await msghandlerCSR.smartpack(
|
||||||
|
* "/test",
|
||||||
|
* [
|
||||||
|
* ["dataname1", data1, "dictionary"],
|
||||||
|
* ["dataname2", tableData, "jsontable"]
|
||||||
|
* ]
|
||||||
|
* );
|
||||||
|
*
|
||||||
|
* // Publish via your transport (NATS, MQTT, HTTP, etc.)
|
||||||
|
* // await myNatsClient.publish("/test", envJsonStr);
|
||||||
|
*/
|
||||||
|
async function smartpack(subject, data, options = {}) {
|
||||||
|
const {
|
||||||
|
broker_url = DEFAULT_BROKER_URL,
|
||||||
|
fileserver_url = DEFAULT_FILESERVER_URL,
|
||||||
|
fileserver_upload_handler = plikOneshotUpload,
|
||||||
|
size_threshold = DEFAULT_SIZE_THRESHOLD,
|
||||||
|
correlation_id = uuidv4(),
|
||||||
|
msg_purpose = 'chat',
|
||||||
|
sender_name = 'msghandler',
|
||||||
|
receiver_name = '',
|
||||||
|
receiver_id = '',
|
||||||
|
reply_to = '',
|
||||||
|
reply_to_msg_id = '',
|
||||||
|
msg_id = uuidv4(),
|
||||||
|
sender_id = uuidv4()
|
||||||
|
} = options;
|
||||||
|
|
||||||
if payload.transport == "link"
|
logTrace(correlation_id, `Starting smartpack for subject: ${subject}`);
|
||||||
log_trace(" URL: $(payload.data)")
|
logTrace(correlation_id, `smartpack: data array length=${data.length}`);
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# Summary
|
// Debug: Log input data structure
|
||||||
println("\n--- Transport Summary ---")
|
for (let i = 0; i < data.length; i++) {
|
||||||
direct_count = count(p -> p.transport == "direct", env.payloads)
|
const [dataname, payloadData, payloadType] = data[i];
|
||||||
link_count = count(p -> p.transport == "link", env.payloads)
|
logTrace(correlation_id, `smartpack: payload[${i}] dataname=${dataname}, type=${payloadType}, data type=${typeof payloadData}, constructor=${payloadData?.constructor?.name}`);
|
||||||
log_trace("Direct transport: $direct_count payloads")
|
}
|
||||||
log_trace("Link transport: $link_count payloads")
|
|
||||||
end
|
|
||||||
|
|
||||||
|
// Process payloads
|
||||||
|
const payloads = [];
|
||||||
|
for (const [dataname, payloadData, payloadType] of data) {
|
||||||
|
logTrace(correlation_id, `smartpack: Processing payload '${dataname}' type=${payloadType}`);
|
||||||
|
logTrace(correlation_id, `smartpack: payloadData type=${typeof payloadData}, constructor=${payloadData?.constructor?.name}`);
|
||||||
|
|
||||||
# Run the test
|
const payloadBytes = await serializeData(payloadData, payloadType);
|
||||||
println("Starting mixed-content transport test...")
|
const payloadSize = payloadBytes.byteLength;
|
||||||
println("Correlation ID: $correlation_id")
|
|
||||||
|
|
||||||
# Run sender
|
logTrace(correlation_id, `Serialized payload '${dataname}' (type: ${payloadType}) size: ${payloadSize} bytes`);
|
||||||
println("start smartpack for mixed content")
|
|
||||||
test_mix_send()
|
|
||||||
|
|
||||||
println("\nTest completed.")
|
// Debug: Show first 20 bytes of serialized data for table type
|
||||||
println("Note: Run test_julia_to_julia_mix_receiver.jl to receive the messages.")
|
if (payloadType === 'table') {
|
||||||
|
const hexPreview = [];
|
||||||
|
for (let i = 0; i < Math.min(20, payloadBytes.length); i++) {
|
||||||
|
hexPreview.push(payloadBytes[i].toString(16).padStart(2, '0'));
|
||||||
|
}
|
||||||
|
logTrace(correlation_id, `Serialized table data first 20 bytes (hex): ${hexPreview.join(' ')}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (payloadSize < size_threshold) {
|
||||||
|
// Direct path
|
||||||
|
const payloadB64 = bufferToBase64(payloadBytes);
|
||||||
|
logTrace(correlation_id, `Using direct transport for ${payloadSize} bytes, base64 length=${payloadB64.length}`);
|
||||||
|
|
||||||
|
const payload = buildPayload(dataname, payloadType, payloadBytes, 'direct', payloadB64);
|
||||||
|
payloads.push(payload);
|
||||||
|
} else {
|
||||||
|
// Link path
|
||||||
|
logTrace(correlation_id, `Using link transport, uploading to fileserver`);
|
||||||
|
|
||||||
|
const response = await fileserver_upload_handler(fileserver_url, dataname, payloadBytes);
|
||||||
|
|
||||||
|
if (response.status !== 200) {
|
||||||
|
throw new Error(`Failed to upload data to fileserver: ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
logTrace(correlation_id, `Uploaded to URL: ${response.url}`);
|
||||||
|
|
||||||
|
const payload = buildPayload(dataname, payloadType, payloadBytes, 'link', response.url);
|
||||||
|
payloads.push(payload);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Build envelope
|
||||||
|
const env = buildEnvelope(subject, payloads, {
|
||||||
|
correlation_id,
|
||||||
|
msg_id,
|
||||||
|
msg_purpose,
|
||||||
|
sender_name,
|
||||||
|
sender_id,
|
||||||
|
receiver_name,
|
||||||
|
receiver_id,
|
||||||
|
reply_to,
|
||||||
|
reply_to_msg_id,
|
||||||
|
broker_url
|
||||||
|
});
|
||||||
|
|
||||||
|
const env_json_str = JSON.stringify(env);
|
||||||
|
|
||||||
|
return [env, env_json_str];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receive and process messages
|
||||||
|
*
|
||||||
|
* This function processes incoming messages, handling both direct transport
|
||||||
|
* (base64 decoded payloads) and link transport (URL-based payloads).
|
||||||
|
* It deserializes the data based on the transport type and returns the result.
|
||||||
|
*
|
||||||
|
* @param {string|Object} msg - Message payload. Accepts either a JSON string directly,
|
||||||
|
* or an object with a `data` or `payload` property containing the JSON string.
|
||||||
|
* @param {Object} options - Optional configuration
|
||||||
|
* @param {Function} [options.fileserver_download_handler=fetchWithBackoff] - Function to handle fileserver downloads
|
||||||
|
* @param {number} [options.max_retries=5] - Maximum retry attempts for fetching URL
|
||||||
|
* @param {number} [options.base_delay=100] - Initial delay for exponential backoff in ms
|
||||||
|
* @param {number} [options.max_delay=5000] - Maximum delay for exponential backoff in ms
|
||||||
|
* @returns {Promise<Object>} Envelope object with processed payloads
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* // Receive from JSON string directly
|
||||||
|
* const env = await msghandlerCSR.smartunpack(jsonString, {
|
||||||
|
* fileserver_download_handler: msghandlerCSR.fetchWithBackoff,
|
||||||
|
* max_retries: 5,
|
||||||
|
* base_delay: 100,
|
||||||
|
* max_delay: 5000
|
||||||
|
* });
|
||||||
|
*
|
||||||
|
* // Receive from transport message object (e.g., NATS, MQTT)
|
||||||
|
* const env = await msghandlerCSR.smartunpack(natsMsg, {
|
||||||
|
* fileserver_download_handler: msghandlerCSR.fetchWithBackoff
|
||||||
|
* });
|
||||||
|
* // env.payloads is an Array of [dataname, data, type] arrays
|
||||||
|
* for (const [dataname, data, type] of env.payloads) {
|
||||||
|
* console.log(`${dataname}: ${data} (type: ${type})`);
|
||||||
|
* }
|
||||||
|
*/
|
||||||
|
async function smartunpack(msg, options = {}) {
|
||||||
|
const {
|
||||||
|
fileserver_download_handler = fetchWithBackoff,
|
||||||
|
max_retries = 5,
|
||||||
|
base_delay = 100,
|
||||||
|
max_delay = 5000
|
||||||
|
} = options;
|
||||||
|
|
||||||
|
let envJsonObj;
|
||||||
|
|
||||||
|
// NATS's Javascript lib already return JSON object
|
||||||
|
if (msg !== null && typeof msg === 'object') {
|
||||||
|
envJsonObj = msg;
|
||||||
|
} else {
|
||||||
|
throw new Error('Invalid message format: expected JSON string or message object');
|
||||||
|
}
|
||||||
|
|
||||||
|
logTrace(envJsonObj.correlation_id, 'Processing received message');
|
||||||
|
logTrace(envJsonObj.correlation_id, `smartunpack: envelope has ${envJsonObj.payloads.length} payloads`);
|
||||||
|
|
||||||
|
// Process all payloads in the envelope
|
||||||
|
const payloadsList = [];
|
||||||
|
const numPayloads = envJsonObj.payloads.length;
|
||||||
|
|
||||||
|
logTrace(envJsonObj.correlation_id, `smartunpack: Processing ${numPayloads} payloads`);
|
||||||
|
|
||||||
|
for (let i = 0; i < numPayloads; i++) {
|
||||||
|
const payloadObj = envJsonObj.payloads[i];
|
||||||
|
const transport = payloadObj.transport;
|
||||||
|
const dataname = payloadObj.dataname;
|
||||||
|
const payloadType = payloadObj.payload_type;
|
||||||
|
|
||||||
|
logTrace(envJsonObj.correlation_id, `smartunpack: Processing payload ${i + 1}/${numPayloads}: dataname=${dataname}, type=${payloadType}, transport=${transport}`);
|
||||||
|
|
||||||
|
if (transport === 'direct') {
|
||||||
|
logTrace(envJsonObj.correlation_id, `Direct transport - decoding payload '${dataname}'`);
|
||||||
|
|
||||||
|
// Extract base64 payload from the payload
|
||||||
|
const payloadB64 = payloadObj.data;
|
||||||
|
logTrace(envJsonObj.correlation_id, `Direct transport: base64 length=${payloadB64?.length}`);
|
||||||
|
|
||||||
|
// Decode Base64 payload
|
||||||
|
const payloadBytes = base64ToBuffer(payloadB64);
|
||||||
|
logTrace(envJsonObj.correlation_id, `Direct transport: decoded bytes=${payloadBytes.length}`);
|
||||||
|
|
||||||
|
// Deserialize based on type
|
||||||
|
const dataType = payloadObj.payload_type;
|
||||||
|
const data = await deserializeData(payloadBytes, dataType, envJsonObj.correlation_id);
|
||||||
|
logTrace(envJsonObj.correlation_id, `Direct transport: deserialized data type=${typeof data}, constructor=${data?.constructor?.name}`);
|
||||||
|
|
||||||
|
payloadsList.push([dataname, data, dataType]);
|
||||||
|
} else if (transport === 'link') {
|
||||||
|
// Extract download URL from the payload
|
||||||
|
const url = payloadObj.data;
|
||||||
|
logTrace(envJsonObj.correlation_id, `Link transport - fetching '${dataname}' from URL: ${url}`);
|
||||||
|
|
||||||
|
// Fetch with exponential backoff using the download handler
|
||||||
|
const downloadedData = await fileserver_download_handler(
|
||||||
|
url,
|
||||||
|
max_retries,
|
||||||
|
base_delay,
|
||||||
|
max_delay,
|
||||||
|
envJsonObj.correlation_id
|
||||||
|
);
|
||||||
|
|
||||||
|
// Deserialize based on type
|
||||||
|
const dataType = payloadObj.payload_type;
|
||||||
|
const data = await deserializeData(downloadedData, dataType, envJsonObj.correlation_id);
|
||||||
|
|
||||||
|
payloadsList.push([dataname, data, dataType]);
|
||||||
|
} else {
|
||||||
|
throw new Error(`Unknown transport type for payload '${dataname}': ${transport}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
logTrace(envJsonObj.correlation_id, `smartunpack: Successfully processed all ${payloadsList.length} payloads`);
|
||||||
|
envJsonObj.payloads = payloadsList;
|
||||||
|
return envJsonObj;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------- Module Exports ---------------------------------------------- //
|
||||||
|
|
||||||
|
const msghandlerCSR = {
|
||||||
|
/**
|
||||||
|
* Send data with automatic transport selection
|
||||||
|
*/
|
||||||
|
smartpack,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Receive and process messages
|
||||||
|
*/
|
||||||
|
smartunpack,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Upload data to plik server in one-shot mode
|
||||||
|
*/
|
||||||
|
plikOneshotUpload,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetch data from URL with exponential backoff
|
||||||
|
*/
|
||||||
|
fetchWithBackoff,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Default constants
|
||||||
|
*/
|
||||||
|
DEFAULT_SIZE_THRESHOLD,
|
||||||
|
DEFAULT_BROKER_URL,
|
||||||
|
DEFAULT_FILESERVER_URL
|
||||||
|
};
|
||||||
|
|
||||||
|
export default msghandlerCSR;
|
||||||
|
|||||||
Reference in New Issue
Block a user