@undefineds.co/xpod 0.1.7 → 0.2.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.
Files changed (350) hide show
  1. package/README.md +164 -3
  2. package/config/cli.json +9 -71
  3. package/config/cloud.json +34 -7
  4. package/config/local.json +6 -2
  5. package/config/resolver.json +11 -49
  6. package/config/runtime-open.json +22 -0
  7. package/config/xpod.base.json +32 -0
  8. package/config/xpod.cluster.json +2 -44
  9. package/config/xpod.json +5 -2
  10. package/dist/agents/AgentExecutorFactory.js +1 -1
  11. package/dist/agents/AgentExecutorFactory.js.map +1 -1
  12. package/dist/agents/AgentManager.js +1 -1
  13. package/dist/agents/AgentManager.js.map +1 -1
  14. package/dist/agents/config/agent-meta-schema.d.ts +7 -7
  15. package/dist/agents/config/agent-meta-schema.js +1 -1
  16. package/dist/agents/config/agent-meta-schema.js.map +1 -1
  17. package/dist/agents/config/resolve.js +1 -1
  18. package/dist/agents/config/resolve.js.map +1 -1
  19. package/dist/agents/schema/agent-config.d.ts +18 -18
  20. package/dist/agents/schema/agent-config.js +1 -1
  21. package/dist/agents/schema/agent-config.js.map +1 -1
  22. package/dist/agents/schema/tables.d.ts +8 -8
  23. package/dist/agents/schema/tables.js +1 -1
  24. package/dist/agents/schema/tables.js.map +1 -1
  25. package/dist/ai/schema/config.d.ts +7 -7
  26. package/dist/ai/schema/config.js +1 -1
  27. package/dist/ai/schema/config.js.map +1 -1
  28. package/dist/ai/schema/model.d.ts +13 -13
  29. package/dist/ai/schema/model.js +1 -1
  30. package/dist/ai/schema/model.js.map +1 -1
  31. package/dist/ai/schema/provider.d.ts +7 -7
  32. package/dist/ai/schema/provider.js +1 -1
  33. package/dist/ai/schema/provider.js.map +1 -1
  34. package/dist/ai/schema/vector-store.d.ts +17 -17
  35. package/dist/ai/schema/vector-store.js +1 -1
  36. package/dist/ai/schema/vector-store.js.map +1 -1
  37. package/dist/ai/service/CredentialReaderImpl.js +1 -1
  38. package/dist/ai/service/CredentialReaderImpl.js.map +1 -1
  39. package/dist/ai/service/DefaultAiConfigService.js.map +1 -1
  40. package/dist/api/ApiServer.d.ts +3 -1
  41. package/dist/api/ApiServer.js +14 -1
  42. package/dist/api/ApiServer.js.map +1 -1
  43. package/dist/api/auth/AuthContext.d.ts +12 -1
  44. package/dist/api/auth/AuthContext.js +18 -1
  45. package/dist/api/auth/AuthContext.js.map +1 -1
  46. package/dist/api/auth/ClientCredentialsAuthenticator.d.ts +0 -1
  47. package/dist/api/auth/ClientCredentialsAuthenticator.js.map +1 -1
  48. package/dist/api/auth/ServiceTokenAuthenticator.d.ts +18 -0
  49. package/dist/api/auth/ServiceTokenAuthenticator.js +50 -0
  50. package/dist/api/auth/ServiceTokenAuthenticator.js.map +1 -0
  51. package/dist/api/auth/index.d.ts +1 -0
  52. package/dist/api/auth/index.js +1 -0
  53. package/dist/api/auth/index.js.map +1 -1
  54. package/dist/api/chatkit/ai-provider.d.ts +0 -10
  55. package/dist/api/chatkit/ai-provider.js +11 -120
  56. package/dist/api/chatkit/ai-provider.js.map +1 -1
  57. package/dist/api/chatkit/default-agent.js +11 -8
  58. package/dist/api/chatkit/default-agent.js.map +1 -1
  59. package/dist/api/chatkit/pod-store.d.ts +6 -0
  60. package/dist/api/chatkit/pod-store.js +103 -36
  61. package/dist/api/chatkit/pod-store.js.map +1 -1
  62. package/dist/api/chatkit/schema.d.ts +32 -26
  63. package/dist/api/chatkit/schema.js +16 -8
  64. package/dist/api/chatkit/schema.js.map +1 -1
  65. package/dist/api/container/business-token.d.ts +9 -0
  66. package/dist/api/container/business-token.js +32 -0
  67. package/dist/api/container/business-token.js.map +1 -0
  68. package/dist/api/container/cloud.js +36 -12
  69. package/dist/api/container/cloud.js.map +1 -1
  70. package/dist/api/container/common.js +13 -5
  71. package/dist/api/container/common.js.map +1 -1
  72. package/dist/api/container/index.js +94 -14
  73. package/dist/api/container/index.js.map +1 -1
  74. package/dist/api/container/local.js +2 -1
  75. package/dist/api/container/local.js.map +1 -1
  76. package/dist/api/container/routes.js +81 -9
  77. package/dist/api/container/routes.js.map +1 -1
  78. package/dist/api/container/types.d.ts +8 -6
  79. package/dist/api/container/types.js.map +1 -1
  80. package/dist/api/handlers/AdminHandler.js +9 -9
  81. package/dist/api/handlers/AdminHandler.js.map +1 -1
  82. package/dist/api/handlers/ApiKeyHandler.js +0 -6
  83. package/dist/api/handlers/ApiKeyHandler.js.map +1 -1
  84. package/dist/api/handlers/EdgeNodeSignalHandler.d.ts +17 -0
  85. package/dist/api/handlers/EdgeNodeSignalHandler.js +171 -0
  86. package/dist/api/handlers/EdgeNodeSignalHandler.js.map +1 -0
  87. package/dist/api/handlers/PodManagementHandler.d.ts +5 -4
  88. package/dist/api/handlers/PodManagementHandler.js +11 -10
  89. package/dist/api/handlers/PodManagementHandler.js.map +1 -1
  90. package/dist/api/handlers/ProvisionHandler.d.ts +42 -0
  91. package/dist/api/handlers/ProvisionHandler.js +161 -0
  92. package/dist/api/handlers/ProvisionHandler.js.map +1 -0
  93. package/dist/api/handlers/QuotaHandler.d.ts +7 -7
  94. package/dist/api/handlers/QuotaHandler.js +143 -73
  95. package/dist/api/handlers/QuotaHandler.js.map +1 -1
  96. package/dist/api/handlers/SubdomainClientHandler.js +2 -2
  97. package/dist/api/handlers/SubdomainClientHandler.js.map +1 -1
  98. package/dist/api/handlers/SubdomainHandler.js +13 -8
  99. package/dist/api/handlers/SubdomainHandler.js.map +1 -1
  100. package/dist/api/handlers/UsageHandler.d.ts +14 -0
  101. package/dist/api/handlers/UsageHandler.js +123 -0
  102. package/dist/api/handlers/UsageHandler.js.map +1 -0
  103. package/dist/api/handlers/index.d.ts +3 -1
  104. package/dist/api/handlers/index.js +3 -1
  105. package/dist/api/handlers/index.js.map +1 -1
  106. package/dist/api/main.js +18 -0
  107. package/dist/api/main.js.map +1 -1
  108. package/dist/api/middleware/OpenAuthMiddleware.d.ts +12 -0
  109. package/dist/api/middleware/OpenAuthMiddleware.js +27 -0
  110. package/dist/api/middleware/OpenAuthMiddleware.js.map +1 -0
  111. package/dist/api/runtime.d.ts +15 -0
  112. package/dist/api/runtime.js +125 -0
  113. package/dist/api/runtime.js.map +1 -0
  114. package/dist/api/service/VectorStoreService.js +1 -1
  115. package/dist/api/service/VectorStoreService.js.map +1 -1
  116. package/dist/api/service/VercelChatService.d.ts +16 -7
  117. package/dist/api/service/VercelChatService.js +98 -178
  118. package/dist/api/service/VercelChatService.js.map +1 -1
  119. package/dist/api/store/DrizzleClientCredentialsStore.d.ts +6 -11
  120. package/dist/api/store/DrizzleClientCredentialsStore.js +9 -39
  121. package/dist/api/store/DrizzleClientCredentialsStore.js.map +1 -1
  122. package/dist/authorization/AuthModeSelector.d.ts +10 -0
  123. package/dist/authorization/AuthModeSelector.js +27 -0
  124. package/dist/authorization/AuthModeSelector.js.map +1 -0
  125. package/dist/authorization/AuthModeSelector.jsonld +81 -0
  126. package/dist/cli/commands/account.d.ts +6 -0
  127. package/dist/cli/commands/account.js +119 -0
  128. package/dist/cli/commands/account.js.map +1 -0
  129. package/dist/cli/commands/auth.js +20 -29
  130. package/dist/cli/commands/auth.js.map +1 -1
  131. package/dist/cli/commands/backup.d.ts +15 -0
  132. package/dist/cli/commands/backup.js +286 -0
  133. package/dist/cli/commands/backup.js.map +1 -0
  134. package/dist/cli/commands/config.d.ts +34 -3
  135. package/dist/cli/commands/config.js +195 -258
  136. package/dist/cli/commands/config.js.map +1 -1
  137. package/dist/cli/commands/doctor.d.ts +6 -0
  138. package/dist/cli/commands/doctor.js +94 -0
  139. package/dist/cli/commands/doctor.js.map +1 -0
  140. package/dist/cli/commands/pod.d.ts +6 -0
  141. package/dist/cli/commands/pod.js +124 -0
  142. package/dist/cli/commands/pod.js.map +1 -0
  143. package/dist/cli/commands/start.js +28 -5
  144. package/dist/cli/commands/start.js.map +1 -1
  145. package/dist/cli/index.js +9 -0
  146. package/dist/cli/index.js.map +1 -1
  147. package/dist/cli/lib/credentials-store.d.ts +17 -0
  148. package/dist/cli/lib/credentials-store.js +73 -0
  149. package/dist/cli/lib/credentials-store.js.map +1 -0
  150. package/dist/cli/lib/css-account.d.ts +17 -0
  151. package/dist/cli/lib/css-account.js +56 -0
  152. package/dist/cli/lib/css-account.js.map +1 -1
  153. package/dist/cli/lib/pod-thread-store.d.ts +57 -0
  154. package/dist/cli/lib/pod-thread-store.js +310 -0
  155. package/dist/cli/lib/pod-thread-store.js.map +1 -0
  156. package/dist/cli/lib/solid-auth.d.ts +20 -0
  157. package/dist/cli/lib/solid-auth.js +70 -0
  158. package/dist/cli/lib/solid-auth.js.map +1 -0
  159. package/dist/components/components.jsonld +5 -8
  160. package/dist/components/context.jsonld +114 -244
  161. package/dist/credential/schema/tables.d.ts +14 -14
  162. package/dist/credential/schema/tables.js +1 -1
  163. package/dist/credential/schema/tables.js.map +1 -1
  164. package/dist/edge/EdgeNodeAgent.js +2 -2
  165. package/dist/edge/EdgeNodeAgent.js.map +1 -1
  166. package/dist/edge/EdgeNodeDnsCoordinator.d.ts +1 -7
  167. package/dist/edge/EdgeNodeDnsCoordinator.js +31 -41
  168. package/dist/edge/EdgeNodeDnsCoordinator.js.map +1 -1
  169. package/dist/edge/EdgeNodeDnsCoordinator.jsonld +1 -27
  170. package/dist/edge/EdgeNodeModeDetector.d.ts +1 -1
  171. package/dist/edge/EdgeNodeModeDetector.js +9 -11
  172. package/dist/edge/EdgeNodeModeDetector.js.map +1 -1
  173. package/dist/http/ClusterIngressRouter.js +3 -3
  174. package/dist/http/ClusterIngressRouter.js.map +1 -1
  175. package/dist/http/ClusterWebSocketConfigurator.js +2 -2
  176. package/dist/http/ClusterWebSocketConfigurator.js.map +1 -1
  177. package/dist/http/PodRoutingHttpHandler.js +2 -2
  178. package/dist/http/PodRoutingHttpHandler.js.map +1 -1
  179. package/dist/http/cluster/PodMigrationHttpHandler.d.ts +1 -1
  180. package/dist/http/cluster/PodMigrationHttpHandler.js +1 -1
  181. package/dist/http/cluster/PodMigrationHttpHandler.js.map +1 -1
  182. package/dist/identity/drizzle/EdgeNodeRepository.d.ts +37 -4
  183. package/dist/identity/drizzle/EdgeNodeRepository.js +120 -128
  184. package/dist/identity/drizzle/EdgeNodeRepository.js.map +1 -1
  185. package/dist/identity/drizzle/ServiceTokenRepository.d.ts +52 -0
  186. package/dist/identity/drizzle/ServiceTokenRepository.js +142 -0
  187. package/dist/identity/drizzle/ServiceTokenRepository.js.map +1 -0
  188. package/dist/identity/drizzle/db.d.ts +9 -0
  189. package/dist/identity/drizzle/db.js +235 -3
  190. package/dist/identity/drizzle/db.js.map +1 -1
  191. package/dist/identity/drizzle/schema.pg.d.ts +5 -0
  192. package/dist/identity/drizzle/schema.pg.js +49 -20
  193. package/dist/identity/drizzle/schema.pg.js.map +1 -1
  194. package/dist/identity/drizzle/schema.sqlite.d.ts +332 -57
  195. package/dist/identity/drizzle/schema.sqlite.js +48 -18
  196. package/dist/identity/drizzle/schema.sqlite.js.map +1 -1
  197. package/dist/identity/oidc/AutoDetectIdentityProviderHandler.js +6 -4
  198. package/dist/identity/oidc/AutoDetectIdentityProviderHandler.js.map +1 -1
  199. package/dist/index.d.ts +6 -9
  200. package/dist/index.js +12 -14
  201. package/dist/index.js.map +1 -1
  202. package/dist/main.js +25 -8
  203. package/dist/main.js.map +1 -1
  204. package/dist/provision/ProvisionCodeCodec.d.ts +39 -0
  205. package/dist/provision/ProvisionCodeCodec.js +65 -0
  206. package/dist/provision/ProvisionCodeCodec.js.map +1 -0
  207. package/dist/provision/ProvisionCodeCodec.jsonld +47 -0
  208. package/dist/provision/ProvisionPodCreator.d.ts +20 -0
  209. package/dist/provision/ProvisionPodCreator.js +84 -0
  210. package/dist/provision/ProvisionPodCreator.js.map +1 -0
  211. package/dist/provision/ProvisionPodCreator.jsonld +118 -0
  212. package/dist/quota/DrizzleQuotaService.d.ts +17 -3
  213. package/dist/quota/DrizzleQuotaService.js +108 -8
  214. package/dist/quota/DrizzleQuotaService.js.map +1 -1
  215. package/dist/quota/DrizzleQuotaService.jsonld +33 -22
  216. package/dist/quota/NoopQuotaService.d.ts +7 -1
  217. package/dist/quota/NoopQuotaService.js +12 -0
  218. package/dist/quota/NoopQuotaService.js.map +1 -1
  219. package/dist/quota/NoopQuotaService.jsonld +24 -0
  220. package/dist/quota/QuotaService.d.ts +17 -0
  221. package/dist/quota/QuotaService.js +5 -0
  222. package/dist/quota/QuotaService.js.map +1 -1
  223. package/dist/quota/QuotaService.jsonld +50 -0
  224. package/dist/runtime/Proxy.d.ts +22 -4
  225. package/dist/runtime/Proxy.js +154 -35
  226. package/dist/runtime/Proxy.js.map +1 -1
  227. package/dist/runtime/XpodRuntime.d.ts +49 -0
  228. package/dist/runtime/XpodRuntime.js +374 -0
  229. package/dist/runtime/XpodRuntime.js.map +1 -0
  230. package/dist/runtime/env-utils.d.ts +2 -0
  231. package/dist/runtime/env-utils.js +55 -0
  232. package/dist/runtime/env-utils.js.map +1 -0
  233. package/dist/runtime/index.d.ts +4 -0
  234. package/dist/runtime/index.js +8 -1
  235. package/dist/runtime/index.js.map +1 -1
  236. package/dist/runtime/socket-fetch.d.ts +1 -0
  237. package/dist/runtime/socket-fetch.js +72 -0
  238. package/dist/runtime/socket-fetch.js.map +1 -0
  239. package/dist/runtime/socket-http.d.ts +1 -0
  240. package/dist/runtime/socket-http.js +142 -0
  241. package/dist/runtime/socket-http.js.map +1 -0
  242. package/dist/runtime/socket-utils.d.ts +2 -0
  243. package/dist/runtime/socket-utils.js +34 -0
  244. package/dist/runtime/socket-utils.js.map +1 -0
  245. package/dist/service/{EdgeNodeHeartbeatService.d.ts → EdgeNodeSignalClient.d.ts} +3 -3
  246. package/dist/service/{EdgeNodeHeartbeatService.js → EdgeNodeSignalClient.js} +4 -4
  247. package/dist/service/EdgeNodeSignalClient.js.map +1 -0
  248. package/dist/service/PodMigrationService.d.ts +1 -2
  249. package/dist/service/PodMigrationService.js +1 -2
  250. package/dist/service/PodMigrationService.js.map +1 -1
  251. package/dist/storage/SparqlUpdateResourceStore.js +1 -1
  252. package/dist/storage/SparqlUpdateResourceStore.js.map +1 -1
  253. package/dist/storage/accessors/MinioDataAccessor.d.ts +6 -0
  254. package/dist/storage/accessors/MinioDataAccessor.js +10 -0
  255. package/dist/storage/accessors/MinioDataAccessor.js.map +1 -1
  256. package/dist/storage/accessors/MinioDataAccessor.jsonld +4 -0
  257. package/dist/storage/accessors/MixDataAccessor.d.ts +2 -1
  258. package/dist/storage/accessors/MixDataAccessor.js +12 -1
  259. package/dist/storage/accessors/MixDataAccessor.js.map +1 -1
  260. package/dist/storage/accessors/MixDataAccessor.jsonld +19 -0
  261. package/dist/storage/locking/UrlAwareRedisLocker.d.ts +18 -0
  262. package/dist/storage/locking/UrlAwareRedisLocker.js +60 -0
  263. package/dist/storage/locking/UrlAwareRedisLocker.js.map +1 -0
  264. package/dist/storage/locking/UrlAwareRedisLocker.jsonld +123 -0
  265. package/dist/storage/quota/UsageRepository.d.ts +41 -8
  266. package/dist/storage/quota/UsageRepository.js +252 -50
  267. package/dist/storage/quota/UsageRepository.js.map +1 -1
  268. package/dist/storage/sparql/ComunicaQuintEngine.d.ts +9 -0
  269. package/dist/storage/sparql/ComunicaQuintEngine.js +50 -9
  270. package/dist/storage/sparql/ComunicaQuintEngine.js.map +1 -1
  271. package/dist/storage/sparql/QueryOptimizer.js +13 -1
  272. package/dist/storage/sparql/QueryOptimizer.js.map +1 -1
  273. package/dist/storage/sparql/QuintQuerySource.d.ts +14 -0
  274. package/dist/storage/sparql/QuintQuerySource.js +152 -1
  275. package/dist/storage/sparql/QuintQuerySource.js.map +1 -1
  276. package/dist/storage/sparql/SubgraphQueryEngine.d.ts +1 -0
  277. package/dist/storage/sparql/SubgraphQueryEngine.js +6 -2
  278. package/dist/storage/sparql/SubgraphQueryEngine.js.map +1 -1
  279. package/dist/storage/sparql/SubgraphQueryEngine.jsonld +4 -0
  280. package/dist/subdomain/SubdomainClient.d.ts +3 -3
  281. package/dist/subdomain/SubdomainClient.js +1 -1
  282. package/dist/subdomain/SubdomainClient.js.map +1 -1
  283. package/dist/subdomain/SubdomainService.d.ts +15 -16
  284. package/dist/subdomain/SubdomainService.js +80 -54
  285. package/dist/subdomain/SubdomainService.js.map +1 -1
  286. package/dist/subdomain/SubdomainService.jsonld +22 -26
  287. package/dist/supervisor/Supervisor.d.ts +7 -2
  288. package/dist/supervisor/Supervisor.js +33 -1
  289. package/dist/supervisor/Supervisor.js.map +1 -1
  290. package/dist/task/DrizzleTaskQueue.d.ts +1 -1
  291. package/dist/task/DrizzleTaskQueue.js +1 -1
  292. package/dist/task/DrizzleTaskQueue.js.map +1 -1
  293. package/dist/task/schema.d.ts +10 -10
  294. package/dist/task/schema.js +1 -1
  295. package/dist/task/schema.js.map +1 -1
  296. package/dist/test-utils/index.d.ts +4 -0
  297. package/dist/test-utils/index.js +8 -0
  298. package/dist/test-utils/index.js.map +1 -0
  299. package/dist/test-utils/no-auth-xpod.d.ts +11 -0
  300. package/dist/test-utils/no-auth-xpod.js +25 -0
  301. package/dist/test-utils/no-auth-xpod.js.map +1 -0
  302. package/dist/test-utils/seed-pod.d.ts +5 -0
  303. package/dist/test-utils/seed-pod.js +61 -0
  304. package/dist/test-utils/seed-pod.js.map +1 -0
  305. package/package.json +38 -10
  306. package/templates/identity/account/create-pod.html.ejs +110 -0
  307. package/templates/main.html.ejs +10 -0
  308. package/dist/api/handlers/DevHandler.d.ts +0 -18
  309. package/dist/api/handlers/DevHandler.js +0 -276
  310. package/dist/api/handlers/DevHandler.js.map +0 -1
  311. package/dist/api/handlers/SignalHandler.d.ts +0 -13
  312. package/dist/api/handlers/SignalHandler.js +0 -122
  313. package/dist/api/handlers/SignalHandler.js.map +0 -1
  314. package/dist/gateway/Proxy.d.ts +0 -24
  315. package/dist/gateway/Proxy.js +0 -209
  316. package/dist/gateway/Proxy.js.map +0 -1
  317. package/dist/gateway/Supervisor.d.ts +0 -2
  318. package/dist/gateway/Supervisor.js +0 -7
  319. package/dist/gateway/Supervisor.js.map +0 -1
  320. package/dist/gateway/port-finder.d.ts +0 -4
  321. package/dist/gateway/port-finder.js +0 -15
  322. package/dist/gateway/port-finder.js.map +0 -1
  323. package/dist/gateway/types.d.ts +0 -1
  324. package/dist/gateway/types.js +0 -3
  325. package/dist/gateway/types.js.map +0 -1
  326. package/dist/http/SignalInterceptHttpHandler.d.ts +0 -24
  327. package/dist/http/SignalInterceptHttpHandler.js +0 -47
  328. package/dist/http/SignalInterceptHttpHandler.js.map +0 -1
  329. package/dist/http/SignalInterceptHttpHandler.jsonld +0 -103
  330. package/dist/http/admin/EdgeNodeSignalHttpHandler.d.ts +0 -71
  331. package/dist/http/admin/EdgeNodeSignalHttpHandler.js +0 -674
  332. package/dist/http/admin/EdgeNodeSignalHttpHandler.js.map +0 -1
  333. package/dist/http/admin/EdgeNodeSignalHttpHandler.jsonld +0 -406
  334. package/dist/http/cluster/PodMigrationHttpHandler.jsonld +0 -169
  335. package/dist/quota/DefaultQuotaService.d.ts +0 -16
  336. package/dist/quota/DefaultQuotaService.js +0 -37
  337. package/dist/quota/DefaultQuotaService.js.map +0 -1
  338. package/dist/quota/DefaultQuotaService.jsonld +0 -85
  339. package/dist/service/EdgeNodeHeartbeatService.js.map +0 -1
  340. package/dist/service/PodMigrationService.jsonld +0 -76
  341. package/dist/storage/MigratableDataAccessor.d.ts +0 -63
  342. package/dist/storage/MigratableDataAccessor.js +0 -11
  343. package/dist/storage/MigratableDataAccessor.js.map +0 -1
  344. package/dist/storage/MigratableDataAccessor.jsonld +0 -60
  345. package/dist/storage/accessors/TieredMinioDataAccessor.d.ts +0 -150
  346. package/dist/storage/accessors/TieredMinioDataAccessor.js +0 -582
  347. package/dist/storage/accessors/TieredMinioDataAccessor.js.map +0 -1
  348. package/dist/storage/accessors/TieredMinioDataAccessor.jsonld +0 -333
  349. package/static/app/assets/index.css +0 -1
  350. package/static/app/assets/main.js +0 -11
@@ -1,4 +1,4 @@
1
- import type { ServiceConfig, ServiceState, StatusChangeHandler } from './types';
1
+ import type { ServiceConfig, ServiceState, ServiceStatus, StatusChangeHandler } from './types';
2
2
  export interface SupervisorLog {
3
3
  timestamp: string;
4
4
  level: 'info' | 'warn' | 'error';
@@ -7,16 +7,21 @@ export interface SupervisorLog {
7
7
  }
8
8
  export declare class Supervisor {
9
9
  private processes;
10
+ private managedStops;
10
11
  private states;
11
12
  private configs;
12
13
  private logs;
13
14
  private onStatusChange?;
14
15
  private isShuttingDown;
15
- constructor();
16
+ constructor(options?: {
17
+ handleProcessSignals?: boolean;
18
+ });
16
19
  private shutdown;
17
20
  private killAll;
18
21
  setStatusChangeHandler(handler: StatusChangeHandler): void;
19
22
  register(config: ServiceConfig): void;
23
+ registerManaged(name: string, stop?: () => Promise<void> | void): void;
24
+ setStatus(name: string, status: ServiceStatus, extra?: Partial<ServiceState>): void;
20
25
  addLog(source: string, level: SupervisorLog['level'], message: string): void;
21
26
  getLogs(filters?: {
22
27
  level?: string;
@@ -9,12 +9,16 @@ const tree_kill_1 = __importDefault(require("tree-kill"));
9
9
  const MAX_RESTARTS = 5;
10
10
  const MAX_LOGS = 500;
11
11
  class Supervisor {
12
- constructor() {
12
+ constructor(options = {}) {
13
13
  this.processes = new Map();
14
+ this.managedStops = new Map();
14
15
  this.states = new Map();
15
16
  this.configs = new Map();
16
17
  this.logs = [];
17
18
  this.isShuttingDown = false;
19
+ if (options.handleProcessSignals === false) {
20
+ return;
21
+ }
18
22
  // 确保父进程退出时清理所有子进程
19
23
  process.on('exit', () => this.killAll());
20
24
  process.on('SIGINT', () => this.shutdown('SIGINT'));
@@ -52,6 +56,29 @@ class Supervisor {
52
56
  restartCount: 0,
53
57
  });
54
58
  }
59
+ registerManaged(name, stop) {
60
+ if (!this.states.has(name)) {
61
+ this.states.set(name, {
62
+ name,
63
+ status: 'stopped',
64
+ restartCount: 0,
65
+ });
66
+ }
67
+ if (stop) {
68
+ this.managedStops.set(name, async () => {
69
+ await stop();
70
+ });
71
+ }
72
+ }
73
+ setStatus(name, status, extra) {
74
+ if (!this.states.has(name)) {
75
+ this.registerManaged(name);
76
+ }
77
+ this.updateState(name, {
78
+ status,
79
+ ...extra,
80
+ });
81
+ }
55
82
  addLog(source, level, message) {
56
83
  this.logs.push({
57
84
  timestamp: new Date().toISOString(),
@@ -88,6 +115,11 @@ class Supervisor {
88
115
  for (const name of this.processes.keys()) {
89
116
  promises.push(this.stop(name));
90
117
  }
118
+ for (const [name, stop] of this.managedStops) {
119
+ promises.push(stop().catch((error) => {
120
+ this.addLog(name, 'error', `Failed to stop managed service: ${String(error)}`);
121
+ }));
122
+ }
91
123
  await Promise.all(promises);
92
124
  }
93
125
  start(name) {
@@ -1 +1 @@
1
- {"version":3,"file":"Supervisor.js","sourceRoot":"","sources":["../../src/supervisor/Supervisor.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn, type ChildProcess } from 'node:child_process';\nimport kill from 'tree-kill';\nimport type { ServiceConfig, ServiceState, StatusChangeHandler } from './types';\n\nconst MAX_RESTARTS = 5;\nconst MAX_LOGS = 500;\n\nexport interface SupervisorLog {\n timestamp: string;\n level: 'info' | 'warn' | 'error';\n source: string;\n message: string;\n}\n\nexport class Supervisor {\n private processes: Map<string, ChildProcess> = new Map();\n private states: Map<string, ServiceState> = new Map();\n private configs: Map<string, ServiceConfig> = new Map();\n private logs: SupervisorLog[] = [];\n private onStatusChange?: StatusChangeHandler;\n private isShuttingDown = false;\n\n constructor() {\n // 确保父进程退出时清理所有子进程\n process.on('exit', () => this.killAll());\n process.on('SIGINT', () => this.shutdown('SIGINT'));\n process.on('SIGTERM', () => this.shutdown('SIGTERM'));\n }\n\n private async shutdown(signal: string): Promise<void> {\n if (this.isShuttingDown) return;\n this.isShuttingDown = true;\n console.log(`[Supervisor] Received ${signal}, stopping all services...`);\n await this.stopAll();\n process.exit(0);\n }\n\n private killAll(): void {\n // 同步杀掉所有子进程(用于 process.on('exit'))\n for (const [, child] of this.processes) {\n if (child.pid) {\n try {\n process.kill(child.pid, 'SIGKILL');\n } catch {\n // 进程可能已经退出\n }\n }\n }\n }\n\n public setStatusChangeHandler(handler: StatusChangeHandler): void {\n this.onStatusChange = handler;\n }\n\n public register(config: ServiceConfig): void {\n this.configs.set(config.name, config);\n this.states.set(config.name, {\n name: config.name,\n status: 'stopped',\n restartCount: 0,\n });\n }\n\n public addLog(source: string, level: SupervisorLog['level'], message: string): void {\n this.logs.push({\n timestamp: new Date().toISOString(),\n level,\n source,\n message,\n });\n\n if (this.logs.length > MAX_LOGS) {\n this.logs.splice(0, this.logs.length - MAX_LOGS);\n }\n }\n\n public getLogs(filters?: {\n level?: string;\n source?: string;\n limit?: number;\n }): SupervisorLog[] {\n let rows = this.logs;\n\n if (filters?.level) {\n rows = rows.filter((item) => item.level === filters.level);\n }\n if (filters?.source) {\n rows = rows.filter((item) => item.source === filters.source);\n }\n\n const limit = filters?.limit;\n if (typeof limit === 'number' && Number.isFinite(limit) && limit > 0) {\n return rows.slice(-limit);\n }\n\n return rows;\n }\n\n public async startAll(): Promise<void> {\n for (const name of this.configs.keys()) {\n this.start(name);\n }\n }\n\n public async stopAll(): Promise<void> {\n this.isShuttingDown = true;\n const promises: Promise<void>[] = [];\n for (const name of this.processes.keys()) {\n promises.push(this.stop(name));\n }\n await Promise.all(promises);\n }\n\n public start(name: string): void {\n const config = this.configs.get(name);\n const state = this.states.get(name);\n if (!config || !state) return;\n\n if (state.status === 'running' || state.status === 'starting') return;\n\n console.log(`[Supervisor] Starting ${name}...`);\n this.addLog(name, 'info', 'Service starting');\n this.updateState(name, { status: 'starting', startTime: Date.now() });\n\n const env = { ...process.env, ...config.env };\n\n const child = spawn(config.command, config.args, {\n stdio: ['ignore', 'pipe', 'pipe'],\n env,\n cwd: config.cwd || process.cwd(),\n detached: false,\n });\n\n this.processes.set(name, child);\n this.updateState(name, { status: 'running', pid: child.pid });\n\n const prefixLog = (source: string, data: Buffer, isError = false): void => {\n const output = data.toString();\n const lines = output.split('\\n');\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) {\n continue;\n }\n\n if (isError) {\n console.error(`[${source}] ${trimmed}`);\n this.addLog(source, 'error', trimmed);\n } else {\n console.log(`[${source}] ${trimmed}`);\n this.addLog(source, 'info', trimmed);\n }\n }\n };\n\n child.stdout?.on('data', (data) => {\n prefixLog(name, data, false);\n });\n\n child.stderr?.on('data', (data) => {\n prefixLog(name, data, true);\n });\n\n child.on('error', (err) => {\n console.error(`[Supervisor] Error spawning ${name}:`, err);\n this.addLog(name, 'error', `Spawn error: ${String(err)}`);\n this.updateState(name, { status: 'crashed' });\n });\n\n child.on('exit', (code, signal) => {\n console.log(`[Supervisor] ${name} exited with code ${code} signal ${signal}`);\n this.addLog(name, code === 0 ? 'info' : 'error', `Exited with code ${code ?? 'null'} signal ${signal ?? 'null'}`);\n const currentState = this.states.get(name);\n const wasManualStop = currentState?.status === 'stopped';\n\n this.updateState(name, {\n status: 'stopped',\n lastExitCode: code ?? undefined,\n pid: undefined,\n });\n this.processes.delete(name);\n\n // Auto-restart on crash (not on manual stop or shutdown)\n if (code !== 0 && !wasManualStop && !this.isShuttingDown) {\n const newState = this.states.get(name);\n const restartCount = (newState?.restartCount || 0) + 1;\n\n if (restartCount <= MAX_RESTARTS) {\n this.updateState(name, { restartCount });\n console.log(`[Supervisor] Restarting ${name} in 2s... (attempt ${restartCount}/${MAX_RESTARTS})`);\n this.addLog(name, 'warn', `Restarting in 2s (attempt ${restartCount}/${MAX_RESTARTS})`);\n setTimeout(() => this.start(name), 2000);\n } else {\n console.error(`[Supervisor] ${name} exceeded max restarts (${MAX_RESTARTS}), giving up`);\n this.addLog(name, 'error', `Exceeded max restarts (${MAX_RESTARTS})`);\n }\n }\n });\n }\n\n public stop(name: string): Promise<void> {\n return new Promise((resolve) => {\n const child = this.processes.get(name);\n if (!child || !child.pid) {\n resolve();\n return;\n }\n\n // Mark as stopped first to prevent auto-restart\n this.updateState(name, { status: 'stopped' });\n this.addLog(name, 'info', 'Stopping service');\n\n kill(child.pid, 'SIGTERM', (err) => {\n if (err) {\n console.error(`[Supervisor] Failed to kill ${name}:`, err);\n this.addLog(name, 'error', `Failed to stop: ${String(err)}`);\n }\n resolve();\n });\n });\n }\n\n public getStatus(name: string): ServiceState | undefined {\n const state = this.states.get(name);\n if (state && state.status === 'running' && state.startTime) {\n return { ...state, uptime: Date.now() - state.startTime };\n }\n return state;\n }\n\n public getAllStatus(): ServiceState[] {\n return Array.from(this.states.values()).map((s) => {\n if (s.status === 'running' && s.startTime) {\n return { ...s, uptime: Date.now() - s.startTime };\n }\n return s;\n });\n }\n\n private updateState(name: string, update: Partial<ServiceState>): void {\n const state = this.states.get(name);\n if (state) {\n Object.assign(state, update);\n this.onStatusChange?.(name, { ...state });\n }\n }\n}\n"]}
1
+ {"version":3,"file":"Supervisor.js","sourceRoot":"","sources":["../../src/supervisor/Supervisor.ts"],"names":[],"mappings":"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","sourcesContent":["import { spawn, type ChildProcess } from 'node:child_process';\nimport kill from 'tree-kill';\nimport type { ServiceConfig, ServiceState, ServiceStatus, StatusChangeHandler } from './types';\n\nconst MAX_RESTARTS = 5;\nconst MAX_LOGS = 500;\n\nexport interface SupervisorLog {\n timestamp: string;\n level: 'info' | 'warn' | 'error';\n source: string;\n message: string;\n}\n\nexport class Supervisor {\n private processes: Map<string, ChildProcess> = new Map();\n private managedStops: Map<string, () => Promise<void>> = new Map();\n private states: Map<string, ServiceState> = new Map();\n private configs: Map<string, ServiceConfig> = new Map();\n private logs: SupervisorLog[] = [];\n private onStatusChange?: StatusChangeHandler;\n private isShuttingDown = false;\n\n constructor(options: { handleProcessSignals?: boolean } = {}) {\n if (options.handleProcessSignals === false) {\n return;\n }\n\n // 确保父进程退出时清理所有子进程\n process.on('exit', () => this.killAll());\n process.on('SIGINT', () => this.shutdown('SIGINT'));\n process.on('SIGTERM', () => this.shutdown('SIGTERM'));\n }\n\n private async shutdown(signal: string): Promise<void> {\n if (this.isShuttingDown) return;\n this.isShuttingDown = true;\n console.log(`[Supervisor] Received ${signal}, stopping all services...`);\n await this.stopAll();\n process.exit(0);\n }\n\n private killAll(): void {\n // 同步杀掉所有子进程(用于 process.on('exit'))\n for (const [, child] of this.processes) {\n if (child.pid) {\n try {\n process.kill(child.pid, 'SIGKILL');\n } catch {\n // 进程可能已经退出\n }\n }\n }\n }\n\n public setStatusChangeHandler(handler: StatusChangeHandler): void {\n this.onStatusChange = handler;\n }\n\n public register(config: ServiceConfig): void {\n this.configs.set(config.name, config);\n this.states.set(config.name, {\n name: config.name,\n status: 'stopped',\n restartCount: 0,\n });\n }\n\n public registerManaged(name: string, stop?: () => Promise<void> | void): void {\n if (!this.states.has(name)) {\n this.states.set(name, {\n name,\n status: 'stopped',\n restartCount: 0,\n });\n }\n\n if (stop) {\n this.managedStops.set(name, async() => {\n await stop();\n });\n }\n }\n\n public setStatus(name: string, status: ServiceStatus, extra?: Partial<ServiceState>): void {\n if (!this.states.has(name)) {\n this.registerManaged(name);\n }\n\n this.updateState(name, {\n status,\n ...extra,\n });\n }\n\n public addLog(source: string, level: SupervisorLog['level'], message: string): void {\n this.logs.push({\n timestamp: new Date().toISOString(),\n level,\n source,\n message,\n });\n\n if (this.logs.length > MAX_LOGS) {\n this.logs.splice(0, this.logs.length - MAX_LOGS);\n }\n }\n\n public getLogs(filters?: {\n level?: string;\n source?: string;\n limit?: number;\n }): SupervisorLog[] {\n let rows = this.logs;\n\n if (filters?.level) {\n rows = rows.filter((item) => item.level === filters.level);\n }\n if (filters?.source) {\n rows = rows.filter((item) => item.source === filters.source);\n }\n\n const limit = filters?.limit;\n if (typeof limit === 'number' && Number.isFinite(limit) && limit > 0) {\n return rows.slice(-limit);\n }\n\n return rows;\n }\n\n public async startAll(): Promise<void> {\n for (const name of this.configs.keys()) {\n this.start(name);\n }\n }\n\n public async stopAll(): Promise<void> {\n this.isShuttingDown = true;\n const promises: Promise<void>[] = [];\n for (const name of this.processes.keys()) {\n promises.push(this.stop(name));\n }\n for (const [ name, stop ] of this.managedStops) {\n promises.push(stop().catch((error) => {\n this.addLog(name, 'error', `Failed to stop managed service: ${String(error)}`);\n }));\n }\n await Promise.all(promises);\n }\n\n public start(name: string): void {\n const config = this.configs.get(name);\n const state = this.states.get(name);\n if (!config || !state) return;\n\n if (state.status === 'running' || state.status === 'starting') return;\n\n console.log(`[Supervisor] Starting ${name}...`);\n this.addLog(name, 'info', 'Service starting');\n this.updateState(name, { status: 'starting', startTime: Date.now() });\n\n const env = { ...process.env, ...config.env };\n\n const child = spawn(config.command, config.args, {\n stdio: ['ignore', 'pipe', 'pipe'],\n env,\n cwd: config.cwd || process.cwd(),\n detached: false,\n });\n\n this.processes.set(name, child);\n this.updateState(name, { status: 'running', pid: child.pid });\n\n const prefixLog = (source: string, data: Buffer, isError = false): void => {\n const output = data.toString();\n const lines = output.split('\\n');\n for (const line of lines) {\n const trimmed = line.trim();\n if (!trimmed) {\n continue;\n }\n\n if (isError) {\n console.error(`[${source}] ${trimmed}`);\n this.addLog(source, 'error', trimmed);\n } else {\n console.log(`[${source}] ${trimmed}`);\n this.addLog(source, 'info', trimmed);\n }\n }\n };\n\n child.stdout?.on('data', (data) => {\n prefixLog(name, data, false);\n });\n\n child.stderr?.on('data', (data) => {\n prefixLog(name, data, true);\n });\n\n child.on('error', (err) => {\n console.error(`[Supervisor] Error spawning ${name}:`, err);\n this.addLog(name, 'error', `Spawn error: ${String(err)}`);\n this.updateState(name, { status: 'crashed' });\n });\n\n child.on('exit', (code, signal) => {\n console.log(`[Supervisor] ${name} exited with code ${code} signal ${signal}`);\n this.addLog(name, code === 0 ? 'info' : 'error', `Exited with code ${code ?? 'null'} signal ${signal ?? 'null'}`);\n const currentState = this.states.get(name);\n const wasManualStop = currentState?.status === 'stopped';\n\n this.updateState(name, {\n status: 'stopped',\n lastExitCode: code ?? undefined,\n pid: undefined,\n });\n this.processes.delete(name);\n\n // Auto-restart on crash (not on manual stop or shutdown)\n if (code !== 0 && !wasManualStop && !this.isShuttingDown) {\n const newState = this.states.get(name);\n const restartCount = (newState?.restartCount || 0) + 1;\n\n if (restartCount <= MAX_RESTARTS) {\n this.updateState(name, { restartCount });\n console.log(`[Supervisor] Restarting ${name} in 2s... (attempt ${restartCount}/${MAX_RESTARTS})`);\n this.addLog(name, 'warn', `Restarting in 2s (attempt ${restartCount}/${MAX_RESTARTS})`);\n setTimeout(() => this.start(name), 2000);\n } else {\n console.error(`[Supervisor] ${name} exceeded max restarts (${MAX_RESTARTS}), giving up`);\n this.addLog(name, 'error', `Exceeded max restarts (${MAX_RESTARTS})`);\n }\n }\n });\n }\n\n public stop(name: string): Promise<void> {\n return new Promise((resolve) => {\n const child = this.processes.get(name);\n if (!child || !child.pid) {\n resolve();\n return;\n }\n\n // Mark as stopped first to prevent auto-restart\n this.updateState(name, { status: 'stopped' });\n this.addLog(name, 'info', 'Stopping service');\n\n kill(child.pid, 'SIGTERM', (err) => {\n if (err) {\n console.error(`[Supervisor] Failed to kill ${name}:`, err);\n this.addLog(name, 'error', `Failed to stop: ${String(err)}`);\n }\n resolve();\n });\n });\n }\n\n public getStatus(name: string): ServiceState | undefined {\n const state = this.states.get(name);\n if (state && state.status === 'running' && state.startTime) {\n return { ...state, uptime: Date.now() - state.startTime };\n }\n return state;\n }\n\n public getAllStatus(): ServiceState[] {\n return Array.from(this.states.values()).map((s) => {\n if (s.status === 'running' && s.startTime) {\n return { ...s, uptime: Date.now() - s.startTime };\n }\n return s;\n });\n }\n\n private updateState(name: string, update: Partial<ServiceState>): void {\n const state = this.states.get(name);\n if (state) {\n Object.assign(state, update);\n this.onStatusChange?.(name, { ...state });\n }\n }\n}\n"]}
@@ -5,7 +5,7 @@
5
5
  *
6
6
  * 任务存储在 Pod 的 /tasks/{YYYY-MM-DD}.ttl 中,按天分片
7
7
  */
8
- import type { SolidDatabase } from 'drizzle-solid';
8
+ import type { SolidDatabase } from '@undefineds.co/drizzle-solid';
9
9
  import { Task as taskTable } from './schema';
10
10
  import type { Task, TaskStatus, CreateTaskInput, TaskQueue, TaskQueueStats, ListTasksOptions } from './types';
11
11
  export interface DrizzleTaskQueueOptions {
@@ -10,7 +10,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
10
10
  exports.DrizzleTaskQueue = void 0;
11
11
  const global_logger_factory_1 = require("global-logger-factory");
12
12
  const crypto_1 = require("crypto");
13
- const drizzle_solid_1 = require("drizzle-solid");
13
+ const drizzle_solid_1 = require("@undefineds.co/drizzle-solid");
14
14
  const schema_1 = require("./schema");
15
15
  /**
16
16
  * 基于 drizzle-solid 的任务队列实现
@@ -1 +1 @@
1
- {"version":3,"file":"DrizzleTaskQueue.js","sourceRoot":"","sources":["../../src/task/DrizzleTaskQueue.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * DrizzleTaskQueue - 基于 drizzle-solid 的任务队列\n *\n * 简化模型:消息 + Agent\n *\n * 任务存储在 Pod 的 /tasks/{YYYY-MM-DD}.ttl 中,按天分片\n */\n\nimport { getLoggerFor } from 'global-logger-factory';\nimport { randomBytes } from 'crypto';\nimport { eq } from 'drizzle-solid';\nimport type { SolidDatabase } from 'drizzle-solid';\n\nimport { Task as taskTable, TaskStatus as TaskStatusConst } from './schema';\nimport type {\n Task,\n TaskStatus,\n CreateTaskInput,\n TaskQueue,\n TaskQueueStats,\n ListTasksOptions,\n} from './types';\n\nexport interface DrizzleTaskQueueOptions {\n /**\n * Pod base URL\n */\n podBaseUrl: string;\n /**\n * drizzle-solid 数据库实例\n */\n db: SolidDatabase<{ task: typeof taskTable }>;\n}\n\n/**\n * 基于 drizzle-solid 的任务队列实现\n */\nexport class DrizzleTaskQueue implements TaskQueue {\n protected readonly logger = getLoggerFor(this);\n private readonly podBaseUrl: string;\n private readonly db: SolidDatabase<{ task: typeof taskTable }>;\n\n public constructor(options: DrizzleTaskQueueOptions) {\n this.podBaseUrl = options.podBaseUrl.endsWith('/') ? options.podBaseUrl : `${options.podBaseUrl}/`;\n this.db = options.db;\n }\n\n /**\n * 创建任务\n */\n public async createTask(input: CreateTaskInput): Promise<Task> {\n const id = this.generateTaskId();\n const now = new Date();\n\n const taskData = {\n id,\n agent: input.agent,\n message: input.message,\n status: TaskStatusConst.PENDING,\n createdAt: now,\n };\n\n await this.db.insert(taskTable).values(taskData);\n\n this.logger.info(`Created task ${id} for agent \"${input.agent}\"`);\n\n return {\n id,\n agent: input.agent,\n message: input.message,\n status: 'pending',\n createdAt: now,\n };\n }\n\n /**\n * 获取任务\n */\n public async getTask(taskId: string): Promise<Task | null> {\n const tasks = await this.db.select().from(taskTable).where(eq(taskTable.id, taskId));\n\n if (tasks.length === 0) {\n return null;\n }\n\n return this.dbTaskToTask(tasks[0]);\n }\n\n /**\n * 获取任务列表\n */\n public async listTasks(options?: ListTasksOptions): Promise<Task[]> {\n let query = this.db.select().from(taskTable);\n\n // 状态过滤\n if (options?.status) {\n query = query.where(eq(taskTable.status, options.status));\n }\n\n const tasks = await query;\n\n // 转换为 Task 接口\n let result = tasks.map((t: Record<string, unknown>) => this.dbTaskToTask(t));\n\n // Agent 过滤\n if (options?.agent) {\n result = result.filter((t: Task) => t.agent === options.agent);\n }\n\n // 排序\n if (options?.orderBy) {\n const order = options.order === 'asc' ? 1 : -1;\n result.sort((a: Task, b: Task) => {\n const aVal = a[options.orderBy!];\n const bVal = b[options.orderBy!];\n if (aVal instanceof Date && bVal instanceof Date) {\n return (aVal.getTime() - bVal.getTime()) * order;\n }\n return 0;\n });\n }\n\n // 分页\n const offset = options?.offset ?? 0;\n const limit = options?.limit ?? result.length;\n return result.slice(offset, offset + limit);\n }\n\n /**\n * 更新任务状态\n */\n public async updateTaskStatus(\n taskId: string,\n status: TaskStatus,\n updates?: Partial<Task>,\n ): Promise<void> {\n const now = new Date();\n\n const updateData: Record<string, unknown> = {\n status,\n };\n\n // 根据状态设置时间字段\n if (status === 'running') {\n updateData.startedAt = now;\n } else if (status === 'completed' || status === 'failed') {\n updateData.completedAt = now;\n }\n\n // 合并其他更新\n if (updates) {\n if (updates.result !== undefined) updateData.result = updates.result;\n if (updates.error !== undefined) updateData.error = updates.error;\n }\n\n await this.db.update(taskTable).set(updateData).where(eq(taskTable.id, taskId));\n\n this.logger.info(`Task ${taskId} status changed to ${status}`);\n }\n\n /**\n * 删除任务\n */\n public async deleteTask(taskId: string): Promise<void> {\n await this.db.delete(taskTable).where(eq(taskTable.id, taskId));\n this.logger.info(`Deleted task ${taskId}`);\n }\n\n /**\n * 获取队列统计\n */\n public async getStats(): Promise<TaskQueueStats> {\n const tasks = await this.db.select().from(taskTable);\n\n const stats: TaskQueueStats = {\n pending: 0,\n running: 0,\n completed: 0,\n failed: 0,\n total: tasks.length,\n byAgent: {},\n };\n\n for (const task of tasks) {\n const taskRecord = task as Record<string, unknown>;\n const status = (taskRecord.status as TaskStatus) ?? 'pending';\n stats[status]++;\n\n // 按 Agent 统计\n const agent = taskRecord.agent as string ?? 'unknown';\n stats.byAgent[agent] = (stats.byAgent[agent] ?? 0) + 1;\n }\n\n return stats;\n }\n\n // ============================================\n // Private Methods\n // ============================================\n\n private generateTaskId(): string {\n const timestamp = Date.now().toString(36);\n const random = randomBytes(4).toString('hex');\n return `task-${timestamp}-${random}`;\n }\n\n /**\n * 将数据库记录转换为 Task 接口\n */\n private dbTaskToTask(dbTask: Record<string, unknown>): Task {\n return {\n id: dbTask.id as string,\n agent: dbTask.agent as string,\n message: dbTask.message as string,\n status: (dbTask.status as TaskStatus) ?? 'pending',\n createdAt: dbTask.createdAt as Date,\n startedAt: dbTask.startedAt as Date | undefined,\n completedAt: dbTask.completedAt as Date | undefined,\n result: dbTask.result as unknown,\n error: dbTask.error as string | undefined,\n };\n }\n}\n"]}
1
+ {"version":3,"file":"DrizzleTaskQueue.js","sourceRoot":"","sources":["../../src/task/DrizzleTaskQueue.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * DrizzleTaskQueue - 基于 drizzle-solid 的任务队列\n *\n * 简化模型:消息 + Agent\n *\n * 任务存储在 Pod 的 /tasks/{YYYY-MM-DD}.ttl 中,按天分片\n */\n\nimport { getLoggerFor } from 'global-logger-factory';\nimport { randomBytes } from 'crypto';\nimport { eq } from '@undefineds.co/drizzle-solid';\nimport type { SolidDatabase } from '@undefineds.co/drizzle-solid';\n\nimport { Task as taskTable, TaskStatus as TaskStatusConst } from './schema';\nimport type {\n Task,\n TaskStatus,\n CreateTaskInput,\n TaskQueue,\n TaskQueueStats,\n ListTasksOptions,\n} from './types';\n\nexport interface DrizzleTaskQueueOptions {\n /**\n * Pod base URL\n */\n podBaseUrl: string;\n /**\n * drizzle-solid 数据库实例\n */\n db: SolidDatabase<{ task: typeof taskTable }>;\n}\n\n/**\n * 基于 drizzle-solid 的任务队列实现\n */\nexport class DrizzleTaskQueue implements TaskQueue {\n protected readonly logger = getLoggerFor(this);\n private readonly podBaseUrl: string;\n private readonly db: SolidDatabase<{ task: typeof taskTable }>;\n\n public constructor(options: DrizzleTaskQueueOptions) {\n this.podBaseUrl = options.podBaseUrl.endsWith('/') ? options.podBaseUrl : `${options.podBaseUrl}/`;\n this.db = options.db;\n }\n\n /**\n * 创建任务\n */\n public async createTask(input: CreateTaskInput): Promise<Task> {\n const id = this.generateTaskId();\n const now = new Date();\n\n const taskData = {\n id,\n agent: input.agent,\n message: input.message,\n status: TaskStatusConst.PENDING,\n createdAt: now,\n };\n\n await this.db.insert(taskTable).values(taskData);\n\n this.logger.info(`Created task ${id} for agent \"${input.agent}\"`);\n\n return {\n id,\n agent: input.agent,\n message: input.message,\n status: 'pending',\n createdAt: now,\n };\n }\n\n /**\n * 获取任务\n */\n public async getTask(taskId: string): Promise<Task | null> {\n const tasks = await this.db.select().from(taskTable).where(eq(taskTable.id, taskId));\n\n if (tasks.length === 0) {\n return null;\n }\n\n return this.dbTaskToTask(tasks[0]);\n }\n\n /**\n * 获取任务列表\n */\n public async listTasks(options?: ListTasksOptions): Promise<Task[]> {\n let query = this.db.select().from(taskTable);\n\n // 状态过滤\n if (options?.status) {\n query = query.where(eq(taskTable.status, options.status));\n }\n\n const tasks = await query;\n\n // 转换为 Task 接口\n let result = tasks.map((t: Record<string, unknown>) => this.dbTaskToTask(t));\n\n // Agent 过滤\n if (options?.agent) {\n result = result.filter((t: Task) => t.agent === options.agent);\n }\n\n // 排序\n if (options?.orderBy) {\n const order = options.order === 'asc' ? 1 : -1;\n result.sort((a: Task, b: Task) => {\n const aVal = a[options.orderBy!];\n const bVal = b[options.orderBy!];\n if (aVal instanceof Date && bVal instanceof Date) {\n return (aVal.getTime() - bVal.getTime()) * order;\n }\n return 0;\n });\n }\n\n // 分页\n const offset = options?.offset ?? 0;\n const limit = options?.limit ?? result.length;\n return result.slice(offset, offset + limit);\n }\n\n /**\n * 更新任务状态\n */\n public async updateTaskStatus(\n taskId: string,\n status: TaskStatus,\n updates?: Partial<Task>,\n ): Promise<void> {\n const now = new Date();\n\n const updateData: Record<string, unknown> = {\n status,\n };\n\n // 根据状态设置时间字段\n if (status === 'running') {\n updateData.startedAt = now;\n } else if (status === 'completed' || status === 'failed') {\n updateData.completedAt = now;\n }\n\n // 合并其他更新\n if (updates) {\n if (updates.result !== undefined) updateData.result = updates.result;\n if (updates.error !== undefined) updateData.error = updates.error;\n }\n\n await this.db.update(taskTable).set(updateData).where(eq(taskTable.id, taskId));\n\n this.logger.info(`Task ${taskId} status changed to ${status}`);\n }\n\n /**\n * 删除任务\n */\n public async deleteTask(taskId: string): Promise<void> {\n await this.db.delete(taskTable).where(eq(taskTable.id, taskId));\n this.logger.info(`Deleted task ${taskId}`);\n }\n\n /**\n * 获取队列统计\n */\n public async getStats(): Promise<TaskQueueStats> {\n const tasks = await this.db.select().from(taskTable);\n\n const stats: TaskQueueStats = {\n pending: 0,\n running: 0,\n completed: 0,\n failed: 0,\n total: tasks.length,\n byAgent: {},\n };\n\n for (const task of tasks) {\n const taskRecord = task as Record<string, unknown>;\n const status = (taskRecord.status as TaskStatus) ?? 'pending';\n stats[status]++;\n\n // 按 Agent 统计\n const agent = taskRecord.agent as string ?? 'unknown';\n stats.byAgent[agent] = (stats.byAgent[agent] ?? 0) + 1;\n }\n\n return stats;\n }\n\n // ============================================\n // Private Methods\n // ============================================\n\n private generateTaskId(): string {\n const timestamp = Date.now().toString(36);\n const random = randomBytes(4).toString('hex');\n return `task-${timestamp}-${random}`;\n }\n\n /**\n * 将数据库记录转换为 Task 接口\n */\n private dbTaskToTask(dbTask: Record<string, unknown>): Task {\n return {\n id: dbTask.id as string,\n agent: dbTask.agent as string,\n message: dbTask.message as string,\n status: (dbTask.status as TaskStatus) ?? 'pending',\n createdAt: dbTask.createdAt as Date,\n startedAt: dbTask.startedAt as Date | undefined,\n completedAt: dbTask.completedAt as Date | undefined,\n result: dbTask.result as unknown,\n error: dbTask.error as string | undefined,\n };\n }\n}\n"]}
@@ -32,16 +32,16 @@ export type TaskStatusType = (typeof TaskStatus)[keyof typeof TaskStatus];
32
32
  * udfs:status "pending" ;
33
33
  * udfs:createdAt "2026-01-09T10:00:00Z"^^xsd:dateTime .
34
34
  */
35
- export declare const Task: import("drizzle-solid/dist/core/schema").PodTableWithColumns<import("drizzle-solid/dist/core/schema").ResolvedColumns<{
36
- id: import("drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
37
- agent: import("drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
38
- message: import("drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
39
- status: import("drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
40
- createdAt: import("drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, false, false>;
41
- startedAt: import("drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, false, false>;
42
- completedAt: import("drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, false, false>;
43
- result: import("drizzle-solid/dist/core/schema").ColumnBuilder<"json", null, false, false>;
44
- error: import("drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
35
+ export declare const Task: import("@undefineds.co/drizzle-solid/dist/core/schema").PodTableWithColumns<import("@undefineds.co/drizzle-solid/dist/core/schema").ResolvedColumns<{
36
+ id: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, true, false>;
37
+ agent: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
38
+ message: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
39
+ status: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
40
+ createdAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, false, false>;
41
+ startedAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, false, false>;
42
+ completedAt: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"datetime", null, false, false>;
43
+ result: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"json", null, false, false>;
44
+ error: import("@undefineds.co/drizzle-solid/dist/core/schema").ColumnBuilder<"string", null, false, false>;
45
45
  }>>;
46
46
  /**
47
47
  * 获取今天的任务文件路径
@@ -15,7 +15,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
15
15
  exports.Task = exports.TaskStatus = void 0;
16
16
  exports.getTodayTaskPath = getTodayTaskPath;
17
17
  exports.getTaskPathForDate = getTaskPathForDate;
18
- const drizzle_solid_1 = require("drizzle-solid");
18
+ const drizzle_solid_1 = require("@undefineds.co/drizzle-solid");
19
19
  const vocab_1 = require("../vocab");
20
20
  /**
21
21
  * 任务状态
@@ -1 +1 @@
1
- {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/task/schema.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;AAqDH,4CAGC;AAKD,gDAGC;AA9DD,iDAAiE;AACjE,oCAAgD;AAEhD;;GAEG;AACU,QAAA,UAAU,GAAG;IACxB,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,WAAW;IACtB,MAAM,EAAE,QAAQ;CACR,CAAC;AAIX;;;;;;;;;;;GAWG;AACU,QAAA,IAAI,GAAG,IAAA,wBAAQ,EAC1B,MAAM,EACN;IACE,EAAE,EAAE,IAAA,sBAAM,EAAC,IAAI,CAAC,CAAC,UAAU,EAAE;IAC7B,KAAK,EAAE,IAAA,sBAAM,EAAC,OAAO,CAAC;IACtB,OAAO,EAAE,IAAA,sBAAM,EAAC,SAAS,CAAC;IAC1B,MAAM,EAAE,IAAA,sBAAM,EAAC,QAAQ,CAAC;IACxB,SAAS,EAAE,IAAA,wBAAQ,EAAC,WAAW,CAAC;IAChC,SAAS,EAAE,IAAA,wBAAQ,EAAC,WAAW,CAAC;IAChC,WAAW,EAAE,IAAA,wBAAQ,EAAC,aAAa,CAAC;IACpC,MAAM,EAAE,IAAA,oBAAI,EAAC,QAAQ,CAAC;IACtB,KAAK,EAAE,IAAA,sBAAM,EAAC,OAAO,CAAC;CACvB,EACD;IACE,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,YAAI,CAAC,IAAI;IACf,SAAS,EAAE,sBAAc;IACzB,eAAe,EAAE,OAAO;CACzB,CACF,CAAC;AAEF;;GAEG;AACH,SAAgB,gBAAgB;IAC9B,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,OAAO,UAAU,KAAK,MAAM,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,SAAgB,kBAAkB,CAAC,IAAU;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,OAAO,UAAU,OAAO,MAAM,CAAC;AACjC,CAAC","sourcesContent":["/**\n * Task Schema - Pod RDF 表定义\n *\n * 简化模型:消息 + Agent\n *\n * 任务系统只负责:\n * - 接收任务 (agent + message)\n * - 调度执行\n * - 记录状态\n *\n * 具体怎么处理、用什么工具、做到什么程度,全部由 Agent 自己决定。\n */\n\nimport { podTable, string, datetime, json } from 'drizzle-solid';\nimport { UDFS, UDFS_NAMESPACE } from '../vocab';\n\n/**\n * 任务状态\n */\nexport const TaskStatus = {\n PENDING: 'pending',\n RUNNING: 'running',\n COMPLETED: 'completed',\n FAILED: 'failed',\n} as const;\n\nexport type TaskStatusType = (typeof TaskStatus)[keyof typeof TaskStatus];\n\n/**\n * Task - 任务实例\n *\n * 存储位置: /tasks/{YYYY-MM-DD}.ttl (按天分片)\n *\n * RDF 示例:\n * <#task-abc123> a udfs:Task ;\n * udfs:agent \"indexing\" ;\n * udfs:message \"用户在 </docs/> 上传了文件 </docs/report.pdf>\" ;\n * udfs:status \"pending\" ;\n * udfs:createdAt \"2026-01-09T10:00:00Z\"^^xsd:dateTime .\n */\nexport const Task = podTable(\n 'Task',\n {\n id: string('id').primaryKey(),\n agent: string('agent'),\n message: string('message'),\n status: string('status'),\n createdAt: datetime('createdAt'),\n startedAt: datetime('startedAt'),\n completedAt: datetime('completedAt'),\n result: json('result'),\n error: string('error'),\n },\n {\n base: '/tasks/',\n type: UDFS.Task,\n namespace: UDFS_NAMESPACE,\n subjectTemplate: '#{id}',\n },\n);\n\n/**\n * 获取今天的任务文件路径\n */\nexport function getTodayTaskPath(): string {\n const today = new Date().toISOString().split('T')[0];\n return `/tasks/${today}.ttl`;\n}\n\n/**\n * 获取指定日期的任务文件路径\n */\nexport function getTaskPathForDate(date: Date): string {\n const dateStr = date.toISOString().split('T')[0];\n return `/tasks/${dateStr}.ttl`;\n}\n\n"]}
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/task/schema.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;GAWG;;;AAqDH,4CAGC;AAKD,gDAGC;AA9DD,gEAAgF;AAChF,oCAAgD;AAEhD;;GAEG;AACU,QAAA,UAAU,GAAG;IACxB,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,SAAS;IAClB,SAAS,EAAE,WAAW;IACtB,MAAM,EAAE,QAAQ;CACR,CAAC;AAIX;;;;;;;;;;;GAWG;AACU,QAAA,IAAI,GAAG,IAAA,wBAAQ,EAC1B,MAAM,EACN;IACE,EAAE,EAAE,IAAA,sBAAM,EAAC,IAAI,CAAC,CAAC,UAAU,EAAE;IAC7B,KAAK,EAAE,IAAA,sBAAM,EAAC,OAAO,CAAC;IACtB,OAAO,EAAE,IAAA,sBAAM,EAAC,SAAS,CAAC;IAC1B,MAAM,EAAE,IAAA,sBAAM,EAAC,QAAQ,CAAC;IACxB,SAAS,EAAE,IAAA,wBAAQ,EAAC,WAAW,CAAC;IAChC,SAAS,EAAE,IAAA,wBAAQ,EAAC,WAAW,CAAC;IAChC,WAAW,EAAE,IAAA,wBAAQ,EAAC,aAAa,CAAC;IACpC,MAAM,EAAE,IAAA,oBAAI,EAAC,QAAQ,CAAC;IACtB,KAAK,EAAE,IAAA,sBAAM,EAAC,OAAO,CAAC;CACvB,EACD;IACE,IAAI,EAAE,SAAS;IACf,IAAI,EAAE,YAAI,CAAC,IAAI;IACf,SAAS,EAAE,sBAAc;IACzB,eAAe,EAAE,OAAO;CACzB,CACF,CAAC;AAEF;;GAEG;AACH,SAAgB,gBAAgB;IAC9B,MAAM,KAAK,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACrD,OAAO,UAAU,KAAK,MAAM,CAAC;AAC/B,CAAC;AAED;;GAEG;AACH,SAAgB,kBAAkB,CAAC,IAAU;IAC3C,MAAM,OAAO,GAAG,IAAI,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACjD,OAAO,UAAU,OAAO,MAAM,CAAC;AACjC,CAAC","sourcesContent":["/**\n * Task Schema - Pod RDF 表定义\n *\n * 简化模型:消息 + Agent\n *\n * 任务系统只负责:\n * - 接收任务 (agent + message)\n * - 调度执行\n * - 记录状态\n *\n * 具体怎么处理、用什么工具、做到什么程度,全部由 Agent 自己决定。\n */\n\nimport { podTable, string, datetime, json } from '@undefineds.co/drizzle-solid';\nimport { UDFS, UDFS_NAMESPACE } from '../vocab';\n\n/**\n * 任务状态\n */\nexport const TaskStatus = {\n PENDING: 'pending',\n RUNNING: 'running',\n COMPLETED: 'completed',\n FAILED: 'failed',\n} as const;\n\nexport type TaskStatusType = (typeof TaskStatus)[keyof typeof TaskStatus];\n\n/**\n * Task - 任务实例\n *\n * 存储位置: /tasks/{YYYY-MM-DD}.ttl (按天分片)\n *\n * RDF 示例:\n * <#task-abc123> a udfs:Task ;\n * udfs:agent \"indexing\" ;\n * udfs:message \"用户在 </docs/> 上传了文件 </docs/report.pdf>\" ;\n * udfs:status \"pending\" ;\n * udfs:createdAt \"2026-01-09T10:00:00Z\"^^xsd:dateTime .\n */\nexport const Task = podTable(\n 'Task',\n {\n id: string('id').primaryKey(),\n agent: string('agent'),\n message: string('message'),\n status: string('status'),\n createdAt: datetime('createdAt'),\n startedAt: datetime('startedAt'),\n completedAt: datetime('completedAt'),\n result: json('result'),\n error: string('error'),\n },\n {\n base: '/tasks/',\n type: UDFS.Task,\n namespace: UDFS_NAMESPACE,\n subjectTemplate: '#{id}',\n },\n);\n\n/**\n * 获取今天的任务文件路径\n */\nexport function getTodayTaskPath(): string {\n const today = new Date().toISOString().split('T')[0];\n return `/tasks/${today}.ttl`;\n}\n\n/**\n * 获取指定日期的任务文件路径\n */\nexport function getTaskPathForDate(date: Date): string {\n const dateStr = date.toISOString().split('T')[0];\n return `/tasks/${dateStr}.ttl`;\n}\n\n"]}
@@ -0,0 +1,4 @@
1
+ export { startNoAuthXpod } from './no-auth-xpod';
2
+ export type { NoAuthXpodOptions } from './no-auth-xpod';
3
+ export { seedPod } from './seed-pod';
4
+ export type { SeedPodOptions } from './seed-pod';
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.seedPod = exports.startNoAuthXpod = void 0;
4
+ var no_auth_xpod_1 = require("./no-auth-xpod");
5
+ Object.defineProperty(exports, "startNoAuthXpod", { enumerable: true, get: function () { return no_auth_xpod_1.startNoAuthXpod; } });
6
+ var seed_pod_1 = require("./seed-pod");
7
+ Object.defineProperty(exports, "seedPod", { enumerable: true, get: function () { return seed_pod_1.seedPod; } });
8
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/test-utils/index.ts"],"names":[],"mappings":";;;AAAA,+CAAiD;AAAxC,+GAAA,eAAe,OAAA;AAExB,uCAAqC;AAA5B,mGAAA,OAAO,OAAA","sourcesContent":["export { startNoAuthXpod } from './no-auth-xpod';\nexport type { NoAuthXpodOptions } from './no-auth-xpod';\nexport { seedPod } from './seed-pod';\nexport type { SeedPodOptions } from './seed-pod';\n"]}
@@ -0,0 +1,11 @@
1
+ export interface NoAuthXpodOptions {
2
+ port?: number;
3
+ baseUrl?: string;
4
+ rootFilePath?: string;
5
+ sparqlEndpoint?: string;
6
+ logLevel?: string;
7
+ }
8
+ export declare function startNoAuthXpod(options?: NoAuthXpodOptions): Promise<{
9
+ baseUrl: string;
10
+ stop: () => Promise<void>;
11
+ }>;
@@ -0,0 +1,25 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.startNoAuthXpod = startNoAuthXpod;
4
+ /**
5
+ * 无鉴权版本的 xpod 启动器
6
+ * 使用进程内 lib 方式启动完整 Xpod(CSS + API + Gateway)
7
+ */
8
+ const XpodRuntime_1 = require("../runtime/XpodRuntime");
9
+ async function startNoAuthXpod(options = {}) {
10
+ const runtime = await (0, XpodRuntime_1.startXpodRuntime)({
11
+ mode: 'local',
12
+ open: true,
13
+ transport: options.port ? 'port' : 'auto',
14
+ gatewayPort: options.port,
15
+ baseUrl: options.baseUrl,
16
+ rootFilePath: options.rootFilePath,
17
+ sparqlEndpoint: options.sparqlEndpoint,
18
+ logLevel: options.logLevel,
19
+ });
20
+ return {
21
+ baseUrl: runtime.baseUrl,
22
+ stop: runtime.stop,
23
+ };
24
+ }
25
+ //# sourceMappingURL=no-auth-xpod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"no-auth-xpod.js","sourceRoot":"","sources":["../../src/test-utils/no-auth-xpod.ts"],"names":[],"mappings":";;AAcA,0CAmBC;AAjCD;;;GAGG;AACH,wDAA0D;AAUnD,KAAK,UAAU,eAAe,CAAC,UAA6B,EAAE;IAInE,MAAM,OAAO,GAAG,MAAM,IAAA,8BAAgB,EAAC;QACrC,IAAI,EAAE,OAAO;QACb,IAAI,EAAE,IAAI;QACV,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM;QACzC,WAAW,EAAE,OAAO,CAAC,IAAI;QACzB,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,YAAY,EAAE,OAAO,CAAC,YAAY;QAClC,cAAc,EAAE,OAAO,CAAC,cAAc;QACtC,QAAQ,EAAE,OAAO,CAAC,QAAQ;KAC3B,CAAC,CAAC;IAEH,OAAO;QACL,OAAO,EAAE,OAAO,CAAC,OAAO;QACxB,IAAI,EAAE,OAAO,CAAC,IAAI;KACnB,CAAC;AACJ,CAAC","sourcesContent":["/**\n * 无鉴权版本的 xpod 启动器\n * 使用进程内 lib 方式启动完整 Xpod(CSS + API + Gateway)\n */\nimport { startXpodRuntime } from '../runtime/XpodRuntime';\n\nexport interface NoAuthXpodOptions {\n port?: number;\n baseUrl?: string;\n rootFilePath?: string;\n sparqlEndpoint?: string;\n logLevel?: string;\n}\n\nexport async function startNoAuthXpod(options: NoAuthXpodOptions = {}): Promise<{\n baseUrl: string;\n stop: () => Promise<void>;\n}> {\n const runtime = await startXpodRuntime({\n mode: 'local',\n open: true,\n transport: options.port ? 'port' : 'auto',\n gatewayPort: options.port,\n baseUrl: options.baseUrl,\n rootFilePath: options.rootFilePath,\n sparqlEndpoint: options.sparqlEndpoint,\n logLevel: options.logLevel,\n });\n\n return {\n baseUrl: runtime.baseUrl,\n stop: runtime.stop,\n };\n}\n"]}
@@ -0,0 +1,5 @@
1
+ export interface SeedPodOptions {
2
+ rootFilePath: string;
3
+ podName?: string;
4
+ }
5
+ export declare function seedPod(options: SeedPodOptions): Promise<void>;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.seedPod = seedPod;
7
+ /**
8
+ * Seed 测试 Pod 数据 - 在 SPARQL 数据库插入容器元数据
9
+ */
10
+ const better_sqlite3_1 = __importDefault(require("better-sqlite3"));
11
+ const fs_1 = require("fs");
12
+ const path_1 = __importDefault(require("path"));
13
+ async function seedPod(options) {
14
+ const { rootFilePath, podName = 'test' } = options;
15
+ // 确保目录存在
16
+ await fs_1.promises.mkdir(rootFilePath, { recursive: true });
17
+ const sparqlDbPath = path_1.default.join(rootFilePath, 'sparql.db');
18
+ const db = new better_sqlite3_1.default(sparqlDbPath);
19
+ // 创建 quints 表(如果不存在)
20
+ db.exec(`
21
+ CREATE TABLE IF NOT EXISTS quints (
22
+ graph TEXT NOT NULL,
23
+ subject TEXT NOT NULL,
24
+ predicate TEXT NOT NULL,
25
+ object TEXT NOT NULL,
26
+ vector TEXT,
27
+ PRIMARY KEY (graph, subject, predicate, object)
28
+ );
29
+ `);
30
+ const baseUrl = 'http://localhost:5741';
31
+ const now = new Date().toISOString();
32
+ const yyyy = new Date().getFullYear();
33
+ const MM = String(new Date().getMonth() + 1).padStart(2, '0');
34
+ const dd = String(new Date().getDate()).padStart(2, '0');
35
+ // 插入容器元数据到 quints 表
36
+ const containers = [
37
+ `${baseUrl}/${podName}/`,
38
+ `${baseUrl}/${podName}/.data/`,
39
+ `${baseUrl}/${podName}/.data/chat/`,
40
+ `${baseUrl}/${podName}/.data/chat/cli-default/`,
41
+ `${baseUrl}/${podName}/.data/chat/cli-default/${yyyy}/`,
42
+ `${baseUrl}/${podName}/.data/chat/cli-default/${yyyy}/${MM}/`,
43
+ `${baseUrl}/${podName}/.data/chat/cli-default/${yyyy}/${MM}/${dd}/`,
44
+ ];
45
+ const insert = db.prepare(`
46
+ INSERT OR IGNORE INTO quints (graph, subject, predicate, object, vector)
47
+ VALUES (?, ?, ?, ?, NULL)
48
+ `);
49
+ for (const container of containers) {
50
+ const metaGraph = `meta:${container}`;
51
+ // 类型
52
+ insert.run(metaGraph, container, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', 'http://www.w3.org/ns/ldp#Container');
53
+ insert.run(metaGraph, container, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', 'http://www.w3.org/ns/ldp#BasicContainer');
54
+ insert.run(metaGraph, container, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', 'http://www.w3.org/ns/ldp#Resource');
55
+ // 修改时间
56
+ insert.run(metaGraph, container, 'http://purl.org/dc/terms/modified', `"${now}"^^http://www.w3.org/2001/XMLSchema#dateTime`);
57
+ }
58
+ db.close();
59
+ console.log(`✓ SPARQL 容器元数据插入完成 (${containers.length} 个容器)`);
60
+ }
61
+ //# sourceMappingURL=seed-pod.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"seed-pod.js","sourceRoot":"","sources":["../../src/test-utils/seed-pod.ts"],"names":[],"mappings":";;;;;AAYA,0BAyDC;AArED;;GAEG;AACH,oEAAsC;AACtC,2BAAoC;AACpC,gDAAwB;AAOjB,KAAK,UAAU,OAAO,CAAC,OAAuB;IACnD,MAAM,EAAE,YAAY,EAAE,OAAO,GAAG,MAAM,EAAE,GAAG,OAAO,CAAC;IAEnD,SAAS;IACT,MAAM,aAAE,CAAC,KAAK,CAAC,YAAY,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAElD,MAAM,YAAY,GAAG,cAAI,CAAC,IAAI,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;IAC1D,MAAM,EAAE,GAAG,IAAI,wBAAQ,CAAC,YAAY,CAAC,CAAC;IAEtC,qBAAqB;IACrB,EAAE,CAAC,IAAI,CAAC;;;;;;;;;GASP,CAAC,CAAC;IAEH,MAAM,OAAO,GAAG,uBAAuB,CAAC;IACxC,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACrC,MAAM,IAAI,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IACtC,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAC9D,MAAM,EAAE,GAAG,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC;IAEzD,oBAAoB;IACpB,MAAM,UAAU,GAAG;QACjB,GAAG,OAAO,IAAI,OAAO,GAAG;QACxB,GAAG,OAAO,IAAI,OAAO,SAAS;QAC9B,GAAG,OAAO,IAAI,OAAO,cAAc;QACnC,GAAG,OAAO,IAAI,OAAO,0BAA0B;QAC/C,GAAG,OAAO,IAAI,OAAO,2BAA2B,IAAI,GAAG;QACvD,GAAG,OAAO,IAAI,OAAO,2BAA2B,IAAI,IAAI,EAAE,GAAG;QAC7D,GAAG,OAAO,IAAI,OAAO,2BAA2B,IAAI,IAAI,EAAE,IAAI,EAAE,GAAG;KACpE,CAAC;IAEF,MAAM,MAAM,GAAG,EAAE,CAAC,OAAO,CAAC;;;GAGzB,CAAC,CAAC;IAEH,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,SAAS,GAAG,QAAQ,SAAS,EAAE,CAAC;QAEtC,KAAK;QACL,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,iDAAiD,EAAE,oCAAoC,CAAC,CAAC;QAC1H,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,iDAAiD,EAAE,yCAAyC,CAAC,CAAC;QAC/H,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,iDAAiD,EAAE,mCAAmC,CAAC,CAAC;QAEzH,OAAO;QACP,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,EAAE,mCAAmC,EAAE,IAAI,GAAG,8CAA8C,CAAC,CAAC;IAC/H,CAAC;IAED,EAAE,CAAC,KAAK,EAAE,CAAC;IACX,OAAO,CAAC,GAAG,CAAC,uBAAuB,UAAU,CAAC,MAAM,OAAO,CAAC,CAAC;AAC/D,CAAC","sourcesContent":["/**\n * Seed 测试 Pod 数据 - 在 SPARQL 数据库插入容器元数据\n */\nimport Database from 'better-sqlite3';\nimport { promises as fs } from 'fs';\nimport path from 'path';\n\nexport interface SeedPodOptions {\n rootFilePath: string;\n podName?: string;\n}\n\nexport async function seedPod(options: SeedPodOptions): Promise<void> {\n const { rootFilePath, podName = 'test' } = options;\n\n // 确保目录存在\n await fs.mkdir(rootFilePath, { recursive: true });\n\n const sparqlDbPath = path.join(rootFilePath, 'sparql.db');\n const db = new Database(sparqlDbPath);\n\n // 创建 quints 表(如果不存在)\n db.exec(`\n CREATE TABLE IF NOT EXISTS quints (\n graph TEXT NOT NULL,\n subject TEXT NOT NULL,\n predicate TEXT NOT NULL,\n object TEXT NOT NULL,\n vector TEXT,\n PRIMARY KEY (graph, subject, predicate, object)\n );\n `);\n\n const baseUrl = 'http://localhost:5741';\n const now = new Date().toISOString();\n const yyyy = new Date().getFullYear();\n const MM = String(new Date().getMonth() + 1).padStart(2, '0');\n const dd = String(new Date().getDate()).padStart(2, '0');\n\n // 插入容器元数据到 quints 表\n const containers = [\n `${baseUrl}/${podName}/`,\n `${baseUrl}/${podName}/.data/`,\n `${baseUrl}/${podName}/.data/chat/`,\n `${baseUrl}/${podName}/.data/chat/cli-default/`,\n `${baseUrl}/${podName}/.data/chat/cli-default/${yyyy}/`,\n `${baseUrl}/${podName}/.data/chat/cli-default/${yyyy}/${MM}/`,\n `${baseUrl}/${podName}/.data/chat/cli-default/${yyyy}/${MM}/${dd}/`,\n ];\n\n const insert = db.prepare(`\n INSERT OR IGNORE INTO quints (graph, subject, predicate, object, vector)\n VALUES (?, ?, ?, ?, NULL)\n `);\n\n for (const container of containers) {\n const metaGraph = `meta:${container}`;\n\n // 类型\n insert.run(metaGraph, container, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', 'http://www.w3.org/ns/ldp#Container');\n insert.run(metaGraph, container, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', 'http://www.w3.org/ns/ldp#BasicContainer');\n insert.run(metaGraph, container, 'http://www.w3.org/1999/02/22-rdf-syntax-ns#type', 'http://www.w3.org/ns/ldp#Resource');\n\n // 修改时间\n insert.run(metaGraph, container, 'http://purl.org/dc/terms/modified', `\"${now}\"^^http://www.w3.org/2001/XMLSchema#dateTime`);\n }\n\n db.close();\n console.log(`✓ SPARQL 容器元数据插入完成 (${containers.length} 个容器)`);\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@undefineds.co/xpod",
3
- "version": "0.1.7",
3
+ "version": "0.2.0",
4
4
  "description": "Xpod is an extended Community Solid Server, offering rich-feature, production-level Solid Pod and identity management.",
5
5
  "repository": "https://github.com/undefinedsco/xpod",
6
6
  "author": "developer@undefineds.co",
@@ -21,6 +21,21 @@
21
21
  },
22
22
  "main": "./dist/index.js",
23
23
  "types": "./dist/index.d.ts",
24
+ "exports": {
25
+ ".": {
26
+ "types": "./dist/index.d.ts",
27
+ "default": "./dist/index.js"
28
+ },
29
+ "./runtime": {
30
+ "types": "./dist/runtime/index.d.ts",
31
+ "default": "./dist/runtime/index.js"
32
+ },
33
+ "./test-utils": {
34
+ "types": "./dist/test-utils/index.d.ts",
35
+ "default": "./dist/test-utils/index.js"
36
+ },
37
+ "./package.json": "./package.json"
38
+ },
24
39
  "lsd:module": "https://linkedsoftwaredependencies.org/bundles/npm/@undefineds.co/xpod",
25
40
  "lsd:components": "dist/components/components.jsonld",
26
41
  "lsd:contexts": {
@@ -43,15 +58,15 @@
43
58
  "clean": "rm -rf data/*",
44
59
  "clean:test": "rm -rf .test-data && rm -f *.sqlite *.sqlite-wal *.sqlite-shm",
45
60
  "vanilla": "yarn community-solid-server -c config/main.vanilla.json -f ./data_vanilla -p 3000",
46
- "cli": "yarn ts-node src/cli/index.ts",
47
- "start": "yarn ts-node src/main.ts",
61
+ "cli": "node scripts/check-native-abi.cjs && yarn ts-node src/cli/index.ts",
62
+ "start": "node scripts/check-native-abi.cjs && yarn ts-node src/main.ts",
48
63
  "local": "dotenv -e .env.local -- yarn start -c config/local.json",
49
64
  "cloud": "dotenv -e .env.cloud -- yarn start -c config/cloud.json",
50
65
  "dev": "./scripts/dev-start.sh",
51
66
  "dev:local": "./scripts/dev-start.sh --local",
52
67
  "dev:seed": "NODE_ENV=development CSS_SEED_CONFIG=$PWD/config/seed.dev.json dotenv -e .env.local -- yarn start -c config/local.json",
53
68
  "dev:cloud": "NODE_ENV=development CSS_SEED_CONFIG=$PWD/config/seed.dev.json dotenv -e .env.cloud -- yarn start -c config/cloud.json",
54
- "dev:api": "NODE_ENV=development dotenv -e .env.local -- yarn ts-node src/api/main.ts",
69
+ "dev:api": "node scripts/check-native-abi.cjs && NODE_ENV=development dotenv -e .env.local -- yarn ts-node src/api/main.ts",
55
70
  "dev:init": "NODE_ENV=development yarn ts-node scripts/init-dev-credentials.ts",
56
71
  "dev:test": "NODE_ENV=development yarn ts-node scripts/test-dev-flow.ts",
57
72
  "dev:cluster": "docker compose -f docker-compose.cluster.yml up --build",
@@ -62,7 +77,8 @@
62
77
  "test:run": "vitest --run",
63
78
  "test:terminal": "npx ts-node scripts/test-terminal.ts",
64
79
  "test:coverage": "vitest --run --coverage",
65
- "test:integration": "yarn test:integration:full",
80
+ "typecheck:test": "tsc --noEmit -p tsconfig.test.json",
81
+ "test:integration": "yarn test:integration:all",
66
82
  "test:cluster": "XPOD_RUN_INTEGRATION_TESTS=true vitest --run tests/integration/MultiNodeCluster.integration.test.ts",
67
83
  "test:all": "XPOD_RUN_INTEGRATION_TESTS=true vitest --run --coverage",
68
84
  "test:quad-vs-quint": "vitest --run tests/storage/quad-vs-quint-comparison.test.ts",
@@ -70,14 +86,15 @@
70
86
  "test:storage": "vitest --run tests/storage/",
71
87
  "dev:cluster:lite": "docker compose -f docker-compose.standalone.yml up --build",
72
88
  "dev:cluster:lite:down": "docker compose -f docker-compose.standalone.yml down",
73
- "test:integration:lite": "yarn ts-node scripts/run-integration-lite-local.ts",
74
- "test:integration:full": "CSS_BASE_URL=http://localhost:${STANDALONE_PORT:-5739} yarn test:setup && XPOD_RUN_INTEGRATION_TESTS=true CSS_BASE_URL=http://localhost:${STANDALONE_PORT:-5739} CSS_SEED_CONFIG=$PWD/config/seeds/test.json dotenv -e .env.local -- vitest --run tests/integration --no-file-parallelism",
75
- "test:integration:all": "yarn test:integration:full",
89
+ "test:integration:lite": "node scripts/check-native-abi.cjs && yarn ts-node scripts/run-integration-lite-local.ts",
90
+ "test:integration:full": "node scripts/check-native-abi.cjs && yarn ts-node scripts/run-integration-cluster.ts",
91
+ "test:integration:all": "yarn test:integration:lite && yarn test:integration:full",
76
92
  "test:integration:lite:up": "docker compose -f docker-compose.standalone.yml up -d --build",
77
93
  "test:integration:lite:down": "docker compose -f docker-compose.standalone.yml down",
78
94
  "build:single": "node scripts/build-single-file.js",
79
95
  "build:single:standalone": "yarn build && node scripts/build-single-file.js",
80
- "test:setup": "dotenv -e .env.local -- yarn ts-node scripts/setup-test-credentials.ts"
96
+ "test:setup": "node scripts/check-native-abi.cjs && dotenv -e .env.local -- yarn ts-node scripts/setup-test-credentials.ts",
97
+ "check:abi": "node scripts/check-native-abi.cjs"
81
98
  },
82
99
  "devDependencies": {
83
100
  "@playwright/test": "^1.57.0",
@@ -113,10 +130,16 @@
113
130
  "@agentclientprotocol/sdk": "^0.14.1",
114
131
  "@ai-sdk/openai": "^3.0.2",
115
132
  "@anthropic-ai/claude-agent-sdk": "^0.2.39",
133
+ "@comunica/core": "^4.5.0",
134
+ "@comunica/query-sparql": "^4.5.0",
116
135
  "@comunica/query-sparql-rdfjs": "^4.0.2",
136
+ "@comunica/query-sparql-solid": "^4.0.2",
137
+ "@comunica/types": "^4.5.0",
138
+ "@comunica/utils-metadata": "^4.5.0",
117
139
  "@electric-sql/pglite": "^0.3.14",
118
140
  "@inrupt/solid-client-authn-node": "^3.1.0",
119
141
  "@solid/community-server": "^8.0.0-alpha.1",
142
+ "@undefineds.co/drizzle-solid": "^0.3.0",
120
143
  "@zed-industries/claude-code-acp": "^0.16.1",
121
144
  "@zed-industries/codex-acp": "^0.9.2",
122
145
  "abstract-level": "^1.0.4",
@@ -125,10 +148,10 @@
125
148
  "asynciterator": "^3.9.0",
126
149
  "awilix": "^12.0.5",
127
150
  "better-sqlite3": "^12.5.0",
151
+ "better-sqlite3-multiple-ciphers": "^12.6.2",
128
152
  "classic-level": "^1.4.1",
129
153
  "clsx": "^2.1.0",
130
154
  "drizzle-orm": "^0.30.10",
131
- "drizzle-solid": "^0.2.5",
132
155
  "http-proxy": "^1.18.1",
133
156
  "i18next": "^23.10.1",
134
157
  "knex": "^3.1.0",
@@ -172,5 +195,10 @@
172
195
  "@comunica/mediator-combine-union": "^4.5.0",
173
196
  "@comunica/mediator-combine-pipeline": "^4.5.0",
174
197
  "componentsjs": "^6.4.0"
198
+ },
199
+ "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
200
+ "volta": {
201
+ "node": "22.21.1",
202
+ "yarn": "1.22.22"
175
203
  }
176
204
  }