@lostgradient/weft 0.7.0 → 0.8.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 +4 -2
- package/dist/cli-main.js +63 -63
- package/dist/core/context/activity-retry-state.d.ts +6 -5
- package/dist/core/context/activity-retry-state.js +31 -21
- package/dist/core/context/durable-activity.d.ts +117 -0
- package/dist/core/context/durable-activity.js +79 -0
- package/dist/core/context/operation-request.d.ts +15 -0
- package/dist/core/context/parallel-operations.js +1 -0
- package/dist/core/context/run-operation-cached-request.d.ts +8 -0
- package/dist/core/context/run-operation-cached-request.js +59 -0
- package/dist/core/context/run-operation.d.ts +23 -5
- package/dist/core/context/run-operation.js +62 -47
- package/dist/core/engine/activity-heartbeat-tracking.d.ts +8 -17
- package/dist/core/engine/activity-heartbeat-tracking.js +7 -1
- package/dist/core/engine/activity-reconciliation.d.ts +1 -0
- package/dist/core/engine/activity-reconciliation.js +7 -2
- package/dist/core/engine/anonymous-signal-sequence.js +6 -4
- package/dist/core/engine/async-activity-completion.d.ts +5 -7
- package/dist/core/engine/async-activity-completion.js +13 -9
- package/dist/core/engine/bulk-operations-purge.js +2 -1
- package/dist/core/engine/bulk-operations.js +8 -7
- package/dist/core/engine/callback-checkpoint-persistence.d.ts +3 -0
- package/dist/core/engine/callback-checkpoint-persistence.js +25 -0
- package/dist/core/engine/callback-creators-bundles.js +4 -1
- package/dist/core/engine/checkpoint-io.d.ts +4 -1
- package/dist/core/engine/checkpoint-io.js +19 -10
- package/dist/core/engine/completed-review-storage.d.ts +2 -1
- package/dist/core/engine/completed-review-storage.js +4 -3
- package/dist/core/engine/index.d.ts +31 -0
- package/dist/core/engine/index.js +6 -1
- package/dist/core/engine/internals.d.ts +2 -1
- package/dist/core/engine/lease-manager.js +2 -2
- package/dist/core/engine/memo-durable-activity.d.ts +11 -0
- package/dist/core/engine/memo-durable-activity.js +282 -0
- package/dist/core/engine/operations-activity.d.ts +5 -1
- package/dist/core/engine/operations-activity.js +19 -7
- package/dist/core/engine/operations-data.d.ts +4 -1
- package/dist/core/engine/operations-data.js +3 -3
- package/dist/core/engine/reviews.js +7 -4
- package/dist/core/engine/schedule-timer.js +2 -0
- package/dist/core/engine/storage-io.js +1 -1
- package/dist/core/json.js +1 -1
- package/dist/core/weft-error.d.ts +1 -1
- package/dist/core/weft-error.js +2 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +6 -0
- package/dist/json-schema.js +1 -1
- package/dist/mcp/cli.js +26 -26
- package/dist/server/handler.js +21 -21
- package/dist/server/index.js +17 -17
- package/dist/server/runtime/websocket-worker.js +7 -2
- package/dist/server/serve-internals.d.ts +28 -0
- package/dist/server/serve-internals.js +4 -2
- package/dist/service-worker/index.js +22 -22
- package/dist/service-worker/setup.d.ts +18 -1
- package/dist/service-worker/setup.js +7 -4
- package/dist/storage/typed-storage.d.ts +1 -1
- package/dist/storage/typed-storage.js +1 -1
- package/dist/testing/index.js +27 -27
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
|
@@ -74,11 +74,16 @@ function registerWorker(context, options, ws, message) {
|
|
|
74
74
|
rejectRegistration(ws, "invalid_registration", "Worker registration requires the workers:write scope", message.protocolVersion);
|
|
75
75
|
return;
|
|
76
76
|
}
|
|
77
|
-
const rawConcurrency = message.concurrency ?? DEFAULT_WORKER_CONCURRENCY, clampedConcurrency = Math.min(Math.max(1, Math.floor(rawConcurrency)), MAX_WORKER_CONCURRENCY), queue = ws.data.queue ?? "default", pendingRequeue = context.pendingWorkerRequeues.get(message.workerId);
|
|
78
|
-
if (
|
|
77
|
+
const rawConcurrency = message.concurrency ?? DEFAULT_WORKER_CONCURRENCY, clampedConcurrency = Math.min(Math.max(1, Math.floor(rawConcurrency)), MAX_WORKER_CONCURRENCY), queue = ws.data.queue ?? "default", pendingRequeue = context.pendingWorkerRequeues.get(message.workerId), isGracePeriodReconnect = pendingRequeue !== void 0;
|
|
78
|
+
if (isGracePeriodReconnect) {
|
|
79
79
|
clearTimeout(pendingRequeue);
|
|
80
80
|
context.pendingWorkerRequeues.delete(message.workerId);
|
|
81
81
|
}
|
|
82
|
+
const existingSocket = context.workerSockets.get(message.workerId);
|
|
83
|
+
if (!isGracePeriodReconnect && existingSocket !== void 0 && existingSocket !== ws) {
|
|
84
|
+
rejectRegistration(ws, "invalid_registration", "workerId is already registered to an active connection", message.protocolVersion);
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
82
87
|
ws.data.workerId = message.workerId;
|
|
83
88
|
ws.data.workerRegistered = !0;
|
|
84
89
|
ws.data.workerProtocolVersion = message.protocolVersion;
|
|
@@ -11,6 +11,27 @@ import type { WebSocketData } from './json-rpc-websocket-runtime.ts';
|
|
|
11
11
|
import { createServerWebSocketHandlers } from './runtime/authentication-bridge.ts';
|
|
12
12
|
import type { ServerContext } from './runtime/context.ts';
|
|
13
13
|
import { type EventBroadcastingHandle } from './runtime/event-broadcasting.ts';
|
|
14
|
+
/**
|
|
15
|
+
* Hard ceiling on the raw WebSocket frame size for every connection (worker
|
|
16
|
+
* stream, `/watch`, token `/stream`, and JSON-RPC). Bun's default is 16 MiB;
|
|
17
|
+
* this caps the frame at the transport layer before any JSON parse, so a
|
|
18
|
+
* malicious peer cannot force a 16 MiB parse per message. A bounded 4 MiB parse
|
|
19
|
+
* is not a CPU-burn, so this constant ceiling fully closes the DoS on its own.
|
|
20
|
+
*
|
|
21
|
+
* This is deliberately NOT derived from `payloadSize.maxBytes`. That option is
|
|
22
|
+
* an application-level admission policy measured on the codec-encoded (msgpack)
|
|
23
|
+
* byte length of the bare value, whereas `maxPayloadLength` bounds the raw
|
|
24
|
+
* UTF-8 JSON frame (envelope plus JSON-serialized value) — different units.
|
|
25
|
+
* Tightening the frame limit down to a smaller `payloadSize.maxBytes` would
|
|
26
|
+
* reject legitimate frames whose value is within the admission cap (JSON and
|
|
27
|
+
* envelope overhead inflate the frame past the msgpack value size) with an
|
|
28
|
+
* opaque transport close instead of a clean `PayloadSizeExceededError`, across
|
|
29
|
+
* every shared WebSocket endpoint — for no additional DoS protection. Value
|
|
30
|
+
* size stays enforced by the post-parse admission check.
|
|
31
|
+
*
|
|
32
|
+
* @internal Exported only for test assertions.
|
|
33
|
+
*/
|
|
34
|
+
export declare const WEBSOCKET_MAX_PAYLOAD_BYTES: number;
|
|
14
35
|
/**
|
|
15
36
|
* @internal
|
|
16
37
|
*
|
|
@@ -77,6 +98,13 @@ export declare function cleanupWorkflowIndex(context: ServerContext, operationId
|
|
|
77
98
|
/**
|
|
78
99
|
* Assembles the `Bun.serve()` options object. Separating this avoids a
|
|
79
100
|
* conditional spread (`...(tlsOptions ? { tls } : {})`) inside `serve()`.
|
|
101
|
+
*
|
|
102
|
+
* Sets a constant `maxPayloadLength` of `WEBSOCKET_MAX_PAYLOAD_BYTES` (4 MiB)
|
|
103
|
+
* so Bun rejects oversized frames at the transport layer before any JSON parse
|
|
104
|
+
* occurs. The cap is intentionally a fixed transport-safety ceiling, not
|
|
105
|
+
* derived from `payloadSize.maxBytes` (see that constant's docs for why mixing
|
|
106
|
+
* the raw-frame limit with the application value-size policy would cause false
|
|
107
|
+
* rejections in the wrong unit).
|
|
80
108
|
*/
|
|
81
109
|
export declare function buildBunServeConfig(port: number, hostname: string, development: boolean, routes: Bun.Serve.Routes<WebSocketData, string>, tlsOptions: ReturnType<typeof buildTLSOptions>, fetchHandler: (request: Request) => Promise<Response | undefined>, websocketCallbacks: ReturnType<typeof createServerWebSocketHandlers>): Parameters<typeof Bun.serve<WebSocketData>>[0];
|
|
82
110
|
/**
|
|
@@ -30,7 +30,9 @@ import { DEFAULT_MAX_STREAM_CONNECTIONS_PER_WORKFLOW } from "./runtime/websocket
|
|
|
30
30
|
import { isInflightRecord, withRetry } from "./runtime/websocket-worker.js";
|
|
31
31
|
import { TaskQueue } from "./task-queue.js";
|
|
32
32
|
import { createWorkflowEventFeed } from "./workflow-event-feed.js";
|
|
33
|
-
const RECONCILIATION_MULTIPLIER = 12, DEFAULT_WORKER_RECONNECT_GRACE_PERIOD_MS = 2000, MAX_WORKER_RECONNECT_GRACE_PERIOD_MS = 5000
|
|
33
|
+
const RECONCILIATION_MULTIPLIER = 12, DEFAULT_WORKER_RECONNECT_GRACE_PERIOD_MS = 2000, MAX_WORKER_RECONNECT_GRACE_PERIOD_MS = 5000;
|
|
34
|
+
export const WEBSOCKET_MAX_PAYLOAD_BYTES = 4194304;
|
|
35
|
+
const AUTHENTICATION_REQUIRED_ENVIRONMENT_VARIABLE = "WEFT_SERVER_AUTHENTICATION_REQUIRED";
|
|
34
36
|
export const NO_AUTHENTICATION_WARNING = '[weft] WARNING: server started with NO authentication; all non-public operations are publicly accessible. Configure serve({ auth }) to lock down, or set unauthenticatedAccess: "reject" in production to fail closed.', MCP_ORIGIN_CONFIGURATION_WARNING = '[weft] WARNING: MCP HTTP transport is enabled without publicOrigin or trustedHosts. Cross-origin /mcp requests are rejected, and discovery routes that emit absolute URLs return 503. Configure serve({ publicOrigin: "https://api.example.com" }) or serve({ trustedHosts: ["api.example.com"] }) before exposing the server through a browser or reverse proxy.';
|
|
35
37
|
const NO_AUTHENTICATION_REJECT_ERROR = '[weft] Refusing to start server with no authentication. Configure serve({ auth }) or set unauthenticatedAccess: "allow" only for trusted local development.', NO_AUTHENTICATION_ENVIRONMENT_ERROR = "[weft] Refusing to start server with no authentication because WEFT_SERVER_AUTHENTICATION_REQUIRED requires authentication. Configure serve({ auth }) or unset WEFT_SERVER_AUTHENTICATION_REQUIRED only for trusted local development.", TRUTHY_AUTHENTICATION_REQUIREMENT_VALUES = new Set(["1", "true", "yes", "on"]), FALSY_AUTHENTICATION_REQUIREMENT_VALUES = new Set(["0", "false", "no", "off"]);
|
|
36
38
|
export function clampWorkerReconnectGracePeriod(value) {
|
|
@@ -149,7 +151,7 @@ export function buildBunServeConfig(port, hostname, development, routes, tlsOpti
|
|
|
149
151
|
development,
|
|
150
152
|
routes,
|
|
151
153
|
fetch: fetchHandler,
|
|
152
|
-
websocket: websocketCallbacks
|
|
154
|
+
websocket: { ...websocketCallbacks, maxPayloadLength: WEBSOCKET_MAX_PAYLOAD_BYTES }
|
|
153
155
|
};
|
|
154
156
|
if (tlsOptions)
|
|
155
157
|
config.tls = tlsOptions;
|