@lovrozagar/honey 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +51 -0
- package/docs/api-ref/go.md +399 -0
- package/docs/api-ref/python.md +399 -0
- package/docs/api-ref/rust.md +399 -0
- package/docs/api-ref/typescript.md +399 -0
- package/docs/invalidate-spec.md +303 -0
- package/docs/sdk.md +722 -0
- package/package.json +120 -0
- package/src/accepts.ts +78 -0
- package/src/body-limit.ts +100 -0
- package/src/build/index.ts +174 -0
- package/src/cli-go/auth.go +15 -0
- package/src/cli-go/config.go +165 -0
- package/src/cli-go/errors.go +57 -0
- package/src/cli-go/multipart.go +55 -0
- package/src/cli-go/output.go +109 -0
- package/src/cli-go/root.go +30 -0
- package/src/cli-go/stream.go +88 -0
- package/src/cli-go/version.go +5 -0
- package/src/cli.ts +204 -0
- package/src/client/error.ts +27 -0
- package/src/client/http.ts +502 -0
- package/src/client/index.ts +127 -0
- package/src/client/sdk.ts +265 -0
- package/src/client/sse.ts +102 -0
- package/src/client/types.ts +211 -0
- package/src/client/ws.ts +115 -0
- package/src/client-go/errors.go +207 -0
- package/src/client-go/invalidation.go +373 -0
- package/src/client-go/realtime.go +317 -0
- package/src/client-go/result.go +20 -0
- package/src/client-go/runtime.go +413 -0
- package/src/client-go/sse.go +149 -0
- package/src/client-go/transport.go +452 -0
- package/src/client-go/ws.go +104 -0
- package/src/client-mcp/README.md +10 -0
- package/src/client-mcp/server.ts +94 -0
- package/src/client-mcp/types.ts +19 -0
- package/src/client-python/_errors.py +115 -0
- package/src/client-python/_invalidation.py +578 -0
- package/src/client-python/_realtime.py +156 -0
- package/src/client-python/_runtime.py +469 -0
- package/src/client-python/_sse.py +99 -0
- package/src/client-python/_transport.py +335 -0
- package/src/client-python/_ws.py +131 -0
- package/src/client-python/py.typed +0 -0
- package/src/client-rust/errors.rs +200 -0
- package/src/client-rust/invalidation.rs +441 -0
- package/src/client-rust/invalidation_sync.rs +306 -0
- package/src/client-rust/realtime.rs +695 -0
- package/src/client-rust/result.rs +22 -0
- package/src/client-rust/runtime.rs +547 -0
- package/src/client-rust/runtime_sync.rs +452 -0
- package/src/client-rust/sse.rs +167 -0
- package/src/client-rust/ws.rs +143 -0
- package/src/cloudflare/realtime.ts +236 -0
- package/src/codegen-go-cli.ts +1180 -0
- package/src/codegen-go.ts +1010 -0
- package/src/codegen-hash.ts +8 -0
- package/src/codegen-ir.ts +517 -0
- package/src/codegen-loaders.ts +53 -0
- package/src/codegen-mcp.ts +364 -0
- package/src/codegen-python.ts +1028 -0
- package/src/codegen-rust.ts +1652 -0
- package/src/codegen-sanitize.ts +67 -0
- package/src/codegen-schema-naming.ts +146 -0
- package/src/codegen.ts +5015 -0
- package/src/context.ts +210 -0
- package/src/cookie-sign.ts +58 -0
- package/src/cookie.ts +89 -0
- package/src/cors.ts +96 -0
- package/src/crypto.ts +19 -0
- package/src/csrf.ts +54 -0
- package/src/curl-logger.ts +235 -0
- package/src/detect-runtime.ts +19 -0
- package/src/error.ts +52 -0
- package/src/errors.ts +87 -0
- package/src/etag.ts +74 -0
- package/src/feature-load.ts +23 -0
- package/src/go-type-emitter.ts +404 -0
- package/src/honey-response.ts +354 -0
- package/src/i18n-slot.ts +20 -0
- package/src/i18n.ts +234 -0
- package/src/index.ts +3843 -0
- package/src/init.ts +149 -0
- package/src/input.ts +8 -0
- package/src/ip-restrict.ts +192 -0
- package/src/logger.ts +149 -0
- package/src/middleware.ts +199 -0
- package/src/node-request.ts +240 -0
- package/src/node.ts +212 -0
- package/src/openapi/register.ts +19 -0
- package/src/openapi/scalar.ts +33 -0
- package/src/openapi/spec-factory.ts +46 -0
- package/src/openapi/spec.ts +31 -0
- package/src/openapi/swagger.ts +34 -0
- package/src/plugin.ts +771 -0
- package/src/powered-by.ts +17 -0
- package/src/pretty-json.ts +39 -0
- package/src/proxy.ts +155 -0
- package/src/python-type-emitter.ts +144 -0
- package/src/realtime/buffer.ts +101 -0
- package/src/realtime/bus.ts +93 -0
- package/src/realtime/longpoll.ts +148 -0
- package/src/realtime/protocol.ts +128 -0
- package/src/realtime/route.ts +104 -0
- package/src/realtime/runtime.ts +430 -0
- package/src/request-id.ts +23 -0
- package/src/request-to-curl.ts +34 -0
- package/src/response.ts +414 -0
- package/src/rust-type-emitter.ts +412 -0
- package/src/secure-headers.ts +69 -0
- package/src/serve-register.ts +8 -0
- package/src/serve-slot.ts +20 -0
- package/src/serve.ts +141 -0
- package/src/server-timing.ts +66 -0
- package/src/static.ts +60 -0
- package/src/telemetry/otel.ts +139 -0
- package/src/testing.ts +114 -0
- package/src/timeout.ts +36 -0
- package/src/tree.ts +464 -0
- package/src/ts-type-emitter.ts +106 -0
- package/src/type-emitter.ts +524 -0
- package/src/type-extractor.ts +749 -0
- package/src/types.ts +638 -0
- package/src/validation.ts +300 -0
- package/src/ws/bun.ts +89 -0
- package/src/ws/cloudflare.ts +133 -0
- package/src/ws/deno.ts +109 -0
- package/src/ws/node.ts +161 -0
- package/src/yaml.ts +80 -0
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
// Code generated by honey. DO NOT EDIT.
|
|
2
|
+
|
|
3
|
+
package sdk
|
|
4
|
+
|
|
5
|
+
import (
|
|
6
|
+
"context"
|
|
7
|
+
"errors"
|
|
8
|
+
"sync"
|
|
9
|
+
"time"
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
// ConnectionState mirrors the TS / Rust / Python realtime lifecycle.
|
|
13
|
+
type ConnectionState int
|
|
14
|
+
|
|
15
|
+
// Connection lifecycle states. Order matches TS createResumableConnection:
|
|
16
|
+
// Connecting → Connected → Reconnecting → Disconnected.
|
|
17
|
+
const (
|
|
18
|
+
StateConnecting ConnectionState = iota
|
|
19
|
+
StateConnected
|
|
20
|
+
StateReconnecting
|
|
21
|
+
StateDisconnected
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
// String returns the lowercase canonical name used by cross-language parity tests.
|
|
25
|
+
func (s ConnectionState) String() string {
|
|
26
|
+
switch s {
|
|
27
|
+
case StateConnecting:
|
|
28
|
+
return "connecting"
|
|
29
|
+
case StateConnected:
|
|
30
|
+
return "connected"
|
|
31
|
+
case StateReconnecting:
|
|
32
|
+
return "reconnecting"
|
|
33
|
+
case StateDisconnected:
|
|
34
|
+
return "disconnected"
|
|
35
|
+
}
|
|
36
|
+
return "unknown"
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// ResumableConnection orchestrates a pluggable Transport chain with
|
|
40
|
+
// proven-transport memoization + full-chain fallback. Events are delivered over
|
|
41
|
+
// Events(); terminal errors are delivered over Errors(). Close() signals the
|
|
42
|
+
// internal goroutine to stop and closes both channels.
|
|
43
|
+
//
|
|
44
|
+
// Mirrors TS createResumableConnection, Rust ResumableConnection::connect, and
|
|
45
|
+
// Python ResumableConnection behavior.
|
|
46
|
+
type ResumableConnection struct {
|
|
47
|
+
url string
|
|
48
|
+
transports []Transport
|
|
49
|
+
opts TransportOpts
|
|
50
|
+
|
|
51
|
+
events chan any
|
|
52
|
+
errs chan error
|
|
53
|
+
closeCh chan struct{}
|
|
54
|
+
|
|
55
|
+
mu sync.Mutex
|
|
56
|
+
state ConnectionState
|
|
57
|
+
conn TransportConn
|
|
58
|
+
provenIdx int /* -1 = none yet */
|
|
59
|
+
closed bool
|
|
60
|
+
closeOnce sync.Once
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
// NewResumableConnection constructs a connection with the given adapter chain.
|
|
64
|
+
// Opts is copied; nil → zero-value defaults. Panics if transports is empty —
|
|
65
|
+
// misconfiguration at construction is a programmer error, not runtime.
|
|
66
|
+
func NewResumableConnection(baseURL string, transports []Transport, opts *TransportOpts) *ResumableConnection {
|
|
67
|
+
if len(transports) == 0 {
|
|
68
|
+
panic("honey: NewResumableConnection requires at least one transport")
|
|
69
|
+
}
|
|
70
|
+
var o TransportOpts
|
|
71
|
+
if opts != nil {
|
|
72
|
+
o = *opts
|
|
73
|
+
}
|
|
74
|
+
return &ResumableConnection{
|
|
75
|
+
url: baseURL,
|
|
76
|
+
transports: transports,
|
|
77
|
+
opts: o,
|
|
78
|
+
events: make(chan any, 16),
|
|
79
|
+
errs: make(chan error, 4),
|
|
80
|
+
closeCh: make(chan struct{}),
|
|
81
|
+
state: StateDisconnected,
|
|
82
|
+
provenIdx: -1,
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// Events returns a receive-only channel of decoded payloads.
|
|
87
|
+
func (r *ResumableConnection) Events() <-chan any { return r.events }
|
|
88
|
+
|
|
89
|
+
// Errors returns a receive-only channel of terminal transport errors.
|
|
90
|
+
func (r *ResumableConnection) Errors() <-chan error { return r.errs }
|
|
91
|
+
|
|
92
|
+
// State reports the current lifecycle state.
|
|
93
|
+
func (r *ResumableConnection) State() ConnectionState {
|
|
94
|
+
r.mu.Lock()
|
|
95
|
+
defer r.mu.Unlock()
|
|
96
|
+
return r.state
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// ProvenTransport reports the kind of the last successfully-opened transport,
|
|
100
|
+
// if any. Returns (zero, false) when no transport has succeeded yet.
|
|
101
|
+
func (r *ResumableConnection) ProvenTransport() (TransportKind, bool) {
|
|
102
|
+
r.mu.Lock()
|
|
103
|
+
defer r.mu.Unlock()
|
|
104
|
+
if r.provenIdx < 0 || r.provenIdx >= len(r.transports) {
|
|
105
|
+
return "", false
|
|
106
|
+
}
|
|
107
|
+
return r.transports[r.provenIdx].Kind(), true
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// Connect opens the chain and spawns the read goroutine. Returns once the first
|
|
111
|
+
// transport has succeeded. Full-chain failure returns the last transport error.
|
|
112
|
+
// Idempotent when already connected.
|
|
113
|
+
func (r *ResumableConnection) Connect(ctx context.Context) error {
|
|
114
|
+
r.mu.Lock()
|
|
115
|
+
if r.closed {
|
|
116
|
+
r.mu.Unlock()
|
|
117
|
+
return errors.New("honey: ResumableConnection closed")
|
|
118
|
+
}
|
|
119
|
+
if r.state == StateConnected {
|
|
120
|
+
r.mu.Unlock()
|
|
121
|
+
return nil
|
|
122
|
+
}
|
|
123
|
+
if r.conn != nil || r.provenIdx >= 0 {
|
|
124
|
+
r.state = StateReconnecting
|
|
125
|
+
} else {
|
|
126
|
+
r.state = StateConnecting
|
|
127
|
+
}
|
|
128
|
+
r.mu.Unlock()
|
|
129
|
+
|
|
130
|
+
if err := r.openChain(ctx); err != nil {
|
|
131
|
+
r.mu.Lock()
|
|
132
|
+
r.state = StateDisconnected
|
|
133
|
+
r.mu.Unlock()
|
|
134
|
+
return err
|
|
135
|
+
}
|
|
136
|
+
go r.readLoop()
|
|
137
|
+
return nil
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// openChain tries the proven adapter first (if memoized), then walks the full
|
|
141
|
+
// chain in order. First success wins; on success, provenIdx is updated.
|
|
142
|
+
func (r *ResumableConnection) openChain(ctx context.Context) error {
|
|
143
|
+
r.mu.Lock()
|
|
144
|
+
proven := r.provenIdx
|
|
145
|
+
r.mu.Unlock()
|
|
146
|
+
|
|
147
|
+
var lastErr error
|
|
148
|
+
if proven >= 0 && proven < len(r.transports) {
|
|
149
|
+
c, err := r.transports[proven].Connect(ctx, r.url, &r.opts)
|
|
150
|
+
if err == nil {
|
|
151
|
+
r.mu.Lock()
|
|
152
|
+
r.conn = c
|
|
153
|
+
r.state = StateConnected
|
|
154
|
+
r.mu.Unlock()
|
|
155
|
+
return nil
|
|
156
|
+
}
|
|
157
|
+
lastErr = err
|
|
158
|
+
}
|
|
159
|
+
for i, t := range r.transports {
|
|
160
|
+
if i == proven {
|
|
161
|
+
continue
|
|
162
|
+
}
|
|
163
|
+
c, err := t.Connect(ctx, r.url, &r.opts)
|
|
164
|
+
if err != nil {
|
|
165
|
+
lastErr = err
|
|
166
|
+
continue
|
|
167
|
+
}
|
|
168
|
+
r.mu.Lock()
|
|
169
|
+
r.conn = c
|
|
170
|
+
r.provenIdx = i
|
|
171
|
+
r.state = StateConnected
|
|
172
|
+
r.mu.Unlock()
|
|
173
|
+
return nil
|
|
174
|
+
}
|
|
175
|
+
if lastErr == nil {
|
|
176
|
+
lastErr = errors.New("honey: no transports configured")
|
|
177
|
+
}
|
|
178
|
+
return lastErr
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// readLoop pumps Recv → events channel. Transport errors trigger reconnect via
|
|
182
|
+
// the full chain (proven is invalidated on failure) up to MaxReconnectAttempts;
|
|
183
|
+
// exhaustion emits on errs and terminates. Close signal short-circuits via ctx.
|
|
184
|
+
func (r *ResumableConnection) readLoop() {
|
|
185
|
+
defer func() {
|
|
186
|
+
r.mu.Lock()
|
|
187
|
+
r.state = StateDisconnected
|
|
188
|
+
if r.conn != nil {
|
|
189
|
+
_ = r.conn.Close()
|
|
190
|
+
r.conn = nil
|
|
191
|
+
}
|
|
192
|
+
r.mu.Unlock()
|
|
193
|
+
r.closeOnce.Do(func() {
|
|
194
|
+
close(r.events)
|
|
195
|
+
close(r.errs)
|
|
196
|
+
})
|
|
197
|
+
}()
|
|
198
|
+
|
|
199
|
+
attempts := 0
|
|
200
|
+
maxAttempts := r.opts.MaxReconnectAttempts
|
|
201
|
+
delay := time.Duration(r.opts.ReconnectDelayMs) * time.Millisecond
|
|
202
|
+
|
|
203
|
+
for {
|
|
204
|
+
select {
|
|
205
|
+
case <-r.closeCh:
|
|
206
|
+
return
|
|
207
|
+
default:
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
r.mu.Lock()
|
|
211
|
+
conn := r.conn
|
|
212
|
+
r.mu.Unlock()
|
|
213
|
+
if conn == nil {
|
|
214
|
+
return
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
recvCtx, cancel := context.WithCancel(context.Background())
|
|
218
|
+
cancelDone := make(chan struct{})
|
|
219
|
+
go func() {
|
|
220
|
+
select {
|
|
221
|
+
case <-r.closeCh:
|
|
222
|
+
cancel()
|
|
223
|
+
case <-cancelDone:
|
|
224
|
+
}
|
|
225
|
+
}()
|
|
226
|
+
v, err := conn.Recv(recvCtx)
|
|
227
|
+
cancel()
|
|
228
|
+
close(cancelDone)
|
|
229
|
+
|
|
230
|
+
if err == nil {
|
|
231
|
+
select {
|
|
232
|
+
case r.events <- v:
|
|
233
|
+
attempts = 0
|
|
234
|
+
case <-r.closeCh:
|
|
235
|
+
return
|
|
236
|
+
}
|
|
237
|
+
continue
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
/* transport died — attempt reconnect unless capped */
|
|
241
|
+
select {
|
|
242
|
+
case <-r.closeCh:
|
|
243
|
+
return
|
|
244
|
+
default:
|
|
245
|
+
}
|
|
246
|
+
attempts++
|
|
247
|
+
if maxAttempts > 0 && attempts > maxAttempts {
|
|
248
|
+
select {
|
|
249
|
+
case r.errs <- err:
|
|
250
|
+
default:
|
|
251
|
+
}
|
|
252
|
+
return
|
|
253
|
+
}
|
|
254
|
+
r.mu.Lock()
|
|
255
|
+
r.state = StateReconnecting
|
|
256
|
+
if r.conn != nil {
|
|
257
|
+
_ = r.conn.Close()
|
|
258
|
+
r.conn = nil
|
|
259
|
+
}
|
|
260
|
+
/* drop proven — prefer full chain on recv failure, matches Python */
|
|
261
|
+
r.provenIdx = -1
|
|
262
|
+
r.mu.Unlock()
|
|
263
|
+
if delay > 0 {
|
|
264
|
+
select {
|
|
265
|
+
case <-time.After(delay):
|
|
266
|
+
case <-r.closeCh:
|
|
267
|
+
return
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
reopenCtx, reopenCancel := context.WithCancel(context.Background())
|
|
271
|
+
reopenDone := make(chan struct{})
|
|
272
|
+
go func() {
|
|
273
|
+
select {
|
|
274
|
+
case <-r.closeCh:
|
|
275
|
+
reopenCancel()
|
|
276
|
+
case <-reopenDone:
|
|
277
|
+
}
|
|
278
|
+
}()
|
|
279
|
+
reopenErr := r.openChain(reopenCtx)
|
|
280
|
+
reopenCancel()
|
|
281
|
+
close(reopenDone)
|
|
282
|
+
if reopenErr != nil {
|
|
283
|
+
select {
|
|
284
|
+
case r.errs <- reopenErr:
|
|
285
|
+
default:
|
|
286
|
+
}
|
|
287
|
+
return
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
// Close signals the read goroutine to stop, closes the active transport, and
|
|
293
|
+
// closes events / errs channels. Safe to call multiple times.
|
|
294
|
+
func (r *ResumableConnection) Close() error {
|
|
295
|
+
r.mu.Lock()
|
|
296
|
+
if r.closed {
|
|
297
|
+
r.mu.Unlock()
|
|
298
|
+
return nil
|
|
299
|
+
}
|
|
300
|
+
r.closed = true
|
|
301
|
+
close(r.closeCh)
|
|
302
|
+
conn := r.conn
|
|
303
|
+
r.conn = nil
|
|
304
|
+
r.state = StateDisconnected
|
|
305
|
+
r.mu.Unlock()
|
|
306
|
+
if conn != nil {
|
|
307
|
+
_ = conn.Close()
|
|
308
|
+
}
|
|
309
|
+
/* when Connect was never called (or failed before spawning readLoop) the
|
|
310
|
+
* defer in readLoop never runs; closeOnce guards against double-close from
|
|
311
|
+
* both paths. */
|
|
312
|
+
r.closeOnce.Do(func() {
|
|
313
|
+
close(r.events)
|
|
314
|
+
close(r.errs)
|
|
315
|
+
})
|
|
316
|
+
return nil
|
|
317
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
// Code generated by honey. DO NOT EDIT.
|
|
2
|
+
|
|
3
|
+
package sdk
|
|
4
|
+
|
|
5
|
+
import "net/http"
|
|
6
|
+
|
|
7
|
+
// SDKResult is a generic result container for safe-mode SDK calls (ThrowOnError=false).
|
|
8
|
+
// In safe mode, methods return SDKResult[T] instead of (*T, error).
|
|
9
|
+
// The error is embedded in the result — the outer error return is always nil in safe mode.
|
|
10
|
+
type SDKResult[T any] struct {
|
|
11
|
+
Data *T
|
|
12
|
+
Err APIError
|
|
13
|
+
Status int
|
|
14
|
+
Response *http.Response
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
// OK returns true when the result carries no error.
|
|
18
|
+
func (r SDKResult[T]) OK() bool {
|
|
19
|
+
return r.Err == nil
|
|
20
|
+
}
|