@01.software/sdk 0.5.2 → 0.5.3

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 (37) hide show
  1. package/dist/auth.d.cts +1 -1
  2. package/dist/auth.d.ts +1 -1
  3. package/dist/{const-Cy_NaRCl.d.cts → const-C9I6r5Wa.d.cts} +1 -1
  4. package/dist/{const-C6vryj3j.d.ts → const-JbuUTzeh.d.ts} +1 -1
  5. package/dist/index.d.cts +6 -6
  6. package/dist/index.d.ts +6 -6
  7. package/dist/{payload-types-JCbsSVeL.d.cts → payload-types-D8fN_vZR.d.cts} +5 -1
  8. package/dist/{payload-types-JCbsSVeL.d.ts → payload-types-D8fN_vZR.d.ts} +5 -1
  9. package/dist/realtime.d.cts +2 -2
  10. package/dist/realtime.d.ts +2 -2
  11. package/dist/{server-B80o7igg.d.cts → server-StNHlSjW.d.cts} +5 -1
  12. package/dist/{server-B80o7igg.d.ts → server-StNHlSjW.d.ts} +5 -1
  13. package/dist/ui/code-block.cjs +5 -1
  14. package/dist/ui/code-block.cjs.map +1 -1
  15. package/dist/ui/code-block.js +5 -1
  16. package/dist/ui/code-block.js.map +1 -1
  17. package/dist/ui/flow/server.cjs +101 -34
  18. package/dist/ui/flow/server.cjs.map +1 -1
  19. package/dist/ui/flow/server.d.cts +1 -1
  20. package/dist/ui/flow/server.d.ts +1 -1
  21. package/dist/ui/flow/server.js +101 -34
  22. package/dist/ui/flow/server.js.map +1 -1
  23. package/dist/ui/flow.cjs +718 -180
  24. package/dist/ui/flow.cjs.map +1 -1
  25. package/dist/ui/flow.d.cts +77 -11
  26. package/dist/ui/flow.d.ts +77 -11
  27. package/dist/ui/flow.js +705 -167
  28. package/dist/ui/flow.js.map +1 -1
  29. package/dist/ui/form.d.cts +1 -1
  30. package/dist/ui/form.d.ts +1 -1
  31. package/dist/ui/video.d.cts +1 -1
  32. package/dist/ui/video.d.ts +1 -1
  33. package/dist/{webhook-Dd_7Qgaa.d.ts → webhook-BkwMrrL1.d.ts} +2 -2
  34. package/dist/{webhook-CDu_s44-.d.cts → webhook-Dbx-pRib.d.cts} +2 -2
  35. package/dist/webhook.d.cts +3 -3
  36. package/dist/webhook.d.ts +3 -3
  37. package/package.json +3 -1
package/dist/auth.d.cts CHANGED
@@ -1,4 +1,4 @@
1
- import './payload-types-JCbsSVeL.cjs';
1
+ import './payload-types-D8fN_vZR.cjs';
2
2
 
3
3
  interface JwtPayload {
4
4
  clientKey: string;
package/dist/auth.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import './payload-types-JCbsSVeL.js';
1
+ import './payload-types-D8fN_vZR.js';
2
2
 
3
3
  interface JwtPayload {
4
4
  clientKey: string;
@@ -1,4 +1,4 @@
1
- import { C as Config } from './payload-types-JCbsSVeL.cjs';
1
+ import { C as Config } from './payload-types-D8fN_vZR.cjs';
2
2
 
3
3
  /**
4
4
  * Collection type derived from Payload Config.
@@ -1,4 +1,4 @@
1
- import { C as Config } from './payload-types-JCbsSVeL.js';
1
+ import { C as Config } from './payload-types-D8fN_vZR.js';
2
2
 
3
3
  /**
4
4
  * Collection type derived from Payload Config.
package/dist/index.d.cts CHANGED
@@ -1,13 +1,13 @@
1
- import { O as Order, a as OrderProduct, T as Transaction, b as Fulfillment, R as Return, E as Exchange, c as Cart, d as CartItem, P as Product } from './payload-types-JCbsSVeL.cjs';
2
- export { o as ApiUsage, au as ApiUsageSelect, A as Audience, aq as AudiencesSelect, bs as Auth, q as BillingHistory, aw as BillingHistorySelect, y as Brand, B as BrandLogo, aF as BrandLogosSelect, aE as BrandsSelect, aV as CartItemsSelect, aU as CartsSelect, g as CodeBlock, br as CollectionsWidget, C as Config, G as Customer, J as CustomerAddress, aS as CustomerAddressesSelect, e as CustomerAuthOperations, H as CustomerGroup, aT as CustomerGroupsSelect, aR as CustomersSelect, W as Discount, aW as DiscountsSelect, $ as Document, b0 as DocumentCategoriesSelect, a1 as DocumentCategory, a0 as DocumentType, b1 as DocumentTypesSelect, a$ as DocumentsSelect, m as EmailLog, ar as EmailLogsSelect, N as ExchangeProduct, aP as ExchangeProductsSelect, aO as ExchangesSelect, j as FieldConfig, an as FieldConfigsSelect, ac as Flow, bf as FlowCategoriesSelect, ad as FlowCategory, ag as FlowEdgeType, be as FlowEdgeTypesSelect, af as FlowNodeType, bd as FlowNodeTypesSelect, ae as FlowTag, bg as FlowTagsSelect, bc as FlowsSelect, F as Form, ah as FormSubmission, bm as FormSubmissionsSelect, bl as FormsSelect, K as FulfillmentItem, aL as FulfillmentItemsSelect, aK as FulfillmentsSelect, b8 as GalleriesSelect, a8 as Gallery, b9 as GalleryCategoriesSelect, a9 as GalleryCategory, ab as GalleryItem, bb as GalleryItemsSelect, aa as GalleryTag, ba as GalleryTagsSelect, I as IframeBlock, k as Image, ao as ImagesSelect, L as LiveStream, bk as LiveStreamsSelect, a5 as Music, b6 as MusicCategoriesSelect, a6 as MusicCategory, a7 as MusicTag, b7 as MusicTagsSelect, b5 as MusicsSelect, aH as OrderProductsSelect, Q as OrderStatusLog, aJ as OrderStatusLogsSelect, aG as OrdersSelect, ai as PayloadKv, bn as PayloadKvSelect, aj as PayloadLockedDocument, bo as PayloadLockedDocumentsSelect, al as PayloadMigration, bq as PayloadMigrationsSelect, ak as PayloadPreference, bp as PayloadPreferencesSelect, f as PlayerBlock, a2 as Playlist, b3 as PlaylistCategoriesSelect, a3 as PlaylistCategory, a4 as PlaylistTag, b4 as PlaylistTagsSelect, b2 as PlaylistsSelect, X as Post, Y as PostAuthor, aY as PostAuthorsSelect, aZ as PostCategoriesSelect, Z as PostCategory, _ as PostTag, a_ as PostTagsSelect, aX as PostsSelect, aB as ProductCategoriesSelect, w as ProductCategory, D as ProductCollection, aD as ProductCollectionsSelect, v as ProductOption, aA as ProductOptionsSelect, x as ProductTag, aC as ProductTagsSelect, u as ProductVariant, az as ProductVariantsSelect, ay as ProductsSelect, M as ReturnProduct, aN as ReturnProductsSelect, aM as ReturnsSelect, aQ as ShippingPoliciesSelect, z as ShippingPolicy, p as Subscription, av as SubscriptionsSelect, S as SupportedTimezones, l as SystemMedia, ap as SystemMediaSelect, i as Tenant, r as TenantLogo, ax as TenantLogosSelect, at as TenantMetadataSelect, n as TenantMetadatum, as as TenantsSelect, aI as TransactionsSelect, h as User, U as UserAuthOperations, am as UsersSelect, V as Video, bi as VideoCategoriesSelect, s as VideoCategory, t as VideoTag, bj as VideoTagsSelect, bh as VideosSelect } from './payload-types-JCbsSVeL.cjs';
1
+ import { O as Order, a as OrderProduct, T as Transaction, b as Fulfillment, R as Return, E as Exchange, c as Cart, d as CartItem, P as Product } from './payload-types-D8fN_vZR.cjs';
2
+ export { o as ApiUsage, au as ApiUsageSelect, A as Audience, aq as AudiencesSelect, bs as Auth, q as BillingHistory, aw as BillingHistorySelect, y as Brand, B as BrandLogo, aF as BrandLogosSelect, aE as BrandsSelect, aV as CartItemsSelect, aU as CartsSelect, g as CodeBlock, br as CollectionsWidget, C as Config, G as Customer, J as CustomerAddress, aS as CustomerAddressesSelect, e as CustomerAuthOperations, H as CustomerGroup, aT as CustomerGroupsSelect, aR as CustomersSelect, W as Discount, aW as DiscountsSelect, $ as Document, b0 as DocumentCategoriesSelect, a1 as DocumentCategory, a0 as DocumentType, b1 as DocumentTypesSelect, a$ as DocumentsSelect, m as EmailLog, ar as EmailLogsSelect, N as ExchangeProduct, aP as ExchangeProductsSelect, aO as ExchangesSelect, j as FieldConfig, an as FieldConfigsSelect, ac as Flow, bf as FlowCategoriesSelect, ad as FlowCategory, ag as FlowEdgeType, be as FlowEdgeTypesSelect, af as FlowNodeType, bd as FlowNodeTypesSelect, ae as FlowTag, bg as FlowTagsSelect, bc as FlowsSelect, F as Form, ah as FormSubmission, bm as FormSubmissionsSelect, bl as FormsSelect, K as FulfillmentItem, aL as FulfillmentItemsSelect, aK as FulfillmentsSelect, b8 as GalleriesSelect, a8 as Gallery, b9 as GalleryCategoriesSelect, a9 as GalleryCategory, ab as GalleryItem, bb as GalleryItemsSelect, aa as GalleryTag, ba as GalleryTagsSelect, I as IframeBlock, k as Image, ao as ImagesSelect, L as LiveStream, bk as LiveStreamsSelect, a5 as Music, b6 as MusicCategoriesSelect, a6 as MusicCategory, a7 as MusicTag, b7 as MusicTagsSelect, b5 as MusicsSelect, aH as OrderProductsSelect, Q as OrderStatusLog, aJ as OrderStatusLogsSelect, aG as OrdersSelect, ai as PayloadKv, bn as PayloadKvSelect, aj as PayloadLockedDocument, bo as PayloadLockedDocumentsSelect, al as PayloadMigration, bq as PayloadMigrationsSelect, ak as PayloadPreference, bp as PayloadPreferencesSelect, f as PlayerBlock, a2 as Playlist, b3 as PlaylistCategoriesSelect, a3 as PlaylistCategory, a4 as PlaylistTag, b4 as PlaylistTagsSelect, b2 as PlaylistsSelect, X as Post, Y as PostAuthor, aY as PostAuthorsSelect, aZ as PostCategoriesSelect, Z as PostCategory, _ as PostTag, a_ as PostTagsSelect, aX as PostsSelect, aB as ProductCategoriesSelect, w as ProductCategory, D as ProductCollection, aD as ProductCollectionsSelect, v as ProductOption, aA as ProductOptionsSelect, x as ProductTag, aC as ProductTagsSelect, u as ProductVariant, az as ProductVariantsSelect, ay as ProductsSelect, M as ReturnProduct, aN as ReturnProductsSelect, aM as ReturnsSelect, aQ as ShippingPoliciesSelect, z as ShippingPolicy, p as Subscription, av as SubscriptionsSelect, S as SupportedTimezones, l as SystemMedia, ap as SystemMediaSelect, i as Tenant, r as TenantLogo, ax as TenantLogosSelect, at as TenantMetadataSelect, n as TenantMetadatum, as as TenantsSelect, aI as TransactionsSelect, h as User, U as UserAuthOperations, am as UsersSelect, V as Video, bi as VideoCategoriesSelect, s as VideoCategory, t as VideoTag, bj as VideoTagsSelect, bh as VideosSelect } from './payload-types-D8fN_vZR.cjs';
3
3
  import { Sort, Where } from 'payload';
4
4
  import * as _tanstack_react_query from '@tanstack/react-query';
5
5
  import { QueryClient, InfiniteData } from '@tanstack/react-query';
6
6
  import { Metadata } from 'next';
7
- import { P as PublicCollection } from './const-Cy_NaRCl.cjs';
8
- export { a as COLLECTIONS, C as Collection } from './const-Cy_NaRCl.cjs';
9
- import { C as CollectionType } from './webhook-CDu_s44-.cjs';
10
- export { a as WebhookEvent, b as WebhookHandler, W as WebhookOperation, c as WebhookOptions, d as createTypedWebhookHandler, h as handleWebhook, i as isValidWebhookEvent } from './webhook-CDu_s44-.cjs';
7
+ import { P as PublicCollection } from './const-C9I6r5Wa.cjs';
8
+ export { a as COLLECTIONS, C as Collection } from './const-C9I6r5Wa.cjs';
9
+ import { C as CollectionType } from './webhook-Dbx-pRib.cjs';
10
+ export { a as WebhookEvent, b as WebhookHandler, W as WebhookOperation, c as WebhookOptions, d as createTypedWebhookHandler, h as handleWebhook, i as isValidWebhookEvent } from './webhook-Dbx-pRib.cjs';
11
11
  export { a as RealtimeConnection, R as RealtimeEvent, b as RealtimeListener } from './realtime-DupPIYx-.cjs';
12
12
  export { b as IMAGE_SIZES, I as ImageData, a as ImagePalette, f as ImagePlaceholderOptions, d as getImageLqip, e as getImagePalette, h as getImagePlaceholderStyle, c as getImageSrcSet, g as getImageUrl } from './image-TT8lTsk5.cjs';
13
13
  export { e as VideoGifOptions, V as VideoThumbnailOptions, a as getVideoGif, c as getVideoMp4Url, d as getVideoStoryboard, b as getVideoStreamUrl, g as getVideoThumbnail } from './video-DbLL8yuc.cjs';
package/dist/index.d.ts CHANGED
@@ -1,13 +1,13 @@
1
- import { O as Order, a as OrderProduct, T as Transaction, b as Fulfillment, R as Return, E as Exchange, c as Cart, d as CartItem, P as Product } from './payload-types-JCbsSVeL.js';
2
- export { o as ApiUsage, au as ApiUsageSelect, A as Audience, aq as AudiencesSelect, bs as Auth, q as BillingHistory, aw as BillingHistorySelect, y as Brand, B as BrandLogo, aF as BrandLogosSelect, aE as BrandsSelect, aV as CartItemsSelect, aU as CartsSelect, g as CodeBlock, br as CollectionsWidget, C as Config, G as Customer, J as CustomerAddress, aS as CustomerAddressesSelect, e as CustomerAuthOperations, H as CustomerGroup, aT as CustomerGroupsSelect, aR as CustomersSelect, W as Discount, aW as DiscountsSelect, $ as Document, b0 as DocumentCategoriesSelect, a1 as DocumentCategory, a0 as DocumentType, b1 as DocumentTypesSelect, a$ as DocumentsSelect, m as EmailLog, ar as EmailLogsSelect, N as ExchangeProduct, aP as ExchangeProductsSelect, aO as ExchangesSelect, j as FieldConfig, an as FieldConfigsSelect, ac as Flow, bf as FlowCategoriesSelect, ad as FlowCategory, ag as FlowEdgeType, be as FlowEdgeTypesSelect, af as FlowNodeType, bd as FlowNodeTypesSelect, ae as FlowTag, bg as FlowTagsSelect, bc as FlowsSelect, F as Form, ah as FormSubmission, bm as FormSubmissionsSelect, bl as FormsSelect, K as FulfillmentItem, aL as FulfillmentItemsSelect, aK as FulfillmentsSelect, b8 as GalleriesSelect, a8 as Gallery, b9 as GalleryCategoriesSelect, a9 as GalleryCategory, ab as GalleryItem, bb as GalleryItemsSelect, aa as GalleryTag, ba as GalleryTagsSelect, I as IframeBlock, k as Image, ao as ImagesSelect, L as LiveStream, bk as LiveStreamsSelect, a5 as Music, b6 as MusicCategoriesSelect, a6 as MusicCategory, a7 as MusicTag, b7 as MusicTagsSelect, b5 as MusicsSelect, aH as OrderProductsSelect, Q as OrderStatusLog, aJ as OrderStatusLogsSelect, aG as OrdersSelect, ai as PayloadKv, bn as PayloadKvSelect, aj as PayloadLockedDocument, bo as PayloadLockedDocumentsSelect, al as PayloadMigration, bq as PayloadMigrationsSelect, ak as PayloadPreference, bp as PayloadPreferencesSelect, f as PlayerBlock, a2 as Playlist, b3 as PlaylistCategoriesSelect, a3 as PlaylistCategory, a4 as PlaylistTag, b4 as PlaylistTagsSelect, b2 as PlaylistsSelect, X as Post, Y as PostAuthor, aY as PostAuthorsSelect, aZ as PostCategoriesSelect, Z as PostCategory, _ as PostTag, a_ as PostTagsSelect, aX as PostsSelect, aB as ProductCategoriesSelect, w as ProductCategory, D as ProductCollection, aD as ProductCollectionsSelect, v as ProductOption, aA as ProductOptionsSelect, x as ProductTag, aC as ProductTagsSelect, u as ProductVariant, az as ProductVariantsSelect, ay as ProductsSelect, M as ReturnProduct, aN as ReturnProductsSelect, aM as ReturnsSelect, aQ as ShippingPoliciesSelect, z as ShippingPolicy, p as Subscription, av as SubscriptionsSelect, S as SupportedTimezones, l as SystemMedia, ap as SystemMediaSelect, i as Tenant, r as TenantLogo, ax as TenantLogosSelect, at as TenantMetadataSelect, n as TenantMetadatum, as as TenantsSelect, aI as TransactionsSelect, h as User, U as UserAuthOperations, am as UsersSelect, V as Video, bi as VideoCategoriesSelect, s as VideoCategory, t as VideoTag, bj as VideoTagsSelect, bh as VideosSelect } from './payload-types-JCbsSVeL.js';
1
+ import { O as Order, a as OrderProduct, T as Transaction, b as Fulfillment, R as Return, E as Exchange, c as Cart, d as CartItem, P as Product } from './payload-types-D8fN_vZR.js';
2
+ export { o as ApiUsage, au as ApiUsageSelect, A as Audience, aq as AudiencesSelect, bs as Auth, q as BillingHistory, aw as BillingHistorySelect, y as Brand, B as BrandLogo, aF as BrandLogosSelect, aE as BrandsSelect, aV as CartItemsSelect, aU as CartsSelect, g as CodeBlock, br as CollectionsWidget, C as Config, G as Customer, J as CustomerAddress, aS as CustomerAddressesSelect, e as CustomerAuthOperations, H as CustomerGroup, aT as CustomerGroupsSelect, aR as CustomersSelect, W as Discount, aW as DiscountsSelect, $ as Document, b0 as DocumentCategoriesSelect, a1 as DocumentCategory, a0 as DocumentType, b1 as DocumentTypesSelect, a$ as DocumentsSelect, m as EmailLog, ar as EmailLogsSelect, N as ExchangeProduct, aP as ExchangeProductsSelect, aO as ExchangesSelect, j as FieldConfig, an as FieldConfigsSelect, ac as Flow, bf as FlowCategoriesSelect, ad as FlowCategory, ag as FlowEdgeType, be as FlowEdgeTypesSelect, af as FlowNodeType, bd as FlowNodeTypesSelect, ae as FlowTag, bg as FlowTagsSelect, bc as FlowsSelect, F as Form, ah as FormSubmission, bm as FormSubmissionsSelect, bl as FormsSelect, K as FulfillmentItem, aL as FulfillmentItemsSelect, aK as FulfillmentsSelect, b8 as GalleriesSelect, a8 as Gallery, b9 as GalleryCategoriesSelect, a9 as GalleryCategory, ab as GalleryItem, bb as GalleryItemsSelect, aa as GalleryTag, ba as GalleryTagsSelect, I as IframeBlock, k as Image, ao as ImagesSelect, L as LiveStream, bk as LiveStreamsSelect, a5 as Music, b6 as MusicCategoriesSelect, a6 as MusicCategory, a7 as MusicTag, b7 as MusicTagsSelect, b5 as MusicsSelect, aH as OrderProductsSelect, Q as OrderStatusLog, aJ as OrderStatusLogsSelect, aG as OrdersSelect, ai as PayloadKv, bn as PayloadKvSelect, aj as PayloadLockedDocument, bo as PayloadLockedDocumentsSelect, al as PayloadMigration, bq as PayloadMigrationsSelect, ak as PayloadPreference, bp as PayloadPreferencesSelect, f as PlayerBlock, a2 as Playlist, b3 as PlaylistCategoriesSelect, a3 as PlaylistCategory, a4 as PlaylistTag, b4 as PlaylistTagsSelect, b2 as PlaylistsSelect, X as Post, Y as PostAuthor, aY as PostAuthorsSelect, aZ as PostCategoriesSelect, Z as PostCategory, _ as PostTag, a_ as PostTagsSelect, aX as PostsSelect, aB as ProductCategoriesSelect, w as ProductCategory, D as ProductCollection, aD as ProductCollectionsSelect, v as ProductOption, aA as ProductOptionsSelect, x as ProductTag, aC as ProductTagsSelect, u as ProductVariant, az as ProductVariantsSelect, ay as ProductsSelect, M as ReturnProduct, aN as ReturnProductsSelect, aM as ReturnsSelect, aQ as ShippingPoliciesSelect, z as ShippingPolicy, p as Subscription, av as SubscriptionsSelect, S as SupportedTimezones, l as SystemMedia, ap as SystemMediaSelect, i as Tenant, r as TenantLogo, ax as TenantLogosSelect, at as TenantMetadataSelect, n as TenantMetadatum, as as TenantsSelect, aI as TransactionsSelect, h as User, U as UserAuthOperations, am as UsersSelect, V as Video, bi as VideoCategoriesSelect, s as VideoCategory, t as VideoTag, bj as VideoTagsSelect, bh as VideosSelect } from './payload-types-D8fN_vZR.js';
3
3
  import { Sort, Where } from 'payload';
4
4
  import * as _tanstack_react_query from '@tanstack/react-query';
5
5
  import { QueryClient, InfiniteData } from '@tanstack/react-query';
6
6
  import { Metadata } from 'next';
7
- import { P as PublicCollection } from './const-C6vryj3j.js';
8
- export { a as COLLECTIONS, C as Collection } from './const-C6vryj3j.js';
9
- import { C as CollectionType } from './webhook-Dd_7Qgaa.js';
10
- export { a as WebhookEvent, b as WebhookHandler, W as WebhookOperation, c as WebhookOptions, d as createTypedWebhookHandler, h as handleWebhook, i as isValidWebhookEvent } from './webhook-Dd_7Qgaa.js';
7
+ import { P as PublicCollection } from './const-JbuUTzeh.js';
8
+ export { a as COLLECTIONS, C as Collection } from './const-JbuUTzeh.js';
9
+ import { C as CollectionType } from './webhook-BkwMrrL1.js';
10
+ export { a as WebhookEvent, b as WebhookHandler, W as WebhookOperation, c as WebhookOptions, d as createTypedWebhookHandler, h as handleWebhook, i as isValidWebhookEvent } from './webhook-BkwMrrL1.js';
11
11
  export { a as RealtimeConnection, R as RealtimeEvent, b as RealtimeListener } from './realtime-DupPIYx-.js';
12
12
  export { b as IMAGE_SIZES, I as ImageData, a as ImagePalette, f as ImagePlaceholderOptions, d as getImageLqip, e as getImagePalette, h as getImagePlaceholderStyle, c as getImageSrcSet, g as getImageUrl } from './image-TT8lTsk5.js';
13
13
  export { e as VideoGifOptions, V as VideoThumbnailOptions, a as getVideoGif, c as getVideoMp4Url, d as getVideoStoryboard, b as getVideoStreamUrl, g as getVideoThumbnail } from './video-DbLL8yuc.js';
@@ -312,6 +312,8 @@ interface User {
312
312
  emailPreferences?: {
313
313
  usageAlerts?: boolean | null;
314
314
  };
315
+ authProvider?: ('local' | 'google') | null;
316
+ googleSub?: string | null;
315
317
  updatedAt: string;
316
318
  createdAt: string;
317
319
  email: string;
@@ -540,7 +542,7 @@ interface EmailLog {
540
542
  to: string;
541
543
  from?: string | null;
542
544
  subject: string;
543
- type: 'usage-alert' | 'verification' | 'password-reset' | 'newsletter' | 'other';
545
+ type: 'usage-alert' | 'verification' | 'password-reset' | 'newsletter' | 'other' | 'oauth-login' | 'account-link';
544
546
  status: 'sent' | 'failed';
545
547
  sentAt: string;
546
548
  error?: string | null;
@@ -3591,6 +3593,8 @@ interface UsersSelect<T extends boolean = true> {
3591
3593
  emailPreferences?: T | {
3592
3594
  usageAlerts?: T;
3593
3595
  };
3596
+ authProvider?: T;
3597
+ googleSub?: T;
3594
3598
  updatedAt?: T;
3595
3599
  createdAt?: T;
3596
3600
  email?: T;
@@ -312,6 +312,8 @@ interface User {
312
312
  emailPreferences?: {
313
313
  usageAlerts?: boolean | null;
314
314
  };
315
+ authProvider?: ('local' | 'google') | null;
316
+ googleSub?: string | null;
315
317
  updatedAt: string;
316
318
  createdAt: string;
317
319
  email: string;
@@ -540,7 +542,7 @@ interface EmailLog {
540
542
  to: string;
541
543
  from?: string | null;
542
544
  subject: string;
543
- type: 'usage-alert' | 'verification' | 'password-reset' | 'newsletter' | 'other';
545
+ type: 'usage-alert' | 'verification' | 'password-reset' | 'newsletter' | 'other' | 'oauth-login' | 'account-link';
544
546
  status: 'sent' | 'failed';
545
547
  sentAt: string;
546
548
  error?: string | null;
@@ -3591,6 +3593,8 @@ interface UsersSelect<T extends boolean = true> {
3591
3593
  emailPreferences?: T | {
3592
3594
  usageAlerts?: T;
3593
3595
  };
3596
+ authProvider?: T;
3597
+ googleSub?: T;
3594
3598
  updatedAt?: T;
3595
3599
  createdAt?: T;
3596
3600
  email?: T;
@@ -1,7 +1,7 @@
1
1
  import { R as RealtimeEvent } from './realtime-DupPIYx-.cjs';
2
2
  export { a as RealtimeConnection, b as RealtimeListener } from './realtime-DupPIYx-.cjs';
3
- import { P as PublicCollection } from './const-Cy_NaRCl.cjs';
4
- import './payload-types-JCbsSVeL.cjs';
3
+ import { P as PublicCollection } from './const-C9I6r5Wa.cjs';
4
+ import './payload-types-D8fN_vZR.cjs';
5
5
 
6
6
  interface UseRealtimeQueryOptions {
7
7
  /** Filter events to specific collections. Empty/undefined = all collections. */
@@ -1,7 +1,7 @@
1
1
  import { R as RealtimeEvent } from './realtime-DupPIYx-.js';
2
2
  export { a as RealtimeConnection, b as RealtimeListener } from './realtime-DupPIYx-.js';
3
- import { P as PublicCollection } from './const-C6vryj3j.js';
4
- import './payload-types-JCbsSVeL.js';
3
+ import { P as PublicCollection } from './const-JbuUTzeh.js';
4
+ import './payload-types-D8fN_vZR.js';
5
5
 
6
6
  interface UseRealtimeQueryOptions {
7
7
  /** Filter events to specific collections. Empty/undefined = all collections. */
@@ -152,6 +152,10 @@ interface FlowBounds {
152
152
  height: number;
153
153
  }
154
154
 
155
+ declare const BUILT_IN_NODE_TYPES: NodeTypeDef[];
156
+
157
+ declare const BUILT_IN_EDGE_TYPES: EdgeTypeDef[];
158
+
155
159
  type FlowCollection = 'flows' | 'flow-node-types' | 'flow-edge-types';
156
160
  type AnyFn = (...args: any[]) => any;
157
161
  interface SDKClient {
@@ -239,4 +243,4 @@ interface FrameData {
239
243
  */
240
244
  declare function getFrameData(data: CanvasData, frameId: string): FrameData | undefined;
241
245
 
242
- export { type CanvasData as C, type DynamicNodeSlotProps as D, type EdgeTypeDef as E, type FlowNode as F, type NodeTypeDef as N, type PrefetchFlowOptions as P, type SDKClient as S, type UseFlowOptions as U, type FlowEdge as a, type FrameNodeSlotProps as b, type EdgeSlotProps as c, type NodeWrapperSlotProps as d, type FlowViewport as e, type FlowBounds as f, type FlowNodePosition as g, type FlowNodeData as h, type DynamicNodeData as i, type FrameNodeData as j, type NodeTypeFieldDef as k, isDynamicNode as l, isFrameNode as m, type UseFlowResult as n, getNodeBounds as o, prefetchFlow as p, getFrames as q, getFrameData as r, type FrameData as s, useFlow as u };
246
+ export { BUILT_IN_NODE_TYPES as B, type CanvasData as C, type DynamicNodeSlotProps as D, type EdgeTypeDef as E, type FlowNode as F, type NodeTypeDef as N, type PrefetchFlowOptions as P, type SDKClient as S, type UseFlowOptions as U, type NodeTypeFieldDef as a, type FlowEdge as b, type FrameNodeSlotProps as c, type EdgeSlotProps as d, type NodeWrapperSlotProps as e, type FlowViewport as f, type FlowBounds as g, type FrameData as h, type FlowNodePosition as i, type FlowNodeData as j, type DynamicNodeData as k, type FrameNodeData as l, isDynamicNode as m, isFrameNode as n, BUILT_IN_EDGE_TYPES as o, type UseFlowResult as p, prefetchFlow as q, getNodeBounds as r, getFrames as s, getFrameData as t, useFlow as u };
@@ -152,6 +152,10 @@ interface FlowBounds {
152
152
  height: number;
153
153
  }
154
154
 
155
+ declare const BUILT_IN_NODE_TYPES: NodeTypeDef[];
156
+
157
+ declare const BUILT_IN_EDGE_TYPES: EdgeTypeDef[];
158
+
155
159
  type FlowCollection = 'flows' | 'flow-node-types' | 'flow-edge-types';
156
160
  type AnyFn = (...args: any[]) => any;
157
161
  interface SDKClient {
@@ -239,4 +243,4 @@ interface FrameData {
239
243
  */
240
244
  declare function getFrameData(data: CanvasData, frameId: string): FrameData | undefined;
241
245
 
242
- export { type CanvasData as C, type DynamicNodeSlotProps as D, type EdgeTypeDef as E, type FlowNode as F, type NodeTypeDef as N, type PrefetchFlowOptions as P, type SDKClient as S, type UseFlowOptions as U, type FlowEdge as a, type FrameNodeSlotProps as b, type EdgeSlotProps as c, type NodeWrapperSlotProps as d, type FlowViewport as e, type FlowBounds as f, type FlowNodePosition as g, type FlowNodeData as h, type DynamicNodeData as i, type FrameNodeData as j, type NodeTypeFieldDef as k, isDynamicNode as l, isFrameNode as m, type UseFlowResult as n, getNodeBounds as o, prefetchFlow as p, getFrames as q, getFrameData as r, type FrameData as s, useFlow as u };
246
+ export { BUILT_IN_NODE_TYPES as B, type CanvasData as C, type DynamicNodeSlotProps as D, type EdgeTypeDef as E, type FlowNode as F, type NodeTypeDef as N, type PrefetchFlowOptions as P, type SDKClient as S, type UseFlowOptions as U, type NodeTypeFieldDef as a, type FlowEdge as b, type FrameNodeSlotProps as c, type EdgeSlotProps as d, type NodeWrapperSlotProps as e, type FlowViewport as f, type FlowBounds as g, type FrameData as h, type FlowNodePosition as i, type FlowNodeData as j, type DynamicNodeData as k, type FrameNodeData as l, isDynamicNode as m, isFrameNode as n, BUILT_IN_EDGE_TYPES as o, type UseFlowResult as p, prefetchFlow as q, getNodeBounds as r, getFrames as s, getFrameData as t, useFlow as u };
@@ -104,8 +104,12 @@ function CodeBlock({
104
104
  const [nodes, setNodes] = (0, import_react2.useState)(initial);
105
105
  const [copied, setCopied] = (0, import_react2.useState)(false);
106
106
  const initialCodeRef = (0, import_react2.useRef)(code);
107
+ const initialNodesRef = (0, import_react2.useRef)(initial);
107
108
  (0, import_react2.useEffect)(() => {
108
- if (initial && code === initialCodeRef.current && nodes === initial) return;
109
+ if (initial && code === initialCodeRef.current && initialNodesRef.current === initial) {
110
+ initialNodesRef.current = void 0;
111
+ return;
112
+ }
109
113
  let cancelled = false;
110
114
  void highlight(code, language, theme).then((el) => {
111
115
  if (!cancelled) setNodes(el);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/ui/CodeBlock/index.tsx","../../src/ui/CodeBlock/highlight.ts"],"sourcesContent":["'use client'\n\nimport React, { useEffect, useRef, useState, type JSX } from 'react'\nimport { highlight, type BundledTheme } from './highlight'\n\nexport type { BundledTheme }\nexport { highlight }\n\nexport interface CodeBlockProps {\n /** Code string to highlight */\n code: string\n /** Language identifier (e.g. 'typescript', 'js', 'python') */\n language?: string\n /** Shiki theme name. Default: 'github-dark' */\n theme?: BundledTheme\n /** CSS class for the wrapper */\n className?: string\n /** Pre-rendered JSX from server component via `highlight()` */\n initial?: JSX.Element\n /** Show line numbers. Default: false */\n showLineNumbers?: boolean\n /** Show copy button. Default: true */\n showCopyButton?: boolean\n}\n\n/**\n * Syntax-highlighted code block using shiki.\n *\n * @example Basic usage\n * ```tsx\n * <CodeBlock code=\"const x = 1\" language=\"typescript\" />\n * ```\n *\n * @example With server pre-rendering (Next.js)\n * ```tsx\n * // Server Component\n * const initial = await highlight(code, 'typescript')\n * return <CodeBlock code={code} language=\"typescript\" initial={initial} />\n * ```\n *\n * @example As RichTextContent block renderer\n * ```tsx\n * <RichTextContent\n * data={data}\n * blocks={{\n * Code: ({ node }) => (\n * <CodeBlock code={node.fields.code} language={node.fields.language} />\n * ),\n * }}\n * />\n * ```\n */\nexport function CodeBlock({\n code,\n language = 'typescript',\n theme = 'github-dark',\n className,\n initial,\n showLineNumbers = false,\n showCopyButton = true,\n}: CodeBlockProps) {\n const [nodes, setNodes] = useState<JSX.Element | undefined>(initial)\n const [copied, setCopied] = useState(false)\n const initialCodeRef = useRef(code)\n\n useEffect(() => {\n // Skip re-highlighting if server pre-rendered and code hasn't changed\n if (initial && code === initialCodeRef.current && nodes === initial) return\n\n let cancelled = false\n void highlight(code, language, theme).then((el) => {\n if (!cancelled) setNodes(el)\n })\n return () => {\n cancelled = true\n }\n }, [code, language, theme, initial])\n\n const handleCopy = () => {\n void navigator.clipboard.writeText(code).then(\n () => {\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n },\n () => {},\n )\n }\n\n return (\n <div className={className} style={{ position: 'relative' }}>\n {showCopyButton && (\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label=\"Copy code\"\n style={{\n position: 'absolute',\n top: 8,\n right: 8,\n zIndex: 1,\n padding: '4px 8px',\n fontSize: 12,\n lineHeight: 1,\n border: '1px solid rgba(255,255,255,0.2)',\n borderRadius: 4,\n background: 'rgba(0,0,0,0.3)',\n color: '#ccc',\n cursor: 'pointer',\n opacity: 0.7,\n transition: 'opacity 0.15s',\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = '1'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = '0.7'\n }}\n >\n {copied ? 'Copied!' : 'Copy'}\n </button>\n )}\n {showLineNumbers && nodes ? (\n <div style={{ display: 'flex' }}>\n <div\n aria-hidden\n style={{\n padding: '1em 0.5em 1em 1em',\n textAlign: 'right',\n userSelect: 'none',\n color: 'rgba(255,255,255,0.3)',\n fontFamily: 'monospace',\n fontSize: 13,\n lineHeight: 1.5,\n }}\n >\n {code.split('\\n').map((_, i) => (\n <div key={i}>{i + 1}</div>\n ))}\n </div>\n <div style={{ flex: 1, overflow: 'auto' }}>{nodes}</div>\n </div>\n ) : (\n (nodes ?? (\n <pre\n style={{\n margin: 0,\n padding: '1em',\n overflow: 'auto',\n fontFamily: 'monospace',\n fontSize: 13,\n lineHeight: 1.5,\n }}\n >\n <code>{code}</code>\n </pre>\n ))\n )}\n </div>\n )\n}\n","import type { JSX } from 'react'\nimport { Fragment } from 'react'\nimport { jsx, jsxs } from 'react/jsx-runtime'\nimport { toJsxRuntime } from 'hast-util-to-jsx-runtime'\nimport { codeToHast, type BundledLanguage, type BundledTheme } from 'shiki'\n\nexport type { BundledLanguage, BundledTheme }\n\n/** Normalize language aliases to shiki-compatible language IDs */\nconst LANGUAGE_ALIASES: Record<string, string> = {\n js: 'javascript',\n ts: 'typescript',\n sh: 'bash',\n shell: 'bash',\n yml: 'yaml',\n py: 'python',\n rb: 'ruby',\n plaintext: 'text',\n}\n\nfunction normalizeLanguage(lang: string): string {\n return LANGUAGE_ALIASES[lang] || lang\n}\n\n/**\n * Highlight code to JSX using shiki.\n * Works in both Server and Client components.\n *\n * @example Server Component\n * ```tsx\n * const highlighted = await highlight('const x = 1', 'typescript')\n * return <div>{highlighted}</div>\n * ```\n */\nexport async function highlight(\n code: string,\n lang: string,\n theme: BundledTheme = 'github-dark',\n): Promise<JSX.Element> {\n const normalized = normalizeLanguage(lang)\n try {\n const hast = await codeToHast(code, {\n lang: normalized as BundledLanguage,\n theme,\n })\n return toJsxRuntime(hast, { Fragment, jsx, jsxs }) as JSX.Element\n } catch {\n // Fallback to plain text if language is not supported\n const hast = await codeToHast(code, { lang: 'text', theme })\n return toJsxRuntime(hast, { Fragment, jsx, jsxs }) as JSX.Element\n }\n}\n"],"mappings":"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","names":["import_react","React"]}
1
+ {"version":3,"sources":["../../src/ui/CodeBlock/index.tsx","../../src/ui/CodeBlock/highlight.ts"],"sourcesContent":["'use client'\n\nimport React, { useEffect, useRef, useState, type JSX } from 'react'\nimport { highlight, type BundledTheme } from './highlight'\n\nexport type { BundledTheme }\nexport { highlight }\n\nexport interface CodeBlockProps {\n /** Code string to highlight */\n code: string\n /** Language identifier (e.g. 'typescript', 'js', 'python') */\n language?: string\n /** Shiki theme name. Default: 'github-dark' */\n theme?: BundledTheme\n /** CSS class for the wrapper */\n className?: string\n /** Pre-rendered JSX from server component via `highlight()` */\n initial?: JSX.Element\n /** Show line numbers. Default: false */\n showLineNumbers?: boolean\n /** Show copy button. Default: true */\n showCopyButton?: boolean\n}\n\n/**\n * Syntax-highlighted code block using shiki.\n *\n * @example Basic usage\n * ```tsx\n * <CodeBlock code=\"const x = 1\" language=\"typescript\" />\n * ```\n *\n * @example With server pre-rendering (Next.js)\n * ```tsx\n * // Server Component\n * const initial = await highlight(code, 'typescript')\n * return <CodeBlock code={code} language=\"typescript\" initial={initial} />\n * ```\n *\n * @example As RichTextContent block renderer\n * ```tsx\n * <RichTextContent\n * data={data}\n * blocks={{\n * Code: ({ node }) => (\n * <CodeBlock code={node.fields.code} language={node.fields.language} />\n * ),\n * }}\n * />\n * ```\n */\nexport function CodeBlock({\n code,\n language = 'typescript',\n theme = 'github-dark',\n className,\n initial,\n showLineNumbers = false,\n showCopyButton = true,\n}: CodeBlockProps) {\n const [nodes, setNodes] = useState<JSX.Element | undefined>(initial)\n const [copied, setCopied] = useState(false)\n const initialCodeRef = useRef(code)\n const initialNodesRef = useRef(initial)\n\n useEffect(() => {\n // Skip re-highlighting if server pre-rendered and code hasn't changed\n if (initial && code === initialCodeRef.current && initialNodesRef.current === initial) {\n initialNodesRef.current = undefined\n return\n }\n\n let cancelled = false\n void highlight(code, language, theme).then((el) => {\n if (!cancelled) setNodes(el)\n })\n return () => {\n cancelled = true\n }\n }, [code, language, theme, initial])\n\n const handleCopy = () => {\n void navigator.clipboard.writeText(code).then(\n () => {\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n },\n () => {},\n )\n }\n\n return (\n <div className={className} style={{ position: 'relative' }}>\n {showCopyButton && (\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label=\"Copy code\"\n style={{\n position: 'absolute',\n top: 8,\n right: 8,\n zIndex: 1,\n padding: '4px 8px',\n fontSize: 12,\n lineHeight: 1,\n border: '1px solid rgba(255,255,255,0.2)',\n borderRadius: 4,\n background: 'rgba(0,0,0,0.3)',\n color: '#ccc',\n cursor: 'pointer',\n opacity: 0.7,\n transition: 'opacity 0.15s',\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = '1'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = '0.7'\n }}\n >\n {copied ? 'Copied!' : 'Copy'}\n </button>\n )}\n {showLineNumbers && nodes ? (\n <div style={{ display: 'flex' }}>\n <div\n aria-hidden\n style={{\n padding: '1em 0.5em 1em 1em',\n textAlign: 'right',\n userSelect: 'none',\n color: 'rgba(255,255,255,0.3)',\n fontFamily: 'monospace',\n fontSize: 13,\n lineHeight: 1.5,\n }}\n >\n {code.split('\\n').map((_, i) => (\n <div key={i}>{i + 1}</div>\n ))}\n </div>\n <div style={{ flex: 1, overflow: 'auto' }}>{nodes}</div>\n </div>\n ) : (\n (nodes ?? (\n <pre\n style={{\n margin: 0,\n padding: '1em',\n overflow: 'auto',\n fontFamily: 'monospace',\n fontSize: 13,\n lineHeight: 1.5,\n }}\n >\n <code>{code}</code>\n </pre>\n ))\n )}\n </div>\n )\n}\n","import type { JSX } from 'react'\nimport { Fragment } from 'react'\nimport { jsx, jsxs } from 'react/jsx-runtime'\nimport { toJsxRuntime } from 'hast-util-to-jsx-runtime'\nimport { codeToHast, type BundledLanguage, type BundledTheme } from 'shiki'\n\nexport type { BundledLanguage, BundledTheme }\n\n/** Normalize language aliases to shiki-compatible language IDs */\nconst LANGUAGE_ALIASES: Record<string, string> = {\n js: 'javascript',\n ts: 'typescript',\n sh: 'bash',\n shell: 'bash',\n yml: 'yaml',\n py: 'python',\n rb: 'ruby',\n plaintext: 'text',\n}\n\nfunction normalizeLanguage(lang: string): string {\n return LANGUAGE_ALIASES[lang] || lang\n}\n\n/**\n * Highlight code to JSX using shiki.\n * Works in both Server and Client components.\n *\n * @example Server Component\n * ```tsx\n * const highlighted = await highlight('const x = 1', 'typescript')\n * return <div>{highlighted}</div>\n * ```\n */\nexport async function highlight(\n code: string,\n lang: string,\n theme: BundledTheme = 'github-dark',\n): Promise<JSX.Element> {\n const normalized = normalizeLanguage(lang)\n try {\n const hast = await codeToHast(code, {\n lang: normalized as BundledLanguage,\n theme,\n })\n return toJsxRuntime(hast, { Fragment, jsx, jsxs }) as JSX.Element\n } catch {\n // Fallback to plain text if language is not supported\n const hast = await codeToHast(code, { lang: 'text', theme })\n return toJsxRuntime(hast, { Fragment, jsx, jsxs }) as JSX.Element\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAEA,IAAAA,gBAA6D;;;ACD7D,mBAAyB;AACzB,yBAA0B;AAC1B,sCAA6B;AAC7B,mBAAoE;AAKpE,IAAM,mBAA2C;AAAA,EAC/C,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,OAAO;AAAA,EACP,KAAK;AAAA,EACL,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,WAAW;AACb;AAEA,SAAS,kBAAkB,MAAsB;AAC/C,SAAO,iBAAiB,IAAI,KAAK;AACnC;AAYA,SAAsB,UACpB,MACA,MACA,QAAsB,eACA;AAAA;AACtB,UAAM,aAAa,kBAAkB,IAAI;AACzC,QAAI;AACF,YAAM,OAAO,UAAM,yBAAW,MAAM;AAAA,QAClC,MAAM;AAAA,QACN;AAAA,MACF,CAAC;AACD,iBAAO,8CAAa,MAAM,EAAE,iCAAU,6BAAK,8BAAK,CAAC;AAAA,IACnD,SAAQ;AAEN,YAAM,OAAO,UAAM,yBAAW,MAAM,EAAE,MAAM,QAAQ,MAAM,CAAC;AAC3D,iBAAO,8CAAa,MAAM,EAAE,iCAAU,6BAAK,8BAAK,CAAC;AAAA,IACnD;AAAA,EACF;AAAA;;;ADCO,SAAS,UAAU;AAAA,EACxB;AAAA,EACA,WAAW;AAAA,EACX,QAAQ;AAAA,EACR;AAAA,EACA;AAAA,EACA,kBAAkB;AAAA,EAClB,iBAAiB;AACnB,GAAmB;AACjB,QAAM,CAAC,OAAO,QAAQ,QAAI,wBAAkC,OAAO;AACnE,QAAM,CAAC,QAAQ,SAAS,QAAI,wBAAS,KAAK;AAC1C,QAAM,qBAAiB,sBAAO,IAAI;AAClC,QAAM,sBAAkB,sBAAO,OAAO;AAEtC,+BAAU,MAAM;AAEd,QAAI,WAAW,SAAS,eAAe,WAAW,gBAAgB,YAAY,SAAS;AACrF,sBAAgB,UAAU;AAC1B;AAAA,IACF;AAEA,QAAI,YAAY;AAChB,SAAK,UAAU,MAAM,UAAU,KAAK,EAAE,KAAK,CAAC,OAAO;AACjD,UAAI,CAAC,UAAW,UAAS,EAAE;AAAA,IAC7B,CAAC;AACD,WAAO,MAAM;AACX,kBAAY;AAAA,IACd;AAAA,EACF,GAAG,CAAC,MAAM,UAAU,OAAO,OAAO,CAAC;AAEnC,QAAM,aAAa,MAAM;AACvB,SAAK,UAAU,UAAU,UAAU,IAAI,EAAE;AAAA,MACvC,MAAM;AACJ,kBAAU,IAAI;AACd,mBAAW,MAAM,UAAU,KAAK,GAAG,GAAI;AAAA,MACzC;AAAA,MACA,MAAM;AAAA,MAAC;AAAA,IACT;AAAA,EACF;AAEA,SACE,8BAAAC,QAAA,cAAC,SAAI,WAAsB,OAAO,EAAE,UAAU,WAAW,KACtD,kBACC,8BAAAA,QAAA;AAAA,IAAC;AAAA;AAAA,MACC,MAAK;AAAA,MACL,SAAS;AAAA,MACT,cAAW;AAAA,MACX,OAAO;AAAA,QACL,UAAU;AAAA,QACV,KAAK;AAAA,QACL,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,QAAQ;AAAA,QACR,cAAc;AAAA,QACd,YAAY;AAAA,QACZ,OAAO;AAAA,QACP,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,YAAY;AAAA,MACd;AAAA,MACA,cAAc,CAAC,MAAM;AACnB,UAAE,cAAc,MAAM,UAAU;AAAA,MAClC;AAAA,MACA,cAAc,CAAC,MAAM;AACnB,UAAE,cAAc,MAAM,UAAU;AAAA,MAClC;AAAA;AAAA,IAEC,SAAS,YAAY;AAAA,EACxB,GAED,mBAAmB,QAClB,8BAAAA,QAAA,cAAC,SAAI,OAAO,EAAE,SAAS,OAAO,KAC5B,8BAAAA,QAAA;AAAA,IAAC;AAAA;AAAA,MACC,eAAW;AAAA,MACX,OAAO;AAAA,QACL,SAAS;AAAA,QACT,WAAW;AAAA,QACX,YAAY;AAAA,QACZ,OAAO;AAAA,QACP,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,YAAY;AAAA,MACd;AAAA;AAAA,IAEC,KAAK,MAAM,IAAI,EAAE,IAAI,CAAC,GAAG,MACxB,8BAAAA,QAAA,cAAC,SAAI,KAAK,KAAI,IAAI,CAAE,CACrB;AAAA,EACH,GACA,8BAAAA,QAAA,cAAC,SAAI,OAAO,EAAE,MAAM,GAAG,UAAU,OAAO,KAAI,KAAM,CACpD,IAEC,wBACC,8BAAAA,QAAA;AAAA,IAAC;AAAA;AAAA,MACC,OAAO;AAAA,QACL,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,UAAU;AAAA,QACV,YAAY;AAAA,QACZ,UAAU;AAAA,QACV,YAAY;AAAA,MACd;AAAA;AAAA,IAEA,8BAAAA,QAAA,cAAC,cAAM,IAAK;AAAA,EACd,CAGN;AAEJ;","names":["import_react","React"]}
@@ -70,8 +70,12 @@ function CodeBlock({
70
70
  const [nodes, setNodes] = useState(initial);
71
71
  const [copied, setCopied] = useState(false);
72
72
  const initialCodeRef = useRef(code);
73
+ const initialNodesRef = useRef(initial);
73
74
  useEffect(() => {
74
- if (initial && code === initialCodeRef.current && nodes === initial) return;
75
+ if (initial && code === initialCodeRef.current && initialNodesRef.current === initial) {
76
+ initialNodesRef.current = void 0;
77
+ return;
78
+ }
75
79
  let cancelled = false;
76
80
  void highlight(code, language, theme).then((el) => {
77
81
  if (!cancelled) setNodes(el);
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/ui/CodeBlock/index.tsx","../../src/ui/CodeBlock/highlight.ts"],"sourcesContent":["'use client'\n\nimport React, { useEffect, useRef, useState, type JSX } from 'react'\nimport { highlight, type BundledTheme } from './highlight'\n\nexport type { BundledTheme }\nexport { highlight }\n\nexport interface CodeBlockProps {\n /** Code string to highlight */\n code: string\n /** Language identifier (e.g. 'typescript', 'js', 'python') */\n language?: string\n /** Shiki theme name. Default: 'github-dark' */\n theme?: BundledTheme\n /** CSS class for the wrapper */\n className?: string\n /** Pre-rendered JSX from server component via `highlight()` */\n initial?: JSX.Element\n /** Show line numbers. Default: false */\n showLineNumbers?: boolean\n /** Show copy button. Default: true */\n showCopyButton?: boolean\n}\n\n/**\n * Syntax-highlighted code block using shiki.\n *\n * @example Basic usage\n * ```tsx\n * <CodeBlock code=\"const x = 1\" language=\"typescript\" />\n * ```\n *\n * @example With server pre-rendering (Next.js)\n * ```tsx\n * // Server Component\n * const initial = await highlight(code, 'typescript')\n * return <CodeBlock code={code} language=\"typescript\" initial={initial} />\n * ```\n *\n * @example As RichTextContent block renderer\n * ```tsx\n * <RichTextContent\n * data={data}\n * blocks={{\n * Code: ({ node }) => (\n * <CodeBlock code={node.fields.code} language={node.fields.language} />\n * ),\n * }}\n * />\n * ```\n */\nexport function CodeBlock({\n code,\n language = 'typescript',\n theme = 'github-dark',\n className,\n initial,\n showLineNumbers = false,\n showCopyButton = true,\n}: CodeBlockProps) {\n const [nodes, setNodes] = useState<JSX.Element | undefined>(initial)\n const [copied, setCopied] = useState(false)\n const initialCodeRef = useRef(code)\n\n useEffect(() => {\n // Skip re-highlighting if server pre-rendered and code hasn't changed\n if (initial && code === initialCodeRef.current && nodes === initial) return\n\n let cancelled = false\n void highlight(code, language, theme).then((el) => {\n if (!cancelled) setNodes(el)\n })\n return () => {\n cancelled = true\n }\n }, [code, language, theme, initial])\n\n const handleCopy = () => {\n void navigator.clipboard.writeText(code).then(\n () => {\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n },\n () => {},\n )\n }\n\n return (\n <div className={className} style={{ position: 'relative' }}>\n {showCopyButton && (\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label=\"Copy code\"\n style={{\n position: 'absolute',\n top: 8,\n right: 8,\n zIndex: 1,\n padding: '4px 8px',\n fontSize: 12,\n lineHeight: 1,\n border: '1px solid rgba(255,255,255,0.2)',\n borderRadius: 4,\n background: 'rgba(0,0,0,0.3)',\n color: '#ccc',\n cursor: 'pointer',\n opacity: 0.7,\n transition: 'opacity 0.15s',\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = '1'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = '0.7'\n }}\n >\n {copied ? 'Copied!' : 'Copy'}\n </button>\n )}\n {showLineNumbers && nodes ? (\n <div style={{ display: 'flex' }}>\n <div\n aria-hidden\n style={{\n padding: '1em 0.5em 1em 1em',\n textAlign: 'right',\n userSelect: 'none',\n color: 'rgba(255,255,255,0.3)',\n fontFamily: 'monospace',\n fontSize: 13,\n lineHeight: 1.5,\n }}\n >\n {code.split('\\n').map((_, i) => (\n <div key={i}>{i + 1}</div>\n ))}\n </div>\n <div style={{ flex: 1, overflow: 'auto' }}>{nodes}</div>\n </div>\n ) : (\n (nodes ?? (\n <pre\n style={{\n margin: 0,\n padding: '1em',\n overflow: 'auto',\n fontFamily: 'monospace',\n fontSize: 13,\n lineHeight: 1.5,\n }}\n >\n <code>{code}</code>\n </pre>\n ))\n )}\n </div>\n )\n}\n","import type { JSX } from 'react'\nimport { Fragment } from 'react'\nimport { jsx, jsxs } from 'react/jsx-runtime'\nimport { toJsxRuntime } from 'hast-util-to-jsx-runtime'\nimport { codeToHast, type BundledLanguage, type BundledTheme } from 'shiki'\n\nexport type { BundledLanguage, BundledTheme }\n\n/** Normalize language aliases to shiki-compatible language IDs */\nconst LANGUAGE_ALIASES: Record<string, string> = {\n js: 'javascript',\n ts: 'typescript',\n sh: 'bash',\n shell: 'bash',\n yml: 'yaml',\n py: 'python',\n rb: 'ruby',\n plaintext: 'text',\n}\n\nfunction normalizeLanguage(lang: string): string {\n return LANGUAGE_ALIASES[lang] || lang\n}\n\n/**\n * Highlight code to JSX using shiki.\n * Works in both Server and Client components.\n *\n * @example Server Component\n * ```tsx\n * const highlighted = await highlight('const x = 1', 'typescript')\n * return <div>{highlighted}</div>\n * ```\n */\nexport async function highlight(\n code: string,\n lang: string,\n theme: BundledTheme = 'github-dark',\n): Promise<JSX.Element> {\n const normalized = normalizeLanguage(lang)\n try {\n const hast = await codeToHast(code, {\n lang: normalized as BundledLanguage,\n theme,\n })\n return toJsxRuntime(hast, { Fragment, jsx, jsxs }) as JSX.Element\n } catch {\n // Fallback to plain text if language is not supported\n const hast = await codeToHast(code, { lang: 'text', theme })\n return toJsxRuntime(hast, { Fragment, jsx, jsxs }) as JSX.Element\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../src/ui/CodeBlock/index.tsx","../../src/ui/CodeBlock/highlight.ts"],"sourcesContent":["'use client'\n\nimport React, { useEffect, useRef, useState, type JSX } from 'react'\nimport { highlight, type BundledTheme } from './highlight'\n\nexport type { BundledTheme }\nexport { highlight }\n\nexport interface CodeBlockProps {\n /** Code string to highlight */\n code: string\n /** Language identifier (e.g. 'typescript', 'js', 'python') */\n language?: string\n /** Shiki theme name. Default: 'github-dark' */\n theme?: BundledTheme\n /** CSS class for the wrapper */\n className?: string\n /** Pre-rendered JSX from server component via `highlight()` */\n initial?: JSX.Element\n /** Show line numbers. Default: false */\n showLineNumbers?: boolean\n /** Show copy button. Default: true */\n showCopyButton?: boolean\n}\n\n/**\n * Syntax-highlighted code block using shiki.\n *\n * @example Basic usage\n * ```tsx\n * <CodeBlock code=\"const x = 1\" language=\"typescript\" />\n * ```\n *\n * @example With server pre-rendering (Next.js)\n * ```tsx\n * // Server Component\n * const initial = await highlight(code, 'typescript')\n * return <CodeBlock code={code} language=\"typescript\" initial={initial} />\n * ```\n *\n * @example As RichTextContent block renderer\n * ```tsx\n * <RichTextContent\n * data={data}\n * blocks={{\n * Code: ({ node }) => (\n * <CodeBlock code={node.fields.code} language={node.fields.language} />\n * ),\n * }}\n * />\n * ```\n */\nexport function CodeBlock({\n code,\n language = 'typescript',\n theme = 'github-dark',\n className,\n initial,\n showLineNumbers = false,\n showCopyButton = true,\n}: CodeBlockProps) {\n const [nodes, setNodes] = useState<JSX.Element | undefined>(initial)\n const [copied, setCopied] = useState(false)\n const initialCodeRef = useRef(code)\n const initialNodesRef = useRef(initial)\n\n useEffect(() => {\n // Skip re-highlighting if server pre-rendered and code hasn't changed\n if (initial && code === initialCodeRef.current && initialNodesRef.current === initial) {\n initialNodesRef.current = undefined\n return\n }\n\n let cancelled = false\n void highlight(code, language, theme).then((el) => {\n if (!cancelled) setNodes(el)\n })\n return () => {\n cancelled = true\n }\n }, [code, language, theme, initial])\n\n const handleCopy = () => {\n void navigator.clipboard.writeText(code).then(\n () => {\n setCopied(true)\n setTimeout(() => setCopied(false), 2000)\n },\n () => {},\n )\n }\n\n return (\n <div className={className} style={{ position: 'relative' }}>\n {showCopyButton && (\n <button\n type=\"button\"\n onClick={handleCopy}\n aria-label=\"Copy code\"\n style={{\n position: 'absolute',\n top: 8,\n right: 8,\n zIndex: 1,\n padding: '4px 8px',\n fontSize: 12,\n lineHeight: 1,\n border: '1px solid rgba(255,255,255,0.2)',\n borderRadius: 4,\n background: 'rgba(0,0,0,0.3)',\n color: '#ccc',\n cursor: 'pointer',\n opacity: 0.7,\n transition: 'opacity 0.15s',\n }}\n onMouseEnter={(e) => {\n e.currentTarget.style.opacity = '1'\n }}\n onMouseLeave={(e) => {\n e.currentTarget.style.opacity = '0.7'\n }}\n >\n {copied ? 'Copied!' : 'Copy'}\n </button>\n )}\n {showLineNumbers && nodes ? (\n <div style={{ display: 'flex' }}>\n <div\n aria-hidden\n style={{\n padding: '1em 0.5em 1em 1em',\n textAlign: 'right',\n userSelect: 'none',\n color: 'rgba(255,255,255,0.3)',\n fontFamily: 'monospace',\n fontSize: 13,\n lineHeight: 1.5,\n }}\n >\n {code.split('\\n').map((_, i) => (\n <div key={i}>{i + 1}</div>\n ))}\n </div>\n <div style={{ flex: 1, overflow: 'auto' }}>{nodes}</div>\n </div>\n ) : (\n (nodes ?? (\n <pre\n style={{\n margin: 0,\n padding: '1em',\n overflow: 'auto',\n fontFamily: 'monospace',\n fontSize: 13,\n lineHeight: 1.5,\n }}\n >\n <code>{code}</code>\n </pre>\n ))\n )}\n </div>\n )\n}\n","import type { JSX } from 'react'\nimport { Fragment } from 'react'\nimport { jsx, jsxs } from 'react/jsx-runtime'\nimport { toJsxRuntime } from 'hast-util-to-jsx-runtime'\nimport { codeToHast, type BundledLanguage, type BundledTheme } from 'shiki'\n\nexport type { BundledLanguage, BundledTheme }\n\n/** Normalize language aliases to shiki-compatible language IDs */\nconst LANGUAGE_ALIASES: Record<string, string> = {\n js: 'javascript',\n ts: 'typescript',\n sh: 'bash',\n shell: 'bash',\n yml: 'yaml',\n py: 'python',\n rb: 'ruby',\n plaintext: 'text',\n}\n\nfunction normalizeLanguage(lang: string): string {\n return LANGUAGE_ALIASES[lang] || lang\n}\n\n/**\n * Highlight code to JSX using shiki.\n * Works in both Server and Client components.\n *\n * @example Server Component\n * ```tsx\n * const highlighted = await highlight('const x = 1', 'typescript')\n * return <div>{highlighted}</div>\n * ```\n */\nexport async function highlight(\n code: string,\n lang: string,\n theme: BundledTheme = 'github-dark',\n): Promise<JSX.Element> {\n const normalized = normalizeLanguage(lang)\n try {\n const hast = await codeToHast(code, {\n lang: normalized as BundledLanguage,\n theme,\n })\n return toJsxRuntime(hast, { Fragment, jsx, jsxs }) as JSX.Element\n } catch {\n // Fallback to plain text if language is not supported\n const hast = await codeToHast(code, { lang: 'text', theme })\n return toJsxRuntime(hast, { Fragment, jsx, jsxs }) as JSX.Element\n }\n}\n"],"mappings":"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","names":[]}
@@ -57,6 +57,8 @@ var __async = (__this, __arguments, generator) => {
57
57
  // src/ui/Flow/server.ts
58
58
  var server_exports = {};
59
59
  __export(server_exports, {
60
+ BUILT_IN_EDGE_TYPES: () => BUILT_IN_EDGE_TYPES,
61
+ BUILT_IN_NODE_TYPES: () => BUILT_IN_NODE_TYPES,
60
62
  getFrameData: () => getFrameData,
61
63
  getFrames: () => getFrames,
62
64
  getNodeBounds: () => getNodeBounds,
@@ -79,40 +81,54 @@ function collectionKeys(collection) {
79
81
  };
80
82
  }
81
83
 
84
+ // src/ui/Flow/query-options.ts
85
+ function flowQueryOptions(client, slug, id) {
86
+ var _a;
87
+ const identifier = (_a = id != null ? id : slug) != null ? _a : "";
88
+ return {
89
+ queryKey: collectionKeys("flows").detail(identifier),
90
+ queryFn: () => __async(null, null, function* () {
91
+ if (id) return client.from("flows").findById(id);
92
+ const result = yield client.from("flows").find({
93
+ where: { slug: { equals: slug } },
94
+ limit: 1
95
+ });
96
+ const doc = result.docs[0];
97
+ if (!doc) throw new Error(`Flow not found: ${slug}`);
98
+ return doc;
99
+ })
100
+ };
101
+ }
102
+ function nodeTypesQueryOptions(client) {
103
+ return {
104
+ queryKey: collectionKeys("flow-node-types").lists(),
105
+ queryFn: () => __async(null, null, function* () {
106
+ const result = yield client.from("flow-node-types").find({ limit: 0 });
107
+ return result.docs;
108
+ })
109
+ };
110
+ }
111
+ function edgeTypesQueryOptions(client) {
112
+ return {
113
+ queryKey: collectionKeys("flow-edge-types").lists(),
114
+ queryFn: () => __async(null, null, function* () {
115
+ const result = yield client.from("flow-edge-types").find({ limit: 0 });
116
+ return result.docs;
117
+ })
118
+ };
119
+ }
120
+
82
121
  // src/ui/Flow/prefetchFlow.ts
83
122
  function prefetchFlow(options) {
84
123
  return __async(this, null, function* () {
85
- var _a;
86
124
  const { client, slug, id } = options;
87
- const identifier = (_a = id != null ? id : slug) != null ? _a : "";
125
+ if (!slug && !id) {
126
+ throw new Error("prefetchFlow requires either slug or id");
127
+ }
88
128
  yield Promise.all([
89
- client.queryClient.prefetchQuery({
90
- queryKey: collectionKeys("flows").detail(identifier),
91
- queryFn: () => __async(null, null, function* () {
92
- if (id) return client.from("flows").findById(id);
93
- const result = yield client.from("flows").find({
94
- where: { slug: { equals: slug } },
95
- limit: 1
96
- });
97
- const doc = result.docs[0];
98
- if (!doc) throw new Error(`Flow not found: ${slug}`);
99
- return doc;
100
- })
101
- }),
102
- client.queryClient.prefetchQuery({
103
- queryKey: collectionKeys("flow-node-types").lists(),
104
- queryFn: () => __async(null, null, function* () {
105
- const result = yield client.from("flow-node-types").find({ limit: 100 });
106
- return result.docs;
107
- })
108
- }),
109
- client.queryClient.prefetchQuery({
110
- queryKey: collectionKeys("flow-edge-types").lists(),
111
- queryFn: () => __async(null, null, function* () {
112
- const result = yield client.from("flow-edge-types").find({ limit: 100 });
113
- return result.docs;
114
- })
115
- })
129
+ client.queryClient.prefetchQuery(flowQueryOptions(client, slug, id)),
130
+ client.queryClient.prefetchQuery(nodeTypesQueryOptions(client)),
131
+ client.queryClient.prefetchQuery(edgeTypesQueryOptions(client))
116
132
  ]);
117
133
  });
118
134
  }
@@ -143,15 +159,28 @@ function getAbsolutePosition(node, nodeMap) {
143
159
  return { x, y };
144
160
  }
145
161
  function collectDescendants(nodes, rootId) {
162
+ const childrenMap = /* @__PURE__ */ new Map();
163
+ for (const n of nodes) {
164
+ if (n.parentId) {
165
+ let siblings = childrenMap.get(n.parentId);
166
+ if (!siblings) {
167
+ siblings = [];
168
+ childrenMap.set(n.parentId, siblings);
169
+ }
170
+ siblings.push(n.id);
171
+ }
172
+ }
146
173
  const result = /* @__PURE__ */ new Set([rootId]);
147
174
  const queue = [rootId];
148
175
  let i = 0;
149
176
  while (i < queue.length) {
150
- const current = queue[i++];
151
- for (const n of nodes) {
152
- if (n.parentId === current && !result.has(n.id)) {
153
- result.add(n.id);
154
- queue.push(n.id);
177
+ const children = childrenMap.get(queue[i++]);
178
+ if (children) {
179
+ for (const childId of children) {
180
+ if (!result.has(childId)) {
181
+ result.add(childId);
182
+ queue.push(childId);
183
+ }
155
184
  }
156
185
  }
157
186
  }
@@ -230,4 +259,42 @@ function isDynamicNode(node) {
230
259
  function isFrameNode(node) {
231
260
  return node.type === "frame";
232
261
  }
262
+
263
+ // src/ui/Flow/built-in-node-types.ts
264
+ var BUILT_IN_NODE_TYPES = [
265
+ {
266
+ slug: "text",
267
+ name: "Text",
268
+ color: "#e5e7eb",
269
+ defaultSize: { width: 200, height: 200 },
270
+ fields: [{ name: "body", label: "Body", fieldType: "textarea" }]
271
+ },
272
+ {
273
+ slug: "image",
274
+ name: "Image",
275
+ color: "#e5e7eb",
276
+ transparentBackground: true,
277
+ defaultSize: { width: 200, height: 200 },
278
+ fields: [
279
+ { name: "image", label: "Image", fieldType: "image" },
280
+ { name: "alt", label: "Alt Text", fieldType: "text" },
281
+ { name: "caption", label: "Caption", fieldType: "text" }
282
+ ]
283
+ }
284
+ ];
285
+
286
+ // src/ui/Flow/built-in-edge-types.ts
287
+ var BUILT_IN_EDGE_TYPES = [
288
+ {
289
+ slug: "default",
290
+ name: "Default",
291
+ color: "",
292
+ strokeWidth: 2,
293
+ animated: false,
294
+ lineStyle: "default",
295
+ markerStart: "none",
296
+ markerEnd: "arrow",
297
+ fields: []
298
+ }
299
+ ];
233
300
  //# sourceMappingURL=server.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/ui/Flow/server.ts","../../../src/core/query/query-keys.ts","../../../src/ui/Flow/prefetchFlow.ts","../../../src/ui/Flow/utils.ts","../../../src/ui/Flow/types.ts"],"sourcesContent":["// Server-safe exports (no 'use client' directive).\n// Use `@01.software/sdk/ui/flow/server` for server components and route loaders.\n\nexport { prefetchFlow } from './prefetchFlow'\nexport type { PrefetchFlowOptions } from './prefetchFlow'\nexport { getNodeBounds, getFrames, getFrameData } from './utils'\nexport type { FrameData } from './utils'\nexport type {\n CanvasData,\n FlowNode,\n FlowEdge,\n FlowViewport,\n FlowNodePosition,\n FlowNodeData,\n DynamicNodeData,\n FrameNodeData,\n FlowBounds,\n NodeTypeDef,\n NodeTypeFieldDef,\n EdgeTypeDef,\n} from './types'\nexport { isDynamicNode, isFrameNode } from './types'\n","import type { PublicCollection, ApiQueryOptions } from '../client/types'\n\nexport function collectionKeys<T extends PublicCollection>(collection: T) {\n return {\n all: [collection] as const,\n lists: () => [collection, 'list'] as const,\n list: (options?: ApiQueryOptions) => [collection, 'list', options] as const,\n details: () => [collection, 'detail'] as const,\n detail: (id: string, options?: ApiQueryOptions) =>\n [collection, 'detail', id, options] as const,\n infinites: () => [collection, 'infinite'] as const,\n infinite: (options?: Omit<ApiQueryOptions, 'page'>) =>\n [collection, 'infinite', options] as const,\n }\n}\n\nexport const customerKeys = {\n all: ['customer'] as const,\n me: () => ['customer', 'me'] as const,\n}\n","import type { SDKClient } from './useFlow'\nimport { collectionKeys } from '../../core/query/query-keys'\n\nexport interface PrefetchFlowOptions {\n /** SDK client instance (Client or ServerClient) */\n client: SDKClient\n /** Flow slug (URL-friendly identifier) */\n slug?: string\n /** Flow document ID (UUID) */\n id?: string\n}\n\n/**\n * Prefetch flow data into the query cache.\n * Call in route loaders or server components to eliminate loading states on mount.\n *\n * ```ts\n * // React Router loader / Server Component\n * await prefetchFlow({ client, slug: 'Home' })\n * ```\n */\nexport async function prefetchFlow(\n options: PrefetchFlowOptions,\n): Promise<void> {\n const { client, slug, id } = options\n const identifier = id ?? slug ?? ''\n\n await Promise.all([\n client.queryClient.prefetchQuery({\n queryKey: collectionKeys('flows').detail(identifier),\n queryFn: async () => {\n if (id) return client.from('flows').findById(id)\n const result = await client.from('flows').find({\n where: { slug: { equals: slug } },\n limit: 1,\n })\n const doc = result.docs[0]\n if (!doc) throw new Error(`Flow not found: ${slug}`)\n return doc\n },\n }),\n client.queryClient.prefetchQuery({\n queryKey: collectionKeys('flow-node-types').lists(),\n queryFn: async () => {\n const result = await client\n .from('flow-node-types')\n .find({ limit: 100 })\n return result.docs\n },\n }),\n client.queryClient.prefetchQuery({\n queryKey: collectionKeys('flow-edge-types').lists(),\n queryFn: async () => {\n const result = await client\n .from('flow-edge-types')\n .find({ limit: 100 })\n return result.docs\n },\n }),\n ])\n}\n","import type { FlowNode, FlowEdge, FlowBounds, CanvasData } from './types'\n\n// ── Shared helpers ──\n\nfunction getNodeSize(node: FlowNode): { width: number; height: number } {\n return {\n width:\n (node.style?.width as number) ??\n node.measured?.width ??\n node.width ??\n 200,\n height:\n (node.style?.height as number) ??\n node.measured?.height ??\n node.height ??\n 200,\n }\n}\n\nfunction getAbsolutePosition(\n node: FlowNode,\n nodeMap: Map<string, FlowNode>,\n): { x: number; y: number } {\n let x = node.position.x\n let y = node.position.y\n let current = node\n const visited = new Set<string>([node.id])\n while (current.parentId) {\n const parentId = current.parentId\n if (visited.has(parentId)) break\n const parent = nodeMap.get(parentId)\n if (!parent) break\n visited.add(parent.id)\n x += parent.position.x\n y += parent.position.y\n current = parent\n }\n return { x, y }\n}\n\n/** Collect a node and all its descendants (BFS with index pointer to avoid O(Q²) shift). */\nfunction collectDescendants(\n nodes: FlowNode[],\n rootId: string,\n): Set<string> {\n const result = new Set<string>([rootId])\n const queue = [rootId]\n let i = 0\n while (i < queue.length) {\n const current = queue[i++]\n for (const n of nodes) {\n if (n.parentId === current && !result.has(n.id)) {\n result.add(n.id)\n queue.push(n.id)\n }\n }\n }\n return result\n}\n\n// ── Public utilities ──\n\n/**\n * Calculate bounding box for given node IDs.\n * Pure function — usable in SSR, server components, or outside React.\n */\nexport function getNodeBounds(\n nodes: FlowNode[],\n nodeIds: string[],\n): FlowBounds | undefined {\n const idSet = new Set(nodeIds)\n const targetNodes = nodes.filter((n) => idSet.has(n.id))\n if (targetNodes.length === 0) return undefined\n\n const nodeMap = new Map(nodes.map((n) => [n.id, n]))\n\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n\n for (const node of targetNodes) {\n const abs = getAbsolutePosition(node, nodeMap)\n const { width: w, height: h } = getNodeSize(node)\n minX = Math.min(minX, abs.x)\n minY = Math.min(minY, abs.y)\n maxX = Math.max(maxX, abs.x + w)\n maxY = Math.max(maxY, abs.y + h)\n }\n\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY }\n}\n\n/**\n * Get all frame nodes with their bounds.\n * Sorted by position (top-left to bottom-right).\n */\nexport function getFrames(\n nodes: FlowNode[],\n): Array<{ id: string; label: string; bounds: FlowBounds }> {\n const frames = nodes.filter((n) => n.type === 'frame')\n if (frames.length === 0) return []\n\n const nodeMap = new Map(nodes.map((n) => [n.id, n]))\n\n return frames\n .map((f) => {\n const data = f.data as { label?: string }\n const abs = getAbsolutePosition(f, nodeMap)\n const { width: w, height: h } = getNodeSize(f)\n return {\n id: f.id,\n label: data.label ?? '',\n bounds: { x: abs.x, y: abs.y, width: w, height: h },\n }\n })\n .sort((a, b) => a.bounds.y - b.bounds.y || a.bounds.x - b.bounds.x)\n}\n\n/** Result of getFrameData — contains filtered canvas + dual bounds. */\nexport interface FrameData {\n /** Canvas data containing only the frame's descendants (nodes have draggable: false). */\n data: CanvasData\n /** Bounding box of child content nodes — use for initial viewport fit (centering). */\n fitBounds: FlowBounds\n /** Bounding box of the frame itself — use for panning/zoom restriction (clamp). */\n clampBounds: FlowBounds\n /** @deprecated Use fitBounds instead. Alias for clampBounds for backward compatibility. */\n bounds: FlowBounds\n}\n\n/**\n * Extract a frame's descendants and related edges from canvas data.\n * Recursively collects all nested children (supports nested frames).\n * Returns undefined if frameId is not found or is not a frame node.\n *\n * Child nodes are marked `draggable: false` to prevent interfering with canvas panning.\n * The frame node itself is included (use `frameRenderer={() => null}` to hide it).\n *\n * Returns dual bounds:\n * - `fitBounds`: child content bounding box (for centering the viewport)\n * - `clampBounds`: frame area bounding box (for panning restriction)\n */\nexport function getFrameData(\n data: CanvasData,\n frameId: string,\n): FrameData | undefined {\n const frame = data.nodes.find((n) => n.id === frameId)\n if (!frame || frame.type !== 'frame') return undefined\n\n // Recursively collect frame + all descendants\n const descendantIds = collectDescendants(data.nodes, frameId)\n const childNodes = data.nodes\n .filter((n) => descendantIds.has(n.id))\n .map((n) => ({ ...n, draggable: false }))\n\n // Keep only edges where both source and target are within the frame\n const childEdges = data.edges.filter(\n (e: FlowEdge) => descendantIds.has(e.source) && descendantIds.has(e.target),\n )\n\n // clampBounds: frame's own bounding box (for panning restriction)\n const frameBounds = getNodeBounds(data.nodes, [frameId])\n const { width: w, height: h } = getNodeSize(frame)\n const clampBounds: FlowBounds = frameBounds ?? {\n x: frame.position.x,\n y: frame.position.y,\n width: w,\n height: h,\n }\n\n // fitBounds: child content bounding box (for centering)\n const contentNodeIds = childNodes\n .filter((n) => n.id !== frameId)\n .map((n) => n.id)\n const contentBounds = contentNodeIds.length > 0\n ? getNodeBounds(data.nodes, contentNodeIds)\n : undefined\n const fitBounds = contentBounds ?? clampBounds\n\n return {\n data: {\n nodes: childNodes,\n edges: childEdges,\n viewport: data.viewport,\n },\n fitBounds,\n clampBounds,\n bounds: clampBounds,\n }\n}\n","import type React from 'react'\n\n// ── Dynamic node data ──\n\nexport interface DynamicNodeData {\n nodeTypeSlug: string\n label: string\n fields: Record<string, unknown>\n}\n\nexport type FlowNodeData = (DynamicNodeData | FrameNodeData) &\n Record<string, unknown>\n\n// ── Canvas types (mirrors @xyflow/react but standalone) ──\n\nexport interface FlowNodePosition {\n x: number\n y: number\n}\n\nexport interface FlowNode {\n id: string\n type?: string\n position: FlowNodePosition\n data: FlowNodeData\n parentId?: string\n style?: React.CSSProperties\n width?: number\n height?: number\n measured?: { width?: number; height?: number }\n draggable?: boolean\n selectable?: boolean\n [key: string]: unknown\n}\n\nexport interface FlowEdge {\n id: string\n source: string\n target: string\n sourceHandle?: string | null\n targetHandle?: string | null\n type?: string\n style?: React.CSSProperties\n animated?: boolean\n markerStart?: unknown\n markerEnd?: unknown\n edgeTypeSlug?: string\n fields?: Record<string, unknown>\n [key: string]: unknown\n}\n\nexport interface FlowViewport {\n x: number\n y: number\n zoom: number\n}\n\nexport interface CanvasData {\n nodes: FlowNode[]\n edges: FlowEdge[]\n viewport: FlowViewport\n}\n\n// ── Node type definitions (mirrors console's NodeTypeDef) ──\n\nexport interface NodeTypeFieldDef {\n name: string\n label: string\n fieldType:\n | 'text'\n | 'textarea'\n | 'number'\n | 'url'\n | 'color'\n | 'image'\n | 'select'\n | 'toggle'\n options?: { label: string; value: string }[]\n defaultValue?: string\n required?: boolean\n}\n\nexport interface NodeTypeDef {\n slug: string\n name: string\n color: string\n defaultSize: { width: number; height: number }\n fields: NodeTypeFieldDef[]\n transparentBackground?: boolean\n template?: string | null\n customCSS?: string | null\n}\n\n// ── Edge type definitions (mirrors console's EdgeTypeDef) ──\n\nexport interface EdgeTypeDef {\n slug: string\n name: string\n color: string\n strokeWidth: number\n animated: boolean\n lineStyle: string\n markerStart: string\n markerEnd: string\n fields: NodeTypeFieldDef[]\n}\n\n// ── Type guards ──\n\nexport function isDynamicNode(\n node: FlowNode,\n): node is FlowNode & { data: DynamicNodeData } {\n return node.type === 'dynamic'\n}\n\nexport function isFrameNode(\n node: FlowNode,\n): node is FlowNode & { data: FrameNodeData } {\n return node.type === 'frame'\n}\n\n// ── Component slot props ──\n\nexport interface DynamicNodeSlotProps {\n id: string\n nodeTypeSlug: string\n label: string\n fields: Record<string, unknown>\n nodeTypeDef?: NodeTypeDef\n /** Whether this node is currently selected */\n selected?: boolean\n /** Measured node width (undefined before first measurement) */\n width?: number\n /** Measured node height (undefined before first measurement) */\n height?: number\n /** The default rendering (template or field-based). Allows custom renderers to wrap/extend instead of replacing entirely. */\n defaultRender?: React.ReactElement\n}\n\n// ── Frame node data ──\n\nexport interface FrameNodeData {\n label: string\n color?: string\n padding?: number\n borderStyle?: 'dashed' | 'solid' | 'none'\n opacity?: number\n}\n\n// S1: Frame renderer slot\nexport interface FrameNodeSlotProps {\n id: string\n label: string\n color?: string\n padding?: number\n borderStyle?: 'dashed' | 'solid' | 'none'\n opacity?: number\n width?: number\n height?: number\n children?: React.ReactNode\n}\n\n// S2: Edge renderer slot\nexport interface EdgeSlotProps {\n id: string\n edgeTypeSlug?: string\n source: string\n target: string\n label?: string\n fields?: Record<string, unknown>\n edgeTypeDef?: EdgeTypeDef\n style?: React.CSSProperties\n}\n\n// S3: Node wrapper slot\nexport interface NodeWrapperSlotProps {\n id: string\n nodeTypeSlug: string\n label: string\n selected?: boolean\n nodeTypeDef?: NodeTypeDef\n children: React.ReactNode\n}\n\n// S8: Viewport focus\nexport interface FlowBounds {\n x: number\n y: number\n width: number\n height: number\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/ui/Flow/server.ts","../../../src/core/query/query-keys.ts","../../../src/ui/Flow/query-options.ts","../../../src/ui/Flow/prefetchFlow.ts","../../../src/ui/Flow/utils.ts","../../../src/ui/Flow/types.ts","../../../src/ui/Flow/built-in-node-types.ts","../../../src/ui/Flow/built-in-edge-types.ts"],"sourcesContent":["// Server-safe exports (no 'use client' directive).\n// Use `@01.software/sdk/ui/flow/server` for server components and route loaders.\n\nexport { prefetchFlow } from './prefetchFlow'\nexport type { PrefetchFlowOptions } from './prefetchFlow'\nexport { getNodeBounds, getFrames, getFrameData } from './utils'\nexport type { FrameData } from './utils'\nexport type {\n CanvasData,\n FlowNode,\n FlowEdge,\n FlowViewport,\n FlowNodePosition,\n FlowNodeData,\n DynamicNodeData,\n FrameNodeData,\n FlowBounds,\n NodeTypeDef,\n NodeTypeFieldDef,\n EdgeTypeDef,\n} from './types'\nexport { isDynamicNode, isFrameNode } from './types'\nexport { BUILT_IN_NODE_TYPES } from './built-in-node-types'\nexport { BUILT_IN_EDGE_TYPES } from './built-in-edge-types'\n","import type { PublicCollection, ApiQueryOptions } from '../client/types'\n\nexport function collectionKeys<T extends PublicCollection>(collection: T) {\n return {\n all: [collection] as const,\n lists: () => [collection, 'list'] as const,\n list: (options?: ApiQueryOptions) => [collection, 'list', options] as const,\n details: () => [collection, 'detail'] as const,\n detail: (id: string, options?: ApiQueryOptions) =>\n [collection, 'detail', id, options] as const,\n infinites: () => [collection, 'infinite'] as const,\n infinite: (options?: Omit<ApiQueryOptions, 'page'>) =>\n [collection, 'infinite', options] as const,\n }\n}\n\nexport const customerKeys = {\n all: ['customer'] as const,\n me: () => ['customer', 'me'] as const,\n}\n","import { collectionKeys } from '../../core/query/query-keys'\nimport type { SDKClient } from './useFlow'\n\nexport function flowQueryOptions(\n client: SDKClient,\n slug?: string,\n id?: string,\n) {\n const identifier = id ?? slug ?? ''\n return {\n queryKey: collectionKeys('flows').detail(identifier),\n queryFn: async () => {\n if (id) return client.from('flows').findById(id)\n const result = await client.from('flows').find({\n where: { slug: { equals: slug } },\n limit: 1,\n })\n const doc = result.docs[0]\n if (!doc) throw new Error(`Flow not found: ${slug}`)\n return doc\n },\n }\n}\n\nexport function nodeTypesQueryOptions(client: SDKClient) {\n return {\n queryKey: collectionKeys('flow-node-types').lists(),\n queryFn: async () => {\n // limit: 0 = fetch all documents (Payload CMS convention, disables pagination)\n const result = await client.from('flow-node-types').find({ limit: 0 })\n return result.docs\n },\n }\n}\n\nexport function edgeTypesQueryOptions(client: SDKClient) {\n return {\n queryKey: collectionKeys('flow-edge-types').lists(),\n queryFn: async () => {\n const result = await client.from('flow-edge-types').find({ limit: 0 })\n return result.docs\n },\n }\n}\n","import type { SDKClient } from './useFlow'\nimport {\n flowQueryOptions,\n nodeTypesQueryOptions,\n edgeTypesQueryOptions,\n} from './query-options'\n\nexport interface PrefetchFlowOptions {\n /** SDK client instance (Client or ServerClient) */\n client: SDKClient\n /** Flow slug (URL-friendly identifier) */\n slug?: string\n /** Flow document ID (UUID) */\n id?: string\n}\n\n/**\n * Prefetch flow data into the query cache.\n * Call in route loaders or server components to eliminate loading states on mount.\n *\n * ```ts\n * // React Router loader / Server Component\n * await prefetchFlow({ client, slug: 'Home' })\n * ```\n */\nexport async function prefetchFlow(\n options: PrefetchFlowOptions,\n): Promise<void> {\n const { client, slug, id } = options\n\n if (!slug && !id) {\n throw new Error('prefetchFlow requires either slug or id')\n }\n\n await Promise.all([\n client.queryClient.prefetchQuery(flowQueryOptions(client, slug, id)),\n client.queryClient.prefetchQuery(nodeTypesQueryOptions(client)),\n client.queryClient.prefetchQuery(edgeTypesQueryOptions(client)),\n ])\n}\n","import type { FlowNode, FlowEdge, FlowBounds, CanvasData } from './types'\n\n// ── Shared helpers ──\n\nfunction getNodeSize(node: FlowNode): { width: number; height: number } {\n return {\n width:\n (node.style?.width as number) ??\n node.measured?.width ??\n node.width ??\n 200,\n height:\n (node.style?.height as number) ??\n node.measured?.height ??\n node.height ??\n 200,\n }\n}\n\nfunction getAbsolutePosition(\n node: FlowNode,\n nodeMap: Map<string, FlowNode>,\n): { x: number; y: number } {\n let x = node.position.x\n let y = node.position.y\n let current = node\n const visited = new Set<string>([node.id])\n while (current.parentId) {\n const parentId = current.parentId\n if (visited.has(parentId)) break\n const parent = nodeMap.get(parentId)\n if (!parent) break\n visited.add(parent.id)\n x += parent.position.x\n y += parent.position.y\n current = parent\n }\n return { x, y }\n}\n\n/** Collect a node and all its descendants using a pre-built parent→children map (O(N)). */\nfunction collectDescendants(\n nodes: FlowNode[],\n rootId: string,\n): Set<string> {\n // Build parent → children lookup in O(N)\n const childrenMap = new Map<string, string[]>()\n for (const n of nodes) {\n if (n.parentId) {\n let siblings = childrenMap.get(n.parentId)\n if (!siblings) {\n siblings = []\n childrenMap.set(n.parentId, siblings)\n }\n siblings.push(n.id)\n }\n }\n\n // BFS over children map in O(descendants)\n const result = new Set<string>([rootId])\n const queue = [rootId]\n let i = 0\n while (i < queue.length) {\n const children = childrenMap.get(queue[i++]!)\n if (children) {\n for (const childId of children) {\n if (!result.has(childId)) {\n result.add(childId)\n queue.push(childId)\n }\n }\n }\n }\n return result\n}\n\n// ── Public utilities ──\n\n/**\n * Calculate bounding box for given node IDs.\n * Pure function — usable in SSR, server components, or outside React.\n */\nexport function getNodeBounds(\n nodes: FlowNode[],\n nodeIds: string[],\n): FlowBounds | undefined {\n const idSet = new Set(nodeIds)\n const targetNodes = nodes.filter((n) => idSet.has(n.id))\n if (targetNodes.length === 0) return undefined\n\n const nodeMap = new Map(nodes.map((n) => [n.id, n]))\n\n let minX = Infinity\n let minY = Infinity\n let maxX = -Infinity\n let maxY = -Infinity\n\n for (const node of targetNodes) {\n const abs = getAbsolutePosition(node, nodeMap)\n const { width: w, height: h } = getNodeSize(node)\n minX = Math.min(minX, abs.x)\n minY = Math.min(minY, abs.y)\n maxX = Math.max(maxX, abs.x + w)\n maxY = Math.max(maxY, abs.y + h)\n }\n\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY }\n}\n\n/**\n * Get all frame nodes with their bounds.\n * Sorted by position (top-left to bottom-right).\n */\nexport function getFrames(\n nodes: FlowNode[],\n): Array<{ id: string; label: string; bounds: FlowBounds }> {\n const frames = nodes.filter((n) => n.type === 'frame')\n if (frames.length === 0) return []\n\n const nodeMap = new Map(nodes.map((n) => [n.id, n]))\n\n return frames\n .map((f) => {\n const data = f.data as { label?: string }\n const abs = getAbsolutePosition(f, nodeMap)\n const { width: w, height: h } = getNodeSize(f)\n return {\n id: f.id,\n label: data.label ?? '',\n bounds: { x: abs.x, y: abs.y, width: w, height: h },\n }\n })\n .sort((a, b) => a.bounds.y - b.bounds.y || a.bounds.x - b.bounds.x)\n}\n\n/** Result of getFrameData — contains filtered canvas + dual bounds. */\nexport interface FrameData {\n /** Canvas data containing only the frame's descendants (nodes have draggable: false). */\n data: CanvasData\n /** Bounding box of child content nodes — use for initial viewport fit (centering). */\n fitBounds: FlowBounds\n /** Bounding box of the frame itself — use for panning/zoom restriction (clamp). */\n clampBounds: FlowBounds\n /** @deprecated Use fitBounds instead. Alias for clampBounds for backward compatibility. */\n bounds: FlowBounds\n}\n\n/**\n * Extract a frame's descendants and related edges from canvas data.\n * Recursively collects all nested children (supports nested frames).\n * Returns undefined if frameId is not found or is not a frame node.\n *\n * Child nodes are marked `draggable: false` to prevent interfering with canvas panning.\n * The frame node itself is included (use `frameRenderer={() => null}` to hide it).\n *\n * Returns dual bounds:\n * - `fitBounds`: child content bounding box (for centering the viewport)\n * - `clampBounds`: frame area bounding box (for panning restriction)\n */\nexport function getFrameData(\n data: CanvasData,\n frameId: string,\n): FrameData | undefined {\n const frame = data.nodes.find((n) => n.id === frameId)\n if (!frame || frame.type !== 'frame') return undefined\n\n // Recursively collect frame + all descendants\n const descendantIds = collectDescendants(data.nodes, frameId)\n const childNodes = data.nodes\n .filter((n) => descendantIds.has(n.id))\n .map((n) => ({ ...n, draggable: false }))\n\n // Keep only edges where both source and target are within the frame\n const childEdges = data.edges.filter(\n (e: FlowEdge) => descendantIds.has(e.source) && descendantIds.has(e.target),\n )\n\n // clampBounds: frame's own bounding box (for panning restriction)\n const frameBounds = getNodeBounds(data.nodes, [frameId])\n const { width: w, height: h } = getNodeSize(frame)\n const clampBounds: FlowBounds = frameBounds ?? {\n x: frame.position.x,\n y: frame.position.y,\n width: w,\n height: h,\n }\n\n // fitBounds: child content bounding box (for centering)\n const contentNodeIds = childNodes\n .filter((n) => n.id !== frameId)\n .map((n) => n.id)\n const contentBounds = contentNodeIds.length > 0\n ? getNodeBounds(data.nodes, contentNodeIds)\n : undefined\n const fitBounds = contentBounds ?? clampBounds\n\n return {\n data: {\n nodes: childNodes,\n edges: childEdges,\n viewport: data.viewport,\n },\n fitBounds,\n clampBounds,\n bounds: clampBounds,\n }\n}\n","import type React from 'react'\n\n// ── Dynamic node data ──\n\nexport interface DynamicNodeData {\n nodeTypeSlug: string\n label: string\n fields: Record<string, unknown>\n}\n\nexport type FlowNodeData = (DynamicNodeData | FrameNodeData) &\n Record<string, unknown>\n\n// ── Canvas types (mirrors @xyflow/react but standalone) ──\n\nexport interface FlowNodePosition {\n x: number\n y: number\n}\n\nexport interface FlowNode {\n id: string\n type?: string\n position: FlowNodePosition\n data: FlowNodeData\n parentId?: string\n style?: React.CSSProperties\n width?: number\n height?: number\n measured?: { width?: number; height?: number }\n draggable?: boolean\n selectable?: boolean\n [key: string]: unknown\n}\n\nexport interface FlowEdge {\n id: string\n source: string\n target: string\n sourceHandle?: string | null\n targetHandle?: string | null\n type?: string\n style?: React.CSSProperties\n animated?: boolean\n markerStart?: unknown\n markerEnd?: unknown\n edgeTypeSlug?: string\n fields?: Record<string, unknown>\n [key: string]: unknown\n}\n\nexport interface FlowViewport {\n x: number\n y: number\n zoom: number\n}\n\nexport interface CanvasData {\n nodes: FlowNode[]\n edges: FlowEdge[]\n viewport: FlowViewport\n}\n\n// ── Node type definitions (mirrors console's NodeTypeDef) ──\n\nexport interface NodeTypeFieldDef {\n name: string\n label: string\n fieldType:\n | 'text'\n | 'textarea'\n | 'number'\n | 'url'\n | 'color'\n | 'image'\n | 'select'\n | 'toggle'\n options?: { label: string; value: string }[]\n defaultValue?: string\n required?: boolean\n}\n\nexport interface NodeTypeDef {\n slug: string\n name: string\n color: string\n defaultSize: { width: number; height: number }\n fields: NodeTypeFieldDef[]\n transparentBackground?: boolean\n template?: string | null\n customCSS?: string | null\n}\n\n// ── Edge type definitions (mirrors console's EdgeTypeDef) ──\n\nexport interface EdgeTypeDef {\n slug: string\n name: string\n color: string\n strokeWidth: number\n animated: boolean\n lineStyle: string\n markerStart: string\n markerEnd: string\n fields: NodeTypeFieldDef[]\n}\n\n// ── Type guards ──\n\nexport function isDynamicNode(\n node: FlowNode,\n): node is FlowNode & { data: DynamicNodeData } {\n return node.type === 'dynamic'\n}\n\nexport function isFrameNode(\n node: FlowNode,\n): node is FlowNode & { data: FrameNodeData } {\n return node.type === 'frame'\n}\n\n// ── Component slot props ──\n\nexport interface DynamicNodeSlotProps {\n id: string\n nodeTypeSlug: string\n label: string\n fields: Record<string, unknown>\n nodeTypeDef?: NodeTypeDef\n /** Whether this node is currently selected */\n selected?: boolean\n /** Measured node width (undefined before first measurement) */\n width?: number\n /** Measured node height (undefined before first measurement) */\n height?: number\n /** The default rendering (template or field-based). Allows custom renderers to wrap/extend instead of replacing entirely. */\n defaultRender?: React.ReactElement\n}\n\n// ── Frame node data ──\n\nexport interface FrameNodeData {\n label: string\n color?: string\n padding?: number\n borderStyle?: 'dashed' | 'solid' | 'none'\n opacity?: number\n}\n\n// S1: Frame renderer slot\nexport interface FrameNodeSlotProps {\n id: string\n label: string\n color?: string\n padding?: number\n borderStyle?: 'dashed' | 'solid' | 'none'\n opacity?: number\n width?: number\n height?: number\n children?: React.ReactNode\n}\n\n// S2: Edge renderer slot\nexport interface EdgeSlotProps {\n id: string\n edgeTypeSlug?: string\n source: string\n target: string\n label?: string\n fields?: Record<string, unknown>\n edgeTypeDef?: EdgeTypeDef\n style?: React.CSSProperties\n}\n\n// S3: Node wrapper slot\nexport interface NodeWrapperSlotProps {\n id: string\n nodeTypeSlug: string\n label: string\n selected?: boolean\n nodeTypeDef?: NodeTypeDef\n children: React.ReactNode\n}\n\n// S8: Viewport focus\nexport interface FlowBounds {\n x: number\n y: number\n width: number\n height: number\n}\n","import type { NodeTypeDef } from './types'\n\nexport const BUILT_IN_NODE_TYPES: NodeTypeDef[] = [\n {\n slug: 'text',\n name: 'Text',\n color: '#e5e7eb',\n defaultSize: { width: 200, height: 200 },\n fields: [{ name: 'body', label: 'Body', fieldType: 'textarea' }],\n },\n {\n slug: 'image',\n name: 'Image',\n color: '#e5e7eb',\n transparentBackground: true,\n defaultSize: { width: 200, height: 200 },\n fields: [\n { name: 'image', label: 'Image', fieldType: 'image' },\n { name: 'alt', label: 'Alt Text', fieldType: 'text' },\n { name: 'caption', label: 'Caption', fieldType: 'text' },\n ],\n },\n]\n","import type { EdgeTypeDef } from './types'\n\nexport const BUILT_IN_EDGE_TYPES: EdgeTypeDef[] = [\n {\n slug: 'default',\n name: 'Default',\n color: '',\n strokeWidth: 2,\n animated: false,\n lineStyle: 'default',\n markerStart: 'none',\n markerEnd: 'arrow',\n fields: [],\n },\n]\n"],"mappings":"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","names":[]}
@@ -1,3 +1,3 @@
1
- export { C as CanvasData, i as DynamicNodeData, E as EdgeTypeDef, f as FlowBounds, a as FlowEdge, F as FlowNode, h as FlowNodeData, g as FlowNodePosition, e as FlowViewport, s as FrameData, j as FrameNodeData, N as NodeTypeDef, k as NodeTypeFieldDef, P as PrefetchFlowOptions, r as getFrameData, q as getFrames, o as getNodeBounds, l as isDynamicNode, m as isFrameNode, p as prefetchFlow } from '../../server-B80o7igg.cjs';
1
+ export { o as BUILT_IN_EDGE_TYPES, B as BUILT_IN_NODE_TYPES, C as CanvasData, k as DynamicNodeData, E as EdgeTypeDef, g as FlowBounds, b as FlowEdge, F as FlowNode, j as FlowNodeData, i as FlowNodePosition, f as FlowViewport, h as FrameData, l as FrameNodeData, N as NodeTypeDef, a as NodeTypeFieldDef, P as PrefetchFlowOptions, t as getFrameData, s as getFrames, r as getNodeBounds, m as isDynamicNode, n as isFrameNode, q as prefetchFlow } from '../../server-StNHlSjW.cjs';
2
2
  import '@tanstack/react-query';
3
3
  import 'react';