@liquidmetal-ai/raindrop 0.13.0 → 0.15.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 (250) hide show
  1. package/README.md +327 -89
  2. package/bundle/build-CBEGQPJT.js +62 -0
  3. package/bundle/{chunk-IEF2XC25.js → chunk-2PH3PHH3.js} +5 -3
  4. package/bundle/{chunk-4HZ22KOV.js → chunk-3CMR7ES5.js} +4 -4
  5. package/bundle/{chunk-JSBM2JYW.js → chunk-3EYKCHIK.js} +1 -1
  6. package/bundle/chunk-5XHDP4VK.js +1697 -0
  7. package/bundle/{chunk-TSQK4HH6.js → chunk-674GMSXY.js} +1 -1
  8. package/bundle/{chunk-PS3WZBDF.js → chunk-6L4V66WZ.js} +1105 -2728
  9. package/bundle/{chunk-5245CEUM.js → chunk-AGG7JZVH.js} +2 -2
  10. package/bundle/{chunk-3GFKUF5D.js → chunk-B3IY2XS6.js} +4 -2
  11. package/bundle/{chunk-WIDI65NO.js → chunk-CBAXTRCS.js} +1 -1
  12. package/bundle/{chunk-JLVDTXO2.js → chunk-DPV5HIG7.js} +4 -4
  13. package/bundle/{chunk-36GNZK4A.js → chunk-EVXLXWP7.js} +1 -1
  14. package/bundle/{chunk-4YVU5KEQ.js → chunk-HN3AAKRY.js} +4 -2
  15. package/bundle/{chunk-NVNEQXHN.js → chunk-IGLE4Y3B.js} +7 -5
  16. package/bundle/{chunk-FGSYWVBA.js → chunk-IQ6HFRA6.js} +1 -1
  17. package/bundle/{chunk-O3QZDJ75.js → chunk-JQONDSHY.js} +2 -2
  18. package/bundle/{chunk-W4IPOFZC.js → chunk-KADMFJLN.js} +8 -6
  19. package/bundle/chunk-KG5BLUGU.js +246 -0
  20. package/bundle/{chunk-V5LHJTYS.js → chunk-KLOYSTZY.js} +13 -2
  21. package/bundle/{chunk-ETC5VU7H.js → chunk-KXHVSLAI.js} +1 -1
  22. package/bundle/{chunk-Y4WFGNPM.js → chunk-L6FRQULN.js} +1 -1
  23. package/bundle/{chunk-3QCVYSRU.js → chunk-LT3BFQ4O.js} +1 -1
  24. package/bundle/{chunk-KQZJHBNG.js → chunk-MBLKVNI5.js} +1 -1
  25. package/bundle/{chunk-6AIUQUUM.js → chunk-MFMVJZW6.js} +71 -15
  26. package/bundle/{chunk-25T7MEKO.js → chunk-MJBLNWG3.js} +1 -1
  27. package/bundle/{chunk-MSJ33O5Y.js → chunk-NRCQIE3Z.js} +95 -115
  28. package/bundle/{chunk-XKKPPSPC.js → chunk-OCYTN4IH.js} +2 -2
  29. package/bundle/{chunk-2GAMWFJE.js → chunk-QEF5D4VE.js} +1 -1
  30. package/bundle/{chunk-4B3QYXBA.js → chunk-T7MQCLXF.js} +5 -3
  31. package/bundle/{chunk-LDFYPOXJ.js → chunk-TFQY5TSY.js} +1 -1
  32. package/bundle/{chunk-BWK4MC7Y.js → chunk-USZXZZAR.js} +8 -6
  33. package/bundle/{chunk-ER2RCPCY.js → chunk-V54KHS5B.js} +2 -2
  34. package/bundle/{chunk-YSKASURB.js → chunk-V6J23FL2.js} +1 -1
  35. package/bundle/{chunk-UHSTDJ7X.js → chunk-VN2QYX4C.js} +1 -1
  36. package/bundle/{chunk-Z4OWKG7J.js → chunk-VOT5MMEY.js} +1 -1
  37. package/bundle/{chunk-W6GU26WO.js → chunk-WG6BDFPZ.js} +1 -1
  38. package/bundle/{chunk-AK77X5GL.js → chunk-XX74I5RK.js} +4 -2
  39. package/bundle/{chunk-6BT265R3.js → chunk-YQCRWPNI.js} +1 -1
  40. package/bundle/commands/annotation/get.js +3 -3
  41. package/bundle/commands/annotation/list.js +3 -3
  42. package/bundle/commands/annotation/put.js +3 -3
  43. package/bundle/commands/auth/apikey.js +2 -2
  44. package/bundle/commands/auth/list.js +2 -2
  45. package/bundle/commands/auth/login.js +2 -2
  46. package/bundle/commands/auth/logout.js +2 -2
  47. package/bundle/commands/auth/select.js +3 -3
  48. package/bundle/commands/bucket/create-credential.js +2 -2
  49. package/bundle/commands/bucket/delete-credential.js +2 -2
  50. package/bundle/commands/bucket/get-credential.js +2 -2
  51. package/bundle/commands/bucket/list-credentials.js +2 -2
  52. package/bundle/commands/build/actor/setup.js +124 -0
  53. package/bundle/commands/build/branch.js +10 -10
  54. package/bundle/commands/build/bucket-events/setup.js +146 -0
  55. package/bundle/commands/build/checkout.js +8 -8
  56. package/bundle/commands/build/clone.js +6 -6
  57. package/bundle/commands/build/delete.js +8 -8
  58. package/bundle/commands/build/deploy.js +10 -10
  59. package/bundle/commands/build/env/get.js +3 -3
  60. package/bundle/commands/build/env/list.js +2 -2
  61. package/bundle/commands/build/env/set.js +3 -3
  62. package/bundle/commands/build/env.js +2 -2
  63. package/bundle/commands/build/features.js +192 -0
  64. package/bundle/commands/build/find.js +4 -4
  65. package/bundle/commands/build/generate.js +52 -3
  66. package/bundle/commands/build/init-workspace.js +3 -3
  67. package/bundle/commands/build/init.js +15 -3
  68. package/bundle/commands/build/list.js +5 -5
  69. package/bundle/commands/build/queue/setup.js +133 -0
  70. package/bundle/commands/build/sandbox.js +6 -6
  71. package/bundle/commands/build/smartbucket/setup.js +165 -0
  72. package/bundle/commands/build/smartmemory/setup.js +171 -0
  73. package/bundle/commands/build/smartsql/setup.js +167 -0
  74. package/bundle/commands/build/start.js +2 -2
  75. package/bundle/commands/build/status.js +5 -5
  76. package/bundle/commands/build/stop.js +2 -2
  77. package/bundle/commands/build/stripe/dashboard.js +3 -3
  78. package/bundle/commands/build/stripe/onboard.js +3 -3
  79. package/bundle/commands/build/stripe/setup.js +3 -3
  80. package/bundle/commands/build/stripe/start.js +14 -14
  81. package/bundle/commands/build/stripe/status.js +3 -3
  82. package/bundle/commands/build/stripe/subscription/create.js +4 -4
  83. package/bundle/commands/build/stripe/subscription/get.js +4 -4
  84. package/bundle/commands/build/stripe/subscription/update.js +4 -4
  85. package/bundle/commands/build/tools/check.js +2 -2
  86. package/bundle/commands/build/tools/fmt.js +2 -2
  87. package/bundle/commands/build/unsandbox.js +6 -6
  88. package/bundle/commands/build/upload.js +5 -5
  89. package/bundle/commands/build/validate.js +85 -14
  90. package/bundle/commands/build/workos/delete.js +6 -6
  91. package/bundle/commands/build/workos/env/attach.js +3 -3
  92. package/bundle/commands/build/workos/env/attached.js +3 -3
  93. package/bundle/commands/build/workos/env/create.js +3 -3
  94. package/bundle/commands/build/workos/env/delete.js +3 -3
  95. package/bundle/commands/build/workos/env/detach.js +3 -3
  96. package/bundle/commands/build/workos/env/dev-login.js +3 -3
  97. package/bundle/commands/build/workos/env/get.js +3 -3
  98. package/bundle/commands/build/workos/env/list.js +3 -3
  99. package/bundle/commands/build/workos/env/set.js +3 -3
  100. package/bundle/commands/build/workos/invite.js +3 -3
  101. package/bundle/commands/build/workos/jwt.js +172 -0
  102. package/bundle/commands/build/workos/setup.js +3 -3
  103. package/bundle/commands/build/workos/status.js +3 -3
  104. package/bundle/commands/dns/create.js +2 -2
  105. package/bundle/commands/dns/delete.js +6 -6
  106. package/bundle/commands/dns/get.js +6 -6
  107. package/bundle/commands/dns/list.js +3 -3
  108. package/bundle/commands/dns/records/create.js +2 -2
  109. package/bundle/commands/dns/records/delete.js +3 -3
  110. package/bundle/commands/dns/records/get.js +2 -2
  111. package/bundle/commands/dns/records/list.js +2 -2
  112. package/bundle/commands/dns/records/update.js +2 -2
  113. package/bundle/commands/doctor.js +309 -0
  114. package/bundle/commands/logs/query.js +3 -3
  115. package/bundle/commands/logs/tail.js +3 -3
  116. package/bundle/commands/mcp/install-claude.js +2 -2
  117. package/bundle/commands/mcp/install-gemini.js +2 -2
  118. package/bundle/commands/mcp/install-goose.js +2 -2
  119. package/bundle/commands/mcp/status.js +2 -2
  120. package/bundle/commands/object/delete.js +5 -37
  121. package/bundle/commands/object/get.js +5 -37
  122. package/bundle/commands/object/list.js +7 -39
  123. package/bundle/commands/object/put.js +5 -37
  124. package/bundle/commands/query/chunk-search.js +14 -46
  125. package/bundle/commands/query/document.js +17 -55
  126. package/bundle/commands/query/events.js +2 -2
  127. package/bundle/commands/query/reindex.js +2 -2
  128. package/bundle/commands/query/search.js +14 -46
  129. package/bundle/commands/tail.js +2 -2
  130. package/bundle/index.js +1 -1
  131. package/dist/commands/build/actor/setup.d.ts +22 -0
  132. package/dist/commands/build/actor/setup.d.ts.map +1 -0
  133. package/dist/commands/build/actor/setup.js +116 -0
  134. package/dist/commands/build/bucket-events/setup.d.ts +22 -0
  135. package/dist/commands/build/bucket-events/setup.d.ts.map +1 -0
  136. package/dist/commands/build/bucket-events/setup.js +134 -0
  137. package/dist/commands/build/features.d.ts +19 -0
  138. package/dist/commands/build/features.d.ts.map +1 -0
  139. package/dist/commands/build/features.js +97 -0
  140. package/dist/commands/build/generate.d.ts +2 -0
  141. package/dist/commands/build/generate.d.ts.map +1 -1
  142. package/dist/commands/build/generate.js +52 -0
  143. package/dist/commands/build/init.d.ts.map +1 -1
  144. package/dist/commands/build/init.js +10 -0
  145. package/dist/commands/build/queue/setup.d.ts +21 -0
  146. package/dist/commands/build/queue/setup.d.ts.map +1 -0
  147. package/dist/commands/build/queue/setup.js +120 -0
  148. package/dist/commands/build/smartbucket/setup.d.ts +23 -0
  149. package/dist/commands/build/smartbucket/setup.d.ts.map +1 -0
  150. package/dist/commands/build/smartbucket/setup.js +167 -0
  151. package/dist/commands/build/smartmemory/setup.d.ts +23 -0
  152. package/dist/commands/build/smartmemory/setup.d.ts.map +1 -0
  153. package/dist/commands/build/smartmemory/setup.js +172 -0
  154. package/dist/commands/build/smartsql/setup.d.ts +23 -0
  155. package/dist/commands/build/smartsql/setup.d.ts.map +1 -0
  156. package/dist/commands/build/smartsql/setup.js +169 -0
  157. package/dist/commands/build/validate.d.ts +2 -0
  158. package/dist/commands/build/validate.d.ts.map +1 -1
  159. package/dist/commands/build/validate.js +80 -8
  160. package/dist/commands/build/workos/jwt.d.ts +23 -0
  161. package/dist/commands/build/workos/jwt.d.ts.map +1 -0
  162. package/dist/commands/build/workos/jwt.js +172 -0
  163. package/dist/commands/doctor.d.ts +27 -0
  164. package/dist/commands/doctor.d.ts.map +1 -0
  165. package/dist/commands/doctor.js +328 -0
  166. package/dist/commands/object/delete.d.ts +0 -2
  167. package/dist/commands/object/delete.d.ts.map +1 -1
  168. package/dist/commands/object/delete.js +3 -38
  169. package/dist/commands/object/get.d.ts +0 -2
  170. package/dist/commands/object/get.d.ts.map +1 -1
  171. package/dist/commands/object/get.js +3 -38
  172. package/dist/commands/object/list.d.ts +0 -2
  173. package/dist/commands/object/list.d.ts.map +1 -1
  174. package/dist/commands/object/list.js +5 -40
  175. package/dist/commands/object/put.d.ts +0 -2
  176. package/dist/commands/object/put.d.ts.map +1 -1
  177. package/dist/commands/object/put.js +3 -38
  178. package/dist/commands/query/chunk-search.d.ts +0 -2
  179. package/dist/commands/query/chunk-search.d.ts.map +1 -1
  180. package/dist/commands/query/chunk-search.js +12 -46
  181. package/dist/commands/query/document.d.ts +1 -3
  182. package/dist/commands/query/document.d.ts.map +1 -1
  183. package/dist/commands/query/document.js +16 -60
  184. package/dist/commands/query/search.d.ts +0 -2
  185. package/dist/commands/query/search.d.ts.map +1 -1
  186. package/dist/commands/query/search.js +12 -46
  187. package/dist/feature-catalog.d.ts +28 -0
  188. package/dist/feature-catalog.d.ts.map +1 -0
  189. package/dist/feature-catalog.js +104 -0
  190. package/dist/index.d.ts.map +1 -1
  191. package/dist/index.js +16 -2
  192. package/oclif.manifest.json +4811 -3433
  193. package/package.json +3 -3
  194. package/templates/examples/smartbucket-minimal.ts.hbs +87 -0
  195. package/templates/examples/smartmemory-minimal.ts.hbs +82 -0
  196. package/templates/examples/smartsql-minimal.ts.hbs +69 -0
  197. package/templates/handlers/actor/index.test.ts.hbs +48 -85
  198. package/templates/handlers/actor/index.ts.hbs +16 -316
  199. package/templates/handlers/bucket-event-notification/index.ts.hbs +32 -235
  200. package/templates/handlers/bucket-event-observer.ts.hbs +79 -0
  201. package/templates/handlers/http-service/index.test.ts.hbs +3 -0
  202. package/templates/handlers/http-service/index.ts.hbs +43 -15
  203. package/templates/handlers/queue-consumer-setup.ts.hbs +45 -0
  204. package/templates/handlers/task/index.test.ts.hbs +30 -112
  205. package/templates/handlers/task/index.ts.hbs +19 -58
  206. package/templates/init/RAINDROP.md.hbs +97 -1
  207. package/templates/init/eslint.config.js +43 -0
  208. package/templates/init/package.json.hbs +4 -1
  209. package/templates/init/tsconfig.json +3 -3
  210. package/bundle/chunk-23UBI7BN.js +0 -48
  211. package/bundle/chunk-2QWMBNE3.js +0 -384
  212. package/bundle/chunk-45IYWQDC.js +0 -384
  213. package/bundle/chunk-5YUO23QU.js +0 -4585
  214. package/bundle/chunk-6MIGCNUO.js +0 -75
  215. package/bundle/chunk-7ZJWA6HP.js +0 -805
  216. package/bundle/chunk-AIYVX2M7.js +0 -44
  217. package/bundle/chunk-BB5TNIEM.js +0 -48
  218. package/bundle/chunk-BUR3HFKH.js +0 -488
  219. package/bundle/chunk-BYSBS7KT.js +0 -488
  220. package/bundle/chunk-CX3RWI62.js +0 -28658
  221. package/bundle/chunk-DLH7MI57.js +0 -305
  222. package/bundle/chunk-E3WJIYJZ.js +0 -12148
  223. package/bundle/chunk-EX7NOPRF.js +0 -12148
  224. package/bundle/chunk-F76JQS2J.js +0 -231
  225. package/bundle/chunk-FBOXMVKD.js +0 -28679
  226. package/bundle/chunk-FTPZ6SQW.js +0 -238909
  227. package/bundle/chunk-H3CFZ7ZH.js +0 -74
  228. package/bundle/chunk-HXOILVWA.js +0 -384
  229. package/bundle/chunk-IMP7O5AC.js +0 -22452
  230. package/bundle/chunk-IPYOAKRE.js +0 -231
  231. package/bundle/chunk-J7HN6XF2.js +0 -4461
  232. package/bundle/chunk-JOLOAALA.js +0 -231
  233. package/bundle/chunk-JZ2G4Q35.js +0 -4585
  234. package/bundle/chunk-KVAWPWF7.js +0 -231
  235. package/bundle/chunk-MEUAAIXV.js +0 -28657
  236. package/bundle/chunk-QBWFE57Z.js +0 -384
  237. package/bundle/chunk-SP3LOXPC.js +0 -46
  238. package/bundle/chunk-T7C564PR.js +0 -28678
  239. package/bundle/chunk-UFH545WJ.js +0 -22452
  240. package/bundle/chunk-UHVMPWM5.js +0 -315
  241. package/bundle/chunk-VB7ZTSZV.js +0 -1089
  242. package/bundle/chunk-VBIJDFMJ.js +0 -384
  243. package/bundle/chunk-VR7RLTE3.js +0 -231
  244. package/bundle/chunk-WFZUJLEC.js +0 -231
  245. package/bundle/chunk-YDGJTLVZ.js +0 -133
  246. package/bundle/chunk-YPNQ7UFK.js +0 -502
  247. package/bundle/chunk-YXFDRMSN.js +0 -384
  248. package/dist/lib/dns-utils.d.ts +0 -7
  249. package/dist/lib/dns-utils.d.ts.map +0 -1
  250. package/dist/lib/dns-utils.js +0 -44
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@liquidmetal-ai/raindrop",
3
3
  "description": "CLI for the Raindrop platform",
4
- "version": "0.13.0",
4
+ "version": "0.15.0",
5
5
  "author": "bosgood",
6
6
  "bin": {
7
7
  "raindrop": "./bin/run.js"
@@ -35,8 +35,8 @@
35
35
  "typescript": "^5",
36
36
  "zod": "^3.23.8",
37
37
  "zx": "^8.1.9",
38
- "@liquidmetal-ai/drizzle": "0.13.0",
39
- "@liquidmetal-ai/raindrop-framework": "0.13.0"
38
+ "@liquidmetal-ai/drizzle": "0.15.0",
39
+ "@liquidmetal-ai/raindrop-framework": "0.15.0"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@changesets/cli": "^2.27.9",
@@ -0,0 +1,87 @@
1
+ import { Service } from '@liquidmetal-ai/raindrop-framework';
2
+ import { Env } from '../{{handlerName}}/raindrop.gen';
3
+
4
+ /**
5
+ * SmartBucket Minimal Example
6
+ *
7
+ * IMPORTANT: SmartBucket provides basic file storage operations.
8
+ * Available methods: put(), get(), delete(), list(), head()
9
+ * NOT available: search(), query(), find() - these do not exist!
10
+ *
11
+ * This example shows how to use SmartBucket for file storage:
12
+ * - Upload files with put()
13
+ * - Download files with get()
14
+ * - Get file metadata with head()
15
+ * - List files with list()
16
+ */
17
+ export default class SmartBucketExample extends Service<Env> {
18
+ async fetch(request: Request): Promise<Response> {
19
+ const url = new URL(request.url);
20
+ const path = url.pathname;
21
+
22
+ try {
23
+ // POST /upload - Upload a file
24
+ if (path === '/upload' && request.method === 'POST') {
25
+ const formData = await request.formData();
26
+ const file = formData.get('file') as File;
27
+ if (!file) {
28
+ return new Response('No file provided', { status: 400 });
29
+ }
30
+
31
+ const result = await this.env.{{bindingName}}.put(file.name, file.stream(), {
32
+ httpMetadata: {
33
+ contentType: file.type,
34
+ },
35
+ });
36
+
37
+ return new Response(JSON.stringify({
38
+ message: 'File uploaded successfully',
39
+ key: result.key,
40
+ size: result.size,
41
+ }), {
42
+ headers: { 'Content-Type': 'application/json' },
43
+ });
44
+ }
45
+
46
+ // GET /files/:key - Download a file
47
+ if (path.startsWith('/files/') && request.method === 'GET') {
48
+ const key = path.split('/files/')[1] || '';
49
+ const object = await this.env.{{bindingName}}.get(key);
50
+
51
+ if (!object) {
52
+ return new Response('File not found', { status: 404 });
53
+ }
54
+
55
+ return new Response(object.body, {
56
+ headers: {
57
+ 'Content-Type': object.httpMetadata?.contentType || 'application/octet-stream',
58
+ },
59
+ });
60
+ }
61
+
62
+ // GET /list - List all files
63
+ if (path === '/list' && request.method === 'GET') {
64
+ const objects = await this.env.{{bindingName}}.list();
65
+
66
+ return new Response(JSON.stringify({
67
+ files: objects.objects.map(obj => ({
68
+ key: obj.key,
69
+ size: obj.size,
70
+ uploaded: obj.uploaded,
71
+ })),
72
+ }), {
73
+ headers: { 'Content-Type': 'application/json' },
74
+ });
75
+ }
76
+
77
+ return new Response('Not found', { status: 404 });
78
+ } catch (error) {
79
+ return new Response(JSON.stringify({
80
+ error: error instanceof Error ? error.message : 'Unknown error',
81
+ }), {
82
+ status: 500,
83
+ headers: { 'Content-Type': 'application/json' },
84
+ });
85
+ }
86
+ }
87
+ }
@@ -0,0 +1,82 @@
1
+ import { Service } from '@liquidmetal-ai/raindrop-framework';
2
+ import { Env } from '../{{handlerName}}/raindrop.gen';
3
+
4
+ /**
5
+ * SmartMemory Minimal Example
6
+ *
7
+ * IMPORTANT: Session Management Pattern
8
+ * - NEW session: startWorkingMemorySession() → returns {sessionId, workingMemory}
9
+ * - EXISTING session: getWorkingMemorySession(sessionId) → returns workingMemory
10
+ *
11
+ * Always use the sessionId returned from startWorkingMemorySession().
12
+ * To continue a conversation, use getWorkingMemorySession(existingSessionId).
13
+ *
14
+ * This example shows how to use SmartMemory for conversation management:
15
+ * - Start a memory session
16
+ * - Store conversation messages
17
+ * - Retrieve conversation history
18
+ * - Search and summarize memories
19
+ */
20
+ export default class SmartMemoryExample extends Service<Env> {
21
+ async fetch(_request: Request): Promise<Response> {
22
+ try {
23
+ // Start a new memory session
24
+ const { sessionId, workingMemory } =
25
+ await this.env.{{bindingName}}.startWorkingMemorySession();
26
+
27
+ // Store conversation messages
28
+ await workingMemory.putMemory({
29
+ content: 'User: Hello! I need help with my project.',
30
+ key: 'message_1',
31
+ timeline: 'conversation',
32
+ agent: 'user',
33
+ });
34
+
35
+ await workingMemory.putMemory({
36
+ content: 'Assistant: I would be happy to help! What kind of project are you working on?',
37
+ key: 'message_2',
38
+ timeline: 'conversation',
39
+ agent: 'assistant',
40
+ });
41
+
42
+ await workingMemory.putMemory({
43
+ content: 'User: It is a web application using TypeScript.',
44
+ key: 'message_3',
45
+ timeline: 'conversation',
46
+ agent: 'user',
47
+ });
48
+
49
+ // Get recent conversation history
50
+ const recentMemories = await workingMemory.getMemory({
51
+ nMostRecent: 10,
52
+ });
53
+
54
+ // Search memories
55
+ const searchResults = await workingMemory.searchMemory({
56
+ terms: 'project TypeScript',
57
+ nMostRecent: 5,
58
+ });
59
+
60
+ // Summarize conversation
61
+ const summary = recentMemories
62
+ ? await workingMemory.summarizeMemory(recentMemories)
63
+ : null;
64
+
65
+ return new Response(JSON.stringify({
66
+ sessionId,
67
+ recentMemories,
68
+ searchResults,
69
+ summary,
70
+ }, null, 2), {
71
+ headers: { 'Content-Type': 'application/json' },
72
+ });
73
+ } catch (error) {
74
+ return new Response(JSON.stringify({
75
+ error: error instanceof Error ? error.message : 'Unknown error',
76
+ }), {
77
+ status: 500,
78
+ headers: { 'Content-Type': 'application/json' },
79
+ });
80
+ }
81
+ }
82
+ }
@@ -0,0 +1,69 @@
1
+ import { Service } from '@liquidmetal-ai/raindrop-framework';
2
+ import { Env } from '../{{handlerName}}/raindrop.gen';
3
+
4
+ /**
5
+ * SmartSQL Minimal Example
6
+ *
7
+ * IMPORTANT: SmartSQL API Methods
8
+ * - executeQuery({ sqlQuery, format }) - Run direct SQL
9
+ * - executeQuery({ textQuery, format }) - Natural language to SQL
10
+ * - getMetadata(tableName?) - Get database schema info
11
+ * - updateMetadata(tables, mode?) - Update schema metadata
12
+ * - getPiiData(tableName, recordId?) - Get PII detection results
13
+ *
14
+ * This example shows how to use SmartSQL for database operations:
15
+ * - Execute direct SQL queries
16
+ * - Use natural language queries
17
+ * - Get and update database metadata
18
+ */
19
+ export default class SmartSqlExample extends Service<Env> {
20
+ async fetch(_request: Request): Promise<Response> {
21
+ try {
22
+ // Create a table
23
+ await this.env.{{bindingName}}.executeQuery({
24
+ sqlQuery: `
25
+ CREATE TABLE IF NOT EXISTS users (
26
+ id INTEGER PRIMARY KEY,
27
+ name TEXT NOT NULL,
28
+ email TEXT UNIQUE NOT NULL
29
+ )
30
+ `,
31
+ });
32
+
33
+ // Insert data
34
+ await this.env.{{bindingName}}.executeQuery({
35
+ sqlQuery: "INSERT OR IGNORE INTO users (id, name, email) VALUES (1, 'Alice', 'alice@example.com')",
36
+ });
37
+
38
+ // Query with SQL
39
+ const sqlResult = await this.env.{{bindingName}}.executeQuery({
40
+ sqlQuery: 'SELECT * FROM users',
41
+ format: 'json',
42
+ });
43
+
44
+ // Query with natural language
45
+ const nlResult = await this.env.{{bindingName}}.executeQuery({
46
+ textQuery: 'Show all users',
47
+ format: 'json',
48
+ });
49
+
50
+ // Get database metadata
51
+ const metadata = await this.env.{{bindingName}}.getMetadata('users');
52
+
53
+ return new Response(JSON.stringify({
54
+ sqlResult,
55
+ nlResult,
56
+ metadata,
57
+ }, null, 2), {
58
+ headers: { 'Content-Type': 'application/json' },
59
+ });
60
+ } catch (error) {
61
+ return new Response(JSON.stringify({
62
+ error: error instanceof Error ? error.message : 'Unknown error',
63
+ }), {
64
+ status: 500,
65
+ headers: { 'Content-Type': 'application/json' },
66
+ });
67
+ }
68
+ }
69
+ }
@@ -1,21 +1,19 @@
1
1
  /**
2
2
  * Tests for Actor Handler
3
- *
4
- * BALANCED TESTING PATTERN:
5
- * - Simple setup (2 minutes)
6
- * - Essential production safety (5 critical tests)
7
- * - No complex mock factories
8
- * - Tests actual business logic, not just "doesn't crash"
9
- *
10
- * For 95% of cases, this template provides adequate safety net.
3
+ *
4
+ * FOCUSED TESTING APPROACH:
5
+ * - Simple, essential tests for actor state management
6
+ * - Tests actual methods, not just instantiation
7
+ * - Covers basic error scenarios
8
+ * - Easy to extend with additional tests
11
9
  */
12
10
 
13
11
  import { expect, test, describe, beforeEach, vi } from 'vitest';
14
12
 
15
- // Simple mock state - no complex implementations
13
+ // Simple mock state - stores data in memory
16
14
  function createMockActorState(id: string = 'test-actor') {
17
15
  const data = new Map<string, unknown>();
18
-
16
+
19
17
  return {
20
18
  id,
21
19
  storage: {
@@ -33,7 +31,7 @@ function createMockActorState(id: string = 'test-actor') {
33
31
  };
34
32
  }
35
33
 
36
- // Simple mock environment - add your actual bindings here
34
+ // Simple mock environment with only what this template uses
37
35
  function createMockEnv() {
38
36
  return {
39
37
  _raindrop: {
@@ -47,10 +45,7 @@ function createMockEnv() {
47
45
  error: vi.fn(),
48
46
  warn: vi.fn(),
49
47
  },
50
- // Add your environment bindings that the actor uses:
51
- // DATABASE: { executeQuery: vi.fn() },
52
- // CACHE: { get: vi.fn(), put: vi.fn() },
53
- // BUCKET: { get: vi.fn(), put: vi.fn() },
48
+ // Add additional bindings here as you add features to your actor
54
49
  };
55
50
  }
56
51
 
@@ -68,90 +63,58 @@ describe('{{actorClassName}}', () => {
68
63
  await actor.initialize();
69
64
  });
70
65
 
71
- test('can instantiate actor', () => {
66
+ test('actor instantiates correctly', () => {
72
67
  expect(actor).toBeDefined();
73
- expect(typeof actor.incrementCounter).toBe('function');
74
- expect(typeof actor.processMessage).toBe('function');
68
+ expect(typeof actor.increment).toBe('function');
69
+ expect(typeof actor.getCount).toBe('function');
75
70
  });
76
71
 
77
72
  test('initializes with default state', async () => {
78
- const stateData = await actor.getState();
79
- expect(stateData).toBeDefined();
80
- expect(stateData!.count).toBe(0);
81
- expect(stateData!.messages).toEqual([]);
82
- expect(stateData!.lastUpdated).toBeDefined();
73
+ const count = await actor.getCount();
74
+ expect(count).toBe(0);
83
75
  });
84
76
 
85
- // === ESSENTIAL PRODUCTION SAFETY TESTS ===
86
-
87
- test('manages state correctly', async () => {
88
- await actor.incrementCounter();
89
- const count = await actor.getCounter();
90
- expect(count).toBe(1);
91
-
92
- const storedData = await actor.getState();
93
- expect(storedData!.count).toBe(1);
77
+ test('has access to environment bindings', () => {
78
+ expect(env.logger).toBeDefined();
79
+ expect(env._raindrop).toBeDefined();
80
+ expect(env._raindrop.app.organizationId).toBe('test-org');
94
81
  });
95
82
 
96
- test('processes messages without crashing', async () => {
97
- const result = await actor.processMessage('test message');
98
- expect(result).toBeDefined();
99
- expect(result.content).toBe('test message');
100
- expect(result.id).toBeDefined();
101
- expect(result.timestamp).toBeDefined();
102
- });
83
+ // === Essential Actor Tests ===
103
84
 
104
- test('handles storage operations', async () => {
105
- // Mock the actor's save/load methods if they exist
106
- const testData = { test: 'data' };
107
-
108
- // Test that storage calls don't crash
109
- expect(() => actor.saveToBucket && actor.saveToBucket('test-key', testData)).not.toThrow();
110
- expect(() => actor.loadFromBucket && actor.loadFromBucket('test-key')).not.toThrow();
85
+ test('increments counter correctly', async () => {
86
+ const firstCount = await actor.increment();
87
+ expect(firstCount).toBe(1);
88
+
89
+ const secondCount = await actor.increment();
90
+ expect(secondCount).toBe(2);
91
+
92
+ const retrievedCount = await actor.getCount();
93
+ expect(retrievedCount).toBe(2);
111
94
  });
112
95
 
113
- test('handles cache operations', async () => {
114
- // Test cache operations if they exist
115
- const testData = { value: 42 };
116
-
117
- expect(() => actor.cacheResult && actor.cacheResult('test-key', testData)).not.toThrow();
118
- expect(() => actor.getCachedResult && actor.getCachedResult('test-key')).not.toThrow();
96
+ test('stores and retrieves data correctly', async () => {
97
+ await actor.updateData('testKey', 'testValue');
98
+ const value = await actor.getData('testKey');
99
+ expect(value).toBe('testValue');
119
100
  });
120
101
 
121
- test('can access environment bindings', () => {
122
- expect(env.logger).toBeDefined();
123
- expect(env._raindrop).toBeDefined();
124
- expect(env._raindrop.app.organizationId).toBe('test-org');
102
+ test('handles complex data structures', async () => {
103
+ const complexData = {
104
+ nested: { value: 123 },
105
+ array: [1, 2, 3],
106
+ text: 'test',
107
+ };
108
+
109
+ await actor.updateData('complex', complexData);
110
+ const retrieved = await actor.getData('complex');
111
+ expect(retrieved).toEqual(complexData);
125
112
  });
126
113
 
127
- test('handles edge cases gracefully', async () => {
128
- // Test null/undefined inputs
129
- await expect(actor.processMessage(null as any)).resolves.toBeDefined();
130
- await expect(actor.processMessage(undefined as any)).resolves.toBeDefined();
131
-
132
- // Test special characters
133
- const specialMessage = '<script>alert("xss")</script>';
134
- const result = await actor.processMessage(specialMessage);
135
- expect(result.content).toBe(specialMessage);
136
-
137
- // Test unicode
138
- const unicodeMessage = 'Hello 世界 🌍';
139
- const unicodeResult = await actor.processMessage(unicodeMessage);
140
- expect(unicodeResult.content).toBe(unicodeMessage);
114
+ test('returns undefined for nonexistent keys', async () => {
115
+ const value = await actor.getData('nonexistent');
116
+ expect(value).toBeUndefined();
141
117
  });
142
118
 
143
- // ADD CUSTOM BUSINESS LOGIC TESTS HERE
144
- // Example:
145
- // test('increments counter correctly', async () => {
146
- // await actor.incrementCounter();
147
- // await actor.incrementCounter();
148
- // const count = await actor.getCounter();
149
- // expect(count).toBe(2);
150
- // });
151
- //
152
- // test('handles alarms correctly', async () => {
153
- // await actor.schedulePeriodicTask('test-task', 60);
154
- // const alarm = await state.storage.getAlarm();
155
- // expect(alarm).toBeGreaterThan(Date.now());
156
- // });
157
- });
119
+ // === Add Your Custom Tests Here ===
120
+ });