acrylblends 0.2.0 → 0.3.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 (109) hide show
  1. package/dist/index.d.ts +17 -16
  2. package/dist/index.js +39 -19
  3. package/dist/index.js.map +1 -1
  4. package/package.json +1 -1
  5. package/plugins/acryl-inspect/LICENSE +21 -0
  6. package/plugins/acryl-inspect/plugin.json +11 -0
  7. package/plugins/acryl-inspect/src/index.ts +3 -0
  8. package/plugins/acryl-inspect/src/report.ts +123 -0
  9. package/plugins/acryl-inspect/src/service.ts +66 -0
  10. package/plugins/acryl-inspect/tests/report.spec.ts +64 -0
  11. package/plugins/acryl-inspect/tests/service.spec.ts +120 -0
  12. package/plugins/acryl-inspect/upstream.json +18 -0
  13. package/plugins/acryl-node-server/LICENSE +21 -0
  14. package/plugins/acryl-node-server/plugin.json +12 -0
  15. package/plugins/acryl-node-server/src/index.ts +94 -0
  16. package/plugins/acryl-node-server/tests/server.spec.ts +105 -0
  17. package/plugins/acryl-node-server/upstream.json +18 -0
  18. package/plugins/acryl-router/LICENSE +21 -0
  19. package/plugins/acryl-router/plugin.json +12 -0
  20. package/plugins/acryl-router/src/compose.ts +21 -0
  21. package/plugins/acryl-router/src/context.ts +59 -0
  22. package/plugins/acryl-router/src/helpers/index.ts +3 -0
  23. package/plugins/acryl-router/src/helpers/read-body.ts +59 -0
  24. package/plugins/acryl-router/src/helpers/sse.ts +83 -0
  25. package/plugins/acryl-router/src/helpers/validate.ts +44 -0
  26. package/plugins/acryl-router/src/http-error.ts +21 -0
  27. package/plugins/acryl-router/src/index.ts +6 -0
  28. package/plugins/acryl-router/src/middleware/body-limit.ts +25 -0
  29. package/plugins/acryl-router/src/middleware/cors.ts +46 -0
  30. package/plugins/acryl-router/src/middleware/index.ts +6 -0
  31. package/plugins/acryl-router/src/middleware/logger.ts +21 -0
  32. package/plugins/acryl-router/src/middleware/loopback-only.ts +82 -0
  33. package/plugins/acryl-router/src/middleware/request-id.ts +24 -0
  34. package/plugins/acryl-router/src/middleware/secure-headers.ts +23 -0
  35. package/plugins/acryl-router/src/pattern.ts +89 -0
  36. package/plugins/acryl-router/src/registrar.ts +90 -0
  37. package/plugins/acryl-router/src/service.ts +164 -0
  38. package/plugins/acryl-router/src/table.ts +156 -0
  39. package/plugins/acryl-router/src/types.ts +73 -0
  40. package/plugins/acryl-router/src/util.ts +23 -0
  41. package/plugins/acryl-router/tests/api.spec.ts +223 -0
  42. package/plugins/acryl-router/tests/conformance.ts +170 -0
  43. package/plugins/acryl-router/tests/helpers.spec.ts +172 -0
  44. package/plugins/acryl-router/tests/live-install.spec.ts +64 -0
  45. package/plugins/acryl-router/tests/loader.spec.ts +71 -0
  46. package/plugins/acryl-router/tests/middleware.spec.ts +183 -0
  47. package/plugins/acryl-router/tests/service.spec.ts +211 -0
  48. package/plugins/acryl-router/tests/table.spec.ts +47 -0
  49. package/plugins/acryl-router/upstream.json +20 -0
  50. package/plugins/acryl-router-http/LICENSE +21 -0
  51. package/plugins/acryl-router-http/plugin.json +11 -0
  52. package/plugins/acryl-router-http/src/bridge.ts +52 -0
  53. package/plugins/acryl-router-http/src/index.ts +63 -0
  54. package/plugins/acryl-router-http/src/serve.ts +24 -0
  55. package/plugins/acryl-router-http/tests/adapter.spec.ts +170 -0
  56. package/plugins/acryl-router-http/tests/stream.spec.ts +133 -0
  57. package/plugins/acryl-router-http/tests/surfaces.spec.ts +99 -0
  58. package/plugins/acryl-router-http/upstream.json +22 -0
  59. package/plugins/acryl-state/LICENSE +21 -0
  60. package/plugins/acryl-state/plugin.json +12 -0
  61. package/plugins/acryl-state/src/cell.ts +67 -0
  62. package/plugins/acryl-state/src/index.ts +3 -0
  63. package/plugins/acryl-state/src/react.ts +11 -0
  64. package/plugins/acryl-state/src/service.ts +101 -0
  65. package/plugins/acryl-state/tests/cell.spec.ts +71 -0
  66. package/plugins/acryl-state/tests/react.spec.ts +39 -0
  67. package/plugins/acryl-state/tests/service.spec.ts +132 -0
  68. package/plugins/acryl-state/upstream.json +20 -0
  69. package/plugins/builder/script.ts +8 -9
  70. package/plugins/extensions/index.ts +18 -1
  71. package/plugins/openai/prompt.ts +9 -5
  72. package/plugins/tasks/index.ts +14 -0
  73. package/plugins/tsconfig.json +9 -1
  74. package/templates/agent/blend.yaml +5 -7
  75. package/templates/agent/src/app.ts +8 -8
  76. package/templates/agent/src/routes.ts +32 -41
  77. package/templates/agent/template.json +3 -3
  78. package/templates/agent/test/builder.test.ts +22 -14
  79. package/templates/agent/test/model.test.ts +2 -3
  80. package/templates/{app → blank}/blend.yaml +3 -3
  81. package/templates/{app → blank}/src/app.ts +5 -5
  82. package/templates/blank/src/routes.ts +14 -0
  83. package/templates/blank/template.json +1 -0
  84. package/templates/{app → blank}/test/app.test.ts +1 -1
  85. package/templates/todo/README.md +27 -0
  86. package/templates/todo/blend.yaml +25 -0
  87. package/templates/todo/gitignore +2 -0
  88. package/templates/todo/package.json +23 -0
  89. package/templates/todo/src/app.ts +71 -0
  90. package/templates/todo/src/main.ts +19 -0
  91. package/templates/todo/src/page.ts +28 -0
  92. package/templates/todo/src/todo.ts +96 -0
  93. package/templates/todo/template.json +1 -0
  94. package/templates/todo/test/todo.test.ts +145 -0
  95. package/templates/todo/tsconfig.json +19 -0
  96. package/templates/todo/upstream.json +12 -0
  97. package/plugins/events/index.ts +0 -42
  98. package/plugins/events/plugin.json +0 -9
  99. package/plugins/http/index.ts +0 -64
  100. package/plugins/http/plugin.json +0 -10
  101. package/plugins/server/index.ts +0 -138
  102. package/plugins/server/plugin.json +0 -10
  103. package/templates/app/src/routes.ts +0 -14
  104. package/templates/app/template.json +0 -1
  105. /package/templates/{app → blank}/README.md +0 -0
  106. /package/templates/{app → blank}/gitignore +0 -0
  107. /package/templates/{app → blank}/package.json +0 -0
  108. /package/templates/{app → blank}/src/main.ts +0 -0
  109. /package/templates/{app → blank}/tsconfig.json +0 -0
@@ -1,138 +0,0 @@
1
- import {
2
- createServer,
3
- type IncomingMessage,
4
- type Server as NodeServer,
5
- type ServerResponse,
6
- } from 'node:http'
7
- import type { AddressInfo } from 'node:net'
8
- import type { Context } from '@deepseek-ai/cordis'
9
- import type { Send, Stream } from '../http/index.ts'
10
-
11
- /** Where the server listens. Passed as this plugin's Cordis config. */
12
- export interface ServerConfig {
13
- readonly port: number
14
- readonly hostname?: string
15
- /** Try the next port when this one is taken (up to 20 more). */
16
- readonly scan?: boolean
17
- }
18
-
19
- /** The running server, provided once it listens. */
20
- export interface Server {
21
- readonly url: string
22
- readonly port: number
23
- }
24
-
25
- declare module '@deepseek-ai/cordis' {
26
- interface Context {
27
- server: Server
28
- }
29
- }
30
-
31
- const SCAN_LIMIT = 20
32
-
33
- async function readJson(
34
- request: IncomingMessage,
35
- ): Promise<{ ok: true; body: unknown } | { ok: false }> {
36
- const chunks: Buffer[] = []
37
- for await (const chunk of request) chunks.push(chunk as Buffer)
38
- if (chunks.length === 0) return { ok: true, body: undefined }
39
- try {
40
- return { ok: true, body: JSON.parse(Buffer.concat(chunks).toString('utf8')) }
41
- } catch {
42
- return { ok: false }
43
- }
44
- }
45
-
46
- function listen(listener: NodeServer, port: number, hostname: string): Promise<void> {
47
- return new Promise((resolve, reject) => {
48
- const onError = (error: Error) => {
49
- listener.off('listening', onListening)
50
- reject(error)
51
- }
52
- const onListening = () => {
53
- listener.off('error', onError)
54
- resolve()
55
- }
56
- listener.once('error', onError)
57
- listener.once('listening', onListening)
58
- listener.listen(port, hostname)
59
- })
60
- }
61
-
62
- const KEEPALIVE_MS = 15_000
63
-
64
- /**
65
- * Answer with server-sent events. Each event has a rising `id`, a `topic` as its event name and JSON `data`; a comment line every 15 s
66
- * keeps proxies from closing an idle stream. When the client leaves (or the server stops) the stream's own cleanup runs.
67
- */
68
- function openStream(request: IncomingMessage, response: ServerResponse, stream: Stream): void {
69
- response.writeHead(200, {
70
- 'content-type': 'text/event-stream',
71
- 'cache-control': 'no-cache',
72
- connection: 'keep-alive',
73
- })
74
- response.write(': connected\n\n')
75
- let id = 0
76
- let open = true
77
- const send: Send = (topic, data) => {
78
- if (!open) return
79
- id += 1
80
- response.write(`id: ${id}\nevent: ${topic}\ndata: ${JSON.stringify(data)}\n\n`)
81
- }
82
- const leave = stream(send)
83
- const keepalive = setInterval(() => response.write(': keepalive\n\n'), KEEPALIVE_MS)
84
- const close = () => {
85
- if (!open) return
86
- open = false
87
- clearInterval(keepalive)
88
- leave()
89
- }
90
- request.on('close', close)
91
- response.on('close', close)
92
- }
93
-
94
- /** Serves the `http` router with Node's own `node:http`. The returned disposer closes the server. */
95
- export const server = {
96
- name: 'server',
97
- inject: ['http'],
98
- async apply(ctx: Context, config: ServerConfig) {
99
- const hostname = config.hostname ?? '127.0.0.1'
100
- const listener = createServer(async (request, response) => {
101
- const send = (status: number, body: unknown) => {
102
- response.writeHead(status, { 'content-type': 'application/json' })
103
- response.end(JSON.stringify(body))
104
- }
105
- try {
106
- const parsed = await readJson(request)
107
- if (!parsed.ok) return send(400, { error: 'invalid JSON' })
108
- const path = new URL(request.url ?? '/', 'http://localhost').pathname
109
- const reply = await ctx.http.handle({
110
- method: request.method ?? 'GET',
111
- path,
112
- body: parsed.body,
113
- })
114
- if (reply.stream) return openStream(request, response, reply.stream)
115
- send(reply.status, reply.body)
116
- } catch (error) {
117
- send(500, { error: error instanceof Error ? error.message : String(error) })
118
- }
119
- })
120
- const attempts = config.scan && config.port !== 0 ? SCAN_LIMIT + 1 : 1
121
- for (let attempt = 0; ; attempt++) {
122
- try {
123
- await listen(listener, config.port + attempt, hostname)
124
- break
125
- } catch (error) {
126
- const inUse = (error as NodeJS.ErrnoException).code === 'EADDRINUSE'
127
- if (!inUse || attempt + 1 >= attempts) throw error
128
- }
129
- }
130
- const { port } = listener.address() as AddressInfo
131
- ctx.provide('server', { url: `http://${hostname}:${port}`, port } satisfies Server)
132
- return () =>
133
- new Promise<void>((done) => {
134
- listener.close(() => done())
135
- listener.closeAllConnections()
136
- })
137
- },
138
- }
@@ -1,10 +0,0 @@
1
- {
2
- "name": "server",
3
- "description": "Serves the http router over node:http; moves to the next free port when asked; closes on stop.",
4
- "requires": ["http"],
5
- "inject": ["http"],
6
- "provides": ["server"],
7
- "dependencies": {
8
- "@deepseek-ai/cordis": "4.0.4"
9
- }
10
- }
@@ -1,14 +0,0 @@
1
- import type { Context } from '@deepseek-ai/cordis'
2
- import type {} from './plugins/http/index.ts'
3
-
4
- export const APP_NAME = '__APP_NAME__'
5
-
6
- /** The app's own routes. Each one lives in a `ctx.effect`, so it is removed when this plugin is disposed. */
7
- export const routes = {
8
- name: 'routes',
9
- inject: ['http'],
10
- apply(ctx: Context) {
11
- ctx.effect(() => ctx.http.route('GET', '/', () => ({ body: { app: APP_NAME, ok: true } })))
12
- ctx.effect(() => ctx.http.route('GET', '/health', () => ({ body: { ok: true } })))
13
- },
14
- }
@@ -1 +0,0 @@
1
- { "plugins": ["instance", "http", "server", "manifest", "save"] }
File without changes
File without changes
File without changes
File without changes
File without changes