@openclaw/crabline 0.1.9 → 0.1.11

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 (189) hide show
  1. package/README.md +47 -22
  2. package/assets/crabline-banner.svg +20 -0
  3. package/dist/src/bin/crabline.js.map +1 -1
  4. package/dist/src/cli/program.d.ts +25 -1
  5. package/dist/src/cli/program.js +579 -82
  6. package/dist/src/cli/program.js.map +1 -1
  7. package/dist/src/config/load.js +59 -6
  8. package/dist/src/config/load.js.map +1 -1
  9. package/dist/src/config/schema.d.ts +116 -92
  10. package/dist/src/config/schema.js +179 -73
  11. package/dist/src/config/schema.js.map +1 -1
  12. package/dist/src/core/errors.js +9 -2
  13. package/dist/src/core/errors.js.map +1 -1
  14. package/dist/src/core/exit-codes.js.map +1 -1
  15. package/dist/src/core/matcher.js +7 -6
  16. package/dist/src/core/matcher.js.map +1 -1
  17. package/dist/src/core/message-template.js.map +1 -1
  18. package/dist/src/core/nonces.d.ts +1 -0
  19. package/dist/src/core/nonces.js +4 -2
  20. package/dist/src/core/nonces.js.map +1 -1
  21. package/dist/src/core/reporters.d.ts +1 -0
  22. package/dist/src/core/reporters.js +42 -4
  23. package/dist/src/core/reporters.js.map +1 -1
  24. package/dist/src/core/run.d.ts +3 -0
  25. package/dist/src/core/run.js +415 -107
  26. package/dist/src/core/run.js.map +1 -1
  27. package/dist/src/core/safe-regex.d.ts +3 -0
  28. package/dist/src/core/safe-regex.js +21 -0
  29. package/dist/src/core/safe-regex.js.map +1 -0
  30. package/dist/src/index.d.ts +2 -2
  31. package/dist/src/index.js +1 -1
  32. package/dist/src/index.js.map +1 -1
  33. package/dist/src/openclaw/artifact-generation.d.ts +43 -0
  34. package/dist/src/openclaw/artifact-generation.js +363 -0
  35. package/dist/src/openclaw/artifact-generation.js.map +1 -0
  36. package/dist/src/openclaw/bridges/matrix.js +97 -12
  37. package/dist/src/openclaw/bridges/matrix.js.map +1 -1
  38. package/dist/src/openclaw/bridges/mattermost.js +32 -10
  39. package/dist/src/openclaw/bridges/mattermost.js.map +1 -1
  40. package/dist/src/openclaw/bridges/signal.js +55 -18
  41. package/dist/src/openclaw/bridges/signal.js.map +1 -1
  42. package/dist/src/openclaw/bridges/slack.js +85 -7
  43. package/dist/src/openclaw/bridges/slack.js.map +1 -1
  44. package/dist/src/openclaw/bridges/telegram.js +124 -30
  45. package/dist/src/openclaw/bridges/telegram.js.map +1 -1
  46. package/dist/src/openclaw/bridges/whatsapp.js +78 -17
  47. package/dist/src/openclaw/bridges/whatsapp.js.map +1 -1
  48. package/dist/src/openclaw/bridges/zalo.js +14 -5
  49. package/dist/src/openclaw/bridges/zalo.js.map +1 -1
  50. package/dist/src/openclaw/outbound-contract.d.ts +5 -0
  51. package/dist/src/openclaw/outbound-contract.js +40 -0
  52. package/dist/src/openclaw/outbound-contract.js.map +1 -0
  53. package/dist/src/openclaw/private-file.d.ts +28 -0
  54. package/dist/src/openclaw/private-file.js +465 -0
  55. package/dist/src/openclaw/private-file.js.map +1 -0
  56. package/dist/src/openclaw/shared.d.ts +21 -2
  57. package/dist/src/openclaw/shared.js +115 -18
  58. package/dist/src/openclaw/shared.js.map +1 -1
  59. package/dist/src/openclaw/smoke-lock.d.ts +63 -0
  60. package/dist/src/openclaw/smoke-lock.js +1004 -0
  61. package/dist/src/openclaw/smoke-lock.js.map +1 -0
  62. package/dist/src/openclaw.d.ts +16 -8
  63. package/dist/src/openclaw.js +334 -52
  64. package/dist/src/openclaw.js.map +1 -1
  65. package/dist/src/providers/builtin/discord.d.ts +10 -1
  66. package/dist/src/providers/builtin/discord.js +144 -18
  67. package/dist/src/providers/builtin/discord.js.map +1 -1
  68. package/dist/src/providers/builtin/external-webhook-auth.d.ts +11 -0
  69. package/dist/src/providers/builtin/external-webhook-auth.js +10 -0
  70. package/dist/src/providers/builtin/external-webhook-auth.js.map +1 -0
  71. package/dist/src/providers/builtin/feishu.d.ts +19 -2
  72. package/dist/src/providers/builtin/feishu.js +307 -25
  73. package/dist/src/providers/builtin/feishu.js.map +1 -1
  74. package/dist/src/providers/builtin/googlechat.d.ts +20 -1
  75. package/dist/src/providers/builtin/googlechat.js +178 -19
  76. package/dist/src/providers/builtin/googlechat.js.map +1 -1
  77. package/dist/src/providers/builtin/imessage.d.ts +4 -0
  78. package/dist/src/providers/builtin/imessage.js +26 -11
  79. package/dist/src/providers/builtin/imessage.js.map +1 -1
  80. package/dist/src/providers/builtin/loopback.js +92 -30
  81. package/dist/src/providers/builtin/loopback.js.map +1 -1
  82. package/dist/src/providers/builtin/matrix.d.ts +11 -1
  83. package/dist/src/providers/builtin/matrix.js +53 -29
  84. package/dist/src/providers/builtin/matrix.js.map +1 -1
  85. package/dist/src/providers/builtin/mattermost.d.ts +10 -0
  86. package/dist/src/providers/builtin/mattermost.js +38 -15
  87. package/dist/src/providers/builtin/mattermost.js.map +1 -1
  88. package/dist/src/providers/builtin/msteams.d.ts +17 -1
  89. package/dist/src/providers/builtin/msteams.js +113 -14
  90. package/dist/src/providers/builtin/msteams.js.map +1 -1
  91. package/dist/src/providers/builtin/native-local-mock.d.ts +2 -9
  92. package/dist/src/providers/builtin/native-local-mock.js +12 -35
  93. package/dist/src/providers/builtin/native-local-mock.js.map +1 -1
  94. package/dist/src/providers/builtin/script.d.ts +11 -15
  95. package/dist/src/providers/builtin/script.js +566 -104
  96. package/dist/src/providers/builtin/script.js.map +1 -1
  97. package/dist/src/providers/builtin/slack.d.ts +6 -0
  98. package/dist/src/providers/builtin/slack.js +99 -40
  99. package/dist/src/providers/builtin/slack.js.map +1 -1
  100. package/dist/src/providers/builtin/telegram.d.ts +6 -0
  101. package/dist/src/providers/builtin/telegram.js +64 -43
  102. package/dist/src/providers/builtin/telegram.js.map +1 -1
  103. package/dist/src/providers/builtin/whatsapp.d.ts +28 -8
  104. package/dist/src/providers/builtin/whatsapp.js +567 -30
  105. package/dist/src/providers/builtin/whatsapp.js.map +1 -1
  106. package/dist/src/providers/builtin/zalo.js +30 -19
  107. package/dist/src/providers/builtin/zalo.js.map +1 -1
  108. package/dist/src/providers/catalog.d.ts +3 -3
  109. package/dist/src/providers/catalog.js +3 -3
  110. package/dist/src/providers/catalog.js.map +1 -1
  111. package/dist/src/providers/local-mock.d.ts +11 -2
  112. package/dist/src/providers/local-mock.js +322 -96
  113. package/dist/src/providers/local-mock.js.map +1 -1
  114. package/dist/src/providers/native-ids.d.ts +1 -0
  115. package/dist/src/providers/native-ids.js +6 -1
  116. package/dist/src/providers/native-ids.js.map +1 -1
  117. package/dist/src/providers/recorder.d.ts +30 -2
  118. package/dist/src/providers/recorder.js +549 -70
  119. package/dist/src/providers/recorder.js.map +1 -1
  120. package/dist/src/providers/registry.d.ts +25 -1
  121. package/dist/src/providers/registry.js +280 -40
  122. package/dist/src/providers/registry.js.map +1 -1
  123. package/dist/src/providers/signed-jwt.d.ts +29 -0
  124. package/dist/src/providers/signed-jwt.js +202 -0
  125. package/dist/src/providers/signed-jwt.js.map +1 -0
  126. package/dist/src/providers/slack-ids.js.map +1 -1
  127. package/dist/src/providers/target-normalizers.d.ts +26 -0
  128. package/dist/src/providers/target-normalizers.js +276 -0
  129. package/dist/src/providers/target-normalizers.js.map +1 -0
  130. package/dist/src/providers/types.d.ts +5 -0
  131. package/dist/src/providers/types.js.map +1 -1
  132. package/dist/src/providers/webhook-server.d.ts +2 -0
  133. package/dist/src/providers/webhook-server.js +72 -25
  134. package/dist/src/providers/webhook-server.js.map +1 -1
  135. package/dist/src/servers/http.d.ts +23 -3
  136. package/dist/src/servers/http.js +213 -20
  137. package/dist/src/servers/http.js.map +1 -1
  138. package/dist/src/servers/index.js +20 -21
  139. package/dist/src/servers/index.js.map +1 -1
  140. package/dist/src/servers/matrix.js +465 -51
  141. package/dist/src/servers/matrix.js.map +1 -1
  142. package/dist/src/servers/mattermost.d.ts +5 -0
  143. package/dist/src/servers/mattermost.js +306 -58
  144. package/dist/src/servers/mattermost.js.map +1 -1
  145. package/dist/src/servers/pending-events.d.ts +2 -0
  146. package/dist/src/servers/pending-events.js +11 -0
  147. package/dist/src/servers/pending-events.js.map +1 -0
  148. package/dist/src/servers/recorder.d.ts +5 -0
  149. package/dist/src/servers/recorder.js +262 -3
  150. package/dist/src/servers/recorder.js.map +1 -1
  151. package/dist/src/servers/signal.d.ts +2 -0
  152. package/dist/src/servers/signal.js +444 -56
  153. package/dist/src/servers/signal.js.map +1 -1
  154. package/dist/src/servers/slack.d.ts +5 -0
  155. package/dist/src/servers/slack.js +515 -49
  156. package/dist/src/servers/slack.js.map +1 -1
  157. package/dist/src/servers/telegram.d.ts +111 -0
  158. package/dist/src/servers/telegram.js +830 -158
  159. package/dist/src/servers/telegram.js.map +1 -1
  160. package/dist/src/servers/webhook-target.d.ts +40 -0
  161. package/dist/src/servers/webhook-target.js +349 -0
  162. package/dist/src/servers/webhook-target.js.map +1 -0
  163. package/dist/src/servers/websocket.d.ts +2 -0
  164. package/dist/src/servers/websocket.js +29 -0
  165. package/dist/src/servers/websocket.js.map +1 -0
  166. package/dist/src/servers/whatsapp-baileys-websocket.d.ts +65 -1
  167. package/dist/src/servers/whatsapp-baileys-websocket.js +723 -99
  168. package/dist/src/servers/whatsapp-baileys-websocket.js.map +1 -1
  169. package/dist/src/servers/whatsapp-jid.d.ts +5 -0
  170. package/dist/src/servers/whatsapp-jid.js +32 -0
  171. package/dist/src/servers/whatsapp-jid.js.map +1 -0
  172. package/dist/src/servers/whatsapp-wire/binary-node.d.ts +5 -0
  173. package/dist/src/servers/whatsapp-wire/binary-node.js +87 -20
  174. package/dist/src/servers/whatsapp-wire/binary-node.js.map +1 -1
  175. package/dist/src/servers/whatsapp-wire/crypto.d.ts +6 -1
  176. package/dist/src/servers/whatsapp-wire/crypto.js +99 -45
  177. package/dist/src/servers/whatsapp-wire/crypto.js.map +1 -1
  178. package/dist/src/servers/whatsapp-wire/handshake.js +39 -4
  179. package/dist/src/servers/whatsapp-wire/handshake.js.map +1 -1
  180. package/dist/src/servers/whatsapp-wire/signal.js.map +1 -1
  181. package/dist/src/servers/whatsapp.d.ts +12 -7
  182. package/dist/src/servers/whatsapp.js +269 -107
  183. package/dist/src/servers/whatsapp.js.map +1 -1
  184. package/dist/src/servers/zalo.d.ts +14 -0
  185. package/dist/src/servers/zalo.js +521 -88
  186. package/dist/src/servers/zalo.js.map +1 -1
  187. package/docs/channel-setup.md +197 -19
  188. package/fixtures/examples/crabline.example.yaml +10 -0
  189. package/package.json +20 -15
@@ -1 +1 @@
1
- {"version":3,"file":"mattermost.js","sourceRoot":"","sources":["../../../src/servers/mattermost.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mattermost.js","sourceRoot":"","sources":["../../../src/servers/mattermost.ts"],"names":[],"mappings":"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","sourcesContent":["import { createHash, randomBytes } from \"node:crypto\";\nimport type { IncomingMessage } from \"node:http\";\nimport path from \"node:path\";\nimport { WebSocket, WebSocketServer, type RawData } from \"ws\";\nimport {\n adminAuthError,\n drainRequestBody,\n hasAdminToken,\n InvalidJsonBodyError,\n isJsonObject,\n isLoopbackHost,\n jsonResponse,\n parseUnknownRequestBody,\n queryRecord,\n readTrimmedString,\n RequestBodyTooLargeError,\n startHttpJsonServer,\n type ServerRequestEvent,\n} from \"./http.js\";\nimport {\n recordCommittedServerEvent,\n recordServerEvent,\n type ServerEventObserver,\n} from \"./recorder.js\";\nimport { resolveMaxPendingInboundEvents } from \"./pending-events.js\";\nimport { closeWebSocketServer } from \"./websocket.js\";\n\nconst DEFAULT_WEBSOCKET_AUTHENTICATION_TIMEOUT_MS = 5_000;\nconst DEFAULT_MAX_WEBSOCKET_BUFFERED_BYTES = 1024 * 1024;\nconst DEFAULT_MAX_WEBSOCKET_MESSAGE_BYTES = 64 * 1024;\nconst DEFAULT_MAX_UNAUTHENTICATED_WEBSOCKET_CLIENTS = 32;\n\nfunction resolvePositiveLimit(value: number | undefined, name: string, fallback: number): number {\n if (value === undefined) {\n return fallback;\n }\n if (!Number.isSafeInteger(value) || value < 1) {\n throw new Error(`${name} must be a positive safe integer.`);\n }\n return value;\n}\n\ntype MattermostPost = {\n channel_id: string;\n create_at: number;\n id: string;\n message: string;\n root_id: string;\n type: string;\n user_id: string;\n};\n\ntype MattermostWebSocketEvent = {\n broadcast: {\n channel_id: string;\n omit_users: null | Record<string, boolean>;\n team_id: string;\n user_id: string;\n };\n data: Record<string, unknown>;\n event: string;\n};\ntype MattermostRecorderEvent = ServerRequestEvent & {\n accepted?: boolean | undefined;\n};\n\ntype MattermostServerState = {\n adminToken: string;\n botToken: string;\n botUserId: string;\n botUsername: string;\n channels: Map<string, { id: string; name: string; display_name: string; type: string }>;\n maxPendingInboundEvents: number;\n maxWebSocketBufferedBytes: number;\n nextPost: number;\n onEvent: ServerEventObserver | undefined;\n pendingEvents: MattermostWebSocketEvent[];\n posts: Map<string, MattermostPost>;\n recorderPath: string;\n users: Map<string, { id: string; username: string; update_at: number }>;\n websocketClients: Map<WebSocket, number>;\n};\n\nexport type MattermostServerManifest = {\n adminToken: string;\n baseUrl: string;\n botToken: string;\n botUserId: string;\n endpoints: {\n adminInboundUrl: string;\n apiRoot: string;\n websocketUrl: string;\n };\n env: {\n MATTERMOST_BOT_TOKEN: string;\n MATTERMOST_URL: string;\n };\n provider: \"mattermost\";\n recorderPath: string;\n version: 1;\n};\n\nexport type StartedMattermostServer = {\n close(): Promise<void>;\n manifest: MattermostServerManifest;\n};\n\nexport type StartMattermostServerParams = {\n adminToken?: string | undefined;\n botToken?: string | undefined;\n botUserId?: string | undefined;\n botUsername?: string | undefined;\n host?: string | undefined;\n onEvent?: ServerEventObserver | undefined;\n port?: number | undefined;\n recorderPath?: string | undefined;\n maxPendingInboundEvents?: number | undefined;\n maxWebSocketBufferedBytes?: number | undefined;\n maxWebSocketMessageBytes?: number | undefined;\n maxUnauthenticatedWebSocketClients?: number | undefined;\n websocketAuthenticationTimeoutMs?: number | undefined;\n};\n\nexport function mattermostId(value: string): string {\n return createHash(\"sha256\").update(value).digest(\"hex\").slice(0, 26);\n}\n\nasync function appendEvent(\n state: MattermostServerState,\n event: ServerRequestEvent,\n committed = false,\n): Promise<void> {\n const params = { event, onEvent: state.onEvent, recorderPath: state.recorderPath };\n await (committed ? recordCommittedServerEvent(params) : recordServerEvent(params));\n}\n\nfunction authorized(request: IncomingMessage, token: string): boolean {\n const [scheme, value] = request.headers.authorization?.trim().split(/\\s+/, 2) ?? [];\n return scheme?.toLowerCase() === \"bearer\" && value === token;\n}\n\nfunction mattermostError(message: string, status: number): Response {\n return jsonResponse(\n {\n id: `api.context.${status}`,\n message,\n request_id: \"\",\n status_code: status,\n },\n status,\n );\n}\n\nfunction decodeMattermostPathSegment(value: string): string | Response {\n try {\n return decodeURIComponent(value);\n } catch {\n return mattermostError(\"Invalid path parameter\", 400);\n }\n}\n\nfunction eventBroadcast(params: {\n channelId?: string;\n omitUsers?: Record<string, boolean>;\n userId?: string;\n}): MattermostWebSocketEvent[\"broadcast\"] {\n return {\n channel_id: params.channelId ?? \"\",\n omit_users: params.omitUsers ?? null,\n team_id: \"\",\n user_id: params.userId ?? \"\",\n };\n}\n\nfunction postEvent(\n event: \"post_deleted\" | \"post_edited\" | \"posted\",\n post: MattermostPost,\n senderName: string,\n channelType: string,\n): MattermostWebSocketEvent {\n return {\n event,\n data: {\n channel_display_name: post.channel_id,\n channel_id: post.channel_id,\n channel_name: post.channel_id,\n channel_type: channelType,\n post: JSON.stringify(post),\n sender_name: senderName,\n },\n broadcast: eventBroadcast({ channelId: post.channel_id, userId: post.user_id }),\n };\n}\n\nfunction webSocketEventBytes(event: MattermostWebSocketEvent): number {\n return Buffer.byteLength(JSON.stringify({ ...event, seq: 0 }), \"utf8\");\n}\n\nfunction sendEvent(\n state: MattermostServerState,\n client: WebSocket,\n event: MattermostWebSocketEvent,\n): boolean {\n const seq = state.websocketClients.get(client);\n if (seq === undefined || client.readyState !== WebSocket.OPEN) {\n state.websocketClients.delete(client);\n return false;\n }\n const payload = JSON.stringify({ ...event, seq });\n if (\n client.bufferedAmount + Buffer.byteLength(payload, \"utf8\") >\n state.maxWebSocketBufferedBytes\n ) {\n state.websocketClients.delete(client);\n client.close(1013, \"client too slow\");\n return false;\n }\n try {\n client.send(payload);\n } catch {\n state.websocketClients.delete(client);\n client.terminate();\n return false;\n }\n state.websocketClients.set(client, seq + 1);\n return true;\n}\n\nfunction sendControlMessage(\n state: MattermostServerState,\n client: WebSocket,\n value: Record<string, unknown>,\n): boolean {\n if (client.readyState !== WebSocket.OPEN) {\n state.websocketClients.delete(client);\n return false;\n }\n const payload = JSON.stringify(value);\n if (\n client.bufferedAmount + Buffer.byteLength(payload, \"utf8\") >\n state.maxWebSocketBufferedBytes\n ) {\n state.websocketClients.delete(client);\n client.close(1013, \"client too slow\");\n return false;\n }\n try {\n client.send(payload);\n return true;\n } catch {\n state.websocketClients.delete(client);\n client.terminate();\n return false;\n }\n}\n\nfunction broadcast(\n state: MattermostServerState,\n event: MattermostWebSocketEvent,\n queueIfUndelivered = true,\n): boolean {\n if (event.broadcast.omit_users?.[state.botUserId]) {\n return true;\n }\n if (webSocketEventBytes(event) > state.maxWebSocketBufferedBytes) {\n for (const client of state.websocketClients.keys()) {\n state.websocketClients.delete(client);\n client.close(1013, \"client too slow\");\n }\n return false;\n }\n let delivered = false;\n for (const client of state.websocketClients.keys()) {\n delivered = sendEvent(state, client, event) || delivered;\n }\n if (delivered) {\n return true;\n }\n if (!queueIfUndelivered) {\n return false;\n }\n if (state.pendingEvents.length >= state.maxPendingInboundEvents) {\n return false;\n }\n state.pendingEvents.push(event);\n return true;\n}\n\nfunction pendingQueueFullResponse(state: MattermostServerState): Response {\n return jsonResponse(\n {\n error: `Pending inbound queue is full (${state.maxPendingInboundEvents} events)`,\n ok: false,\n },\n 503,\n );\n}\n\nfunction createPost(params: {\n channelId: string;\n message: string;\n rootId?: string | undefined;\n state: MattermostServerState;\n userId: string;\n}): MattermostPost {\n const id = mattermostId(`post-${params.state.nextPost++}`);\n const post = {\n channel_id: params.channelId,\n create_at: Date.now(),\n id,\n message: params.message,\n root_id: params.rootId ?? \"\",\n type: \"\",\n user_id: params.userId,\n };\n params.state.posts.set(id, post);\n return post;\n}\n\nfunction handleAdminInbound(params: {\n body: Record<string, unknown>;\n state: MattermostServerState;\n}): Response {\n const channelId = readTrimmedString(params.body.channelId ?? params.body.channel_id);\n const senderId = readTrimmedString(params.body.senderId ?? params.body.user_id);\n const text = readTrimmedString(params.body.text ?? params.body.message);\n if (!channelId || !senderId || !text) {\n return jsonResponse({ error: \"channelId, senderId, and text are required\", ok: false }, 400);\n }\n if (\n params.state.websocketClients.size === 0 &&\n params.state.pendingEvents.length >= params.state.maxPendingInboundEvents\n ) {\n return pendingQueueFullResponse(params.state);\n }\n const previousUser = params.state.users.get(senderId);\n const previousChannel = params.state.channels.get(channelId);\n const senderName =\n readTrimmedString(params.body.senderName) ?? previousUser?.username ?? senderId;\n const channelType = readTrimmedString(params.body.channelType) ?? previousChannel?.type ?? \"D\";\n const previousNextPost = params.state.nextPost;\n params.state.users.set(senderId, { id: senderId, update_at: Date.now(), username: senderName });\n params.state.channels.set(channelId, {\n display_name: previousChannel?.display_name ?? channelId,\n id: channelId,\n name: previousChannel?.name ?? channelId,\n type: channelType,\n });\n const post = createPost({\n channelId,\n message: text,\n rootId: readTrimmedString(params.body.rootId ?? params.body.root_id),\n state: params.state,\n userId: senderId,\n });\n const rollback = () => {\n params.state.posts.delete(post.id);\n params.state.nextPost = previousNextPost;\n if (previousUser) {\n params.state.users.set(senderId, previousUser);\n } else {\n params.state.users.delete(senderId);\n }\n if (previousChannel) {\n params.state.channels.set(channelId, previousChannel);\n } else {\n params.state.channels.delete(channelId);\n }\n };\n const event = postEvent(\"posted\", post, senderName, channelType);\n if (webSocketEventBytes(event) > params.state.maxWebSocketBufferedBytes) {\n rollback();\n return jsonResponse({ error: \"Inbound event is too large\", ok: false }, 413);\n }\n if (!broadcast(params.state, event)) {\n rollback();\n return pendingQueueFullResponse(params.state);\n }\n return jsonResponse({ ok: true, post });\n}\n\nasync function handleApi(params: {\n body: unknown;\n method: string;\n path: string;\n state: MattermostServerState;\n}): Promise<Response> {\n const { body, method, path: apiPath, state } = params;\n if (method === \"GET\" && apiPath === \"/users/me\") {\n return jsonResponse(state.users.get(state.botUserId));\n }\n const usernameMatch = /^\\/users\\/username\\/([^/]+)$/u.exec(apiPath);\n if (method === \"GET\" && usernameMatch?.[1]) {\n const username = decodeMattermostPathSegment(usernameMatch[1]);\n if (username instanceof Response) {\n return username;\n }\n const user = [...state.users.values()].find((entry) => entry.username === username);\n return user ? jsonResponse(user) : mattermostError(\"User not found\", 404);\n }\n const userMatch = /^\\/users\\/([^/]+)$/u.exec(apiPath);\n if (method === \"GET\" && userMatch?.[1]) {\n const user = state.users.get(userMatch[1]);\n return user ? jsonResponse(user) : mattermostError(\"User not found\", 404);\n }\n const channelMatch = /^\\/channels\\/([^/]+)$/u.exec(apiPath);\n if (method === \"GET\" && channelMatch?.[1]) {\n const channel = state.channels.get(channelMatch[1]);\n return channel ? jsonResponse(channel) : mattermostError(\"Channel not found\", 404);\n }\n if (method === \"POST\" && apiPath === \"/channels/direct\") {\n const userIds = Array.isArray(body) ? body.map(readTrimmedString) : [];\n if (userIds.length !== 2 || userIds.some((value) => !value)) {\n return mattermostError(\"Two user IDs are required\", 400);\n }\n const [firstUserId, secondUserId] = userIds as [string, string];\n if (firstUserId === secondUserId) {\n return mattermostError(\"Direct channel users must be distinct\", 400);\n }\n if (!state.users.has(firstUserId) || !state.users.has(secondUserId)) {\n return mattermostError(\"User not found\", 404);\n }\n if (firstUserId !== state.botUserId && secondUserId !== state.botUserId) {\n return mattermostError(\"Authenticated user must belong to the direct channel\", 403);\n }\n const channelId = mattermostId(`dm:${userIds.sort().join(\":\")}`);\n const channel = { display_name: \"\", id: channelId, name: channelId, type: \"D\" };\n state.channels.set(channelId, channel);\n return jsonResponse(channel, 201);\n }\n if (!isJsonObject(body)) {\n return mattermostError(\"Request body must be a JSON object\", 400);\n }\n if (method === \"POST\" && apiPath === \"/users/me/typing\") {\n const channelId = readTrimmedString(body.channel_id);\n if (!channelId) {\n return mattermostError(\"channel_id is required\", 400);\n }\n if (!state.channels.has(channelId)) {\n return mattermostError(\"Channel not found\", 404);\n }\n broadcast(\n state,\n {\n broadcast: eventBroadcast({\n channelId,\n omitUsers: { [state.botUserId]: true },\n }),\n data: {\n channel_id: channelId,\n ...(readTrimmedString(body.parent_id)\n ? { parent_id: readTrimmedString(body.parent_id) }\n : {}),\n user_id: state.botUserId,\n },\n event: \"typing\",\n },\n false,\n );\n return jsonResponse({ status: \"OK\" });\n }\n if (method === \"POST\" && apiPath === \"/posts\") {\n const channelId = readTrimmedString(body.channel_id);\n const message = readTrimmedString(body.message);\n if (!channelId || !message) {\n return mattermostError(\"channel_id and message are required\", 400);\n }\n const channel = state.channels.get(channelId);\n if (!channel) {\n return mattermostError(\"Channel not found\", 404);\n }\n const rootId = readTrimmedString(body.root_id);\n if (rootId) {\n const rootPost = state.posts.get(rootId);\n if (!rootPost) {\n return mattermostError(\"Root post not found\", 404);\n }\n if (rootPost.channel_id !== channelId) {\n return mattermostError(\"Root post belongs to another channel\", 400);\n }\n }\n const post = createPost({\n channelId,\n message,\n rootId,\n state,\n userId: state.botUserId,\n });\n broadcast(state, postEvent(\"posted\", post, state.botUsername, channel.type), false);\n return jsonResponse(post, 201);\n }\n const postMatch = /^\\/posts\\/([^/]+)$/u.exec(apiPath);\n if (postMatch?.[1] && method === \"PUT\") {\n const post = state.posts.get(postMatch[1]);\n if (!post) {\n return mattermostError(\"Post not found\", 404);\n }\n if (post.user_id !== state.botUserId) {\n return mattermostError(\"You do not have permission to edit this post\", 403);\n }\n const updated = { ...post, message: readTrimmedString(body.message) ?? post.message };\n state.posts.set(updated.id, updated);\n broadcast(\n state,\n postEvent(\n \"post_edited\",\n updated,\n state.botUsername,\n state.channels.get(updated.channel_id)?.type ?? \"O\",\n ),\n false,\n );\n return jsonResponse(updated);\n }\n if (postMatch?.[1] && method === \"DELETE\") {\n const post = state.posts.get(postMatch[1]);\n if (!post) {\n return mattermostError(\"Post not found\", 404);\n }\n if (post.user_id !== state.botUserId) {\n return mattermostError(\"You do not have permission to delete this post\", 403);\n }\n state.posts.delete(post.id);\n broadcast(\n state,\n postEvent(\n \"post_deleted\",\n post,\n state.botUsername,\n state.channels.get(post.channel_id)?.type ?? \"O\",\n ),\n false,\n );\n return jsonResponse({ status: \"OK\" });\n }\n return mattermostError(\"Not found\", 404);\n}\n\nasync function handleRequest(request: IncomingMessage, state: MattermostServerState) {\n const url = new URL(request.url ?? \"/\", \"http://localhost\");\n const method = request.method ?? \"GET\";\n if (url.pathname === \"/crabline/mattermost/inbound\" && method === \"POST\") {\n if (!hasAdminToken(request, state.adminToken)) {\n drainRequestBody(request);\n return adminAuthError();\n }\n const body = await parseUnknownRequestBody(request);\n if (!isJsonObject(body)) {\n return jsonResponse({ error: \"Request body must be a JSON object\", ok: false }, 400);\n }\n await appendEvent(state, {\n at: new Date().toISOString(),\n body,\n method,\n path: url.pathname,\n query: queryRecord(url),\n type: \"admin\",\n });\n return handleAdminInbound({ body, state });\n }\n if (!url.pathname.startsWith(\"/api/v4/\")) {\n return new Response(\"not found\", { status: 404 });\n }\n if (!authorized(request, state.botToken)) {\n drainRequestBody(request);\n return mattermostError(\"Invalid or missing token\", 401);\n }\n const body =\n method === \"GET\" || method === \"DELETE\" ? {} : await parseUnknownRequestBody(request);\n const event: MattermostRecorderEvent = {\n at: new Date().toISOString(),\n ...(typeof body === \"object\" && body !== null && Object.keys(body).length > 0 ? { body } : {}),\n method,\n path: url.pathname,\n query: queryRecord(url),\n type: \"api\",\n };\n const response = await handleApi({\n body,\n method,\n path: url.pathname.slice(\"/api/v4\".length),\n state,\n });\n if (method === \"POST\" && url.pathname === \"/api/v4/posts\") {\n event.accepted = response.status === 201;\n }\n await appendEvent(state, event, response.ok && method !== \"GET\");\n return response;\n}\n\nfunction attachWebSocketServer(params: {\n authenticationTimeoutMs: number;\n maxMessageBytes: number;\n maxUnauthenticatedClients: number;\n state: MattermostServerState;\n server: import(\"node:http\").Server;\n}) {\n const websocketServer = new WebSocketServer({\n maxPayload: params.maxMessageBytes,\n noServer: true,\n });\n const unauthenticatedClients = new Set<WebSocket>();\n const onUpgrade = (\n request: IncomingMessage,\n socket: import(\"node:stream\").Duplex,\n head: Buffer,\n ) => {\n if (new URL(request.url ?? \"/\", \"http://localhost\").pathname !== \"/api/v4/websocket\") {\n socket.destroy();\n return;\n }\n websocketServer.handleUpgrade(request, socket, head, (client) => {\n websocketServer.emit(\"connection\", client, request);\n });\n };\n params.server.on(\"upgrade\", onUpgrade);\n websocketServer.on(\"connection\", (client) => {\n client.on(\"error\", () => {\n unauthenticatedClients.delete(client);\n params.state.websocketClients.delete(client);\n });\n if (unauthenticatedClients.size >= params.maxUnauthenticatedClients) {\n client.terminate();\n return;\n }\n unauthenticatedClients.add(client);\n let authenticationOpen = true;\n const authenticationTimeout = setTimeout(() => {\n authenticationOpen = false;\n client.close(4001, \"authentication timeout\");\n }, params.authenticationTimeoutMs);\n authenticationTimeout.unref();\n client.on(\"message\", (raw: RawData) => {\n let message: {\n action?: string;\n data?: { channel_id?: string; parent_id?: string; token?: string };\n seq?: number;\n };\n try {\n message = JSON.parse(raw.toString()) as typeof message;\n } catch {\n client.close(1003, \"invalid json\");\n return;\n }\n if (!isJsonObject(message)) {\n client.close(1003, \"invalid json\");\n return;\n }\n const seq = message.seq ?? 0;\n if (!params.state.websocketClients.has(client)) {\n if (!authenticationOpen || client.readyState !== WebSocket.OPEN) {\n return;\n }\n if (\n message.action !== \"authentication_challenge\" ||\n message.data?.token !== params.state.botToken\n ) {\n sendControlMessage(params.state, client, {\n error: { id: \"api.context.unauthorized\", message: \"Authentication failed\" },\n seq_reply: seq,\n status: \"FAIL\",\n });\n authenticationOpen = false;\n client.close(4001, \"authentication failed\");\n return;\n }\n clearTimeout(authenticationTimeout);\n authenticationOpen = false;\n unauthenticatedClients.delete(client);\n params.state.websocketClients.set(client, 0);\n sendControlMessage(params.state, client, { seq_reply: seq, status: \"OK\" });\n sendEvent(params.state, client, {\n broadcast: eventBroadcast({ userId: params.state.botUserId }),\n data: {\n connection_id: mattermostId(`connection-${Date.now()}-${Math.random()}`),\n server_version: \"crabline-mattermost.1\",\n },\n event: \"hello\",\n });\n const pending = params.state.pendingEvents.splice(0);\n for (const [index, event] of pending.entries()) {\n if (!sendEvent(params.state, client, event)) {\n params.state.pendingEvents.unshift(...pending.slice(index));\n break;\n }\n }\n return;\n }\n if (message.action === \"user_typing\") {\n const channelId = readTrimmedString(message.data?.channel_id);\n if (!channelId || !params.state.channels.has(channelId)) {\n sendControlMessage(params.state, client, {\n error: {\n id: \"api.channel.get.find.app_error\",\n message: \"Channel not found\",\n },\n seq_reply: seq,\n status: \"FAIL\",\n });\n return;\n }\n broadcast(\n params.state,\n {\n broadcast: eventBroadcast({\n channelId,\n omitUsers: { [params.state.botUserId]: true },\n }),\n data: {\n channel_id: channelId,\n parent_id: readTrimmedString(message.data?.parent_id) ?? \"\",\n user_id: params.state.botUserId,\n },\n event: \"typing\",\n },\n false,\n );\n sendControlMessage(params.state, client, { seq_reply: seq, status: \"OK\" });\n return;\n }\n if (message.action === \"ping\") {\n sendControlMessage(params.state, client, {\n data: { text: \"pong\" },\n seq_reply: seq,\n status: \"OK\",\n });\n return;\n }\n sendControlMessage(params.state, client, {\n error: { id: \"api.websocket.invalid_action\", message: \"Unsupported action\" },\n seq_reply: seq,\n status: \"FAIL\",\n });\n });\n client.once(\"close\", () => {\n authenticationOpen = false;\n clearTimeout(authenticationTimeout);\n unauthenticatedClients.delete(client);\n params.state.websocketClients.delete(client);\n });\n });\n return async () => {\n params.server.off(\"upgrade\", onUpgrade);\n await closeWebSocketServer(websocketServer);\n };\n}\n\nexport async function startMattermostServer(\n params: StartMattermostServerParams = {},\n): Promise<StartedMattermostServer> {\n const host = params.host ?? \"127.0.0.1\";\n const botUserId = params.botUserId ?? mattermostId(\"crabline-mattermost-bot\");\n const botUsername = params.botUsername ?? \"crabline_bot\";\n const maxWebSocketMessageBytes = resolvePositiveLimit(\n params.maxWebSocketMessageBytes,\n \"maxWebSocketMessageBytes\",\n DEFAULT_MAX_WEBSOCKET_MESSAGE_BYTES,\n );\n const maxUnauthenticatedWebSocketClients = resolvePositiveLimit(\n params.maxUnauthenticatedWebSocketClients,\n \"maxUnauthenticatedWebSocketClients\",\n DEFAULT_MAX_UNAUTHENTICATED_WEBSOCKET_CLIENTS,\n );\n const state: MattermostServerState = {\n adminToken: params.adminToken ?? randomBytes(24).toString(\"base64url\"),\n botToken:\n params.botToken ??\n (isLoopbackHost(host) ? \"crabline-mattermost-token\" : randomBytes(13).toString(\"hex\")),\n botUserId,\n botUsername,\n channels: new Map(),\n maxPendingInboundEvents: resolveMaxPendingInboundEvents(params.maxPendingInboundEvents),\n maxWebSocketBufferedBytes: resolvePositiveLimit(\n params.maxWebSocketBufferedBytes,\n \"maxWebSocketBufferedBytes\",\n DEFAULT_MAX_WEBSOCKET_BUFFERED_BYTES,\n ),\n nextPost: 1,\n onEvent: params.onEvent,\n pendingEvents: [],\n posts: new Map(),\n recorderPath: params.recorderPath ?? path.resolve(\".crabline\", \"servers\", \"mattermost.jsonl\"),\n users: new Map([[botUserId, { id: botUserId, update_at: Date.now(), username: botUsername }]]),\n websocketClients: new Map(),\n };\n const httpServer = await startHttpJsonServer({\n handle: (request) => handleRequest(request, state),\n handleError: (error) => {\n if (error instanceof InvalidJsonBodyError) {\n return mattermostError(\"Request body is not valid JSON\", 400);\n }\n if (error instanceof RequestBodyTooLargeError) {\n return mattermostError(\"Request body is too large\", 413);\n }\n return undefined;\n },\n host,\n port: params.port ?? 0,\n serverName: \"Mattermost\",\n });\n const closeMattermostWebSocketServer = attachWebSocketServer({\n authenticationTimeoutMs:\n params.websocketAuthenticationTimeoutMs ?? DEFAULT_WEBSOCKET_AUTHENTICATION_TIMEOUT_MS,\n maxMessageBytes: maxWebSocketMessageBytes,\n maxUnauthenticatedClients: maxUnauthenticatedWebSocketClients,\n server: httpServer.server,\n state,\n });\n return {\n async close() {\n await closeMattermostWebSocketServer();\n await httpServer.close();\n },\n manifest: {\n adminToken: state.adminToken,\n baseUrl: httpServer.baseUrl,\n botToken: state.botToken,\n botUserId,\n endpoints: {\n adminInboundUrl: `${httpServer.baseUrl}/crabline/mattermost/inbound`,\n apiRoot: `${httpServer.baseUrl}/api/v4`,\n websocketUrl: `${httpServer.baseUrl.replace(/^http/u, \"ws\")}/api/v4/websocket`,\n },\n env: {\n MATTERMOST_BOT_TOKEN: state.botToken,\n MATTERMOST_URL: httpServer.baseUrl,\n },\n provider: \"mattermost\",\n recorderPath: state.recorderPath,\n version: 1,\n },\n };\n}\n"]}
@@ -0,0 +1,2 @@
1
+ export declare const DEFAULT_MAX_PENDING_INBOUND_EVENTS = 1000;
2
+ export declare function resolveMaxPendingInboundEvents(value: number | undefined): number;
@@ -0,0 +1,11 @@
1
+ export const DEFAULT_MAX_PENDING_INBOUND_EVENTS = 1_000;
2
+ export function resolveMaxPendingInboundEvents(value) {
3
+ if (value === undefined) {
4
+ return DEFAULT_MAX_PENDING_INBOUND_EVENTS;
5
+ }
6
+ if (!Number.isSafeInteger(value) || value < 1) {
7
+ throw new Error("maxPendingInboundEvents must be a positive safe integer.");
8
+ }
9
+ return value;
10
+ }
11
+ //# sourceMappingURL=pending-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pending-events.js","sourceRoot":"","sources":["../../../src/servers/pending-events.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,kCAAkC,GAAG,KAAK,CAAC;AAExD,MAAM,UAAU,8BAA8B,CAAC,KAAyB;IACtE,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,OAAO,kCAAkC,CAAC;IAC5C,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;QAC9C,MAAM,IAAI,KAAK,CAAC,0DAA0D,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC","sourcesContent":["export const DEFAULT_MAX_PENDING_INBOUND_EVENTS = 1_000;\n\nexport function resolveMaxPendingInboundEvents(value: number | undefined): number {\n if (value === undefined) {\n return DEFAULT_MAX_PENDING_INBOUND_EVENTS;\n }\n if (!Number.isSafeInteger(value) || value < 1) {\n throw new Error(\"maxPendingInboundEvents must be a positive safe integer.\");\n }\n return value;\n}\n"]}
@@ -5,3 +5,8 @@ export declare function recordServerEvent(params: {
5
5
  onEvent: ServerEventObserver | undefined;
6
6
  recorderPath: string;
7
7
  }): Promise<void>;
8
+ export declare function recordCommittedServerEvent(params: {
9
+ event: ServerRequestEvent;
10
+ onEvent: ServerEventObserver | undefined;
11
+ recorderPath: string;
12
+ }): Promise<void>;
@@ -1,8 +1,267 @@
1
- import fs from "node:fs/promises";
1
+ import { chmod, mkdir, open } from "node:fs/promises";
2
2
  import path from "node:path";
3
+ import { lock } from "proper-lockfile";
4
+ const pendingAppends = new Map();
5
+ const durableRecorderIdentities = new Map();
6
+ const MAX_DURABLE_RECORDER_IDENTITIES = 128;
7
+ const MAX_RECOVERY_VALIDATION_BYTES = 64 * 1024 * 1024;
8
+ const MAX_RECOVERY_SCAN_BYTES = MAX_RECOVERY_VALIDATION_BYTES + 1;
9
+ const RECORDER_LOCK_RETRY_MS = 100;
10
+ const RECORDER_LOCK_STALE_MS = 30_000;
11
+ const RECORDER_LOCK_UPDATE_MS = 10_000;
12
+ const TAIL_SCAN_CHUNK_BYTES = 64 * 1024;
13
+ function isManagedRecorderDirectory(directory) {
14
+ return (directory === path.resolve(".crabline", "servers") ||
15
+ directory === path.resolve("artifacts", "crabline"));
16
+ }
17
+ async function readBufferAt(file, length, position) {
18
+ const buffer = Buffer.alloc(length);
19
+ let bytesRead = 0;
20
+ while (bytesRead < length) {
21
+ const result = await file.read(buffer, bytesRead, length - bytesRead, position + bytesRead);
22
+ if (result.bytesRead === 0) {
23
+ break;
24
+ }
25
+ bytesRead += result.bytesRead;
26
+ }
27
+ return buffer.subarray(0, bytesRead);
28
+ }
29
+ async function findIncompleteTailStart(file, fileSize) {
30
+ let position = fileSize;
31
+ while (position > 0) {
32
+ const scannedBytes = fileSize - position;
33
+ const remainingScanBytes = MAX_RECOVERY_SCAN_BYTES - scannedBytes;
34
+ if (remainingScanBytes <= 0) {
35
+ throw recoveryValidationLimitError();
36
+ }
37
+ const chunkStart = Math.max(0, position - Math.min(TAIL_SCAN_CHUNK_BYTES, remainingScanBytes));
38
+ const chunk = await readBufferAt(file, position - chunkStart, chunkStart);
39
+ const lastNewline = chunk.lastIndexOf(0x0a);
40
+ if (lastNewline >= 0) {
41
+ return chunkStart + lastNewline + 1;
42
+ }
43
+ if (chunk.length === 0) {
44
+ break;
45
+ }
46
+ position = chunkStart;
47
+ }
48
+ return 0;
49
+ }
50
+ function recoveryValidationLimitError() {
51
+ return new Error("Server recorder final record is too large to validate safely; refusing to modify it.");
52
+ }
53
+ async function openRecorderFile(filePath) {
54
+ try {
55
+ return {
56
+ created: true,
57
+ file: await open(filePath, "ax+", 0o600),
58
+ };
59
+ }
60
+ catch (error) {
61
+ if (error.code !== "EEXIST") {
62
+ throw error;
63
+ }
64
+ return {
65
+ created: false,
66
+ file: await open(filePath, "a+", 0o600),
67
+ };
68
+ }
69
+ }
70
+ async function syncDirectory(directoryPath) {
71
+ if (process.platform === "win32") {
72
+ return;
73
+ }
74
+ const directory = await open(directoryPath, "r");
75
+ try {
76
+ await directory.sync();
77
+ }
78
+ finally {
79
+ await directory.close();
80
+ }
81
+ }
82
+ async function syncRecorderPathAncestry(filePath, firstCreatedDirectory) {
83
+ if (process.platform === "win32") {
84
+ return;
85
+ }
86
+ const resolvedFilePath = path.resolve(filePath);
87
+ let currentPath = resolvedFilePath;
88
+ const syncThroughPath = firstCreatedDirectory === undefined ? undefined : path.resolve(firstCreatedDirectory);
89
+ for (;;) {
90
+ const directoryPath = path.dirname(currentPath);
91
+ const mandatory = syncThroughPath !== undefined || currentPath === resolvedFilePath;
92
+ try {
93
+ await syncDirectory(directoryPath);
94
+ }
95
+ catch (error) {
96
+ const code = error.code;
97
+ if (!mandatory && (code === "EACCES" || code === "EPERM")) {
98
+ return;
99
+ }
100
+ throw error;
101
+ }
102
+ if (currentPath === syncThroughPath) {
103
+ return;
104
+ }
105
+ if (path.dirname(directoryPath) === directoryPath) {
106
+ return;
107
+ }
108
+ currentPath = directoryPath;
109
+ }
110
+ }
111
+ function recorderIdentity(stats) {
112
+ if (stats.dev === undefined || stats.ino === undefined) {
113
+ return undefined;
114
+ }
115
+ return `${stats.dev}:${stats.ino}`;
116
+ }
117
+ function rememberDurableRecorderIdentity(filePath, identity) {
118
+ durableRecorderIdentities.delete(filePath);
119
+ durableRecorderIdentities.set(filePath, identity);
120
+ if (durableRecorderIdentities.size > MAX_DURABLE_RECORDER_IDENTITIES) {
121
+ const oldestPath = durableRecorderIdentities.keys().next().value;
122
+ if (oldestPath !== undefined) {
123
+ durableRecorderIdentities.delete(oldestPath);
124
+ }
125
+ }
126
+ }
127
+ function recorderLockReleaseError(filePath, operationError, releaseError) {
128
+ return new AggregateError([operationError, releaseError], `Server recorder append and lock release both failed for "${filePath}".`, { cause: operationError });
129
+ }
130
+ function isRecorderLockContention(error) {
131
+ return (typeof error === "object" &&
132
+ error !== null &&
133
+ error.code === "ELOCKED");
134
+ }
135
+ async function acquireRecorderLock(filePath) {
136
+ while (true) {
137
+ try {
138
+ return await lock(filePath, {
139
+ realpath: false,
140
+ retries: 0,
141
+ stale: RECORDER_LOCK_STALE_MS,
142
+ update: RECORDER_LOCK_UPDATE_MS,
143
+ });
144
+ }
145
+ catch (error) {
146
+ if (!isRecorderLockContention(error)) {
147
+ throw error;
148
+ }
149
+ await new Promise((resolve) => setTimeout(resolve, RECORDER_LOCK_RETRY_MS));
150
+ }
151
+ }
152
+ }
153
+ async function withRecorderLock(filePath, operation) {
154
+ const release = await acquireRecorderLock(filePath);
155
+ let operationFailed = false;
156
+ let operationError;
157
+ let result;
158
+ try {
159
+ result = await operation();
160
+ }
161
+ catch (error) {
162
+ operationFailed = true;
163
+ operationError = error;
164
+ }
165
+ try {
166
+ await release();
167
+ }
168
+ catch (releaseError) {
169
+ if (operationFailed) {
170
+ throw recorderLockReleaseError(filePath, operationError, releaseError);
171
+ }
172
+ throw releaseError;
173
+ }
174
+ if (operationFailed) {
175
+ throw operationError;
176
+ }
177
+ return result;
178
+ }
179
+ async function appendJsonLine(filePath, line, durable) {
180
+ const key = path.resolve(filePath);
181
+ const previous = pendingAppends.get(key) ?? Promise.resolve();
182
+ const current = previous
183
+ .catch(() => { })
184
+ .then(async () => {
185
+ const directory = path.dirname(filePath);
186
+ const createdDirectory = await mkdir(directory, { mode: 0o700, recursive: true });
187
+ if (createdDirectory !== undefined || isManagedRecorderDirectory(path.resolve(directory))) {
188
+ await chmod(directory, 0o700);
189
+ }
190
+ await withRecorderLock(key, async () => {
191
+ const opened = await openRecorderFile(filePath);
192
+ const { file } = opened;
193
+ try {
194
+ await file.chmod(0o600);
195
+ const stats = await file.stat();
196
+ const identity = recorderIdentity(stats);
197
+ const needsPathDurability = opened.created ||
198
+ identity === undefined ||
199
+ durableRecorderIdentities.get(key) !== identity;
200
+ if (stats.size > 0) {
201
+ const finalByte = await readBufferAt(file, 1, stats.size - 1);
202
+ if (finalByte[0] !== 0x0a) {
203
+ const tailStart = await findIncompleteTailStart(file, stats.size);
204
+ const tailLength = stats.size - tailStart;
205
+ if (tailLength > MAX_RECOVERY_VALIDATION_BYTES) {
206
+ throw recoveryValidationLimitError();
207
+ }
208
+ const tail = await readBufferAt(file, tailLength, tailStart);
209
+ if (tail.length !== tailLength) {
210
+ throw new Error("Server recorder changed while repairing its final record.");
211
+ }
212
+ try {
213
+ JSON.parse(tail.toString("utf8"));
214
+ await file.appendFile("\n", { encoding: "utf8" });
215
+ }
216
+ catch (error) {
217
+ if (!(error instanceof SyntaxError)) {
218
+ throw error;
219
+ }
220
+ await file.truncate(tailStart);
221
+ }
222
+ }
223
+ }
224
+ await file.appendFile(line, { encoding: "utf8" });
225
+ if (durable || needsPathDurability) {
226
+ await file.sync();
227
+ }
228
+ if (needsPathDurability) {
229
+ const firstCreatedPath = createdDirectory ?? (opened.created ? path.resolve(filePath) : undefined);
230
+ await syncRecorderPathAncestry(filePath, firstCreatedPath);
231
+ if (identity === undefined) {
232
+ durableRecorderIdentities.delete(key);
233
+ }
234
+ else {
235
+ rememberDurableRecorderIdentity(key, identity);
236
+ }
237
+ }
238
+ }
239
+ finally {
240
+ await file.close();
241
+ }
242
+ });
243
+ });
244
+ pendingAppends.set(key, current);
245
+ try {
246
+ await current;
247
+ }
248
+ finally {
249
+ if (pendingAppends.get(key) === current) {
250
+ pendingAppends.delete(key);
251
+ }
252
+ }
253
+ }
3
254
  export async function recordServerEvent(params) {
4
- await fs.mkdir(path.dirname(params.recorderPath), { recursive: true });
5
- await fs.appendFile(params.recorderPath, `${JSON.stringify(params.event)}\n`, "utf8");
255
+ // Observers only see events after the recorder append is durable.
256
+ await appendJsonLine(params.recorderPath, `${JSON.stringify(params.event)}\n`, params.onEvent !== undefined);
6
257
  await params.onEvent?.(params.event);
7
258
  }
259
+ export async function recordCommittedServerEvent(params) {
260
+ try {
261
+ await recordServerEvent(params);
262
+ }
263
+ catch {
264
+ // The provider mutation already committed, so telemetry failure cannot change its response.
265
+ }
266
+ }
8
267
  //# sourceMappingURL=recorder.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"recorder.js","sourceRoot":"","sources":["../../../src/servers/recorder.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAK7B,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,MAIvC;IACC,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACvE,MAAM,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,YAAY,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACtF,MAAM,MAAM,CAAC,OAAO,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACvC,CAAC"}
1
+ {"version":3,"file":"recorder.js","sourceRoot":"","sources":["../../../src/servers/recorder.ts"],"names":[],"mappings":"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","sourcesContent":["import { chmod, mkdir, open } from \"node:fs/promises\";\nimport path from \"node:path\";\nimport { lock } from \"proper-lockfile\";\nimport type { ServerRequestEvent } from \"./http.js\";\n\nexport type ServerEventObserver = (event: ServerRequestEvent) => void | Promise<void>;\n\nconst pendingAppends = new Map<string, Promise<void>>();\nconst durableRecorderIdentities = new Map<string, string>();\nconst MAX_DURABLE_RECORDER_IDENTITIES = 128;\nconst MAX_RECOVERY_VALIDATION_BYTES = 64 * 1024 * 1024;\nconst MAX_RECOVERY_SCAN_BYTES = MAX_RECOVERY_VALIDATION_BYTES + 1;\nconst RECORDER_LOCK_RETRY_MS = 100;\nconst RECORDER_LOCK_STALE_MS = 30_000;\nconst RECORDER_LOCK_UPDATE_MS = 10_000;\nconst TAIL_SCAN_CHUNK_BYTES = 64 * 1024;\n\nfunction isManagedRecorderDirectory(directory: string): boolean {\n return (\n directory === path.resolve(\".crabline\", \"servers\") ||\n directory === path.resolve(\"artifacts\", \"crabline\")\n );\n}\n\nasync function readBufferAt(\n file: Awaited<ReturnType<typeof open>>,\n length: number,\n position: number,\n): Promise<Buffer> {\n const buffer = Buffer.alloc(length);\n let bytesRead = 0;\n while (bytesRead < length) {\n const result = await file.read(buffer, bytesRead, length - bytesRead, position + bytesRead);\n if (result.bytesRead === 0) {\n break;\n }\n bytesRead += result.bytesRead;\n }\n return buffer.subarray(0, bytesRead);\n}\n\nasync function findIncompleteTailStart(\n file: Awaited<ReturnType<typeof open>>,\n fileSize: number,\n): Promise<number> {\n let position = fileSize;\n while (position > 0) {\n const scannedBytes = fileSize - position;\n const remainingScanBytes = MAX_RECOVERY_SCAN_BYTES - scannedBytes;\n if (remainingScanBytes <= 0) {\n throw recoveryValidationLimitError();\n }\n const chunkStart = Math.max(0, position - Math.min(TAIL_SCAN_CHUNK_BYTES, remainingScanBytes));\n const chunk = await readBufferAt(file, position - chunkStart, chunkStart);\n const lastNewline = chunk.lastIndexOf(0x0a);\n if (lastNewline >= 0) {\n return chunkStart + lastNewline + 1;\n }\n if (chunk.length === 0) {\n break;\n }\n position = chunkStart;\n }\n return 0;\n}\n\nfunction recoveryValidationLimitError(): Error {\n return new Error(\n \"Server recorder final record is too large to validate safely; refusing to modify it.\",\n );\n}\n\nasync function openRecorderFile(\n filePath: string,\n): Promise<{ created: boolean; file: Awaited<ReturnType<typeof open>> }> {\n try {\n return {\n created: true,\n file: await open(filePath, \"ax+\", 0o600),\n };\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code !== \"EEXIST\") {\n throw error;\n }\n return {\n created: false,\n file: await open(filePath, \"a+\", 0o600),\n };\n }\n}\n\nasync function syncDirectory(directoryPath: string): Promise<void> {\n if (process.platform === \"win32\") {\n return;\n }\n const directory = await open(directoryPath, \"r\");\n try {\n await directory.sync();\n } finally {\n await directory.close();\n }\n}\n\nasync function syncRecorderPathAncestry(\n filePath: string,\n firstCreatedDirectory?: string,\n): Promise<void> {\n if (process.platform === \"win32\") {\n return;\n }\n const resolvedFilePath = path.resolve(filePath);\n let currentPath = resolvedFilePath;\n const syncThroughPath =\n firstCreatedDirectory === undefined ? undefined : path.resolve(firstCreatedDirectory);\n for (;;) {\n const directoryPath = path.dirname(currentPath);\n const mandatory = syncThroughPath !== undefined || currentPath === resolvedFilePath;\n try {\n await syncDirectory(directoryPath);\n } catch (error) {\n const code = (error as NodeJS.ErrnoException).code;\n if (!mandatory && (code === \"EACCES\" || code === \"EPERM\")) {\n return;\n }\n throw error;\n }\n if (currentPath === syncThroughPath) {\n return;\n }\n if (path.dirname(directoryPath) === directoryPath) {\n return;\n }\n currentPath = directoryPath;\n }\n}\n\nfunction recorderIdentity(stats: {\n dev?: bigint | number;\n ino?: bigint | number;\n}): string | undefined {\n if (stats.dev === undefined || stats.ino === undefined) {\n return undefined;\n }\n return `${stats.dev}:${stats.ino}`;\n}\n\nfunction rememberDurableRecorderIdentity(filePath: string, identity: string): void {\n durableRecorderIdentities.delete(filePath);\n durableRecorderIdentities.set(filePath, identity);\n if (durableRecorderIdentities.size > MAX_DURABLE_RECORDER_IDENTITIES) {\n const oldestPath = durableRecorderIdentities.keys().next().value;\n if (oldestPath !== undefined) {\n durableRecorderIdentities.delete(oldestPath);\n }\n }\n}\n\nfunction recorderLockReleaseError(\n filePath: string,\n operationError: unknown,\n releaseError: unknown,\n): AggregateError {\n return new AggregateError(\n [operationError, releaseError],\n `Server recorder append and lock release both failed for \"${filePath}\".`,\n { cause: operationError },\n );\n}\n\nfunction isRecorderLockContention(error: unknown): boolean {\n return (\n typeof error === \"object\" &&\n error !== null &&\n (error as NodeJS.ErrnoException).code === \"ELOCKED\"\n );\n}\n\nasync function acquireRecorderLock(filePath: string): Promise<() => Promise<void>> {\n while (true) {\n try {\n return await lock(filePath, {\n realpath: false,\n retries: 0,\n stale: RECORDER_LOCK_STALE_MS,\n update: RECORDER_LOCK_UPDATE_MS,\n });\n } catch (error) {\n if (!isRecorderLockContention(error)) {\n throw error;\n }\n await new Promise((resolve) => setTimeout(resolve, RECORDER_LOCK_RETRY_MS));\n }\n }\n}\n\nasync function withRecorderLock<T>(filePath: string, operation: () => Promise<T>): Promise<T> {\n const release = await acquireRecorderLock(filePath);\n let operationFailed = false;\n let operationError: unknown;\n let result: T | undefined;\n try {\n result = await operation();\n } catch (error) {\n operationFailed = true;\n operationError = error;\n }\n try {\n await release();\n } catch (releaseError) {\n if (operationFailed) {\n throw recorderLockReleaseError(filePath, operationError, releaseError);\n }\n throw releaseError;\n }\n if (operationFailed) {\n throw operationError;\n }\n return result as T;\n}\n\nasync function appendJsonLine(filePath: string, line: string, durable: boolean): Promise<void> {\n const key = path.resolve(filePath);\n const previous = pendingAppends.get(key) ?? Promise.resolve();\n const current = previous\n .catch(() => {})\n .then(async () => {\n const directory = path.dirname(filePath);\n const createdDirectory = await mkdir(directory, { mode: 0o700, recursive: true });\n if (createdDirectory !== undefined || isManagedRecorderDirectory(path.resolve(directory))) {\n await chmod(directory, 0o700);\n }\n await withRecorderLock(key, async () => {\n const opened = await openRecorderFile(filePath);\n const { file } = opened;\n try {\n await file.chmod(0o600);\n const stats = await file.stat();\n const identity = recorderIdentity(stats);\n const needsPathDurability =\n opened.created ||\n identity === undefined ||\n durableRecorderIdentities.get(key) !== identity;\n if (stats.size > 0) {\n const finalByte = await readBufferAt(file, 1, stats.size - 1);\n if (finalByte[0] !== 0x0a) {\n const tailStart = await findIncompleteTailStart(file, stats.size);\n const tailLength = stats.size - tailStart;\n if (tailLength > MAX_RECOVERY_VALIDATION_BYTES) {\n throw recoveryValidationLimitError();\n }\n const tail = await readBufferAt(file, tailLength, tailStart);\n if (tail.length !== tailLength) {\n throw new Error(\"Server recorder changed while repairing its final record.\");\n }\n try {\n JSON.parse(tail.toString(\"utf8\"));\n await file.appendFile(\"\\n\", { encoding: \"utf8\" });\n } catch (error) {\n if (!(error instanceof SyntaxError)) {\n throw error;\n }\n await file.truncate(tailStart);\n }\n }\n }\n await file.appendFile(line, { encoding: \"utf8\" });\n if (durable || needsPathDurability) {\n await file.sync();\n }\n if (needsPathDurability) {\n const firstCreatedPath =\n createdDirectory ?? (opened.created ? path.resolve(filePath) : undefined);\n await syncRecorderPathAncestry(filePath, firstCreatedPath);\n if (identity === undefined) {\n durableRecorderIdentities.delete(key);\n } else {\n rememberDurableRecorderIdentity(key, identity);\n }\n }\n } finally {\n await file.close();\n }\n });\n });\n pendingAppends.set(key, current);\n\n try {\n await current;\n } finally {\n if (pendingAppends.get(key) === current) {\n pendingAppends.delete(key);\n }\n }\n}\n\nexport async function recordServerEvent(params: {\n event: ServerRequestEvent;\n onEvent: ServerEventObserver | undefined;\n recorderPath: string;\n}): Promise<void> {\n // Observers only see events after the recorder append is durable.\n await appendJsonLine(\n params.recorderPath,\n `${JSON.stringify(params.event)}\\n`,\n params.onEvent !== undefined,\n );\n await params.onEvent?.(params.event);\n}\n\nexport async function recordCommittedServerEvent(params: {\n event: ServerRequestEvent;\n onEvent: ServerEventObserver | undefined;\n recorderPath: string;\n}): Promise<void> {\n try {\n await recordServerEvent(params);\n } catch {\n // The provider mutation already committed, so telemetry failure cannot change its response.\n }\n}\n"]}
@@ -25,5 +25,7 @@ export type StartSignalServerParams = {
25
25
  onEvent?: ServerEventObserver | undefined;
26
26
  port?: number | undefined;
27
27
  recorderPath?: string | undefined;
28
+ maxPendingInboundEvents?: number | undefined;
29
+ maxSseClients?: number | undefined;
28
30
  };
29
31
  export declare function startSignalServer(params?: StartSignalServerParams): Promise<StartedSignalServer>;