@swirls/looms 0.0.1

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 (270) hide show
  1. package/LICENSE +190 -0
  2. package/README.md +9 -0
  3. package/dist/actor/cell.d.ts +27 -0
  4. package/dist/actor/cell.js +41 -0
  5. package/dist/actor/host.d.ts +27 -0
  6. package/dist/actor/host.js +82 -0
  7. package/dist/actor/index.d.ts +3 -0
  8. package/dist/actor/index.js +3 -0
  9. package/dist/actor/routing.d.ts +15 -0
  10. package/dist/actor/routing.js +80 -0
  11. package/dist/agent/definitions-store.d.ts +11 -0
  12. package/dist/agent/definitions-store.js +10 -0
  13. package/dist/agent/definitions.d.ts +152 -0
  14. package/dist/agent/definitions.js +74 -0
  15. package/dist/agent/effects.d.ts +425 -0
  16. package/dist/agent/effects.js +318 -0
  17. package/dist/agent/events.d.ts +170 -0
  18. package/dist/agent/events.js +61 -0
  19. package/dist/agent/index.d.ts +13 -0
  20. package/dist/agent/index.js +13 -0
  21. package/dist/agent/llm.d.ts +35 -0
  22. package/dist/agent/llm.js +48 -0
  23. package/dist/agent/module.d.ts +1037 -0
  24. package/dist/agent/module.js +27 -0
  25. package/dist/agent/projections.d.ts +17 -0
  26. package/dist/agent/projections.js +81 -0
  27. package/dist/agent/scope.d.ts +171 -0
  28. package/dist/agent/scope.js +7 -0
  29. package/dist/agent/signals.d.ts +17 -0
  30. package/dist/agent/signals.js +19 -0
  31. package/dist/agent/stop-when.d.ts +12 -0
  32. package/dist/agent/stop-when.js +6 -0
  33. package/dist/agent/threads.d.ts +34 -0
  34. package/dist/agent/threads.js +407 -0
  35. package/dist/agent/tool-schema.d.ts +21 -0
  36. package/dist/agent/tool-schema.js +67 -0
  37. package/dist/agent/types.d.ts +87 -0
  38. package/dist/agent/types.js +32 -0
  39. package/dist/ai-vercel/index.d.ts +2 -0
  40. package/dist/ai-vercel/index.js +2 -0
  41. package/dist/ai-vercel/messages.d.ts +9 -0
  42. package/dist/ai-vercel/messages.js +68 -0
  43. package/dist/ai-vercel/vercel-llm.d.ts +8 -0
  44. package/dist/ai-vercel/vercel-llm.js +98 -0
  45. package/dist/approval/effects.d.ts +133 -0
  46. package/dist/approval/effects.js +13 -0
  47. package/dist/approval/events.d.ts +52 -0
  48. package/dist/approval/events.js +28 -0
  49. package/dist/approval/index.d.ts +6 -0
  50. package/dist/approval/index.js +6 -0
  51. package/dist/approval/module.d.ts +342 -0
  52. package/dist/approval/module.js +10 -0
  53. package/dist/approval/projections.d.ts +42 -0
  54. package/dist/approval/projections.js +57 -0
  55. package/dist/approval/scope.d.ts +45 -0
  56. package/dist/approval/scope.js +7 -0
  57. package/dist/approval/signals.d.ts +19 -0
  58. package/dist/approval/signals.js +34 -0
  59. package/dist/cli/cli.d.ts +2 -0
  60. package/dist/cli/cli.js +6 -0
  61. package/dist/cli/commands.d.ts +13 -0
  62. package/dist/cli/commands.js +133 -0
  63. package/dist/cli/index.d.ts +1 -0
  64. package/dist/cli/index.js +1 -0
  65. package/dist/client/client.d.ts +69 -0
  66. package/dist/client/client.js +179 -0
  67. package/dist/client/index.d.ts +2 -0
  68. package/dist/client/index.js +2 -0
  69. package/dist/client/sse.d.ts +10 -0
  70. package/dist/client/sse.js +103 -0
  71. package/dist/cloudflare/alarm-scheduler.d.ts +9 -0
  72. package/dist/cloudflare/alarm-scheduler.js +13 -0
  73. package/dist/cloudflare/durable-object.d.ts +24 -0
  74. package/dist/cloudflare/durable-object.js +43 -0
  75. package/dist/cloudflare/event-store.d.ts +10 -0
  76. package/dist/cloudflare/event-store.js +18 -0
  77. package/dist/cloudflare/index.d.ts +4 -0
  78. package/dist/cloudflare/index.js +4 -0
  79. package/dist/cloudflare/router.d.ts +12 -0
  80. package/dist/cloudflare/router.js +26 -0
  81. package/dist/core/bun-sqlite.d.ts +13 -0
  82. package/dist/core/bun-sqlite.js +19 -0
  83. package/dist/core/catalog.d.ts +49 -0
  84. package/dist/core/catalog.js +39 -0
  85. package/dist/core/coalesce.d.ts +21 -0
  86. package/dist/core/coalesce.js +178 -0
  87. package/dist/core/compose.d.ts +59 -0
  88. package/dist/core/compose.js +97 -0
  89. package/dist/core/cursor.d.ts +16 -0
  90. package/dist/core/cursor.js +46 -0
  91. package/dist/core/effects.d.ts +110 -0
  92. package/dist/core/effects.js +99 -0
  93. package/dist/core/envelope.d.ts +79 -0
  94. package/dist/core/envelope.js +68 -0
  95. package/dist/core/event-codec.d.ts +8 -0
  96. package/dist/core/event-codec.js +82 -0
  97. package/dist/core/event-index.d.ts +28 -0
  98. package/dist/core/event-index.js +86 -0
  99. package/dist/core/fold.d.ts +19 -0
  100. package/dist/core/fold.js +362 -0
  101. package/dist/core/ids.d.ts +11 -0
  102. package/dist/core/ids.js +47 -0
  103. package/dist/core/index.d.ts +26 -0
  104. package/dist/core/index.js +25 -0
  105. package/dist/core/match.d.ts +8 -0
  106. package/dist/core/match.js +58 -0
  107. package/dist/core/module-scope.d.ts +99 -0
  108. package/dist/core/module-scope.js +72 -0
  109. package/dist/core/module.d.ts +74 -0
  110. package/dist/core/module.js +3 -0
  111. package/dist/core/projection.d.ts +83 -0
  112. package/dist/core/projection.js +241 -0
  113. package/dist/core/protocol.d.ts +99 -0
  114. package/dist/core/protocol.js +101 -0
  115. package/dist/core/replay.d.ts +13 -0
  116. package/dist/core/replay.js +34 -0
  117. package/dist/core/schema.d.ts +35 -0
  118. package/dist/core/schema.js +130 -0
  119. package/dist/core/serialize.d.ts +14 -0
  120. package/dist/core/serialize.js +42 -0
  121. package/dist/core/snapshot-store.d.ts +39 -0
  122. package/dist/core/snapshot-store.js +53 -0
  123. package/dist/core/snapshots.d.ts +26 -0
  124. package/dist/core/snapshots.js +100 -0
  125. package/dist/core/sqlite-store.d.ts +31 -0
  126. package/dist/core/sqlite-store.js +328 -0
  127. package/dist/core/state.d.ts +43 -0
  128. package/dist/core/state.js +31 -0
  129. package/dist/core/store.d.ts +146 -0
  130. package/dist/core/store.js +229 -0
  131. package/dist/core/thread.d.ts +41 -0
  132. package/dist/core/thread.js +13 -0
  133. package/dist/core/types.d.ts +27 -0
  134. package/dist/core/types.js +42 -0
  135. package/dist/core/validate-event.d.ts +19 -0
  136. package/dist/core/validate-event.js +42 -0
  137. package/dist/debugger/components/debugger-split.d.ts +23 -0
  138. package/dist/debugger/components/debugger-split.js +25 -0
  139. package/dist/debugger/components/event-inspector.d.ts +5 -0
  140. package/dist/debugger/components/event-inspector.js +38 -0
  141. package/dist/debugger/components/event-stream.d.ts +13 -0
  142. package/dist/debugger/components/event-stream.js +119 -0
  143. package/dist/debugger/components/json-view.d.ts +5 -0
  144. package/dist/debugger/components/json-view.js +5 -0
  145. package/dist/debugger/components/run-tree.d.ts +14 -0
  146. package/dist/debugger/components/run-tree.js +38 -0
  147. package/dist/debugger/components/status-dot.d.ts +3 -0
  148. package/dist/debugger/components/status-dot.js +5 -0
  149. package/dist/debugger/contracts.d.ts +22 -0
  150. package/dist/debugger/contracts.js +1 -0
  151. package/dist/debugger/events/catalog.d.ts +6 -0
  152. package/dist/debugger/events/catalog.js +27 -0
  153. package/dist/debugger/events/domain-summarize.d.ts +3 -0
  154. package/dist/debugger/events/domain-summarize.js +107 -0
  155. package/dist/debugger/events/family.d.ts +8 -0
  156. package/dist/debugger/events/family.js +44 -0
  157. package/dist/debugger/events/protocol-summarize.d.ts +3 -0
  158. package/dist/debugger/events/protocol-summarize.js +70 -0
  159. package/dist/debugger/index.d.ts +17 -0
  160. package/dist/debugger/index.js +16 -0
  161. package/dist/debugger/lib/cn.d.ts +5 -0
  162. package/dist/debugger/lib/cn.js +17 -0
  163. package/dist/debugger/lib/event-counts.d.ts +5 -0
  164. package/dist/debugger/lib/event-counts.js +23 -0
  165. package/dist/debugger/lib/event-meta.d.ts +8 -0
  166. package/dist/debugger/lib/event-meta.js +20 -0
  167. package/dist/debugger/lib/project-run.d.ts +9 -0
  168. package/dist/debugger/lib/project-run.js +14 -0
  169. package/dist/debugger/lib/status.d.ts +3 -0
  170. package/dist/debugger/lib/status.js +31 -0
  171. package/dist/debugger/lib/visible-events.d.ts +8 -0
  172. package/dist/debugger/lib/visible-events.js +21 -0
  173. package/dist/debugger/styles.css +71 -0
  174. package/dist/debugger/ui/checkbox.d.ts +4 -0
  175. package/dist/debugger/ui/checkbox.js +9 -0
  176. package/dist/debugger/ui/input.d.ts +3 -0
  177. package/dist/debugger/ui/input.js +7 -0
  178. package/dist/debugger/ui/scroll-area.d.ts +9 -0
  179. package/dist/debugger/ui/scroll-area.js +10 -0
  180. package/dist/debugger/ui/tabs.d.ts +7 -0
  181. package/dist/debugger/ui/tabs.js +17 -0
  182. package/dist/index.d.ts +2 -0
  183. package/dist/index.js +2 -0
  184. package/dist/projectors/index-model.d.ts +56 -0
  185. package/dist/projectors/index-model.js +117 -0
  186. package/dist/projectors/index.d.ts +4 -0
  187. package/dist/projectors/index.js +3 -0
  188. package/dist/projectors/memory.d.ts +5 -0
  189. package/dist/projectors/memory.js +77 -0
  190. package/dist/projectors/postgres.d.ts +9 -0
  191. package/dist/projectors/postgres.js +108 -0
  192. package/dist/projectors/projector.d.ts +11 -0
  193. package/dist/projectors/projector.js +1 -0
  194. package/dist/projectors/schema.d.ts +5 -0
  195. package/dist/projectors/schema.js +43 -0
  196. package/dist/projectors/sqlite.d.ts +9 -0
  197. package/dist/projectors/sqlite.js +103 -0
  198. package/dist/projectors/with-projectors.d.ts +17 -0
  199. package/dist/projectors/with-projectors.js +55 -0
  200. package/dist/react/derived.d.ts +19 -0
  201. package/dist/react/derived.js +50 -0
  202. package/dist/react/index.d.ts +6 -0
  203. package/dist/react/index.js +5 -0
  204. package/dist/react/materialize.d.ts +3 -0
  205. package/dist/react/materialize.js +86 -0
  206. package/dist/react/notify.d.ts +18 -0
  207. package/dist/react/notify.js +80 -0
  208. package/dist/react/react.d.ts +61 -0
  209. package/dist/react/react.js +187 -0
  210. package/dist/react/register.d.ts +31 -0
  211. package/dist/react/register.js +1 -0
  212. package/dist/react/sse.d.ts +1 -0
  213. package/dist/react/sse.js +1 -0
  214. package/dist/react/store.d.ts +56 -0
  215. package/dist/react/store.js +340 -0
  216. package/dist/react/tables.d.ts +21 -0
  217. package/dist/react/tables.js +6 -0
  218. package/dist/runtime/dispatch-effect.d.ts +3 -0
  219. package/dist/runtime/dispatch-effect.js +113 -0
  220. package/dist/runtime/events-api.d.ts +4 -0
  221. package/dist/runtime/events-api.js +84 -0
  222. package/dist/runtime/index.d.ts +5 -0
  223. package/dist/runtime/index.js +5 -0
  224. package/dist/runtime/looms.d.ts +74 -0
  225. package/dist/runtime/looms.js +109 -0
  226. package/dist/runtime/runtime-helpers.d.ts +51 -0
  227. package/dist/runtime/runtime-helpers.js +230 -0
  228. package/dist/runtime/runtime.d.ts +91 -0
  229. package/dist/runtime/runtime.js +531 -0
  230. package/dist/runtime/server.d.ts +17 -0
  231. package/dist/runtime/server.js +226 -0
  232. package/dist/runtime/sse.d.ts +15 -0
  233. package/dist/runtime/sse.js +96 -0
  234. package/dist/runtime/wake-scheduler.d.ts +8 -0
  235. package/dist/runtime/wake-scheduler.js +38 -0
  236. package/dist/s2/config.d.ts +27 -0
  237. package/dist/s2/config.js +54 -0
  238. package/dist/s2/index.d.ts +6 -0
  239. package/dist/s2/index.js +6 -0
  240. package/dist/s2/lite.d.ts +26 -0
  241. package/dist/s2/lite.js +150 -0
  242. package/dist/s2/projector.d.ts +8 -0
  243. package/dist/s2/projector.js +28 -0
  244. package/dist/s2/serialize.d.ts +1 -0
  245. package/dist/s2/serialize.js +1 -0
  246. package/dist/s2/snapshot-store.d.ts +17 -0
  247. package/dist/s2/snapshot-store.js +320 -0
  248. package/dist/s2/store.d.ts +35 -0
  249. package/dist/s2/store.js +337 -0
  250. package/dist/testing/index.d.ts +11 -0
  251. package/dist/testing/index.js +63 -0
  252. package/dist/workflow/definitions-store.d.ts +11 -0
  253. package/dist/workflow/definitions-store.js +8 -0
  254. package/dist/workflow/definitions.d.ts +82 -0
  255. package/dist/workflow/definitions.js +32 -0
  256. package/dist/workflow/effects.d.ts +305 -0
  257. package/dist/workflow/effects.js +208 -0
  258. package/dist/workflow/events.d.ts +60 -0
  259. package/dist/workflow/events.js +39 -0
  260. package/dist/workflow/index.d.ts +8 -0
  261. package/dist/workflow/index.js +8 -0
  262. package/dist/workflow/module.d.ts +926 -0
  263. package/dist/workflow/module.js +19 -0
  264. package/dist/workflow/projections.d.ts +30 -0
  265. package/dist/workflow/projections.js +43 -0
  266. package/dist/workflow/scope.d.ts +61 -0
  267. package/dist/workflow/scope.js +7 -0
  268. package/dist/workflow/threads.d.ts +171 -0
  269. package/dist/workflow/threads.js +287 -0
  270. package/package.json +183 -0
@@ -0,0 +1,71 @@
1
+ @source "./**/*.{ts,tsx}";
2
+
3
+ @theme inline {
4
+ --color-status-running: var(--status-running);
5
+ --color-status-waiting: var(--status-waiting);
6
+ --color-status-completed: var(--status-completed);
7
+ --color-status-failed: var(--status-failed);
8
+ --color-status-cancelled: var(--status-cancelled);
9
+ --color-family-runtime: var(--family-runtime);
10
+ --color-family-agent: var(--family-agent);
11
+ --color-family-workflow: var(--family-workflow);
12
+ --color-family-approval: var(--family-approval);
13
+ --color-family-payments: var(--family-payments);
14
+ --color-family-wait: var(--family-wait);
15
+ }
16
+
17
+ :root {
18
+ --status-running: oklch(0.74 0.12 240);
19
+ --status-waiting: oklch(0.8 0.14 85);
20
+ --status-completed: oklch(0.76 0.13 155);
21
+ --status-failed: oklch(0.68 0.18 25);
22
+ --status-cancelled: oklch(0.62 0.01 260);
23
+ --family-runtime: oklch(0.76 0.13 155);
24
+ --family-agent: oklch(0.74 0.12 240);
25
+ --family-workflow: oklch(0.76 0.12 300);
26
+ --family-approval: oklch(0.8 0.14 85);
27
+ --family-payments: oklch(0.78 0.1 175);
28
+ --family-wait: oklch(0.8 0.14 85);
29
+ }
30
+
31
+ .debugger-event-stream {
32
+ container-type: inline-size;
33
+ }
34
+
35
+ .debugger-event-offset,
36
+ .debugger-event-causation,
37
+ .debugger-event-thread {
38
+ display: none;
39
+ }
40
+
41
+ @container (min-width: 24rem) {
42
+ .debugger-event-offset {
43
+ display: inline;
44
+ }
45
+ }
46
+
47
+ @container (min-width: 34rem) {
48
+ .debugger-event-thread {
49
+ display: inline;
50
+ }
51
+ }
52
+
53
+ @container (min-width: 44rem) {
54
+ .debugger-event-causation {
55
+ display: inline;
56
+ }
57
+ }
58
+
59
+ @container (max-width: 22rem) {
60
+ .debugger-follow-label {
61
+ position: absolute;
62
+ width: 1px;
63
+ height: 1px;
64
+ padding: 0;
65
+ margin: -1px;
66
+ overflow: hidden;
67
+ clip: rect(0, 0, 0, 0);
68
+ white-space: nowrap;
69
+ border: 0;
70
+ }
71
+ }
@@ -0,0 +1,4 @@
1
+ import { Checkbox as CheckboxPrimitive } from 'radix-ui';
2
+ import * as React from 'react';
3
+ declare function Checkbox({ className, ...props }: React.ComponentProps<typeof CheckboxPrimitive.Root>): React.JSX.Element;
4
+ export { Checkbox };
@@ -0,0 +1,9 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Check } from 'lucide-react';
3
+ import { Checkbox as CheckboxPrimitive } from 'radix-ui';
4
+ import * as React from 'react';
5
+ import { cn } from '../lib/cn.js';
6
+ function Checkbox({ className, ...props }) {
7
+ return (_jsx(CheckboxPrimitive.Root, { "data-slot": "checkbox", className: cn('border-input data-[state=checked]:bg-foreground data-[state=checked]:text-background focus-visible:border-ring focus-visible:ring-ring/50 peer size-3.5 shrink-0 rounded-[3px] border transition-colors outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50', className), ...props, children: _jsx(CheckboxPrimitive.Indicator, { "data-slot": "checkbox-indicator", className: "flex items-center justify-center", children: _jsx(Check, { className: "size-2.5", strokeWidth: 3 }) }) }));
8
+ }
9
+ export { Checkbox };
@@ -0,0 +1,3 @@
1
+ import * as React from 'react';
2
+ declare function Input({ className, type, ...props }: React.ComponentProps<'input'>): React.JSX.Element;
3
+ export { Input };
@@ -0,0 +1,7 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import * as React from 'react';
3
+ import { cn } from '../lib/cn.js';
4
+ function Input({ className, type, ...props }) {
5
+ return (_jsx("input", { type: type, "data-slot": "input", className: cn('border-input placeholder:text-muted-foreground focus-visible:border-ring focus-visible:ring-ring/50 flex h-8 w-full min-w-0 rounded-md border bg-transparent px-2.5 py-1 text-sm transition-colors outline-none focus-visible:ring-[3px] disabled:cursor-not-allowed disabled:opacity-50', className), ...props }));
6
+ }
7
+ export { Input };
@@ -0,0 +1,9 @@
1
+ import { ScrollArea as ScrollAreaPrimitive } from 'radix-ui';
2
+ import type { ComponentProps, Ref, UIEventHandler } from 'react';
3
+ declare function ScrollArea({ className, children, viewportRef, onViewportScroll, horizontal, ...props }: ComponentProps<typeof ScrollAreaPrimitive.Root> & {
4
+ viewportRef?: Ref<HTMLDivElement>;
5
+ onViewportScroll?: UIEventHandler<HTMLDivElement>;
6
+ horizontal?: boolean;
7
+ }): import("react").JSX.Element;
8
+ declare function ScrollBar({ className, orientation, ...props }: ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>): import("react").JSX.Element;
9
+ export { ScrollArea, ScrollBar };
@@ -0,0 +1,10 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ScrollArea as ScrollAreaPrimitive } from 'radix-ui';
3
+ import { cn } from '../lib/cn.js';
4
+ function ScrollArea({ className, children, viewportRef, onViewportScroll, horizontal = false, ...props }) {
5
+ return (_jsxs(ScrollAreaPrimitive.Root, { "data-slot": "scroll-area", type: "always", className: cn('relative overflow-hidden', className), ...props, children: [_jsx(ScrollAreaPrimitive.Viewport, { ref: viewportRef, "data-slot": "scroll-area-viewport", className: "size-full [scrollbar-width:none] rounded-[inherit] [&::-webkit-scrollbar]:hidden", onScroll: onViewportScroll, children: children }), _jsx(ScrollBar, {}), horizontal ? _jsx(ScrollBar, { orientation: "horizontal" }) : null, _jsx(ScrollAreaPrimitive.Corner, {})] }));
6
+ }
7
+ function ScrollBar({ className, orientation = 'vertical', ...props }) {
8
+ return (_jsx(ScrollAreaPrimitive.ScrollAreaScrollbar, { "data-slot": "scroll-area-scrollbar", orientation: orientation, className: cn('flex touch-none p-px select-none', orientation === 'vertical' && 'h-full w-2 border-l border-l-transparent', orientation === 'horizontal' && 'h-2 flex-col border-t border-t-transparent', className), ...props, children: _jsx(ScrollAreaPrimitive.ScrollAreaThumb, { "data-slot": "scroll-area-thumb", className: "bg-border relative flex-1 rounded-full" }) }));
9
+ }
10
+ export { ScrollArea, ScrollBar };
@@ -0,0 +1,7 @@
1
+ import { Tabs as TabsPrimitive } from 'radix-ui';
2
+ import * as React from 'react';
3
+ declare function Tabs({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Root>): React.JSX.Element;
4
+ declare function TabsList({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.List>): React.JSX.Element;
5
+ declare function TabsTrigger({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Trigger>): React.JSX.Element;
6
+ declare function TabsContent({ className, ...props }: React.ComponentProps<typeof TabsPrimitive.Content>): React.JSX.Element;
7
+ export { Tabs, TabsList, TabsTrigger, TabsContent };
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import { Tabs as TabsPrimitive } from 'radix-ui';
3
+ import * as React from 'react';
4
+ import { cn } from '../lib/cn.js';
5
+ function Tabs({ className, ...props }) {
6
+ return (_jsx(TabsPrimitive.Root, { "data-slot": "tabs", className: cn('flex flex-col gap-2', className), ...props }));
7
+ }
8
+ function TabsList({ className, ...props }) {
9
+ return (_jsx(TabsPrimitive.List, { "data-slot": "tabs-list", className: cn('bg-secondary text-muted-foreground inline-flex h-8 w-fit items-center justify-center rounded-md p-0.5', className), ...props }));
10
+ }
11
+ function TabsTrigger({ className, ...props }) {
12
+ return (_jsx(TabsPrimitive.Trigger, { "data-slot": "tabs-trigger", className: cn('focus-visible:ring-ring/50 data-[state=active]:bg-background data-[state=active]:text-foreground inline-flex h-7 items-center justify-center rounded-sm px-2.5 text-xs font-medium whitespace-nowrap transition-colors focus-visible:ring-[3px] focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50', className), ...props }));
13
+ }
14
+ function TabsContent({ className, ...props }) {
15
+ return (_jsx(TabsPrimitive.Content, { "data-slot": "tabs-content", className: cn('min-h-0 flex-1 outline-none', className), ...props }));
16
+ }
17
+ export { Tabs, TabsList, TabsTrigger, TabsContent };
@@ -0,0 +1,2 @@
1
+ export * from './core/index.js'
2
+ export * from './runtime/index.js'
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ export * from './core/index.js'
2
+ export * from './runtime/index.js'
@@ -0,0 +1,56 @@
1
+ import type { EventEnvelope } from '@swirls/looms/core';
2
+ import type { Projector } from './projector';
3
+ export interface ActorIndexRow {
4
+ actorId: string;
5
+ kind: string | null;
6
+ status: string | null;
7
+ definitionName: string | null;
8
+ parentActorId: string | null;
9
+ updatedAt: number;
10
+ }
11
+ export interface ReviewIndexRow {
12
+ reviewId: string;
13
+ actorId: string;
14
+ status: string;
15
+ title: string;
16
+ updatedAt: number;
17
+ }
18
+ export type IndexOp = {
19
+ type: 'upsertActor';
20
+ actorId: string;
21
+ kind: string | null;
22
+ status: string | null;
23
+ definitionName: string | null;
24
+ parentActorId: string | null;
25
+ updatedAt: number;
26
+ } | {
27
+ type: 'setActorStatus';
28
+ actorId: string;
29
+ status: string;
30
+ updatedAt: number;
31
+ } | {
32
+ type: 'upsertReview';
33
+ reviewId: string;
34
+ actorId: string;
35
+ status: string;
36
+ title: string;
37
+ updatedAt: number;
38
+ } | {
39
+ type: 'setReviewStatus';
40
+ reviewId: string;
41
+ status: string;
42
+ updatedAt: number;
43
+ };
44
+ export interface IndexBackend {
45
+ applyOps: (ops: ReadonlyArray<IndexOp>) => Promise<void>;
46
+ getActor: (actorId: string) => Promise<ActorIndexRow | null>;
47
+ listReviews: (actorId?: string) => Promise<ReviewIndexRow[]>;
48
+ init?: () => Promise<void>;
49
+ dispose?: () => Promise<void>;
50
+ }
51
+ export interface IndexProjector extends Projector {
52
+ getActor: (actorId: string) => Promise<ActorIndexRow | null>;
53
+ listReviews: (actorId?: string) => Promise<ReviewIndexRow[]>;
54
+ }
55
+ export declare function indexOpsFor(event: EventEnvelope): IndexOp[];
56
+ export declare function createIndexProjector(name: string, backend: IndexBackend): IndexProjector;
@@ -0,0 +1,117 @@
1
+ import { Predicate } from 'effect';
2
+ function payloadObject(event) {
3
+ if (!Predicate.isObject(event.payload)) {
4
+ return {};
5
+ }
6
+ return event.payload;
7
+ }
8
+ function readString(obj, key) {
9
+ const value = obj[key];
10
+ return Predicate.isString(value) ? value : undefined;
11
+ }
12
+ export function indexOpsFor(event) {
13
+ const payload = payloadObject(event);
14
+ switch (event.type) {
15
+ case 'runtime.run.started':
16
+ return [
17
+ {
18
+ type: 'upsertActor',
19
+ actorId: event.runId,
20
+ kind: readString(payload, 'kind') ?? null,
21
+ status: 'running',
22
+ definitionName: readString(payload, 'definitionName') ?? null,
23
+ parentActorId: null,
24
+ updatedAt: event.ts,
25
+ },
26
+ ];
27
+ case 'runtime.thread.started':
28
+ return [
29
+ {
30
+ type: 'upsertActor',
31
+ actorId: readString(payload, 'threadId') ?? event.threadId ?? event.runId,
32
+ kind: readString(payload, 'kind') ?? null,
33
+ status: 'running',
34
+ definitionName: readString(payload, 'definitionName') ?? null,
35
+ parentActorId: readString(payload, 'parentThreadId') ?? null,
36
+ updatedAt: event.ts,
37
+ },
38
+ ];
39
+ case 'runtime.run.completed':
40
+ case 'runtime.thread.completed':
41
+ return [
42
+ {
43
+ type: 'setActorStatus',
44
+ actorId: readString(payload, 'threadId') ?? event.threadId ?? event.runId,
45
+ status: 'completed',
46
+ updatedAt: event.ts,
47
+ },
48
+ ];
49
+ case 'runtime.thread.failed':
50
+ return [
51
+ {
52
+ type: 'setActorStatus',
53
+ actorId: readString(payload, 'threadId') ?? event.threadId ?? event.runId,
54
+ status: 'failed',
55
+ updatedAt: event.ts,
56
+ },
57
+ ];
58
+ case 'runtime.thread.cancelled':
59
+ return [
60
+ {
61
+ type: 'setActorStatus',
62
+ actorId: readString(payload, 'threadId') ?? event.threadId ?? event.runId,
63
+ status: 'cancelled',
64
+ updatedAt: event.ts,
65
+ },
66
+ ];
67
+ case 'approval.requested':
68
+ return [
69
+ {
70
+ type: 'upsertReview',
71
+ reviewId: readString(payload, 'approvalId') ?? 'unknown',
72
+ actorId: event.runId,
73
+ status: 'pending',
74
+ title: readString(payload, 'title') ?? 'Approval',
75
+ updatedAt: event.ts,
76
+ },
77
+ ];
78
+ case 'approval.decided':
79
+ return [
80
+ {
81
+ type: 'upsertReview',
82
+ reviewId: readString(payload, 'approvalId') ?? 'unknown',
83
+ actorId: event.runId,
84
+ status: payload.outcome === 'reject' ? 'rejected' : 'approved',
85
+ title: 'Approval',
86
+ updatedAt: event.ts,
87
+ },
88
+ ];
89
+ case 'approval.timed_out':
90
+ return [
91
+ {
92
+ type: 'setReviewStatus',
93
+ reviewId: readString(payload, 'approvalId') ?? 'unknown',
94
+ status: 'timed_out',
95
+ updatedAt: event.ts,
96
+ },
97
+ ];
98
+ default:
99
+ return [];
100
+ }
101
+ }
102
+ export function createIndexProjector(name, backend) {
103
+ return {
104
+ name,
105
+ init: backend.init,
106
+ dispose: backend.dispose,
107
+ project: async (events) => {
108
+ const ops = events.flatMap(indexOpsFor);
109
+ if (ops.length === 0) {
110
+ return;
111
+ }
112
+ await backend.applyOps(ops);
113
+ },
114
+ getActor: (actorId) => backend.getActor(actorId),
115
+ listReviews: (actorId) => backend.listReviews(actorId),
116
+ };
117
+ }
@@ -0,0 +1,4 @@
1
+ export type { Projector, ProjectorErrorHandler } from './projector';
2
+ export { withProjectors, projectEvents, ProjectorsStoreLive, type WithProjectorsOptions, } from './with-projectors';
3
+ export { indexOpsFor, createIndexProjector, type IndexOp, type IndexBackend, type IndexProjector, type ActorIndexRow, type ReviewIndexRow, } from './index-model';
4
+ export { memory, noop } from './memory';
@@ -0,0 +1,3 @@
1
+ export { withProjectors, projectEvents, ProjectorsStoreLive, } from './with-projectors.js';
2
+ export { indexOpsFor, createIndexProjector, } from './index-model.js';
3
+ export { memory, noop } from './memory.js';
@@ -0,0 +1,5 @@
1
+ import { type IndexProjector } from './index-model';
2
+ import type { Projector } from './projector';
3
+ export declare function memory(): IndexProjector;
4
+ /** No-op projector — safe default when indexing is disabled. */
5
+ export declare function noop(): Projector;
@@ -0,0 +1,77 @@
1
+ import { createIndexProjector, } from './index-model.js';
2
+ function applyOp(actors, reviews, op) {
3
+ switch (op.type) {
4
+ case 'upsertActor':
5
+ actors.set(op.actorId, {
6
+ actorId: op.actorId,
7
+ kind: op.kind,
8
+ status: op.status,
9
+ definitionName: op.definitionName,
10
+ parentActorId: op.parentActorId,
11
+ updatedAt: op.updatedAt,
12
+ });
13
+ return;
14
+ case 'setActorStatus': {
15
+ const existing = actors.get(op.actorId);
16
+ actors.set(op.actorId, {
17
+ actorId: op.actorId,
18
+ kind: existing?.kind ?? null,
19
+ status: op.status,
20
+ definitionName: existing?.definitionName ?? null,
21
+ parentActorId: existing?.parentActorId ?? null,
22
+ updatedAt: op.updatedAt,
23
+ });
24
+ return;
25
+ }
26
+ case 'upsertReview': {
27
+ const existing = reviews.get(op.reviewId);
28
+ reviews.set(op.reviewId, {
29
+ reviewId: op.reviewId,
30
+ actorId: op.actorId,
31
+ status: op.status,
32
+ title: existing?.title ?? op.title,
33
+ updatedAt: op.updatedAt,
34
+ });
35
+ return;
36
+ }
37
+ case 'setReviewStatus': {
38
+ const existing = reviews.get(op.reviewId);
39
+ if (existing) {
40
+ reviews.set(op.reviewId, { ...existing, status: op.status, updatedAt: op.updatedAt });
41
+ }
42
+ return;
43
+ }
44
+ default: {
45
+ const exhaustiveCheck = op;
46
+ return exhaustiveCheck;
47
+ }
48
+ }
49
+ }
50
+ export function memory() {
51
+ const actors = new Map();
52
+ const reviews = new Map();
53
+ const backend = {
54
+ applyOps: async (ops) => {
55
+ for (const op of ops) {
56
+ applyOp(actors, reviews, op);
57
+ }
58
+ },
59
+ getActor: async (actorId) => actors.get(actorId) ?? null,
60
+ listReviews: async (actorId) => {
61
+ const rows = [...reviews.values()];
62
+ return actorId ? rows.filter((row) => row.actorId === actorId) : rows;
63
+ },
64
+ dispose: async () => {
65
+ actors.clear();
66
+ reviews.clear();
67
+ },
68
+ };
69
+ return createIndexProjector('memory', backend);
70
+ }
71
+ /** No-op projector — safe default when indexing is disabled. */
72
+ export function noop() {
73
+ return {
74
+ name: 'noop',
75
+ project: async () => { },
76
+ };
77
+ }
@@ -0,0 +1,9 @@
1
+ import { type Sql } from 'postgres';
2
+ import { type IndexProjector } from './index-model';
3
+ export { POSTGRES_SCHEMA_SQL } from './schema';
4
+ export type PostgresProjectorOptions = {
5
+ url: string;
6
+ } | {
7
+ sql: Sql;
8
+ };
9
+ export declare function postgres(options: PostgresProjectorOptions): IndexProjector;
@@ -0,0 +1,108 @@
1
+ import createPostgresClient, {} from 'postgres';
2
+ import { createIndexProjector, } from './index-model.js';
3
+ import { POSTGRES_SCHEMA_SQL } from './schema.js';
4
+ export { POSTGRES_SCHEMA_SQL } from './schema.js';
5
+ function ownsClient(options) {
6
+ return 'url' in options;
7
+ }
8
+ async function applyOp(sql, op) {
9
+ switch (op.type) {
10
+ case 'upsertActor':
11
+ await sql `
12
+ INSERT INTO looms_actors (actor_id, kind, status, definition_name, parent_actor_id, updated_at)
13
+ VALUES (${op.actorId}, ${op.kind}, ${op.status}, ${op.definitionName}, ${op.parentActorId}, ${new Date(op.updatedAt)})
14
+ ON CONFLICT (actor_id) DO UPDATE SET
15
+ kind = EXCLUDED.kind,
16
+ status = EXCLUDED.status,
17
+ definition_name = EXCLUDED.definition_name,
18
+ parent_actor_id = EXCLUDED.parent_actor_id,
19
+ updated_at = EXCLUDED.updated_at
20
+ `;
21
+ return;
22
+ case 'setActorStatus':
23
+ await sql `
24
+ INSERT INTO looms_actors (actor_id, status, updated_at)
25
+ VALUES (${op.actorId}, ${op.status}, ${new Date(op.updatedAt)})
26
+ ON CONFLICT (actor_id) DO UPDATE SET
27
+ status = EXCLUDED.status,
28
+ updated_at = EXCLUDED.updated_at
29
+ `;
30
+ return;
31
+ case 'upsertReview':
32
+ await sql `
33
+ INSERT INTO looms_reviews (review_id, actor_id, status, title, updated_at)
34
+ VALUES (${op.reviewId}, ${op.actorId}, ${op.status}, ${op.title}, ${new Date(op.updatedAt)})
35
+ ON CONFLICT (review_id) DO UPDATE SET
36
+ status = EXCLUDED.status,
37
+ updated_at = EXCLUDED.updated_at
38
+ `;
39
+ return;
40
+ case 'setReviewStatus':
41
+ await sql `
42
+ UPDATE looms_reviews SET status = ${op.status}, updated_at = ${new Date(op.updatedAt)}
43
+ WHERE review_id = ${op.reviewId}
44
+ `;
45
+ return;
46
+ default: {
47
+ const exhaustiveCheck = op;
48
+ return exhaustiveCheck;
49
+ }
50
+ }
51
+ }
52
+ export function postgres(options) {
53
+ const createdClient = ownsClient(options);
54
+ const sql = createdClient ? createPostgresClient(options.url) : options.sql;
55
+ const backend = {
56
+ init: async () => {
57
+ await sql.unsafe(POSTGRES_SCHEMA_SQL);
58
+ },
59
+ applyOps: async (ops) => {
60
+ await sql.begin(async (tx) => {
61
+ for (const op of ops) {
62
+ await applyOp(tx, op);
63
+ }
64
+ });
65
+ },
66
+ getActor: async (actorId) => {
67
+ const rows = await sql `
68
+ SELECT actor_id, kind, status, definition_name, parent_actor_id, updated_at
69
+ FROM looms_actors WHERE actor_id = ${actorId}
70
+ `;
71
+ const row = rows[0];
72
+ if (!row) {
73
+ return null;
74
+ }
75
+ return {
76
+ actorId: row.actor_id,
77
+ kind: row.kind,
78
+ status: row.status,
79
+ definitionName: row.definition_name,
80
+ parentActorId: row.parent_actor_id,
81
+ updatedAt: row.updated_at.getTime(),
82
+ };
83
+ },
84
+ listReviews: async (actorId) => {
85
+ const rows = actorId
86
+ ? await sql `
87
+ SELECT review_id, actor_id, status, title, updated_at
88
+ FROM looms_reviews WHERE actor_id = ${actorId}
89
+ `
90
+ : await sql `
91
+ SELECT review_id, actor_id, status, title, updated_at FROM looms_reviews
92
+ `;
93
+ return rows.map((row) => ({
94
+ reviewId: row.review_id,
95
+ actorId: row.actor_id,
96
+ status: row.status,
97
+ title: row.title,
98
+ updatedAt: row.updated_at.getTime(),
99
+ }));
100
+ },
101
+ dispose: async () => {
102
+ if (createdClient) {
103
+ await sql.end({ timeout: 5 });
104
+ }
105
+ },
106
+ };
107
+ return createIndexProjector('postgres', backend);
108
+ }
@@ -0,0 +1,11 @@
1
+ import type { EventEnvelope } from '@swirls/looms/core';
2
+ export interface Projector {
3
+ /** Used in error reporting / diagnostics. */
4
+ readonly name: string;
5
+ /** Optional one-time setup (open connection, create tables). Runtime calls this before the first `project`. */
6
+ readonly init?: () => Promise<void>;
7
+ /** Apply a batch of events in log order. Must be idempotent (a batch may be redelivered). */
8
+ readonly project: (events: ReadonlyArray<EventEnvelope>) => Promise<void>;
9
+ readonly dispose?: () => Promise<void>;
10
+ }
11
+ export type ProjectorErrorHandler = (error: Error, projector: Projector, events: ReadonlyArray<EventEnvelope>) => void;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,5 @@
1
+ /**
2
+ * SQL schema for the optional Looms secondary index.
3
+ */
4
+ export declare const POSTGRES_SCHEMA_SQL: string;
5
+ export declare const SQLITE_SCHEMA_SQL: string;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * SQL schema for the optional Looms secondary index.
3
+ */
4
+ export const POSTGRES_SCHEMA_SQL = `
5
+ CREATE TABLE IF NOT EXISTS looms_actors (
6
+ actor_id TEXT PRIMARY KEY,
7
+ kind TEXT,
8
+ status TEXT,
9
+ definition_name TEXT,
10
+ parent_actor_id TEXT,
11
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
12
+ );
13
+
14
+ CREATE TABLE IF NOT EXISTS looms_reviews (
15
+ review_id TEXT PRIMARY KEY,
16
+ actor_id TEXT NOT NULL,
17
+ status TEXT NOT NULL,
18
+ title TEXT NOT NULL,
19
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
20
+ );
21
+
22
+ CREATE INDEX IF NOT EXISTS looms_reviews_actor_id_idx ON looms_reviews (actor_id);
23
+ `.trim();
24
+ export const SQLITE_SCHEMA_SQL = `
25
+ CREATE TABLE IF NOT EXISTS looms_actors (
26
+ actor_id TEXT PRIMARY KEY,
27
+ kind TEXT,
28
+ status TEXT,
29
+ definition_name TEXT,
30
+ parent_actor_id TEXT,
31
+ updated_at INTEGER NOT NULL
32
+ );
33
+
34
+ CREATE TABLE IF NOT EXISTS looms_reviews (
35
+ review_id TEXT PRIMARY KEY,
36
+ actor_id TEXT NOT NULL,
37
+ status TEXT NOT NULL,
38
+ title TEXT NOT NULL,
39
+ updated_at INTEGER NOT NULL
40
+ );
41
+
42
+ CREATE INDEX IF NOT EXISTS looms_reviews_actor_id_idx ON looms_reviews (actor_id);
43
+ `.trim();
@@ -0,0 +1,9 @@
1
+ import { Database } from 'bun:sqlite';
2
+ import { type IndexProjector } from './index-model';
3
+ export { SQLITE_SCHEMA_SQL } from './schema';
4
+ export type SqliteProjectorOptions = {
5
+ path?: string;
6
+ } | {
7
+ db: Database;
8
+ };
9
+ export declare function sqlite(options?: SqliteProjectorOptions): IndexProjector;