@lobb-js/studio 0.1.31

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 (208) hide show
  1. package/.env.example +1 -0
  2. package/.storybook/main.ts +31 -0
  3. package/.storybook/preview.ts +21 -0
  4. package/.storybook/vitest.setup.ts +7 -0
  5. package/README.md +47 -0
  6. package/components.json +16 -0
  7. package/docker-entrypoint.sh +7 -0
  8. package/dockerfile +27 -0
  9. package/index.html +13 -0
  10. package/package.json +77 -0
  11. package/public/lobb.svg +15 -0
  12. package/src/Studio.svelte +150 -0
  13. package/src/app.css +121 -0
  14. package/src/components-export.ts +21 -0
  15. package/src/extensions/extension.types.ts +93 -0
  16. package/src/extensions/extensionUtils.ts +192 -0
  17. package/src/lib/Lobb.ts +241 -0
  18. package/src/lib/components/LlmButton.svelte +136 -0
  19. package/src/lib/components/alertView.svelte +20 -0
  20. package/src/lib/components/breadCrumbs.svelte +60 -0
  21. package/src/lib/components/combobox.svelte +92 -0
  22. package/src/lib/components/confirmationDialog/confirmationDialog.svelte +33 -0
  23. package/src/lib/components/confirmationDialog/store.svelte.ts +28 -0
  24. package/src/lib/components/createManyButton.svelte +107 -0
  25. package/src/lib/components/dataTable/childRecords.svelte +140 -0
  26. package/src/lib/components/dataTable/dataTable.svelte +223 -0
  27. package/src/lib/components/dataTable/fieldCell.svelte +74 -0
  28. package/src/lib/components/dataTable/filter.svelte +282 -0
  29. package/src/lib/components/dataTable/filterButton.svelte +39 -0
  30. package/src/lib/components/dataTable/footer.svelte +84 -0
  31. package/src/lib/components/dataTable/header.svelte +154 -0
  32. package/src/lib/components/dataTable/sort.svelte +171 -0
  33. package/src/lib/components/dataTable/sortButton.svelte +36 -0
  34. package/src/lib/components/dataTable/table.svelte +337 -0
  35. package/src/lib/components/dataTable/utils.ts +127 -0
  36. package/src/lib/components/detailView/create/children.svelte +68 -0
  37. package/src/lib/components/detailView/create/createDetailView.svelte +226 -0
  38. package/src/lib/components/detailView/create/createDetailViewButton.svelte +32 -0
  39. package/src/lib/components/detailView/create/createManyView.svelte +250 -0
  40. package/src/lib/components/detailView/create/subRecords.svelte +48 -0
  41. package/src/lib/components/detailView/detailViewForm.svelte +104 -0
  42. package/src/lib/components/detailView/fieldCustomInput.svelte +23 -0
  43. package/src/lib/components/detailView/fieldInput.svelte +287 -0
  44. package/src/lib/components/detailView/fieldInputReplacement.svelte +199 -0
  45. package/src/lib/components/detailView/store.svelte.ts +61 -0
  46. package/src/lib/components/detailView/update/children.svelte +94 -0
  47. package/src/lib/components/detailView/update/updateDetailView.svelte +175 -0
  48. package/src/lib/components/detailView/update/updateDetailViewButton.svelte +32 -0
  49. package/src/lib/components/detailView/utils.ts +177 -0
  50. package/src/lib/components/diffViewer.svelte +102 -0
  51. package/src/lib/components/drawer.svelte +28 -0
  52. package/src/lib/components/extensionsComponents.svelte +31 -0
  53. package/src/lib/components/foreingKeyInput.svelte +80 -0
  54. package/src/lib/components/header.svelte +45 -0
  55. package/src/lib/components/loadingTypesForMonacoEditor.ts +36 -0
  56. package/src/lib/components/miniSidebar.svelte +238 -0
  57. package/src/lib/components/monacoEditor.svelte +181 -0
  58. package/src/lib/components/rangeCalendarButton.svelte +257 -0
  59. package/src/lib/components/selectRecord.svelte +126 -0
  60. package/src/lib/components/setServerPage.svelte +48 -0
  61. package/src/lib/components/sidebar/index.ts +4 -0
  62. package/src/lib/components/sidebar/sidebar.svelte +149 -0
  63. package/src/lib/components/sidebar/sidebarElements.svelte +144 -0
  64. package/src/lib/components/sidebar/sidebarTrigger.svelte +33 -0
  65. package/src/lib/components/singletone.svelte +69 -0
  66. package/src/lib/components/ui/accordion/accordion-content.svelte +22 -0
  67. package/src/lib/components/ui/accordion/accordion-item.svelte +12 -0
  68. package/src/lib/components/ui/accordion/accordion-trigger.svelte +31 -0
  69. package/src/lib/components/ui/accordion/index.ts +17 -0
  70. package/src/lib/components/ui/alert/alert-description.svelte +16 -0
  71. package/src/lib/components/ui/alert/alert-title.svelte +24 -0
  72. package/src/lib/components/ui/alert/alert.svelte +39 -0
  73. package/src/lib/components/ui/alert/index.ts +14 -0
  74. package/src/lib/components/ui/alert-dialog/alert-dialog-action.svelte +13 -0
  75. package/src/lib/components/ui/alert-dialog/alert-dialog-cancel.svelte +17 -0
  76. package/src/lib/components/ui/alert-dialog/alert-dialog-content.svelte +26 -0
  77. package/src/lib/components/ui/alert-dialog/alert-dialog-description.svelte +16 -0
  78. package/src/lib/components/ui/alert-dialog/alert-dialog-footer.svelte +20 -0
  79. package/src/lib/components/ui/alert-dialog/alert-dialog-header.svelte +20 -0
  80. package/src/lib/components/ui/alert-dialog/alert-dialog-overlay.svelte +19 -0
  81. package/src/lib/components/ui/alert-dialog/alert-dialog-title.svelte +18 -0
  82. package/src/lib/components/ui/alert-dialog/index.ts +40 -0
  83. package/src/lib/components/ui/breadcrumb/breadcrumb-ellipsis.svelte +23 -0
  84. package/src/lib/components/ui/breadcrumb/breadcrumb-item.svelte +16 -0
  85. package/src/lib/components/ui/breadcrumb/breadcrumb-link.svelte +31 -0
  86. package/src/lib/components/ui/breadcrumb/breadcrumb-list.svelte +23 -0
  87. package/src/lib/components/ui/breadcrumb/breadcrumb-page.svelte +23 -0
  88. package/src/lib/components/ui/breadcrumb/breadcrumb-separator.svelte +27 -0
  89. package/src/lib/components/ui/breadcrumb/breadcrumb.svelte +15 -0
  90. package/src/lib/components/ui/breadcrumb/index.ts +25 -0
  91. package/src/lib/components/ui/button/button.svelte +110 -0
  92. package/src/lib/components/ui/button/index.ts +17 -0
  93. package/src/lib/components/ui/checkbox/checkbox.svelte +35 -0
  94. package/src/lib/components/ui/checkbox/index.ts +6 -0
  95. package/src/lib/components/ui/command/command-dialog.svelte +35 -0
  96. package/src/lib/components/ui/command/command-empty.svelte +12 -0
  97. package/src/lib/components/ui/command/command-group.svelte +31 -0
  98. package/src/lib/components/ui/command/command-input.svelte +25 -0
  99. package/src/lib/components/ui/command/command-item.svelte +19 -0
  100. package/src/lib/components/ui/command/command-link-item.svelte +19 -0
  101. package/src/lib/components/ui/command/command-list.svelte +16 -0
  102. package/src/lib/components/ui/command/command-separator.svelte +12 -0
  103. package/src/lib/components/ui/command/command-shortcut.svelte +20 -0
  104. package/src/lib/components/ui/command/command.svelte +21 -0
  105. package/src/lib/components/ui/command/index.ts +40 -0
  106. package/src/lib/components/ui/dialog/dialog-content.svelte +38 -0
  107. package/src/lib/components/ui/dialog/dialog-description.svelte +16 -0
  108. package/src/lib/components/ui/dialog/dialog-footer.svelte +20 -0
  109. package/src/lib/components/ui/dialog/dialog-header.svelte +20 -0
  110. package/src/lib/components/ui/dialog/dialog-overlay.svelte +19 -0
  111. package/src/lib/components/ui/dialog/dialog-title.svelte +16 -0
  112. package/src/lib/components/ui/dialog/index.ts +37 -0
  113. package/src/lib/components/ui/input/index.ts +7 -0
  114. package/src/lib/components/ui/input/input.svelte +46 -0
  115. package/src/lib/components/ui/label/index.ts +7 -0
  116. package/src/lib/components/ui/label/label.svelte +19 -0
  117. package/src/lib/components/ui/popover/index.ts +17 -0
  118. package/src/lib/components/ui/popover/popover-content.svelte +28 -0
  119. package/src/lib/components/ui/range-calendar/index.ts +30 -0
  120. package/src/lib/components/ui/range-calendar/range-calendar-cell.svelte +19 -0
  121. package/src/lib/components/ui/range-calendar/range-calendar-day.svelte +35 -0
  122. package/src/lib/components/ui/range-calendar/range-calendar-grid-body.svelte +12 -0
  123. package/src/lib/components/ui/range-calendar/range-calendar-grid-head.svelte +12 -0
  124. package/src/lib/components/ui/range-calendar/range-calendar-grid-row.svelte +12 -0
  125. package/src/lib/components/ui/range-calendar/range-calendar-grid.svelte +16 -0
  126. package/src/lib/components/ui/range-calendar/range-calendar-head-cell.svelte +16 -0
  127. package/src/lib/components/ui/range-calendar/range-calendar-header.svelte +16 -0
  128. package/src/lib/components/ui/range-calendar/range-calendar-heading.svelte +16 -0
  129. package/src/lib/components/ui/range-calendar/range-calendar-months.svelte +20 -0
  130. package/src/lib/components/ui/range-calendar/range-calendar-next-button.svelte +27 -0
  131. package/src/lib/components/ui/range-calendar/range-calendar-prev-button.svelte +27 -0
  132. package/src/lib/components/ui/range-calendar/range-calendar.svelte +57 -0
  133. package/src/lib/components/ui/select/index.ts +34 -0
  134. package/src/lib/components/ui/select/select-content.svelte +38 -0
  135. package/src/lib/components/ui/select/select-group-heading.svelte +16 -0
  136. package/src/lib/components/ui/select/select-item.svelte +37 -0
  137. package/src/lib/components/ui/select/select-scroll-down-button.svelte +19 -0
  138. package/src/lib/components/ui/select/select-scroll-up-button.svelte +19 -0
  139. package/src/lib/components/ui/select/select-separator.svelte +13 -0
  140. package/src/lib/components/ui/select/select-trigger.svelte +24 -0
  141. package/src/lib/components/ui/separator/index.ts +7 -0
  142. package/src/lib/components/ui/separator/separator.svelte +22 -0
  143. package/src/lib/components/ui/skeleton/index.ts +7 -0
  144. package/src/lib/components/ui/skeleton/skeleton.svelte +22 -0
  145. package/src/lib/components/ui/sonner/index.ts +1 -0
  146. package/src/lib/components/ui/sonner/sonner.svelte +20 -0
  147. package/src/lib/components/ui/switch/index.ts +7 -0
  148. package/src/lib/components/ui/switch/switch.svelte +27 -0
  149. package/src/lib/components/ui/textarea/index.ts +7 -0
  150. package/src/lib/components/ui/textarea/textarea.svelte +22 -0
  151. package/src/lib/components/ui/tooltip/index.ts +18 -0
  152. package/src/lib/components/ui/tooltip/tooltip-content.svelte +21 -0
  153. package/src/lib/components/workflowEditor.svelte +187 -0
  154. package/src/lib/eventSystem.ts +38 -0
  155. package/src/lib/index.ts +40 -0
  156. package/src/lib/store.svelte.ts +21 -0
  157. package/src/lib/store.types.ts +28 -0
  158. package/src/lib/utils.ts +84 -0
  159. package/src/main.ts +18 -0
  160. package/src/routes/collections/collection.svelte +46 -0
  161. package/src/routes/collections/collections.svelte +43 -0
  162. package/src/routes/data_model/dataModel.svelte +40 -0
  163. package/src/routes/data_model/flow.css +22 -0
  164. package/src/routes/data_model/flow.svelte +82 -0
  165. package/src/routes/data_model/syncManager.svelte +93 -0
  166. package/src/routes/data_model/utils.ts +35 -0
  167. package/src/routes/extensions/extension.svelte +16 -0
  168. package/src/routes/home.svelte +36 -0
  169. package/src/routes/workflows/workflows.svelte +135 -0
  170. package/src/stories/Configure.mdx +364 -0
  171. package/src/stories/assets/accessibility.png +0 -0
  172. package/src/stories/assets/accessibility.svg +1 -0
  173. package/src/stories/assets/addon-library.png +0 -0
  174. package/src/stories/assets/assets.png +0 -0
  175. package/src/stories/assets/avif-test-image.avif +0 -0
  176. package/src/stories/assets/context.png +0 -0
  177. package/src/stories/assets/discord.svg +1 -0
  178. package/src/stories/assets/docs.png +0 -0
  179. package/src/stories/assets/figma-plugin.png +0 -0
  180. package/src/stories/assets/github.svg +1 -0
  181. package/src/stories/assets/share.png +0 -0
  182. package/src/stories/assets/styling.png +0 -0
  183. package/src/stories/assets/testing.png +0 -0
  184. package/src/stories/assets/theming.png +0 -0
  185. package/src/stories/assets/tutorials.svg +1 -0
  186. package/src/stories/assets/youtube.svg +1 -0
  187. package/src/stories/detailView/detailViewForm.stories.svelte +79 -0
  188. package/src/stories/examples/Button.stories.svelte +31 -0
  189. package/src/stories/examples/Button.svelte +30 -0
  190. package/src/stories/examples/Header.stories.svelte +26 -0
  191. package/src/stories/examples/Header.svelte +45 -0
  192. package/src/stories/examples/Page.stories.svelte +29 -0
  193. package/src/stories/examples/Page.svelte +70 -0
  194. package/src/stories/examples/button.css +30 -0
  195. package/src/stories/examples/header.css +32 -0
  196. package/src/stories/examples/page.css +68 -0
  197. package/src/vite-env.d.ts +2 -0
  198. package/svelte.config.js +7 -0
  199. package/todo.md +24 -0
  200. package/tsconfig.app.json +25 -0
  201. package/tsconfig.json +14 -0
  202. package/tsconfig.node.json +24 -0
  203. package/vite-plugin-contextual-lib.js +66 -0
  204. package/vite.build.svelte.config.ts +18 -0
  205. package/vite.config.ts +84 -0
  206. package/vite.extension.config.ts +81 -0
  207. package/vite_utils.ts +28 -0
  208. package/vitest.shims.d.ts +1 -0
@@ -0,0 +1,37 @@
1
+ <script lang="ts">
2
+ import { Select as SelectPrimitive, type WithoutChild } from "bits-ui";
3
+ import Check from "@lucide/svelte/icons/check";
4
+ import { cn } from "$lib/utils.js";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ class: className,
9
+ value,
10
+ label,
11
+ children: childrenProp,
12
+ ...restProps
13
+ }: WithoutChild<SelectPrimitive.ItemProps> = $props();
14
+ </script>
15
+
16
+ <SelectPrimitive.Item
17
+ bind:ref
18
+ {value}
19
+ class={cn(
20
+ "data-[highlighted]:bg-accent data-[highlighted]:text-accent-foreground relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-2 pr-8 text-sm outline-none data-disabled:pointer-events-none data-disabled:opacity-50",
21
+ className
22
+ )}
23
+ {...restProps}
24
+ >
25
+ {#snippet children({ selected, highlighted })}
26
+ <span class="absolute right-2 flex size-3.5 items-center justify-center">
27
+ {#if selected}
28
+ <Check class="size-4" />
29
+ {/if}
30
+ </span>
31
+ {#if childrenProp}
32
+ {@render childrenProp({ selected, highlighted })}
33
+ {:else}
34
+ {label || value}
35
+ {/if}
36
+ {/snippet}
37
+ </SelectPrimitive.Item>
@@ -0,0 +1,19 @@
1
+ <script lang="ts">
2
+ import ChevronDown from "@lucide/svelte/icons/chevron-down";
3
+ import { Select as SelectPrimitive, type WithoutChildrenOrChild } from "bits-ui";
4
+ import { cn } from "$lib/utils.js";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ class: className,
9
+ ...restProps
10
+ }: WithoutChildrenOrChild<SelectPrimitive.ScrollDownButtonProps> = $props();
11
+ </script>
12
+
13
+ <SelectPrimitive.ScrollDownButton
14
+ bind:ref
15
+ class={cn("flex cursor-default items-center justify-center py-1", className)}
16
+ {...restProps}
17
+ >
18
+ <ChevronDown class="size-4" />
19
+ </SelectPrimitive.ScrollDownButton>
@@ -0,0 +1,19 @@
1
+ <script lang="ts">
2
+ import ChevronUp from "@lucide/svelte/icons/chevron-up";
3
+ import { Select as SelectPrimitive, type WithoutChildrenOrChild } from "bits-ui";
4
+ import { cn } from "$lib/utils.js";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ class: className,
9
+ ...restProps
10
+ }: WithoutChildrenOrChild<SelectPrimitive.ScrollDownButtonProps> = $props();
11
+ </script>
12
+
13
+ <SelectPrimitive.ScrollUpButton
14
+ bind:ref
15
+ class={cn("flex cursor-default items-center justify-center py-1", className)}
16
+ {...restProps}
17
+ >
18
+ <ChevronUp class="size-4" />
19
+ </SelectPrimitive.ScrollUpButton>
@@ -0,0 +1,13 @@
1
+ <script lang="ts">
2
+ import type { Separator as SeparatorPrimitive } from "bits-ui";
3
+ import { Separator } from "$lib/components/ui/separator/index.js";
4
+ import { cn } from "$lib/utils.js";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ class: className,
9
+ ...restProps
10
+ }: SeparatorPrimitive.RootProps = $props();
11
+ </script>
12
+
13
+ <Separator bind:ref class={cn("bg-muted -mx-1 my-1 h-px", className)} {...restProps} />
@@ -0,0 +1,24 @@
1
+ <script lang="ts">
2
+ import { Select as SelectPrimitive, type WithoutChild } from "bits-ui";
3
+ import ChevronDown from "@lucide/svelte/icons/chevron-down";
4
+ import { cn } from "$lib/utils.js";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ class: className,
9
+ children,
10
+ ...restProps
11
+ }: WithoutChild<SelectPrimitive.TriggerProps> = $props();
12
+ </script>
13
+
14
+ <SelectPrimitive.Trigger
15
+ bind:ref
16
+ class={cn(
17
+ "border-input ring-offset-background data-[placeholder]:text-muted-foreground focus:ring-ring flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border bg-transparent px-3 py-2 text-sm shadow-sm focus:outline-none focus:ring-1 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
18
+ className
19
+ )}
20
+ {...restProps}
21
+ >
22
+ {@render children?.()}
23
+ <ChevronDown class="size-4 opacity-50" />
24
+ </SelectPrimitive.Trigger>
@@ -0,0 +1,7 @@
1
+ import Root from "./separator.svelte";
2
+
3
+ export {
4
+ Root,
5
+ //
6
+ Root as Separator,
7
+ };
@@ -0,0 +1,22 @@
1
+ <script lang="ts">
2
+ import { Separator as SeparatorPrimitive } from "bits-ui";
3
+ import { cn } from "$lib/utils.js";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ orientation = "horizontal",
9
+ ...restProps
10
+ }: SeparatorPrimitive.RootProps = $props();
11
+ </script>
12
+
13
+ <SeparatorPrimitive.Root
14
+ bind:ref
15
+ class={cn(
16
+ "bg-border shrink-0",
17
+ orientation === "horizontal" ? "h-px w-full" : "min-h-full w-px",
18
+ className
19
+ )}
20
+ {orientation}
21
+ {...restProps}
22
+ />
@@ -0,0 +1,7 @@
1
+ import Root from "./skeleton.svelte";
2
+
3
+ export {
4
+ Root,
5
+ //
6
+ Root as Skeleton,
7
+ };
@@ -0,0 +1,22 @@
1
+ <script lang="ts">
2
+ import type { WithElementRef, WithoutChildren } from "bits-ui";
3
+ import type { HTMLAttributes } from "svelte/elements";
4
+ import { cn } from "$lib/utils.js";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ class: className,
9
+ ...restProps
10
+ }: WithoutChildren<
11
+ WithElementRef<HTMLAttributes<HTMLDivElement>>
12
+ > = $props();
13
+ </script>
14
+
15
+ <div
16
+ bind:this={ref}
17
+ class={cn(
18
+ "bg-primary/10 animate-pulse rounded-md",
19
+ className,
20
+ )}
21
+ {...restProps}
22
+ ></div>
@@ -0,0 +1 @@
1
+ export { default as Toaster } from "./sonner.svelte";
@@ -0,0 +1,20 @@
1
+ <script lang="ts">
2
+ import { Toaster as Sonner, type ToasterProps as SonnerProps } from "svelte-sonner";
3
+ import { mode } from "mode-watcher";
4
+
5
+ let { ...restProps }: SonnerProps = $props();
6
+ </script>
7
+
8
+ <Sonner
9
+ theme={$mode}
10
+ class="toaster group"
11
+ toastOptions={{
12
+ classes: {
13
+ toast: "group toast group-[.toaster]:bg-background group-[.toaster]:text-foreground group-[.toaster]:border group-[.toaster]:shadow-lg",
14
+ description: "group-[.toast]:text-muted-foreground",
15
+ actionButton: "group-[.toast]:bg-primary group-[.toast]:text-primary-foreground",
16
+ cancelButton: "group-[.toast]:bg-muted group-[.toast]:text-muted-foreground",
17
+ },
18
+ }}
19
+ {...restProps}
20
+ />
@@ -0,0 +1,7 @@
1
+ import Root from "./switch.svelte";
2
+
3
+ export {
4
+ Root,
5
+ //
6
+ Root as Switch,
7
+ };
@@ -0,0 +1,27 @@
1
+ <script lang="ts">
2
+ import { Switch as SwitchPrimitive, type WithoutChildrenOrChild } from "bits-ui";
3
+ import { cn } from "$lib/utils.js";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ checked = $bindable(false),
8
+ class: className,
9
+ ...restProps
10
+ }: WithoutChildrenOrChild<SwitchPrimitive.RootProps> = $props();
11
+ </script>
12
+
13
+ <SwitchPrimitive.Root
14
+ bind:ref
15
+ bind:checked
16
+ class={cn(
17
+ "focus-visible:ring-ring focus-visible:ring-offset-background data-[state=checked]:bg-primary data-[state=unchecked]:bg-input peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
18
+ className
19
+ )}
20
+ {...restProps}
21
+ >
22
+ <SwitchPrimitive.Thumb
23
+ class={cn(
24
+ "bg-background pointer-events-none block size-4 rounded-full shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-4 data-[state=unchecked]:translate-x-0"
25
+ )}
26
+ />
27
+ </SwitchPrimitive.Root>
@@ -0,0 +1,7 @@
1
+ import Root from "./textarea.svelte";
2
+
3
+ export {
4
+ Root,
5
+ //
6
+ Root as Textarea,
7
+ };
@@ -0,0 +1,22 @@
1
+ <script lang="ts">
2
+ import type { WithElementRef, WithoutChildren } from "bits-ui";
3
+ import type { HTMLTextareaAttributes } from "svelte/elements";
4
+ import { cn } from "$lib/utils.js";
5
+
6
+ let {
7
+ ref = $bindable(null),
8
+ value = $bindable(),
9
+ class: className,
10
+ ...restProps
11
+ }: WithoutChildren<WithElementRef<HTMLTextareaAttributes>> = $props();
12
+ </script>
13
+
14
+ <textarea
15
+ bind:this={ref}
16
+ bind:value
17
+ class={cn(
18
+ "border-input placeholder:text-muted-foreground focus-visible:ring-ring flex min-h-[60px] w-full rounded-md border bg-transparent px-3 py-2 text-base shadow-sm focus-visible:outline-none focus-visible:ring-1 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
19
+ className
20
+ )}
21
+ {...restProps}
22
+ ></textarea>
@@ -0,0 +1,18 @@
1
+ import { Tooltip as TooltipPrimitive } from "bits-ui";
2
+ import Content from "./tooltip-content.svelte";
3
+
4
+ const Root = TooltipPrimitive.Root;
5
+ const Trigger = TooltipPrimitive.Trigger;
6
+ const Provider = TooltipPrimitive.Provider;
7
+
8
+ export {
9
+ Root,
10
+ Trigger,
11
+ Content,
12
+ Provider,
13
+ //
14
+ Root as Tooltip,
15
+ Content as TooltipContent,
16
+ Trigger as TooltipTrigger,
17
+ Provider as TooltipProvider,
18
+ };
@@ -0,0 +1,21 @@
1
+ <script lang="ts">
2
+ import { Tooltip as TooltipPrimitive } from "bits-ui";
3
+ import { cn } from "$lib/utils.js";
4
+
5
+ let {
6
+ ref = $bindable(null),
7
+ class: className,
8
+ sideOffset = 4,
9
+ ...restProps
10
+ }: TooltipPrimitive.ContentProps = $props();
11
+ </script>
12
+
13
+ <TooltipPrimitive.Content
14
+ bind:ref
15
+ {sideOffset}
16
+ class={cn(
17
+ "bg-primary text-primary-foreground animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 overflow-hidden rounded-md px-3 py-1.5 text-xs",
18
+ className
19
+ )}
20
+ {...restProps}
21
+ />
@@ -0,0 +1,187 @@
1
+ <script lang="ts" module>
2
+ export interface WorkflowEntry {
3
+ id?: string;
4
+ name: string;
5
+ directory: string;
6
+ event_name: string;
7
+ input_schema?: string;
8
+ output_schema?: string;
9
+ handler?: string;
10
+ }
11
+ </script>
12
+
13
+ <script lang="ts">
14
+ import { lobb } from "$lib";
15
+ import MonacoEditor from "$lib/components/monacoEditor.svelte";
16
+ import Button from "$lib/components/ui/button/button.svelte";
17
+ import Input from "$lib/components/ui/input/input.svelte";
18
+ import { ctx } from "$lib/store.svelte";
19
+ import { location } from "@wjfe/n-savant";
20
+ import { Edit, Plus } from "lucide-svelte";
21
+ import { toast } from "svelte-sonner";
22
+ import { isEqual } from "lodash";
23
+
24
+ interface Props {
25
+ workflow: WorkflowEntry;
26
+ refreshSidebar: () => Promise<void>;
27
+ }
28
+
29
+ let { workflow = $bindable(), refreshSidebar }: Props = $props();
30
+
31
+ let initialWorkflow = $state.snapshot(workflow);
32
+ let workflowHasChanged = $state(false);
33
+
34
+ // track editor change
35
+ $effect(() => {
36
+ const hasChanged = !isEqual(workflow, initialWorkflow);
37
+ workflowHasChanged = hasChanged;
38
+ });
39
+
40
+ $effect(() => {
41
+ handleWorkflowEventChange(workflow.event_name);
42
+ });
43
+
44
+ function handleCtrlSave() {
45
+ if (workflow.id) {
46
+ handleUpdateWorkflow();
47
+ } else {
48
+ handleCreateWorkflow();
49
+ }
50
+ }
51
+
52
+ let types = $state("");
53
+ let eventsOptions = $derived([
54
+ {
55
+ label: "No Event",
56
+ value: "",
57
+ },
58
+ ...ctx.meta.events.map((event) => ({
59
+ label: event.name,
60
+ value: event.name,
61
+ })),
62
+ ]);
63
+
64
+ function handleWorkflowEventChange(eventName: WorkflowEntry["event_name"]) {
65
+ setTimeout(() => {
66
+ const event = ctx.meta.events.find(
67
+ (event) => event.name === eventName,
68
+ );
69
+ let localType = "";
70
+ if (event && event.inputSchema) {
71
+ localType += event.inputSchema;
72
+ } else {
73
+ localType += "type Input = unknown;";
74
+ }
75
+ if (ctx.meta.event_context_type) {
76
+ localType += ctx.meta.event_context_type;
77
+ } else {
78
+ localType += "type Context = unknown;";
79
+ }
80
+ if (event && event.outputSchema) {
81
+ localType += event.outputSchema;
82
+ } else {
83
+ localType += "type Output = Promise<unknown>;";
84
+ }
85
+ types = localType;
86
+ }, 100);
87
+ }
88
+
89
+ async function handleCreateWorkflow() {
90
+ if (!workflow.name) {
91
+ toast.error("You need to specify a workflow name");
92
+ return;
93
+ }
94
+
95
+ const reponse = await lobb.createOne("core_workflows", workflow);
96
+ const result = await reponse.json();
97
+ const workflowEntry = result.data;
98
+ location.navigate(`/workflows/${workflowEntry.name}`);
99
+ await refreshSidebar();
100
+ }
101
+
102
+ async function handleUpdateWorkflow() {
103
+ if (!workflow.id) {
104
+ throw new Error(
105
+ "For some reasont the id of the currentWorkflow doesnt exist",
106
+ );
107
+ }
108
+ const reponse = await lobb.updateOne("core_workflows", workflow.id, {
109
+ name: workflow.name,
110
+ event_name: workflow.event_name,
111
+ handler: workflow.handler,
112
+ });
113
+ const result = await reponse.json();
114
+
115
+ if (!(reponse.status >= 400)) {
116
+ toast.success("The workflow was updated successfully");
117
+ }
118
+
119
+ workflow = result.data;
120
+
121
+ await refreshSidebar();
122
+ }
123
+ </script>
124
+
125
+ <div class="flex flex-col h-full">
126
+ <div
127
+ class="flex justify-between items-start py-2 pl-9 pr-2 bg-background border-b"
128
+ >
129
+ <div class="flex gap-2 flex-wrap">
130
+ <Input
131
+ bind:value={workflow.name}
132
+ class="h-7 w-48 bg-background"
133
+ placeholder="Workflow name"
134
+ />
135
+ <Input
136
+ bind:value={workflow.event_name}
137
+ class="h-7 w-48 bg-background"
138
+ placeholder="Workflow event"
139
+ list="events_options"
140
+ />
141
+ <datalist id="events_options">
142
+ {#each eventsOptions as eventOption}
143
+ <option value={eventOption.value}>
144
+ {eventOption.label}
145
+ </option>
146
+ {/each}
147
+ </datalist>
148
+ <Input
149
+ bind:value={workflow.directory}
150
+ class="h-7 w-48 bg-background"
151
+ placeholder="Workflow directory"
152
+ />
153
+ </div>
154
+ <div>
155
+ {#if workflow.id}
156
+ <Button
157
+ class="h-7 px-3 text-xs font-normal w-full"
158
+ variant="default"
159
+ onclick={handleUpdateWorkflow}
160
+ Icon={Edit}
161
+ disabled={!workflowHasChanged}
162
+ >
163
+ Save
164
+ </Button>
165
+ {:else}
166
+ <Button
167
+ class="h-7 px-3 text-xs font-normal w-full"
168
+ variant="default"
169
+ onclick={handleCreateWorkflow}
170
+ Icon={Plus}
171
+ >
172
+ Create
173
+ </Button>
174
+ {/if}
175
+ </div>
176
+ </div>
177
+ {#key types}
178
+ <MonacoEditor
179
+ type="typescript"
180
+ name="workflow"
181
+ class="h-full rounded-none border-none"
182
+ {types}
183
+ {handleCtrlSave}
184
+ bind:value={workflow.handler}
185
+ />
186
+ {/key}
187
+ </div>
@@ -0,0 +1,38 @@
1
+ import { toast } from "svelte-sonner";
2
+ import { ctx } from "./store.svelte";
3
+ import { openCreateDetailView, openUpdateDetailView } from "./components/detailView/store.svelte";
4
+
5
+ export async function emitEvent(eventName: string, input: Record<string, any>) {
6
+ const workflows = ctx.meta.studio_workflows.filter(
7
+ (workflow) => {
8
+ return eventName.startsWith(workflow.eventName);
9
+ },
10
+ );
11
+
12
+ for (let index = 0; index < workflows.length; index++) {
13
+ const workflow = workflows[index];
14
+ try {
15
+ const localOutput = await workflow.handler(
16
+ input,
17
+ await getEventContext(),
18
+ );
19
+
20
+ if (localOutput) {
21
+ input = localOutput;
22
+ }
23
+ } catch (error) {
24
+ toast.error((error as any).message);
25
+ throw error;
26
+ }
27
+ }
28
+
29
+ return input;
30
+ }
31
+
32
+ async function getEventContext() {
33
+ return {
34
+ toast,
35
+ openCreateDetailView,
36
+ openUpdateDetailView,
37
+ };
38
+ }
@@ -0,0 +1,40 @@
1
+ import { Lobb } from "./Lobb";
2
+ import { ctx } from "$lib/store.svelte";
3
+ import { toast } from "svelte-sonner";
4
+
5
+ export const lobb = new Lobb(ctx.lobbUrl);
6
+
7
+ // logging the message if got any bad responses
8
+ lobb.onResponse(async (response) => {
9
+ if (response.status >= 400) {
10
+ const body = await response.json();
11
+ toast.error(body.message);
12
+ }
13
+ });
14
+
15
+ export function createSet(lastNumber: number): Set<number> {
16
+ const set = new Set() as Set<number>;
17
+ for (let i = 0; i <= lastNumber; i++) {
18
+ set.add(i);
19
+ }
20
+ return set;
21
+ }
22
+
23
+ export function moveElement<T>(array: T[], fromIndex: number, toIndex: number) {
24
+ if (
25
+ fromIndex < 0 || fromIndex >= array.length || toIndex < 0 ||
26
+ toIndex >= array.length
27
+ ) {
28
+ throw new Error("Index out of bounds");
29
+ }
30
+ const [element] = array.splice(fromIndex, 1);
31
+ array.splice(toIndex, 0, element);
32
+ return array;
33
+ }
34
+
35
+ export function pxToRem(px: number) {
36
+ const rootFontSize = parseFloat(
37
+ getComputedStyle(document.documentElement).fontSize,
38
+ );
39
+ return px / rootFontSize;
40
+ }
@@ -0,0 +1,21 @@
1
+ import type { CTX } from './store.types';
2
+ import pkg from '../../package.json';
3
+
4
+ if (!window.APP_ENV) {
5
+ window.APP_ENV = {};
6
+ }
7
+
8
+ if (window.APP_ENV.LOBB_URL === '%LOBB_URL%') {
9
+ window.APP_ENV.LOBB_URL = null;
10
+ }
11
+
12
+ export const ctx: CTX = $state.raw({
13
+ studioVersion: pkg.version,
14
+ lobbUrl: window.APP_ENV.LOBB_URL || localStorage.getItem("lobb_url"),
15
+ extensions: {},
16
+ meta: {
17
+ collections: null,
18
+ extensions: null,
19
+ filter: null
20
+ },
21
+ });
@@ -0,0 +1,28 @@
1
+ import type { Extension } from "../extensions/extension.types";
2
+
3
+ interface Collection {
4
+ category: string;
5
+ owner: string;
6
+ fields: Record<string, any>;
7
+ singleton: boolean;
8
+ }
9
+ type Collections = Record<string, Collection>;
10
+
11
+ interface Meta {
12
+ version: string;
13
+ relations: Array<any>;
14
+ collections: Collections;
15
+ extensions: Record<string, any>;
16
+ filter: any;
17
+ events: any[];
18
+ event_context_type: string;
19
+ studio_workflows: any[];
20
+ }
21
+
22
+ export interface CTX {
23
+ studioVersion: string;
24
+ lobbUrl: string | null;
25
+ extensions: Record<string, Extension>;
26
+ meta: Meta;
27
+ currentUrl: URL;
28
+ }