@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.
- package/LICENSE +190 -0
- package/README.md +9 -0
- package/dist/actor/cell.d.ts +27 -0
- package/dist/actor/cell.js +41 -0
- package/dist/actor/host.d.ts +27 -0
- package/dist/actor/host.js +82 -0
- package/dist/actor/index.d.ts +3 -0
- package/dist/actor/index.js +3 -0
- package/dist/actor/routing.d.ts +15 -0
- package/dist/actor/routing.js +80 -0
- package/dist/agent/definitions-store.d.ts +11 -0
- package/dist/agent/definitions-store.js +10 -0
- package/dist/agent/definitions.d.ts +152 -0
- package/dist/agent/definitions.js +74 -0
- package/dist/agent/effects.d.ts +425 -0
- package/dist/agent/effects.js +318 -0
- package/dist/agent/events.d.ts +170 -0
- package/dist/agent/events.js +61 -0
- package/dist/agent/index.d.ts +13 -0
- package/dist/agent/index.js +13 -0
- package/dist/agent/llm.d.ts +35 -0
- package/dist/agent/llm.js +48 -0
- package/dist/agent/module.d.ts +1037 -0
- package/dist/agent/module.js +27 -0
- package/dist/agent/projections.d.ts +17 -0
- package/dist/agent/projections.js +81 -0
- package/dist/agent/scope.d.ts +171 -0
- package/dist/agent/scope.js +7 -0
- package/dist/agent/signals.d.ts +17 -0
- package/dist/agent/signals.js +19 -0
- package/dist/agent/stop-when.d.ts +12 -0
- package/dist/agent/stop-when.js +6 -0
- package/dist/agent/threads.d.ts +34 -0
- package/dist/agent/threads.js +407 -0
- package/dist/agent/tool-schema.d.ts +21 -0
- package/dist/agent/tool-schema.js +67 -0
- package/dist/agent/types.d.ts +87 -0
- package/dist/agent/types.js +32 -0
- package/dist/ai-vercel/index.d.ts +2 -0
- package/dist/ai-vercel/index.js +2 -0
- package/dist/ai-vercel/messages.d.ts +9 -0
- package/dist/ai-vercel/messages.js +68 -0
- package/dist/ai-vercel/vercel-llm.d.ts +8 -0
- package/dist/ai-vercel/vercel-llm.js +98 -0
- package/dist/approval/effects.d.ts +133 -0
- package/dist/approval/effects.js +13 -0
- package/dist/approval/events.d.ts +52 -0
- package/dist/approval/events.js +28 -0
- package/dist/approval/index.d.ts +6 -0
- package/dist/approval/index.js +6 -0
- package/dist/approval/module.d.ts +342 -0
- package/dist/approval/module.js +10 -0
- package/dist/approval/projections.d.ts +42 -0
- package/dist/approval/projections.js +57 -0
- package/dist/approval/scope.d.ts +45 -0
- package/dist/approval/scope.js +7 -0
- package/dist/approval/signals.d.ts +19 -0
- package/dist/approval/signals.js +34 -0
- package/dist/cli/cli.d.ts +2 -0
- package/dist/cli/cli.js +6 -0
- package/dist/cli/commands.d.ts +13 -0
- package/dist/cli/commands.js +133 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.js +1 -0
- package/dist/client/client.d.ts +69 -0
- package/dist/client/client.js +179 -0
- package/dist/client/index.d.ts +2 -0
- package/dist/client/index.js +2 -0
- package/dist/client/sse.d.ts +10 -0
- package/dist/client/sse.js +103 -0
- package/dist/cloudflare/alarm-scheduler.d.ts +9 -0
- package/dist/cloudflare/alarm-scheduler.js +13 -0
- package/dist/cloudflare/durable-object.d.ts +24 -0
- package/dist/cloudflare/durable-object.js +43 -0
- package/dist/cloudflare/event-store.d.ts +10 -0
- package/dist/cloudflare/event-store.js +18 -0
- package/dist/cloudflare/index.d.ts +4 -0
- package/dist/cloudflare/index.js +4 -0
- package/dist/cloudflare/router.d.ts +12 -0
- package/dist/cloudflare/router.js +26 -0
- package/dist/core/bun-sqlite.d.ts +13 -0
- package/dist/core/bun-sqlite.js +19 -0
- package/dist/core/catalog.d.ts +49 -0
- package/dist/core/catalog.js +39 -0
- package/dist/core/coalesce.d.ts +21 -0
- package/dist/core/coalesce.js +178 -0
- package/dist/core/compose.d.ts +59 -0
- package/dist/core/compose.js +97 -0
- package/dist/core/cursor.d.ts +16 -0
- package/dist/core/cursor.js +46 -0
- package/dist/core/effects.d.ts +110 -0
- package/dist/core/effects.js +99 -0
- package/dist/core/envelope.d.ts +79 -0
- package/dist/core/envelope.js +68 -0
- package/dist/core/event-codec.d.ts +8 -0
- package/dist/core/event-codec.js +82 -0
- package/dist/core/event-index.d.ts +28 -0
- package/dist/core/event-index.js +86 -0
- package/dist/core/fold.d.ts +19 -0
- package/dist/core/fold.js +362 -0
- package/dist/core/ids.d.ts +11 -0
- package/dist/core/ids.js +47 -0
- package/dist/core/index.d.ts +26 -0
- package/dist/core/index.js +25 -0
- package/dist/core/match.d.ts +8 -0
- package/dist/core/match.js +58 -0
- package/dist/core/module-scope.d.ts +99 -0
- package/dist/core/module-scope.js +72 -0
- package/dist/core/module.d.ts +74 -0
- package/dist/core/module.js +3 -0
- package/dist/core/projection.d.ts +83 -0
- package/dist/core/projection.js +241 -0
- package/dist/core/protocol.d.ts +99 -0
- package/dist/core/protocol.js +101 -0
- package/dist/core/replay.d.ts +13 -0
- package/dist/core/replay.js +34 -0
- package/dist/core/schema.d.ts +35 -0
- package/dist/core/schema.js +130 -0
- package/dist/core/serialize.d.ts +14 -0
- package/dist/core/serialize.js +42 -0
- package/dist/core/snapshot-store.d.ts +39 -0
- package/dist/core/snapshot-store.js +53 -0
- package/dist/core/snapshots.d.ts +26 -0
- package/dist/core/snapshots.js +100 -0
- package/dist/core/sqlite-store.d.ts +31 -0
- package/dist/core/sqlite-store.js +328 -0
- package/dist/core/state.d.ts +43 -0
- package/dist/core/state.js +31 -0
- package/dist/core/store.d.ts +146 -0
- package/dist/core/store.js +229 -0
- package/dist/core/thread.d.ts +41 -0
- package/dist/core/thread.js +13 -0
- package/dist/core/types.d.ts +27 -0
- package/dist/core/types.js +42 -0
- package/dist/core/validate-event.d.ts +19 -0
- package/dist/core/validate-event.js +42 -0
- package/dist/debugger/components/debugger-split.d.ts +23 -0
- package/dist/debugger/components/debugger-split.js +25 -0
- package/dist/debugger/components/event-inspector.d.ts +5 -0
- package/dist/debugger/components/event-inspector.js +38 -0
- package/dist/debugger/components/event-stream.d.ts +13 -0
- package/dist/debugger/components/event-stream.js +119 -0
- package/dist/debugger/components/json-view.d.ts +5 -0
- package/dist/debugger/components/json-view.js +5 -0
- package/dist/debugger/components/run-tree.d.ts +14 -0
- package/dist/debugger/components/run-tree.js +38 -0
- package/dist/debugger/components/status-dot.d.ts +3 -0
- package/dist/debugger/components/status-dot.js +5 -0
- package/dist/debugger/contracts.d.ts +22 -0
- package/dist/debugger/contracts.js +1 -0
- package/dist/debugger/events/catalog.d.ts +6 -0
- package/dist/debugger/events/catalog.js +27 -0
- package/dist/debugger/events/domain-summarize.d.ts +3 -0
- package/dist/debugger/events/domain-summarize.js +107 -0
- package/dist/debugger/events/family.d.ts +8 -0
- package/dist/debugger/events/family.js +44 -0
- package/dist/debugger/events/protocol-summarize.d.ts +3 -0
- package/dist/debugger/events/protocol-summarize.js +70 -0
- package/dist/debugger/index.d.ts +17 -0
- package/dist/debugger/index.js +16 -0
- package/dist/debugger/lib/cn.d.ts +5 -0
- package/dist/debugger/lib/cn.js +17 -0
- package/dist/debugger/lib/event-counts.d.ts +5 -0
- package/dist/debugger/lib/event-counts.js +23 -0
- package/dist/debugger/lib/event-meta.d.ts +8 -0
- package/dist/debugger/lib/event-meta.js +20 -0
- package/dist/debugger/lib/project-run.d.ts +9 -0
- package/dist/debugger/lib/project-run.js +14 -0
- package/dist/debugger/lib/status.d.ts +3 -0
- package/dist/debugger/lib/status.js +31 -0
- package/dist/debugger/lib/visible-events.d.ts +8 -0
- package/dist/debugger/lib/visible-events.js +21 -0
- package/dist/debugger/styles.css +71 -0
- package/dist/debugger/ui/checkbox.d.ts +4 -0
- package/dist/debugger/ui/checkbox.js +9 -0
- package/dist/debugger/ui/input.d.ts +3 -0
- package/dist/debugger/ui/input.js +7 -0
- package/dist/debugger/ui/scroll-area.d.ts +9 -0
- package/dist/debugger/ui/scroll-area.js +10 -0
- package/dist/debugger/ui/tabs.d.ts +7 -0
- package/dist/debugger/ui/tabs.js +17 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/projectors/index-model.d.ts +56 -0
- package/dist/projectors/index-model.js +117 -0
- package/dist/projectors/index.d.ts +4 -0
- package/dist/projectors/index.js +3 -0
- package/dist/projectors/memory.d.ts +5 -0
- package/dist/projectors/memory.js +77 -0
- package/dist/projectors/postgres.d.ts +9 -0
- package/dist/projectors/postgres.js +108 -0
- package/dist/projectors/projector.d.ts +11 -0
- package/dist/projectors/projector.js +1 -0
- package/dist/projectors/schema.d.ts +5 -0
- package/dist/projectors/schema.js +43 -0
- package/dist/projectors/sqlite.d.ts +9 -0
- package/dist/projectors/sqlite.js +103 -0
- package/dist/projectors/with-projectors.d.ts +17 -0
- package/dist/projectors/with-projectors.js +55 -0
- package/dist/react/derived.d.ts +19 -0
- package/dist/react/derived.js +50 -0
- package/dist/react/index.d.ts +6 -0
- package/dist/react/index.js +5 -0
- package/dist/react/materialize.d.ts +3 -0
- package/dist/react/materialize.js +86 -0
- package/dist/react/notify.d.ts +18 -0
- package/dist/react/notify.js +80 -0
- package/dist/react/react.d.ts +61 -0
- package/dist/react/react.js +187 -0
- package/dist/react/register.d.ts +31 -0
- package/dist/react/register.js +1 -0
- package/dist/react/sse.d.ts +1 -0
- package/dist/react/sse.js +1 -0
- package/dist/react/store.d.ts +56 -0
- package/dist/react/store.js +340 -0
- package/dist/react/tables.d.ts +21 -0
- package/dist/react/tables.js +6 -0
- package/dist/runtime/dispatch-effect.d.ts +3 -0
- package/dist/runtime/dispatch-effect.js +113 -0
- package/dist/runtime/events-api.d.ts +4 -0
- package/dist/runtime/events-api.js +84 -0
- package/dist/runtime/index.d.ts +5 -0
- package/dist/runtime/index.js +5 -0
- package/dist/runtime/looms.d.ts +74 -0
- package/dist/runtime/looms.js +109 -0
- package/dist/runtime/runtime-helpers.d.ts +51 -0
- package/dist/runtime/runtime-helpers.js +230 -0
- package/dist/runtime/runtime.d.ts +91 -0
- package/dist/runtime/runtime.js +531 -0
- package/dist/runtime/server.d.ts +17 -0
- package/dist/runtime/server.js +226 -0
- package/dist/runtime/sse.d.ts +15 -0
- package/dist/runtime/sse.js +96 -0
- package/dist/runtime/wake-scheduler.d.ts +8 -0
- package/dist/runtime/wake-scheduler.js +38 -0
- package/dist/s2/config.d.ts +27 -0
- package/dist/s2/config.js +54 -0
- package/dist/s2/index.d.ts +6 -0
- package/dist/s2/index.js +6 -0
- package/dist/s2/lite.d.ts +26 -0
- package/dist/s2/lite.js +150 -0
- package/dist/s2/projector.d.ts +8 -0
- package/dist/s2/projector.js +28 -0
- package/dist/s2/serialize.d.ts +1 -0
- package/dist/s2/serialize.js +1 -0
- package/dist/s2/snapshot-store.d.ts +17 -0
- package/dist/s2/snapshot-store.js +320 -0
- package/dist/s2/store.d.ts +35 -0
- package/dist/s2/store.js +337 -0
- package/dist/testing/index.d.ts +11 -0
- package/dist/testing/index.js +63 -0
- package/dist/workflow/definitions-store.d.ts +11 -0
- package/dist/workflow/definitions-store.js +8 -0
- package/dist/workflow/definitions.d.ts +82 -0
- package/dist/workflow/definitions.js +32 -0
- package/dist/workflow/effects.d.ts +305 -0
- package/dist/workflow/effects.js +208 -0
- package/dist/workflow/events.d.ts +60 -0
- package/dist/workflow/events.js +39 -0
- package/dist/workflow/index.d.ts +8 -0
- package/dist/workflow/index.js +8 -0
- package/dist/workflow/module.d.ts +926 -0
- package/dist/workflow/module.js +19 -0
- package/dist/workflow/projections.d.ts +30 -0
- package/dist/workflow/projections.js +43 -0
- package/dist/workflow/scope.d.ts +61 -0
- package/dist/workflow/scope.js +7 -0
- package/dist/workflow/threads.d.ts +171 -0
- package/dist/workflow/threads.js +287 -0
- 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,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,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 };
|
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -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,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,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;
|