@01.software/sdk 0.3.0 → 0.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +5 -2
- package/dist/auth.d.cts +1 -1
- package/dist/auth.d.ts +1 -1
- package/dist/const-BsO3aVX_.d.cts +19 -0
- package/dist/const-DZyvV9wU.d.ts +19 -0
- package/dist/index.cjs +285 -86
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +114 -196
- package/dist/index.d.ts +114 -196
- package/dist/index.js +285 -86
- package/dist/index.js.map +1 -1
- package/dist/{payload-types-ggU6BNuH.d.cts → payload-types-BsjHfeAF.d.cts} +68 -7
- package/dist/{payload-types-ggU6BNuH.d.ts → payload-types-BsjHfeAF.d.ts} +68 -7
- package/dist/realtime-DupPIYx-.d.cts +33 -0
- package/dist/realtime-DupPIYx-.d.ts +33 -0
- package/dist/realtime.cjs +263 -0
- package/dist/realtime.cjs.map +1 -0
- package/dist/realtime.d.cts +38 -0
- package/dist/realtime.d.ts +38 -0
- package/dist/realtime.js +241 -0
- package/dist/realtime.js.map +1 -0
- package/dist/ui/code-block.cjs +3 -1
- package/dist/ui/code-block.cjs.map +1 -1
- package/dist/ui/code-block.js +4 -2
- package/dist/ui/code-block.js.map +1 -1
- package/dist/ui/flow.cjs +282 -39
- package/dist/ui/flow.cjs.map +1 -1
- package/dist/ui/flow.d.cts +104 -3
- package/dist/ui/flow.d.ts +104 -3
- package/dist/ui/flow.js +270 -24
- package/dist/ui/flow.js.map +1 -1
- package/dist/ui/form.d.cts +1 -1
- package/dist/ui/form.d.ts +1 -1
- package/dist/ui/rich-text.cjs +8 -1
- package/dist/ui/rich-text.cjs.map +1 -1
- package/dist/ui/rich-text.d.cts +20 -1
- package/dist/ui/rich-text.d.ts +20 -1
- package/dist/ui/rich-text.js +8 -1
- package/dist/ui/rich-text.js.map +1 -1
- package/dist/ui/video.cjs +219 -0
- package/dist/ui/video.cjs.map +1 -0
- package/dist/ui/video.d.cts +96 -0
- package/dist/ui/video.d.ts +96 -0
- package/dist/ui/video.js +191 -0
- package/dist/ui/video.js.map +1 -0
- package/dist/video-DbLL8yuc.d.cts +85 -0
- package/dist/video-DbLL8yuc.d.ts +85 -0
- package/dist/webhook-BBWl8O2f.d.ts +20 -0
- package/dist/webhook-CkL56e65.d.cts +20 -0
- package/dist/webhook.cjs +8 -8
- package/dist/webhook.cjs.map +1 -1
- package/dist/webhook.d.cts +3 -2
- package/dist/webhook.d.ts +3 -2
- package/dist/webhook.js +8 -8
- package/dist/webhook.js.map +1 -1
- package/package.json +30 -4
- package/dist/webhook-B54a-HGd.d.ts +0 -35
- package/dist/webhook-DInps2xX.d.cts +0 -35
package/dist/ui/code-block.cjs
CHANGED
|
@@ -103,7 +103,9 @@ function CodeBlock({
|
|
|
103
103
|
}) {
|
|
104
104
|
const [nodes, setNodes] = (0, import_react2.useState)(initial);
|
|
105
105
|
const [copied, setCopied] = (0, import_react2.useState)(false);
|
|
106
|
+
const initialCodeRef = (0, import_react2.useRef)(code);
|
|
106
107
|
(0, import_react2.useEffect)(() => {
|
|
108
|
+
if (initial && code === initialCodeRef.current && nodes === initial) return;
|
|
107
109
|
let cancelled = false;
|
|
108
110
|
void highlight(code, language, theme).then((el) => {
|
|
109
111
|
if (!cancelled) setNodes(el);
|
|
@@ -111,7 +113,7 @@ function CodeBlock({
|
|
|
111
113
|
return () => {
|
|
112
114
|
cancelled = true;
|
|
113
115
|
};
|
|
114
|
-
}, [code, language, theme]);
|
|
116
|
+
}, [code, language, theme, initial]);
|
|
115
117
|
const handleCopy = () => {
|
|
116
118
|
void navigator.clipboard.writeText(code).then(
|
|
117
119
|
() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ui/CodeBlock/index.tsx","../../src/ui/CodeBlock/highlight.ts"],"sourcesContent":["'use client'\n\nimport React, { useEffect, 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\n useEffect(() => {\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])\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,
|
|
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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;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;AAElC,+BAAU,MAAM;AAEd,QAAI,WAAW,SAAS,eAAe,WAAW,UAAU,QAAS;AAErE,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"]}
|
package/dist/ui/code-block.js
CHANGED
|
@@ -21,7 +21,7 @@ var __async = (__this, __arguments, generator) => {
|
|
|
21
21
|
};
|
|
22
22
|
|
|
23
23
|
// src/ui/CodeBlock/index.tsx
|
|
24
|
-
import React, { useEffect, useState } from "react";
|
|
24
|
+
import React, { useEffect, useRef, useState } from "react";
|
|
25
25
|
|
|
26
26
|
// src/ui/CodeBlock/highlight.ts
|
|
27
27
|
import { Fragment } from "react";
|
|
@@ -69,7 +69,9 @@ function CodeBlock({
|
|
|
69
69
|
}) {
|
|
70
70
|
const [nodes, setNodes] = useState(initial);
|
|
71
71
|
const [copied, setCopied] = useState(false);
|
|
72
|
+
const initialCodeRef = useRef(code);
|
|
72
73
|
useEffect(() => {
|
|
74
|
+
if (initial && code === initialCodeRef.current && nodes === initial) return;
|
|
73
75
|
let cancelled = false;
|
|
74
76
|
void highlight(code, language, theme).then((el) => {
|
|
75
77
|
if (!cancelled) setNodes(el);
|
|
@@ -77,7 +79,7 @@ function CodeBlock({
|
|
|
77
79
|
return () => {
|
|
78
80
|
cancelled = true;
|
|
79
81
|
};
|
|
80
|
-
}, [code, language, theme]);
|
|
82
|
+
}, [code, language, theme, initial]);
|
|
81
83
|
const handleCopy = () => {
|
|
82
84
|
void navigator.clipboard.writeText(code).then(
|
|
83
85
|
() => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/ui/CodeBlock/index.tsx","../../src/ui/CodeBlock/highlight.ts"],"sourcesContent":["'use client'\n\nimport React, { useEffect, 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\n useEffect(() => {\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])\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":";;;;;;;;;;;;;;;;;;;;;;;AAEA,OAAO,SAAS,WAAW,gBAA0B;;;
|
|
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":[]}
|
package/dist/ui/flow.cjs
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
"use client";
|
|
3
3
|
var __create = Object.create;
|
|
4
4
|
var __defProp = Object.defineProperty;
|
|
5
|
+
var __defProps = Object.defineProperties;
|
|
5
6
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
7
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
6
8
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
9
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
8
10
|
var __getProtoOf = Object.getPrototypeOf;
|
|
@@ -20,6 +22,7 @@ var __spreadValues = (a, b) => {
|
|
|
20
22
|
}
|
|
21
23
|
return a;
|
|
22
24
|
};
|
|
25
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
23
26
|
var __export = (target, all) => {
|
|
24
27
|
for (var name in all)
|
|
25
28
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -68,13 +71,16 @@ __export(Flow_exports, {
|
|
|
68
71
|
BUILT_IN_EDGE_TYPES: () => BUILT_IN_EDGE_TYPES,
|
|
69
72
|
BUILT_IN_NODE_TYPES: () => BUILT_IN_NODE_TYPES,
|
|
70
73
|
FlowRenderer: () => FlowRenderer,
|
|
74
|
+
getFrames: () => getFrames,
|
|
75
|
+
getNodeBounds: () => getNodeBounds,
|
|
71
76
|
isDynamicNode: () => isDynamicNode,
|
|
72
77
|
isFrameNode: () => isFrameNode,
|
|
73
|
-
useFlow: () => useFlow
|
|
78
|
+
useFlow: () => useFlow,
|
|
79
|
+
useFlowData: () => useFlowData
|
|
74
80
|
});
|
|
75
81
|
module.exports = __toCommonJS(Flow_exports);
|
|
76
|
-
var
|
|
77
|
-
var
|
|
82
|
+
var import_react3 = __toESM(require("react"), 1);
|
|
83
|
+
var import_react4 = require("@xyflow/react");
|
|
78
84
|
|
|
79
85
|
// src/ui/Flow/types.ts
|
|
80
86
|
function isDynamicNode(node) {
|
|
@@ -125,6 +131,21 @@ var BUILT_IN_EDGE_TYPES = [
|
|
|
125
131
|
// src/ui/Flow/useFlow.ts
|
|
126
132
|
var import_react_query = require("@tanstack/react-query");
|
|
127
133
|
var import_react = require("react");
|
|
134
|
+
|
|
135
|
+
// src/core/query/query-keys.ts
|
|
136
|
+
function collectionKeys(collection) {
|
|
137
|
+
return {
|
|
138
|
+
all: [collection],
|
|
139
|
+
lists: () => [collection, "list"],
|
|
140
|
+
list: (options) => [collection, "list", options],
|
|
141
|
+
details: () => [collection, "detail"],
|
|
142
|
+
detail: (id, options) => [collection, "detail", id, options],
|
|
143
|
+
infinites: () => [collection, "infinite"],
|
|
144
|
+
infinite: (options) => [collection, "infinite", options]
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// src/ui/Flow/useFlow.ts
|
|
128
149
|
function toNodeTypeDef(doc) {
|
|
129
150
|
var _a, _b, _c, _d;
|
|
130
151
|
return {
|
|
@@ -160,7 +181,7 @@ function useFlow(options) {
|
|
|
160
181
|
const identifier = (_a = id != null ? id : slug) != null ? _a : "";
|
|
161
182
|
const flowQuery = (0, import_react_query.useQuery)(
|
|
162
183
|
{
|
|
163
|
-
queryKey:
|
|
184
|
+
queryKey: collectionKeys("flows").detail(identifier),
|
|
164
185
|
queryFn: () => __async(null, null, function* () {
|
|
165
186
|
if (id) {
|
|
166
187
|
return client.from("flows").findById(id);
|
|
@@ -179,7 +200,7 @@ function useFlow(options) {
|
|
|
179
200
|
);
|
|
180
201
|
const nodeTypesQuery = (0, import_react_query.useQuery)(
|
|
181
202
|
{
|
|
182
|
-
queryKey:
|
|
203
|
+
queryKey: collectionKeys("flow-node-types").lists(),
|
|
183
204
|
queryFn: () => __async(null, null, function* () {
|
|
184
205
|
const result = yield client.from("flow-node-types").find({ limit: 100 });
|
|
185
206
|
return result.docs;
|
|
@@ -190,7 +211,7 @@ function useFlow(options) {
|
|
|
190
211
|
);
|
|
191
212
|
const edgeTypesQuery = (0, import_react_query.useQuery)(
|
|
192
213
|
{
|
|
193
|
-
queryKey:
|
|
214
|
+
queryKey: collectionKeys("flow-edge-types").lists(),
|
|
194
215
|
queryFn: () => __async(null, null, function* () {
|
|
195
216
|
const result = yield client.from("flow-edge-types").find({ limit: 100 });
|
|
196
217
|
return result.docs;
|
|
@@ -225,6 +246,104 @@ function useFlow(options) {
|
|
|
225
246
|
};
|
|
226
247
|
}
|
|
227
248
|
|
|
249
|
+
// src/ui/Flow/useFlowData.ts
|
|
250
|
+
var import_react2 = require("react");
|
|
251
|
+
function useFlowData(options) {
|
|
252
|
+
const { data, nodeTypeDefs: inputNodeDefs, edgeTypeDefs: inputEdgeDefs } = options;
|
|
253
|
+
const nodeTypeDefsMap = (0, import_react2.useMemo)(() => {
|
|
254
|
+
const allDefs = inputNodeDefs != null ? inputNodeDefs : BUILT_IN_NODE_TYPES;
|
|
255
|
+
return new Map(allDefs.map((d) => [d.slug, d]));
|
|
256
|
+
}, [inputNodeDefs]);
|
|
257
|
+
const edgeTypeDefsMap = (0, import_react2.useMemo)(() => {
|
|
258
|
+
const allDefs = inputEdgeDefs != null ? inputEdgeDefs : BUILT_IN_EDGE_TYPES;
|
|
259
|
+
return new Map(allDefs.map((d) => [d.slug, d]));
|
|
260
|
+
}, [inputEdgeDefs]);
|
|
261
|
+
const nodes = (0, import_react2.useMemo)(() => {
|
|
262
|
+
var _a;
|
|
263
|
+
return (_a = data == null ? void 0 : data.nodes) != null ? _a : [];
|
|
264
|
+
}, [data == null ? void 0 : data.nodes]);
|
|
265
|
+
const edges = (0, import_react2.useMemo)(() => {
|
|
266
|
+
var _a;
|
|
267
|
+
return (_a = data == null ? void 0 : data.edges) != null ? _a : [];
|
|
268
|
+
}, [data == null ? void 0 : data.edges]);
|
|
269
|
+
return {
|
|
270
|
+
nodes,
|
|
271
|
+
edges,
|
|
272
|
+
nodeTypeDefsMap,
|
|
273
|
+
edgeTypeDefsMap
|
|
274
|
+
};
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
// src/ui/Flow/utils.ts
|
|
278
|
+
function getNodeBounds(nodes, nodeIds) {
|
|
279
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
|
|
280
|
+
const idSet = new Set(nodeIds);
|
|
281
|
+
const targetNodes = nodes.filter((n) => idSet.has(n.id));
|
|
282
|
+
if (targetNodes.length === 0) return void 0;
|
|
283
|
+
const nodeMap = new Map(nodes.map((n) => [n.id, n]));
|
|
284
|
+
function getAbsolutePosition(node) {
|
|
285
|
+
let x = node.position.x;
|
|
286
|
+
let y = node.position.y;
|
|
287
|
+
let current = node;
|
|
288
|
+
const visited = /* @__PURE__ */ new Set([node.id]);
|
|
289
|
+
while (current.parentId) {
|
|
290
|
+
const parentId = current.parentId;
|
|
291
|
+
if (visited.has(parentId)) break;
|
|
292
|
+
const parent = nodeMap.get(parentId);
|
|
293
|
+
if (!parent) break;
|
|
294
|
+
visited.add(parent.id);
|
|
295
|
+
x += parent.position.x;
|
|
296
|
+
y += parent.position.y;
|
|
297
|
+
current = parent;
|
|
298
|
+
}
|
|
299
|
+
return { x, y };
|
|
300
|
+
}
|
|
301
|
+
let minX = Infinity;
|
|
302
|
+
let minY = Infinity;
|
|
303
|
+
let maxX = -Infinity;
|
|
304
|
+
let maxY = -Infinity;
|
|
305
|
+
for (const node of targetNodes) {
|
|
306
|
+
const abs = getAbsolutePosition(node);
|
|
307
|
+
const w = (_e = (_d = (_c = (_a = node.style) == null ? void 0 : _a.width) != null ? _c : (_b = node.measured) == null ? void 0 : _b.width) != null ? _d : node.width) != null ? _e : 200;
|
|
308
|
+
const h = (_j = (_i = (_h = (_f = node.style) == null ? void 0 : _f.height) != null ? _h : (_g = node.measured) == null ? void 0 : _g.height) != null ? _i : node.height) != null ? _j : 200;
|
|
309
|
+
minX = Math.min(minX, abs.x);
|
|
310
|
+
minY = Math.min(minY, abs.y);
|
|
311
|
+
maxX = Math.max(maxX, abs.x + w);
|
|
312
|
+
maxY = Math.max(maxY, abs.y + h);
|
|
313
|
+
}
|
|
314
|
+
return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };
|
|
315
|
+
}
|
|
316
|
+
function getFrames(nodes) {
|
|
317
|
+
const frames = nodes.filter((n) => n.type === "frame");
|
|
318
|
+
if (frames.length === 0) return [];
|
|
319
|
+
const nodeMap = new Map(nodes.map((n) => [n.id, n]));
|
|
320
|
+
function getAbsolutePosition(node) {
|
|
321
|
+
let x = node.position.x;
|
|
322
|
+
let y = node.position.y;
|
|
323
|
+
let current = node;
|
|
324
|
+
const visited = /* @__PURE__ */ new Set([node.id]);
|
|
325
|
+
while (current.parentId) {
|
|
326
|
+
const parentId = current.parentId;
|
|
327
|
+
if (visited.has(parentId)) break;
|
|
328
|
+
const parent = nodeMap.get(parentId);
|
|
329
|
+
if (!parent) break;
|
|
330
|
+
visited.add(parent.id);
|
|
331
|
+
x += parent.position.x;
|
|
332
|
+
y += parent.position.y;
|
|
333
|
+
current = parent;
|
|
334
|
+
}
|
|
335
|
+
return { x, y };
|
|
336
|
+
}
|
|
337
|
+
return frames.map((f) => {
|
|
338
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k;
|
|
339
|
+
const data = f.data;
|
|
340
|
+
const abs = getAbsolutePosition(f);
|
|
341
|
+
const w = (_e = (_d = (_c = (_a = f.style) == null ? void 0 : _a.width) != null ? _c : (_b = f.measured) == null ? void 0 : _b.width) != null ? _d : f.width) != null ? _e : 200;
|
|
342
|
+
const h = (_j = (_i = (_h = (_f = f.style) == null ? void 0 : _f.height) != null ? _h : (_g = f.measured) == null ? void 0 : _g.height) != null ? _i : f.height) != null ? _j : 200;
|
|
343
|
+
return { id: f.id, label: (_k = data.label) != null ? _k : "", bounds: { x: abs.x, y: abs.y, width: w, height: h } };
|
|
344
|
+
}).sort((a, b) => a.bounds.y - b.bounds.y || a.bounds.x - b.bounds.x);
|
|
345
|
+
}
|
|
346
|
+
|
|
228
347
|
// src/ui/Flow/index.tsx
|
|
229
348
|
function sanitizeUrl(url) {
|
|
230
349
|
if (!url) return url;
|
|
@@ -237,8 +356,8 @@ function sanitizeUrl(url) {
|
|
|
237
356
|
}
|
|
238
357
|
}
|
|
239
358
|
function toMarkerType(value) {
|
|
240
|
-
if (value === "arrow") return
|
|
241
|
-
if (value === "arrowclosed") return
|
|
359
|
+
if (value === "arrow") return import_react4.MarkerType.Arrow;
|
|
360
|
+
if (value === "arrowclosed") return import_react4.MarkerType.ArrowClosed;
|
|
242
361
|
return void 0;
|
|
243
362
|
}
|
|
244
363
|
function renderFieldValue(key, val, fieldDef) {
|
|
@@ -248,7 +367,7 @@ function renderFieldValue(key, val, fieldDef) {
|
|
|
248
367
|
const imgUrl = typeof val === "string" ? val : val == null ? void 0 : val.url;
|
|
249
368
|
const safeUrl = sanitizeUrl(imgUrl);
|
|
250
369
|
if (!safeUrl) return null;
|
|
251
|
-
return /* @__PURE__ */
|
|
370
|
+
return /* @__PURE__ */ import_react3.default.createElement(
|
|
252
371
|
"img",
|
|
253
372
|
{
|
|
254
373
|
key,
|
|
@@ -259,7 +378,7 @@ function renderFieldValue(key, val, fieldDef) {
|
|
|
259
378
|
}
|
|
260
379
|
);
|
|
261
380
|
}
|
|
262
|
-
return /* @__PURE__ */
|
|
381
|
+
return /* @__PURE__ */ import_react3.default.createElement(
|
|
263
382
|
"div",
|
|
264
383
|
{
|
|
265
384
|
key,
|
|
@@ -276,7 +395,7 @@ function renderFieldValue(key, val, fieldDef) {
|
|
|
276
395
|
}
|
|
277
396
|
function DefaultDynamicNode({ data }) {
|
|
278
397
|
const d = data;
|
|
279
|
-
return /* @__PURE__ */
|
|
398
|
+
return /* @__PURE__ */ import_react3.default.createElement(
|
|
280
399
|
"div",
|
|
281
400
|
{
|
|
282
401
|
style: {
|
|
@@ -293,7 +412,7 @@ function EnhancedDynamicNode({
|
|
|
293
412
|
data,
|
|
294
413
|
typeDef
|
|
295
414
|
}) {
|
|
296
|
-
return /* @__PURE__ */
|
|
415
|
+
return /* @__PURE__ */ import_react3.default.createElement(
|
|
297
416
|
"div",
|
|
298
417
|
{
|
|
299
418
|
style: {
|
|
@@ -322,7 +441,7 @@ function DefaultFrameNode({ data }) {
|
|
|
322
441
|
if (m) return `rgba(${m[1]},${m[2]},${m[3]},${opacity})`;
|
|
323
442
|
return baseColor;
|
|
324
443
|
})();
|
|
325
|
-
return /* @__PURE__ */
|
|
444
|
+
return /* @__PURE__ */ import_react3.default.createElement(
|
|
326
445
|
"div",
|
|
327
446
|
{
|
|
328
447
|
style: {
|
|
@@ -333,7 +452,7 @@ function DefaultFrameNode({ data }) {
|
|
|
333
452
|
border: borderStyle === "none" ? "none" : `2px ${borderStyle} rgba(128,128,128,0.3)`
|
|
334
453
|
}
|
|
335
454
|
},
|
|
336
|
-
/* @__PURE__ */
|
|
455
|
+
/* @__PURE__ */ import_react3.default.createElement(
|
|
337
456
|
"div",
|
|
338
457
|
{
|
|
339
458
|
style: {
|
|
@@ -347,14 +466,15 @@ function DefaultFrameNode({ data }) {
|
|
|
347
466
|
)
|
|
348
467
|
);
|
|
349
468
|
}
|
|
350
|
-
function createNodeTypes(nodeRenderers, nodeTypeDefsMap) {
|
|
469
|
+
function createNodeTypes(nodeRenderers, nodeTypeDefsMap, frameRenderer, nodeWrapper, renderNode) {
|
|
351
470
|
const types = {};
|
|
352
471
|
types.dynamic = ((props) => {
|
|
353
472
|
const d = props.data;
|
|
354
473
|
const typeDef = nodeTypeDefsMap == null ? void 0 : nodeTypeDefsMap.get(d.nodeTypeSlug);
|
|
355
474
|
const CustomRenderer = nodeRenderers == null ? void 0 : nodeRenderers[d.nodeTypeSlug];
|
|
475
|
+
let content;
|
|
356
476
|
if (CustomRenderer) {
|
|
357
|
-
|
|
477
|
+
content = /* @__PURE__ */ import_react3.default.createElement(
|
|
358
478
|
CustomRenderer,
|
|
359
479
|
{
|
|
360
480
|
id: props.id,
|
|
@@ -364,15 +484,94 @@ function createNodeTypes(nodeRenderers, nodeTypeDefsMap) {
|
|
|
364
484
|
nodeTypeDef: typeDef
|
|
365
485
|
}
|
|
366
486
|
);
|
|
487
|
+
} else if (typeDef) {
|
|
488
|
+
content = /* @__PURE__ */ import_react3.default.createElement(EnhancedDynamicNode, { data: d, typeDef });
|
|
489
|
+
} else {
|
|
490
|
+
content = /* @__PURE__ */ import_react3.default.createElement(DefaultDynamicNode, __spreadValues({}, props));
|
|
367
491
|
}
|
|
368
|
-
if (
|
|
369
|
-
|
|
492
|
+
if (renderNode) {
|
|
493
|
+
const slotProps = {
|
|
494
|
+
id: props.id,
|
|
495
|
+
nodeTypeSlug: d.nodeTypeSlug,
|
|
496
|
+
label: d.label,
|
|
497
|
+
fields: d.fields,
|
|
498
|
+
nodeTypeDef: typeDef
|
|
499
|
+
};
|
|
500
|
+
const result = renderNode(slotProps, content);
|
|
501
|
+
if (result !== null) content = result;
|
|
370
502
|
}
|
|
371
|
-
|
|
503
|
+
if (nodeWrapper) {
|
|
504
|
+
const Wrapper = nodeWrapper;
|
|
505
|
+
content = /* @__PURE__ */ import_react3.default.createElement(
|
|
506
|
+
Wrapper,
|
|
507
|
+
{
|
|
508
|
+
id: props.id,
|
|
509
|
+
nodeTypeSlug: d.nodeTypeSlug,
|
|
510
|
+
label: d.label,
|
|
511
|
+
selected: props.selected,
|
|
512
|
+
nodeTypeDef: typeDef
|
|
513
|
+
},
|
|
514
|
+
content
|
|
515
|
+
);
|
|
516
|
+
}
|
|
517
|
+
return content;
|
|
372
518
|
});
|
|
373
|
-
types.frame =
|
|
519
|
+
types.frame = frameRenderer ? ((props) => {
|
|
520
|
+
const d = props.data;
|
|
521
|
+
const Renderer = frameRenderer;
|
|
522
|
+
return /* @__PURE__ */ import_react3.default.createElement(
|
|
523
|
+
Renderer,
|
|
524
|
+
{
|
|
525
|
+
id: props.id,
|
|
526
|
+
label: d.label,
|
|
527
|
+
color: d.color,
|
|
528
|
+
padding: d.padding,
|
|
529
|
+
borderStyle: d.borderStyle,
|
|
530
|
+
opacity: d.opacity
|
|
531
|
+
}
|
|
532
|
+
);
|
|
533
|
+
}) : DefaultFrameNode;
|
|
534
|
+
return types;
|
|
535
|
+
}
|
|
536
|
+
function createEdgeTypes(edgeRenderers, edgeTypeDefsMap) {
|
|
537
|
+
if (!edgeRenderers || Object.keys(edgeRenderers).length === 0) return void 0;
|
|
538
|
+
const types = {};
|
|
539
|
+
for (const [slug, Renderer] of Object.entries(edgeRenderers)) {
|
|
540
|
+
types[slug] = ((props) => {
|
|
541
|
+
var _a;
|
|
542
|
+
const def = edgeTypeDefsMap == null ? void 0 : edgeTypeDefsMap.get(slug);
|
|
543
|
+
return /* @__PURE__ */ import_react3.default.createElement(
|
|
544
|
+
Renderer,
|
|
545
|
+
{
|
|
546
|
+
id: props.id,
|
|
547
|
+
edgeTypeSlug: slug,
|
|
548
|
+
source: props.source,
|
|
549
|
+
target: props.target,
|
|
550
|
+
label: props.label,
|
|
551
|
+
fields: (_a = props.data) == null ? void 0 : _a.fields,
|
|
552
|
+
edgeTypeDef: def,
|
|
553
|
+
style: props.style
|
|
554
|
+
}
|
|
555
|
+
);
|
|
556
|
+
});
|
|
557
|
+
}
|
|
374
558
|
return types;
|
|
375
559
|
}
|
|
560
|
+
function FocusHandler({
|
|
561
|
+
bounds,
|
|
562
|
+
padding,
|
|
563
|
+
animation
|
|
564
|
+
}) {
|
|
565
|
+
const { fitBounds } = (0, import_react4.useReactFlow)();
|
|
566
|
+
const boundsKey = `${bounds.x},${bounds.y},${bounds.width},${bounds.height}`;
|
|
567
|
+
const boundsRef = import_react3.default.useRef(bounds);
|
|
568
|
+
boundsRef.current = bounds;
|
|
569
|
+
import_react3.default.useEffect(() => {
|
|
570
|
+
const duration = animation === true ? 300 : typeof animation === "number" ? animation : 0;
|
|
571
|
+
fitBounds(boundsRef.current, { padding, duration });
|
|
572
|
+
}, [boundsKey, padding, animation, fitBounds]);
|
|
573
|
+
return null;
|
|
574
|
+
}
|
|
376
575
|
var EDGE_TYPE_MAP = {
|
|
377
576
|
step: "step",
|
|
378
577
|
smoothstep: "smoothstep",
|
|
@@ -419,50 +618,78 @@ function FlowRenderer({
|
|
|
419
618
|
nodeRenderers,
|
|
420
619
|
nodeTypeDefs,
|
|
421
620
|
edgeTypeDefs,
|
|
422
|
-
background =
|
|
621
|
+
background = false,
|
|
423
622
|
interactive = false,
|
|
424
623
|
fitView = true,
|
|
425
624
|
onNodeClick,
|
|
426
|
-
onEdgeClick
|
|
625
|
+
onEdgeClick,
|
|
626
|
+
frameRenderer,
|
|
627
|
+
edgeRenderers,
|
|
628
|
+
nodeWrapper,
|
|
629
|
+
controls,
|
|
630
|
+
minimap,
|
|
631
|
+
minimapNodeColor,
|
|
632
|
+
children,
|
|
633
|
+
renderNode,
|
|
634
|
+
onViewportChange,
|
|
635
|
+
defaultViewport: defaultViewportProp,
|
|
636
|
+
bounds,
|
|
637
|
+
focusPadding,
|
|
638
|
+
focusAnimation
|
|
427
639
|
}) {
|
|
428
640
|
var _a;
|
|
429
|
-
const nodeTypeDefsMap =
|
|
641
|
+
const nodeTypeDefsMap = import_react3.default.useMemo(() => {
|
|
430
642
|
if (!(nodeTypeDefs == null ? void 0 : nodeTypeDefs.length)) return void 0;
|
|
431
643
|
return new Map(nodeTypeDefs.map((d) => [d.slug, d]));
|
|
432
644
|
}, [nodeTypeDefs]);
|
|
433
|
-
const edgeTypeDefsMap =
|
|
645
|
+
const edgeTypeDefsMap = import_react3.default.useMemo(() => {
|
|
434
646
|
if (!(edgeTypeDefs == null ? void 0 : edgeTypeDefs.length)) return void 0;
|
|
435
647
|
return new Map(edgeTypeDefs.map((d) => [d.slug, d]));
|
|
436
648
|
}, [edgeTypeDefs]);
|
|
437
|
-
const nodeTypes =
|
|
438
|
-
() => createNodeTypes(nodeRenderers, nodeTypeDefsMap),
|
|
439
|
-
[nodeRenderers, nodeTypeDefsMap]
|
|
649
|
+
const nodeTypes = import_react3.default.useMemo(
|
|
650
|
+
() => createNodeTypes(nodeRenderers, nodeTypeDefsMap, frameRenderer, nodeWrapper, renderNode),
|
|
651
|
+
[nodeRenderers, nodeTypeDefsMap, frameRenderer, nodeWrapper, renderNode]
|
|
440
652
|
);
|
|
441
|
-
const
|
|
442
|
-
() =>
|
|
443
|
-
|
|
444
|
-
return applyEdgeStyles((_a2 = data == null ? void 0 : data.edges) != null ? _a2 : [], edgeTypeDefsMap);
|
|
445
|
-
},
|
|
446
|
-
[data == null ? void 0 : data.edges, edgeTypeDefsMap]
|
|
653
|
+
const customEdgeTypes = import_react3.default.useMemo(
|
|
654
|
+
() => createEdgeTypes(edgeRenderers, edgeTypeDefsMap),
|
|
655
|
+
[edgeRenderers, edgeTypeDefsMap]
|
|
447
656
|
);
|
|
657
|
+
const styledEdges = import_react3.default.useMemo(() => {
|
|
658
|
+
var _a2;
|
|
659
|
+
let edges = applyEdgeStyles((_a2 = data == null ? void 0 : data.edges) != null ? _a2 : [], edgeTypeDefsMap);
|
|
660
|
+
if (edgeRenderers) {
|
|
661
|
+
edges = edges.map((edge) => {
|
|
662
|
+
const slug = edge.edgeTypeSlug;
|
|
663
|
+
if (slug && edgeRenderers[slug]) {
|
|
664
|
+
return __spreadProps(__spreadValues({}, edge), { type: slug });
|
|
665
|
+
}
|
|
666
|
+
return edge;
|
|
667
|
+
});
|
|
668
|
+
}
|
|
669
|
+
return edges;
|
|
670
|
+
}, [data == null ? void 0 : data.edges, edgeTypeDefsMap, edgeRenderers]);
|
|
448
671
|
if (!data) return null;
|
|
449
|
-
const
|
|
450
|
-
return /* @__PURE__ */
|
|
672
|
+
const resolvedDefaultViewport = defaultViewportProp != null ? defaultViewportProp : !fitView && data.viewport ? data.viewport : void 0;
|
|
673
|
+
return /* @__PURE__ */ import_react3.default.createElement(import_react4.ReactFlowProvider, null, /* @__PURE__ */ import_react3.default.createElement(
|
|
451
674
|
"div",
|
|
452
675
|
{
|
|
453
676
|
className,
|
|
454
677
|
style: __spreadValues({ width: "100%", height: "100%" }, style)
|
|
455
678
|
},
|
|
456
|
-
/* @__PURE__ */
|
|
457
|
-
|
|
679
|
+
/* @__PURE__ */ import_react3.default.createElement(
|
|
680
|
+
import_react4.ReactFlow,
|
|
458
681
|
{
|
|
459
682
|
nodes: (_a = data.nodes) != null ? _a : [],
|
|
460
683
|
edges: styledEdges,
|
|
461
684
|
nodeTypes,
|
|
462
|
-
|
|
685
|
+
edgeTypes: customEdgeTypes,
|
|
686
|
+
defaultViewport: resolvedDefaultViewport,
|
|
463
687
|
fitView,
|
|
464
688
|
onNodeClick,
|
|
465
689
|
onEdgeClick,
|
|
690
|
+
onMoveEnd: onViewportChange ? ((_, vp) => {
|
|
691
|
+
onViewportChange(vp);
|
|
692
|
+
}) : void 0,
|
|
466
693
|
nodesDraggable: interactive ? void 0 : false,
|
|
467
694
|
nodesConnectable: false,
|
|
468
695
|
elementsSelectable: interactive || !!onNodeClick || !!onEdgeClick,
|
|
@@ -471,7 +698,23 @@ function FlowRenderer({
|
|
|
471
698
|
zoomOnPinch: interactive,
|
|
472
699
|
zoomOnDoubleClick: false
|
|
473
700
|
},
|
|
474
|
-
background && /* @__PURE__ */
|
|
701
|
+
background && /* @__PURE__ */ import_react3.default.createElement(import_react4.Background, null),
|
|
702
|
+
controls && /* @__PURE__ */ import_react3.default.createElement(import_react4.Controls, null),
|
|
703
|
+
minimap && /* @__PURE__ */ import_react3.default.createElement(
|
|
704
|
+
import_react4.MiniMap,
|
|
705
|
+
{
|
|
706
|
+
nodeColor: minimapNodeColor
|
|
707
|
+
}
|
|
708
|
+
),
|
|
709
|
+
bounds && /* @__PURE__ */ import_react3.default.createElement(
|
|
710
|
+
FocusHandler,
|
|
711
|
+
{
|
|
712
|
+
bounds,
|
|
713
|
+
padding: focusPadding != null ? focusPadding : 0.1,
|
|
714
|
+
animation: focusAnimation != null ? focusAnimation : true
|
|
715
|
+
}
|
|
716
|
+
),
|
|
717
|
+
children
|
|
475
718
|
)
|
|
476
719
|
));
|
|
477
720
|
}
|