stitchkit 0.59.1 → 0.59.2

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.
Files changed (42) hide show
  1. package/README.md +44 -4
  2. package/dist/application/activity.d.ts +70 -0
  3. package/dist/application/activity.d.ts.map +1 -0
  4. package/dist/application/events.d.ts +65 -0
  5. package/dist/application/events.d.ts.map +1 -0
  6. package/dist/application/grammy.d.ts +35 -0
  7. package/dist/application/grammy.d.ts.map +1 -0
  8. package/dist/application/graph.d.ts +11 -0
  9. package/dist/application/graph.d.ts.map +1 -0
  10. package/dist/application/health.d.ts +13 -0
  11. package/dist/application/health.d.ts.map +1 -0
  12. package/dist/application/kernel.d.ts +31 -0
  13. package/dist/application/kernel.d.ts.map +1 -0
  14. package/dist/application/latest-sink.d.ts +39 -0
  15. package/dist/application/latest-sink.d.ts.map +1 -0
  16. package/dist/application/resource.d.ts +30 -0
  17. package/dist/application/resource.d.ts.map +1 -0
  18. package/dist/application/schedule.d.ts +112 -0
  19. package/dist/application/schedule.d.ts.map +1 -0
  20. package/dist/application/schemas.d.ts +160 -0
  21. package/dist/application/schemas.d.ts.map +1 -0
  22. package/dist/application/server-resource.d.ts +12 -0
  23. package/dist/application/server-resource.d.ts.map +1 -0
  24. package/dist/application-grammy.d.ts +2 -0
  25. package/dist/application-grammy.d.ts.map +1 -0
  26. package/dist/application-grammy.js +165 -0
  27. package/dist/application.d.ts +10 -0
  28. package/dist/application.d.ts.map +1 -0
  29. package/dist/application.js +1370 -0
  30. package/dist/index-dk6e56g0.js +211 -0
  31. package/dist/{index-9zn9fb4e.js → index-he4psyve.js} +6 -213
  32. package/dist/index-yr276yz0.js +6 -0
  33. package/dist/internal/fetch-port.d.ts +2 -0
  34. package/dist/internal/fetch-port.d.ts.map +1 -0
  35. package/dist/node.js +115 -13
  36. package/dist/server/index.js +8 -6
  37. package/dist/server/node.d.ts.map +1 -1
  38. package/dist/server/process-signals.d.ts +10 -8
  39. package/dist/server/process-signals.d.ts.map +1 -1
  40. package/llms-full.txt +379 -0
  41. package/llms.txt +1 -0
  42. package/package.json +15 -2
@@ -0,0 +1,211 @@
1
+ // src/server/shutdown.ts
2
+ import { z } from "zod";
3
+ var ShutdownStateSchema = z.enum([
4
+ "running",
5
+ "draining-http",
6
+ "closing-realtime",
7
+ "stopping-runtime",
8
+ "clean",
9
+ "forced"
10
+ ]);
11
+ var ShutdownOptionsSchema = z.object({
12
+ gracePeriodMs: z.number().int().nonnegative().default(30000),
13
+ forceTimeoutMs: z.number().int().nonnegative().default(5000),
14
+ retryAfterSeconds: z.number().int().nonnegative().default(5),
15
+ signal: z.custom((value) => typeof value === "object" && value !== null && ("aborted" in value) && ("addEventListener" in value), "Expected an AbortSignal").optional()
16
+ });
17
+ var ShutdownStatusSchema = z.object({
18
+ state: ShutdownStateSchema,
19
+ acceptedRequests: z.number().int().nonnegative(),
20
+ completedRequests: z.number().int().nonnegative(),
21
+ pendingRequests: z.number().int().nonnegative(),
22
+ pendingWebSockets: z.number().int().nonnegative()
23
+ });
24
+ var ShutdownResultSchema = z.object({
25
+ outcome: z.enum(["clean", "forced"]),
26
+ reason: z.enum(["deadline", "signal"]).optional(),
27
+ acceptedRequests: z.number().int().nonnegative(),
28
+ completedRequests: z.number().int().nonnegative(),
29
+ pendingRequests: z.number().int().nonnegative(),
30
+ pendingWebSockets: z.number().int().nonnegative(),
31
+ pendingRequestsAtForce: z.number().int().nonnegative(),
32
+ pendingWebSocketsAtForce: z.number().int().nonnegative(),
33
+ abortedRequests: z.number().int().nonnegative(),
34
+ forcedWebSockets: z.number().int().nonnegative(),
35
+ durationMs: z.number().nonnegative()
36
+ });
37
+ function rejectedResponse(retryAfterSeconds) {
38
+ return Response.json({ error: { code: "SERVER_SHUTTING_DOWN", message: "Server is shutting down" } }, {
39
+ status: 503,
40
+ headers: {
41
+ Connection: "close",
42
+ "Retry-After": String(retryAfterSeconds)
43
+ }
44
+ });
45
+ }
46
+ function waitForZero(read, signal) {
47
+ if (read() === 0)
48
+ return Promise.resolve();
49
+ return new Promise((resolve) => {
50
+ const check = () => {
51
+ if (read() === 0 || signal.aborted) {
52
+ clearInterval(timer);
53
+ signal.removeEventListener("abort", check);
54
+ resolve();
55
+ }
56
+ };
57
+ const timer = setInterval(check, 5);
58
+ signal.addEventListener("abort", check, { once: true });
59
+ });
60
+ }
61
+ function untilAbort(signal) {
62
+ if (signal.aborted)
63
+ return Promise.resolve();
64
+ return new Promise((resolve) => signal.addEventListener("abort", () => resolve(), { once: true }));
65
+ }
66
+ function withTimeout(promise, timeoutMs, message) {
67
+ return new Promise((resolve, reject) => {
68
+ const timer = setTimeout(() => reject(new Error(message)), timeoutMs);
69
+ promise.then((value) => {
70
+ clearTimeout(timer);
71
+ resolve(value);
72
+ }, (error) => {
73
+ clearTimeout(timer);
74
+ reject(error);
75
+ });
76
+ });
77
+ }
78
+ function createServerLifecycle(getAdapter) {
79
+ let state = "running";
80
+ let acceptedRequests = 0;
81
+ let completedRequests = 0;
82
+ let pendingApplicationRequests = 0;
83
+ let retryAfterSeconds = 5;
84
+ let shutdownPromise;
85
+ const status = () => {
86
+ const adapter = getAdapter();
87
+ return ShutdownStatusSchema.parse({
88
+ state,
89
+ acceptedRequests,
90
+ completedRequests,
91
+ pendingRequests: adapter.pendingRequests(),
92
+ pendingWebSockets: adapter.pendingWebSockets()
93
+ });
94
+ };
95
+ const wrapFetch = (handler) => {
96
+ return async (request, server) => {
97
+ if (state !== "running")
98
+ return rejectedResponse(retryAfterSeconds);
99
+ acceptedRequests += 1;
100
+ pendingApplicationRequests += 1;
101
+ try {
102
+ return await handler(request, server);
103
+ } finally {
104
+ pendingApplicationRequests -= 1;
105
+ completedRequests += 1;
106
+ }
107
+ };
108
+ };
109
+ const shutdown = (options) => {
110
+ if (shutdownPromise)
111
+ return shutdownPromise;
112
+ const parsed = ShutdownOptionsSchema.parse(options ?? {});
113
+ retryAfterSeconds = parsed.retryAfterSeconds;
114
+ const startedAt = performance.now();
115
+ const adapter = getAdapter();
116
+ state = "draining-http";
117
+ adapter.beginShutdown(retryAfterSeconds);
118
+ shutdownPromise = new Promise((resolve, reject) => {
119
+ const phaseAbort = new AbortController;
120
+ let forcedReason;
121
+ let phaseError;
122
+ const force = (reason) => {
123
+ if (forcedReason)
124
+ return;
125
+ forcedReason = reason;
126
+ phaseAbort.abort();
127
+ };
128
+ const timer = setTimeout(() => force("deadline"), parsed.gracePeriodMs);
129
+ const onExternalAbort = () => force("signal");
130
+ parsed.signal?.addEventListener("abort", onExternalAbort, { once: true });
131
+ if (parsed.signal?.aborted)
132
+ force("signal");
133
+ const cleanup = () => {
134
+ clearTimeout(timer);
135
+ parsed.signal?.removeEventListener("abort", onExternalAbort);
136
+ };
137
+ (async () => {
138
+ try {
139
+ await waitForZero(() => pendingApplicationRequests, phaseAbort.signal);
140
+ if (!forcedReason) {
141
+ state = "closing-realtime";
142
+ await Promise.race([adapter.closeRealtime(), untilAbort(phaseAbort.signal)]);
143
+ }
144
+ if (!forcedReason) {
145
+ state = "stopping-runtime";
146
+ await Promise.race([adapter.stopGracefully(), untilAbort(phaseAbort.signal)]);
147
+ }
148
+ } catch (error) {
149
+ if (!forcedReason) {
150
+ phaseError = error;
151
+ force("error");
152
+ }
153
+ }
154
+ let pendingRequestsAtForce = 0;
155
+ let pendingWebSocketsAtForce = 0;
156
+ if (forcedReason) {
157
+ state = "stopping-runtime";
158
+ pendingRequestsAtForce = adapter.pendingRequests();
159
+ pendingWebSocketsAtForce = adapter.pendingWebSockets();
160
+ let forceError;
161
+ let forceFailed = false;
162
+ try {
163
+ await withTimeout(adapter.forceStop(), parsed.forceTimeoutMs, `[stitchkit] forced shutdown did not complete within ${parsed.forceTimeoutMs}ms`);
164
+ } catch (error) {
165
+ forceFailed = true;
166
+ forceError = error;
167
+ } finally {
168
+ state = "forced";
169
+ }
170
+ if (forcedReason === "error") {
171
+ if (forceFailed) {
172
+ throw new AggregateError([phaseError, forceError], "[stitchkit] graceful shutdown failed and forced cleanup also failed", { cause: phaseError });
173
+ }
174
+ throw phaseError;
175
+ }
176
+ if (forceFailed)
177
+ throw forceError;
178
+ } else {
179
+ state = "clean";
180
+ }
181
+ cleanup();
182
+ resolve(ShutdownResultSchema.parse({
183
+ outcome: forcedReason ? "forced" : "clean",
184
+ ...forcedReason && { reason: forcedReason },
185
+ acceptedRequests,
186
+ completedRequests,
187
+ pendingRequests: adapter.pendingRequests(),
188
+ pendingWebSockets: adapter.pendingWebSockets(),
189
+ pendingRequestsAtForce,
190
+ pendingWebSocketsAtForce,
191
+ abortedRequests: pendingRequestsAtForce,
192
+ forcedWebSockets: pendingWebSocketsAtForce,
193
+ durationMs: performance.now() - startedAt
194
+ }));
195
+ })().catch((error) => {
196
+ cleanup();
197
+ reject(error);
198
+ });
199
+ });
200
+ return shutdownPromise;
201
+ };
202
+ return {
203
+ wrapFetch,
204
+ get status() {
205
+ return status();
206
+ },
207
+ shutdown
208
+ };
209
+ }
210
+
211
+ export { ShutdownStateSchema, ShutdownOptionsSchema, ShutdownStatusSchema, ShutdownResultSchema, createServerLifecycle };
@@ -1,3 +1,6 @@
1
+ import {
2
+ ShutdownOptionsSchema
3
+ } from "./index-dk6e56g0.js";
1
4
  import {
2
5
  DEFAULT_PROCESS_SIGNALS,
3
6
  RUNTIME_CONTEXT_RESERVED_KEYS,
@@ -1457,216 +1460,6 @@ function json(data, status, cors, req) {
1457
1460
  return Response.json(data, { status, headers: corsHeaders2(cors, req) });
1458
1461
  }
1459
1462
 
1460
- // src/server/shutdown.ts
1461
- import { z } from "zod";
1462
- var ShutdownStateSchema = z.enum([
1463
- "running",
1464
- "draining-http",
1465
- "closing-realtime",
1466
- "stopping-runtime",
1467
- "clean",
1468
- "forced"
1469
- ]);
1470
- var ShutdownOptionsSchema = z.object({
1471
- gracePeriodMs: z.number().int().nonnegative().default(30000),
1472
- forceTimeoutMs: z.number().int().nonnegative().default(5000),
1473
- retryAfterSeconds: z.number().int().nonnegative().default(5),
1474
- signal: z.custom((value) => typeof value === "object" && value !== null && ("aborted" in value) && ("addEventListener" in value), "Expected an AbortSignal").optional()
1475
- });
1476
- var ShutdownStatusSchema = z.object({
1477
- state: ShutdownStateSchema,
1478
- acceptedRequests: z.number().int().nonnegative(),
1479
- completedRequests: z.number().int().nonnegative(),
1480
- pendingRequests: z.number().int().nonnegative(),
1481
- pendingWebSockets: z.number().int().nonnegative()
1482
- });
1483
- var ShutdownResultSchema = z.object({
1484
- outcome: z.enum(["clean", "forced"]),
1485
- reason: z.enum(["deadline", "signal"]).optional(),
1486
- acceptedRequests: z.number().int().nonnegative(),
1487
- completedRequests: z.number().int().nonnegative(),
1488
- pendingRequests: z.number().int().nonnegative(),
1489
- pendingWebSockets: z.number().int().nonnegative(),
1490
- pendingRequestsAtForce: z.number().int().nonnegative(),
1491
- pendingWebSocketsAtForce: z.number().int().nonnegative(),
1492
- abortedRequests: z.number().int().nonnegative(),
1493
- forcedWebSockets: z.number().int().nonnegative(),
1494
- durationMs: z.number().nonnegative()
1495
- });
1496
- function rejectedResponse(retryAfterSeconds) {
1497
- return Response.json({ error: { code: "SERVER_SHUTTING_DOWN", message: "Server is shutting down" } }, {
1498
- status: 503,
1499
- headers: {
1500
- Connection: "close",
1501
- "Retry-After": String(retryAfterSeconds)
1502
- }
1503
- });
1504
- }
1505
- function waitForZero(read, signal) {
1506
- if (read() === 0)
1507
- return Promise.resolve();
1508
- return new Promise((resolve) => {
1509
- const check = () => {
1510
- if (read() === 0 || signal.aborted) {
1511
- clearInterval(timer);
1512
- signal.removeEventListener("abort", check);
1513
- resolve();
1514
- }
1515
- };
1516
- const timer = setInterval(check, 5);
1517
- signal.addEventListener("abort", check, { once: true });
1518
- });
1519
- }
1520
- function untilAbort(signal) {
1521
- if (signal.aborted)
1522
- return Promise.resolve();
1523
- return new Promise((resolve) => signal.addEventListener("abort", () => resolve(), { once: true }));
1524
- }
1525
- function withTimeout(promise, timeoutMs, message) {
1526
- return new Promise((resolve, reject) => {
1527
- const timer = setTimeout(() => reject(new Error(message)), timeoutMs);
1528
- promise.then((value) => {
1529
- clearTimeout(timer);
1530
- resolve(value);
1531
- }, (error) => {
1532
- clearTimeout(timer);
1533
- reject(error);
1534
- });
1535
- });
1536
- }
1537
- function createServerLifecycle(getAdapter) {
1538
- let state = "running";
1539
- let acceptedRequests = 0;
1540
- let completedRequests = 0;
1541
- let pendingApplicationRequests = 0;
1542
- let retryAfterSeconds = 5;
1543
- let shutdownPromise;
1544
- const status = () => {
1545
- const adapter = getAdapter();
1546
- return ShutdownStatusSchema.parse({
1547
- state,
1548
- acceptedRequests,
1549
- completedRequests,
1550
- pendingRequests: adapter.pendingRequests(),
1551
- pendingWebSockets: adapter.pendingWebSockets()
1552
- });
1553
- };
1554
- const wrapFetch = (handler) => {
1555
- return async (request, server) => {
1556
- if (state !== "running")
1557
- return rejectedResponse(retryAfterSeconds);
1558
- acceptedRequests += 1;
1559
- pendingApplicationRequests += 1;
1560
- try {
1561
- return await handler(request, server);
1562
- } finally {
1563
- pendingApplicationRequests -= 1;
1564
- completedRequests += 1;
1565
- }
1566
- };
1567
- };
1568
- const shutdown = (options) => {
1569
- if (shutdownPromise)
1570
- return shutdownPromise;
1571
- const parsed = ShutdownOptionsSchema.parse(options ?? {});
1572
- retryAfterSeconds = parsed.retryAfterSeconds;
1573
- const startedAt = performance.now();
1574
- const adapter = getAdapter();
1575
- state = "draining-http";
1576
- adapter.beginShutdown(retryAfterSeconds);
1577
- shutdownPromise = new Promise((resolve, reject) => {
1578
- const phaseAbort = new AbortController;
1579
- let forcedReason;
1580
- let phaseError;
1581
- const force = (reason) => {
1582
- if (forcedReason)
1583
- return;
1584
- forcedReason = reason;
1585
- phaseAbort.abort();
1586
- };
1587
- const timer = setTimeout(() => force("deadline"), parsed.gracePeriodMs);
1588
- const onExternalAbort = () => force("signal");
1589
- parsed.signal?.addEventListener("abort", onExternalAbort, { once: true });
1590
- if (parsed.signal?.aborted)
1591
- force("signal");
1592
- const cleanup = () => {
1593
- clearTimeout(timer);
1594
- parsed.signal?.removeEventListener("abort", onExternalAbort);
1595
- };
1596
- (async () => {
1597
- try {
1598
- await waitForZero(() => pendingApplicationRequests, phaseAbort.signal);
1599
- if (!forcedReason) {
1600
- state = "closing-realtime";
1601
- await Promise.race([adapter.closeRealtime(), untilAbort(phaseAbort.signal)]);
1602
- }
1603
- if (!forcedReason) {
1604
- state = "stopping-runtime";
1605
- await Promise.race([adapter.stopGracefully(), untilAbort(phaseAbort.signal)]);
1606
- }
1607
- } catch (error) {
1608
- if (!forcedReason) {
1609
- phaseError = error;
1610
- force("error");
1611
- }
1612
- }
1613
- let pendingRequestsAtForce = 0;
1614
- let pendingWebSocketsAtForce = 0;
1615
- if (forcedReason) {
1616
- state = "stopping-runtime";
1617
- pendingRequestsAtForce = adapter.pendingRequests();
1618
- pendingWebSocketsAtForce = adapter.pendingWebSockets();
1619
- let forceError;
1620
- let forceFailed = false;
1621
- try {
1622
- await withTimeout(adapter.forceStop(), parsed.forceTimeoutMs, `[stitchkit] forced shutdown did not complete within ${parsed.forceTimeoutMs}ms`);
1623
- } catch (error) {
1624
- forceFailed = true;
1625
- forceError = error;
1626
- } finally {
1627
- state = "forced";
1628
- }
1629
- if (forcedReason === "error") {
1630
- if (forceFailed) {
1631
- throw new AggregateError([phaseError, forceError], "[stitchkit] graceful shutdown failed and forced cleanup also failed", { cause: phaseError });
1632
- }
1633
- throw phaseError;
1634
- }
1635
- if (forceFailed)
1636
- throw forceError;
1637
- } else {
1638
- state = "clean";
1639
- }
1640
- cleanup();
1641
- resolve(ShutdownResultSchema.parse({
1642
- outcome: forcedReason ? "forced" : "clean",
1643
- ...forcedReason && { reason: forcedReason },
1644
- acceptedRequests,
1645
- completedRequests,
1646
- pendingRequests: adapter.pendingRequests(),
1647
- pendingWebSockets: adapter.pendingWebSockets(),
1648
- pendingRequestsAtForce,
1649
- pendingWebSocketsAtForce,
1650
- abortedRequests: pendingRequestsAtForce,
1651
- forcedWebSockets: pendingWebSocketsAtForce,
1652
- durationMs: performance.now() - startedAt
1653
- }));
1654
- })().catch((error) => {
1655
- cleanup();
1656
- reject(error);
1657
- });
1658
- });
1659
- return shutdownPromise;
1660
- };
1661
- return {
1662
- wrapFetch,
1663
- get status() {
1664
- return status();
1665
- },
1666
- shutdown
1667
- };
1668
- }
1669
-
1670
1463
  // src/server/process-signals.ts
1671
1464
  var bound = new WeakSet;
1672
1465
  function bindProcessSignals(handle, options = {}) {
@@ -1775,9 +1568,9 @@ function bindProcessSignals(handle, options = {}) {
1775
1568
  }
1776
1569
 
1777
1570
  // src/realtime/rejection.ts
1778
- import { z as z2 } from "zod";
1571
+ import { z } from "zod";
1779
1572
  function realtimeContractViolation(options) {
1780
- const issues = options.cause instanceof z2.ZodError ? zodIssues(options.cause) : undefined;
1573
+ const issues = options.cause instanceof z.ZodError ? zodIssues(options.cause) : undefined;
1781
1574
  const reason = options.reason.replaceAll("-", " ");
1782
1575
  const error = new AppError("REALTIME_CONTRACT_VIOLATION", `Realtime event "${options.event}" (${options.direction}, ${options.phase}): ${reason}`, 500, {
1783
1576
  event: options.event,
@@ -2227,4 +2020,4 @@ function socketIoLane(websocket) {
2227
2020
  });
2228
2021
  }
2229
2022
 
2230
- export { parseMultipart, createHandler, ShutdownStateSchema, ShutdownOptionsSchema, ShutdownStatusSchema, ShutdownResultSchema, createServerLifecycle, bindProcessSignals, bindRealtimeServer, webSocketLane, composeWebSocketHandlers, createSocketIOServer, socketIoLane };
2023
+ export { parseMultipart, createHandler, bindProcessSignals, bindRealtimeServer, webSocketLane, composeWebSocketHandlers, createSocketIOServer, socketIoLane };
@@ -0,0 +1,6 @@
1
+ // src/application/resource.ts
2
+ function defineManagedResource(resource) {
3
+ return resource;
4
+ }
5
+
6
+ export { defineManagedResource };
@@ -0,0 +1,2 @@
1
+ export declare function isFetchBlockedPort(port: number): boolean;
2
+ //# sourceMappingURL=fetch-port.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch-port.d.ts","sourceRoot":"","sources":["../../src/internal/fetch-port.ts"],"names":[],"mappings":"AAaA,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAExD"}
package/dist/node.js CHANGED
@@ -1,14 +1,16 @@
1
1
  import {
2
- ShutdownOptionsSchema,
3
- ShutdownResultSchema,
4
- ShutdownStateSchema,
5
- ShutdownStatusSchema,
6
2
  bindProcessSignals,
7
3
  bindRealtimeServer,
8
4
  createHandler,
9
- createServerLifecycle,
10
5
  createSocketIOServer
11
- } from "./index-9zn9fb4e.js";
6
+ } from "./index-he4psyve.js";
7
+ import {
8
+ ShutdownOptionsSchema,
9
+ ShutdownResultSchema,
10
+ ShutdownStateSchema,
11
+ ShutdownStatusSchema,
12
+ createServerLifecycle
13
+ } from "./index-dk6e56g0.js";
12
14
  import {
13
15
  createImplement,
14
16
  createImplementRegistry,
@@ -36,6 +38,97 @@ import"./index-smpbdg6k.js";
36
38
  import"./index-1bx83sw4.js";
37
39
  // src/server/node.ts
38
40
  import { serve } from "srvx/node";
41
+
42
+ // src/internal/fetch-port.ts
43
+ var FETCH_BLOCKED_PORTS = new Set([
44
+ 1,
45
+ 7,
46
+ 9,
47
+ 11,
48
+ 13,
49
+ 15,
50
+ 17,
51
+ 19,
52
+ 20,
53
+ 21,
54
+ 22,
55
+ 23,
56
+ 25,
57
+ 37,
58
+ 42,
59
+ 43,
60
+ 53,
61
+ 69,
62
+ 77,
63
+ 79,
64
+ 87,
65
+ 95,
66
+ 101,
67
+ 102,
68
+ 103,
69
+ 104,
70
+ 109,
71
+ 110,
72
+ 111,
73
+ 113,
74
+ 115,
75
+ 117,
76
+ 119,
77
+ 123,
78
+ 135,
79
+ 137,
80
+ 139,
81
+ 143,
82
+ 161,
83
+ 179,
84
+ 389,
85
+ 427,
86
+ 465,
87
+ 512,
88
+ 513,
89
+ 514,
90
+ 515,
91
+ 526,
92
+ 530,
93
+ 531,
94
+ 532,
95
+ 540,
96
+ 548,
97
+ 554,
98
+ 556,
99
+ 563,
100
+ 587,
101
+ 601,
102
+ 636,
103
+ 989,
104
+ 990,
105
+ 993,
106
+ 995,
107
+ 1719,
108
+ 1720,
109
+ 1723,
110
+ 2049,
111
+ 3659,
112
+ 4045,
113
+ 4190,
114
+ 5060,
115
+ 5061,
116
+ 6000,
117
+ 6566,
118
+ 6665,
119
+ 6666,
120
+ 6667,
121
+ 6668,
122
+ 6669,
123
+ 6679,
124
+ 6697,
125
+ 10080
126
+ ]);
127
+ function isFetchBlockedPort(port) {
128
+ return FETCH_BLOCKED_PORTS.has(port);
129
+ }
130
+
131
+ // src/server/node.ts
39
132
  async function serveNode(config) {
40
133
  const { port = 3000, hostname, socket, wrapFetch, ...handlerConfig } = config;
41
134
  const handler = createHandler(handlerConfig);
@@ -101,14 +194,23 @@ async function serveNode(config) {
101
194
  const lifecycle = createServerLifecycle(() => adapter);
102
195
  const consumerFetch = wrapFetch ? wrapFetch(handler) : handler;
103
196
  const fetch = lifecycle.wrapFetch(consumerFetch);
104
- runtime = serve({ port, hostname, fetch, gracefulShutdown: false });
105
- await runtime.ready();
106
- const candidate = runtime.node?.server;
107
- if (!candidate || !("maxRequestsPerSocket" in candidate)) {
108
- await runtime.close(true);
109
- throw new Error("[stitchkit] serveNode: expected a node:http.Server for the managed lifecycle.");
197
+ for (;; ) {
198
+ runtime = serve({ port, hostname, fetch, gracefulShutdown: false });
199
+ await runtime.ready();
200
+ const candidate = runtime.node?.server;
201
+ if (!candidate || !("maxRequestsPerSocket" in candidate)) {
202
+ await runtime.close(true);
203
+ throw new Error("[stitchkit] serveNode: expected a node:http.Server for the managed lifecycle.");
204
+ }
205
+ const candidateUrl = runtime.url ?? `http://${hostname ?? "localhost"}:${port}`;
206
+ const candidatePort = Number(new URL(candidateUrl).port) || port;
207
+ if (port === 0 && isFetchBlockedPort(candidatePort)) {
208
+ await runtime.close(true);
209
+ continue;
210
+ }
211
+ nodeServer = candidate;
212
+ break;
110
213
  }
111
- nodeServer = candidate;
112
214
  nodeServer.on("connection", (activeSocket) => {
113
215
  sockets.add(activeSocket);
114
216
  activeSocket.once("close", () => {
@@ -1,18 +1,20 @@
1
1
  import {
2
- ShutdownOptionsSchema,
3
- ShutdownResultSchema,
4
- ShutdownStateSchema,
5
- ShutdownStatusSchema,
6
2
  bindProcessSignals,
7
3
  bindRealtimeServer,
8
4
  composeWebSocketHandlers,
9
5
  createHandler,
10
- createServerLifecycle,
11
6
  createSocketIOServer,
12
7
  parseMultipart,
13
8
  socketIoLane,
14
9
  webSocketLane
15
- } from "../index-9zn9fb4e.js";
10
+ } from "../index-he4psyve.js";
11
+ import {
12
+ ShutdownOptionsSchema,
13
+ ShutdownResultSchema,
14
+ ShutdownStateSchema,
15
+ ShutdownStatusSchema,
16
+ createServerLifecycle
17
+ } from "../index-dk6e56g0.js";
16
18
  import {
17
19
  composeAuthHooks,
18
20
  createAuthHook,
@@ -1 +1 @@
1
- {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/server/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAkB,MAAM,WAAW,CAAC;AAEtE,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAElC,OAAO,EAEL,KAAK,mBAAmB,EAEzB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE/D,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;IACjC,aAAa,IAAI,IAAI,CAAC;IACtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,WAAW,IAAI,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,gBAAiB,SAAQ,aAAa,EAAE,gBAAgB;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,mBAAmB,CAAC;CAC9B;AAED,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AACzD,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;AAEtE,wBAAsB,SAAS,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAoHnF"}
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../src/server/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAkB,MAAM,WAAW,CAAC;AAEtE,OAAO,EAAE,KAAK,EAAE,MAAM,WAAW,CAAC;AAGlC,OAAO,EAEL,KAAK,mBAAmB,EAEzB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EAAE,gBAAgB,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAE/D,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,MAAM,EAAE,UAAU,GAAG,IAAI,CAAC;IACjC,aAAa,IAAI,IAAI,CAAC;IACtB,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IACvB,WAAW,IAAI,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,gBAAiB,SAAQ,aAAa,EAAE,gBAAgB;IACvE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,8DAA8D;IAC9D,MAAM,CAAC,EAAE,mBAAmB,CAAC;CAC9B;AAED,MAAM,MAAM,iBAAiB,GAAG,UAAU,CAAC,OAAO,KAAK,CAAC,CAAC;AACzD,MAAM,MAAM,gBAAgB,GAAG,mBAAmB,CAAC,iBAAiB,CAAC,CAAC;AAEtE,wBAAsB,SAAS,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAmInF"}