@powerhousedao/vetra 6.2.1-dev.1 → 6.2.1-dev.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.
@@ -2,7 +2,7 @@ import { t as createAppModuleDocument } from "../ph-factories-Dvy-HW6C.js";
2
2
  import { t as createDocumentEditorDocument } from "../ph-factories-BKH_LPa8.js";
3
3
  import { t as createProcessorModuleDocument } from "../ph-factories-qCTFKODg.js";
4
4
  import { n as createSubgraphModuleDocument } from "../ph-factories-BL1-hdeG.js";
5
- import { a as getDocument, c as getDocuments, d as getSpecEntry, f as listSpecDocumentTypes, g as stripLeadingDot, h as specPath, i as deleteDocument, l as validateActions, m as specDir, n as addActionsAndSave, o as getDocumentModelSchema, p as saveSpec, r as createDocument, s as getDocumentModels, t as addActions, u as SPECS_DIRNAME } from "../spec-api-CT1DqmgF.js";
5
+ import { a as getDocument, c as getDocuments, d as getSpecEntry, f as listSpecDocumentTypes, g as stripLeadingDot, h as specPath, i as deleteDocument, l as validateActions, m as specDir, n as addActionsAndSave, o as getDocumentModelSchema, p as saveSpec, r as createDocument, s as getDocumentModels, t as addActions, u as SPECS_DIRNAME } from "../spec-api-D2QObgjc.js";
6
6
  import { documentModelDocumentModelModule } from "document-model";
7
7
  import { PROCESSOR_APPS } from "@powerhousedao/shared/processors";
8
8
  import { generateId } from "@powerhousedao/shared/document-model";
@@ -1,2 +1,2 @@
1
- import { a as getDocument, c as getDocuments, d as getSpecEntry, f as listSpecDocumentTypes, g as stripLeadingDot, h as specPath, i as deleteDocument, l as validateActions, m as specDir, n as addActionsAndSave, o as getDocumentModelSchema, p as saveSpec, r as createDocument, s as getDocumentModels, t as addActions, u as SPECS_DIRNAME } from "../spec-api-CT1DqmgF.js";
1
+ import { a as getDocument, c as getDocuments, d as getSpecEntry, f as listSpecDocumentTypes, g as stripLeadingDot, h as specPath, i as deleteDocument, l as validateActions, m as specDir, n as addActionsAndSave, o as getDocumentModelSchema, p as saveSpec, r as createDocument, s as getDocumentModels, t as addActions, u as SPECS_DIRNAME } from "../spec-api-D2QObgjc.js";
2
2
  export { SPECS_DIRNAME, addActions, addActionsAndSave, createDocument, deleteDocument, getDocument, getDocumentModelSchema, getDocumentModels, getDocuments, getSpecEntry, listSpecDocumentTypes, saveSpec, specDir, specPath, stripLeadingDot, validateActions };
@@ -1,6 +1,6 @@
1
1
  import { _ as removeDocumentType, b as setProcessorStatus, h as addProcessorApp, m as addDocumentType, v as removeProcessorApp, x as setProcessorType, y as setProcessorName } from "./utils-CkWB3DRk.js";
2
2
  import { StatusPill } from "./editors/components/index.js";
3
- import { n as useAvailableDocumentTypes, t as useDebounce } from "./hooks-D_8Uwk1s.js";
3
+ import { n as useAvailableDocumentTypes, t as useDebounce } from "./hooks-Btogj1f0.js";
4
4
  import { n as useSelectedProcessorModuleDocument } from "./useVetraDocument-BpPD6DKR.js";
5
5
  import { useSetPHDocumentEditorConfig } from "@powerhousedao/reactor-browser";
6
6
  import { PROCESSOR_APPS } from "@powerhousedao/shared/processors";
@@ -241,4 +241,4 @@ function Editor() {
241
241
  //#endregion
242
242
  export { Editor as default };
243
243
 
244
- //# sourceMappingURL=editor-saGUzfCl.js.map
244
+ //# sourceMappingURL=editor-0Boxg7qN.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"editor-saGUzfCl.js","names":[],"sources":["../editors/processor-editor/components/ProcessorEditorForm.tsx","../editors/processor-editor/config.ts","../editors/processor-editor/editor.tsx"],"sourcesContent":["import {\n PROCESSOR_APPS,\n type ProcessorApp,\n type ProcessorApps,\n} from \"@powerhousedao/shared/processors\";\nimport { useEffect, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport type { DocumentTypeItem } from \"../../../document-models/processor-module/index.js\";\nimport { StatusPill } from \"../../components/index.js\";\nimport { useAvailableDocumentTypes, useDebounce } from \"../../hooks/index.js\";\n\nexport interface ProcessorEditorFormProps {\n processorName?: string;\n processorType?: string;\n documentTypes?: DocumentTypeItem[];\n processorApps?: ProcessorApps;\n status?: string;\n onNameChange?: (name: string) => void;\n onTypeChange?: (type: string) => void;\n onAddDocumentType?: (id: string, documentType: string) => void;\n onRemoveDocumentType?: (id: string) => void;\n onAddProcessorApp?: (processorApp: ProcessorApp) => void;\n onRemoveProcessorApp?: (processorApp: ProcessorApp) => void;\n onConfirm?: () => void;\n}\n\nexport const ProcessorEditorForm: React.FC<ProcessorEditorFormProps> = ({\n processorName: initialProcessorName = \"\",\n processorType: initialProcessorType = \"\",\n documentTypes: initialDocumentTypes = [],\n processorApps: initialProcessorApps = [],\n status = \"DRAFT\",\n onNameChange,\n onTypeChange,\n onAddDocumentType,\n onRemoveDocumentType,\n onAddProcessorApp,\n onRemoveProcessorApp,\n onConfirm,\n}) => {\n const [processorName, setProcessorName] = useState(initialProcessorName);\n const [processorType, setProcessorType] = useState(initialProcessorType);\n const [documentTypes, setDocumentTypes] =\n useState<DocumentTypeItem[]>(initialDocumentTypes);\n const [selectedDocumentType, setSelectedDocumentType] = useState(\"\");\n const [processorApps, setProcessorApps] = useState(initialProcessorApps);\n const [isConfirmed, setIsConfirmed] = useState(false);\n\n // Get available document types from the hook (combines reactor and vetra drive)\n const availableDocumentTypes = useAvailableDocumentTypes();\n\n // Use the debounce hook for name and type changes\n useDebounce(processorName, onNameChange, 300);\n useDebounce(processorType, onTypeChange, 300);\n\n // Update local state when initial values change\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setProcessorName(initialProcessorName);\n }, [initialProcessorName]);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setProcessorType(initialProcessorType);\n }, [initialProcessorType]);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setDocumentTypes(initialDocumentTypes);\n }, [initialDocumentTypes]);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setProcessorApps(initialProcessorApps);\n }, [initialProcessorApps]);\n\n // Reset confirmation state if status changes back to DRAFT\n useEffect(() => {\n if (status === \"DRAFT\") {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setIsConfirmed(false);\n }\n }, [status]);\n\n // Check if form should be read-only\n const isReadOnly = isConfirmed || status === \"CONFIRMED\";\n\n const handleConfirm = () => {\n if (\n processorName.trim() &&\n processorType &&\n documentTypes.length > 0 &&\n processorApps.length > 0\n ) {\n setIsConfirmed(true); // Immediate UI update\n onConfirm?.();\n }\n };\n\n const handleRemoveDocumentType = (id: string) => {\n setDocumentTypes(documentTypes.filter((dt) => dt.id !== id));\n onRemoveDocumentType?.(id);\n };\n\n const canConfirm =\n !!processorName.trim() &&\n !!processorType &&\n documentTypes.length > 0 &&\n processorApps.length > 0;\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-lg font-medium text-foreground\">\n Processor Configuration\n </h2>\n <StatusPill\n status={status === \"CONFIRMED\" ? \"confirmed\" : \"draft\"}\n label={status === \"CONFIRMED\" ? \"Confirmed\" : \"Draft\"}\n />\n </div>\n\n {/* Processor Name Field */}\n <div>\n <label\n htmlFor=\"processor-name\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Processor Name\n </label>\n <input\n id=\"processor-name\"\n type=\"text\"\n value={processorName}\n onChange={(e) => setProcessorName(e.target.value)}\n disabled={isReadOnly}\n className={twMerge(\n \"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\",\n isReadOnly\n ? \"cursor-not-allowed bg-muted text-muted-foreground\"\n : \"\",\n )}\n placeholder=\"Enter processor name\"\n />\n </div>\n\n {/* Processor Type Dropdown */}\n <div>\n <label\n htmlFor=\"processor-type\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Type\n </label>\n <select\n id=\"processor-type\"\n value={processorType}\n onChange={(e) => setProcessorType(e.target.value)}\n disabled={isReadOnly}\n className={twMerge(\n \"w-full rounded-md border border-border px-3 py-2 text-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none\",\n isReadOnly ? \"cursor-not-allowed bg-muted\" : \"\",\n )}\n >\n <option value=\"\">Select type...</option>\n <option value=\"analytics\">Analytics</option>\n <option value=\"relational\">Relational Database</option>\n </select>\n </div>\n\n {/* Document Types Field */}\n <div>\n <label\n htmlFor=\"document-types\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Document Types\n </label>\n <div className=\"space-y-2\">\n {!isReadOnly && availableDocumentTypes.length > 0 && (\n <select\n id=\"document-types\"\n value={selectedDocumentType}\n onChange={(e) => {\n const selectedValue = e.target.value;\n if (\n selectedValue &&\n !documentTypes.some((dt) => dt.documentType === selectedValue)\n ) {\n const id = Date.now().toString();\n const newType: DocumentTypeItem = {\n id,\n documentType: selectedValue,\n };\n setDocumentTypes([...documentTypes, newType]);\n onAddDocumentType?.(id, selectedValue);\n }\n setSelectedDocumentType(\"\");\n }}\n className=\"w-full rounded-md border border-border px-3 py-2 text-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none\"\n >\n <option value=\"\">Select a document type to add</option>\n {availableDocumentTypes\n .filter(\n (docType) =>\n !documentTypes.some((dt) => dt.documentType === docType),\n )\n .map((docType) => (\n <option key={docType} value={docType}>\n {docType}\n </option>\n ))}\n </select>\n )}\n <div className=\"space-y-1\">\n {documentTypes.map((type) => (\n <div key={type.id} className=\"flex items-center py-1\">\n <span className=\"text-sm text-foreground\">\n {type.documentType}\n </span>\n {!isReadOnly && (\n <button\n onClick={() => handleRemoveDocumentType(type.id)}\n className=\"ml-2 text-muted-foreground hover:hover-effect focus:outline-none\"\n >\n ×\n </button>\n )}\n </div>\n ))}\n </div>\n </div>\n </div>\n {/* Processor Apps Field */}\n <div>\n <label\n htmlFor=\"processor-apps\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Processor Apps\n </label>\n <div className=\"space-y-2\">\n {!isReadOnly && (\n <>\n {PROCESSOR_APPS.map((processorApp) => (\n <div key={processorApp} className=\"flex gap-1\">\n <input\n type=\"checkbox\"\n name={processorApp}\n id={processorApp}\n checked={processorApps.includes(processorApp)}\n onChange={(event) => {\n const isChecked = event.target.checked;\n if (isChecked) {\n setProcessorApps((processorApps) => [\n ...new Set([...processorApps, processorApp]),\n ]);\n onAddProcessorApp?.(processorApp);\n } else {\n if (processorApps.length > 1) {\n setProcessorApps((processorApps) =>\n processorApps.filter((p) => p !== processorApp),\n );\n onRemoveProcessorApp?.(processorApp);\n }\n }\n }}\n />\n <label htmlFor={processorApp} className=\"text-foreground\">\n {processorApp}\n </label>\n </div>\n ))}\n </>\n )}\n <div className=\"space-y-1\">\n {isReadOnly &&\n processorApps.map((processorApp) => (\n <span key={processorApp} className=\"text-sm text-foreground\">\n {processorApp}\n </span>\n ))}\n </div>\n </div>\n </div>\n {/* Confirm Button - only show if not in read-only mode */}\n {!isReadOnly && (\n <div>\n <button\n onClick={handleConfirm}\n disabled={!canConfirm}\n className=\"rounded-md bg-primary px-4 py-2 text-primary-foreground hover:hover-effect focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-none disabled:disabled-effect\"\n >\n Confirm\n </button>\n </div>\n )}\n </div>\n );\n};\n","import type { PHDocumentEditorConfig } from \"@powerhousedao/reactor-browser\";\n\nexport const editorConfig: PHDocumentEditorConfig = {\n isExternalControlsEnabled: false,\n};\n","import { DocumentToolbar } from \"@powerhousedao/design-system/connect\";\nimport { useSetPHDocumentEditorConfig } from \"@powerhousedao/reactor-browser\";\nimport type {\n ProcessorApp,\n ProcessorApps,\n} from \"@powerhousedao/shared/processors\";\nimport { useCallback } from \"react\";\nimport {\n addDocumentType,\n addProcessorApp,\n removeDocumentType,\n removeProcessorApp,\n setProcessorName,\n setProcessorStatus,\n setProcessorType,\n} from \"../../document-models/processor-module/index.js\";\nimport { useSelectedProcessorModuleDocument } from \"../hooks/useVetraDocument.js\";\nimport { ProcessorEditorForm } from \"./components/ProcessorEditorForm.js\";\nimport { editorConfig } from \"./config.js\";\n\nexport default function Editor() {\n useSetPHDocumentEditorConfig(editorConfig);\n const [document, dispatch] = useSelectedProcessorModuleDocument();\n\n const onConfirm = useCallback(() => {\n // Dispatch all actions at once\n dispatch([setProcessorStatus({ status: \"CONFIRMED\" })]);\n }, [dispatch]);\n\n const onNameChange = useCallback(\n (name: string) => {\n if (name === document.state.global.name) return;\n dispatch(setProcessorName({ name }));\n },\n [document.state.global.name, dispatch],\n );\n\n const onTypeChange = useCallback(\n (type: string) => {\n if (type === document.state.global.type) return;\n dispatch(setProcessorType({ type }));\n },\n [document.state.global.type, dispatch],\n );\n\n const onAddDocumentType = useCallback(\n (id: string, documentType: string) => {\n dispatch(addDocumentType({ id, documentType }));\n },\n [dispatch],\n );\n\n const onRemoveDocumentType = useCallback(\n (id: string) => {\n dispatch(removeDocumentType({ id }));\n },\n [dispatch],\n );\n\n const onAddProcessorApp = useCallback(\n (processorApp: ProcessorApp) => {\n dispatch(addProcessorApp({ processorApp }));\n },\n [dispatch],\n );\n\n const onRemoveProcessorApp = useCallback(\n (processorApp: ProcessorApp) => {\n dispatch(removeProcessorApp({ processorApp }));\n },\n [dispatch],\n );\n\n return (\n <div className=\"bg-background p-6\">\n <DocumentToolbar />\n <ProcessorEditorForm\n onNameChange={onNameChange}\n onTypeChange={onTypeChange}\n onAddDocumentType={onAddDocumentType}\n onRemoveDocumentType={onRemoveDocumentType}\n onAddProcessorApp={onAddProcessorApp}\n onRemoveProcessorApp={onRemoveProcessorApp}\n status={document.state.global.status}\n processorName={document.state.global.name ?? \"\"}\n processorType={document.state.global.type ?? \"\"}\n documentTypes={document.state.global.documentTypes ?? []}\n processorApps={document.state.global.processorApps as ProcessorApps}\n onConfirm={onConfirm}\n />\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"editor-0Boxg7qN.js","names":[],"sources":["../editors/processor-editor/components/ProcessorEditorForm.tsx","../editors/processor-editor/config.ts","../editors/processor-editor/editor.tsx"],"sourcesContent":["import {\n PROCESSOR_APPS,\n type ProcessorApp,\n type ProcessorApps,\n} from \"@powerhousedao/shared/processors\";\nimport { useEffect, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport type { DocumentTypeItem } from \"../../../document-models/processor-module/index.js\";\nimport { StatusPill } from \"../../components/index.js\";\nimport { useAvailableDocumentTypes, useDebounce } from \"../../hooks/index.js\";\n\nexport interface ProcessorEditorFormProps {\n processorName?: string;\n processorType?: string;\n documentTypes?: DocumentTypeItem[];\n processorApps?: ProcessorApps;\n status?: string;\n onNameChange?: (name: string) => void;\n onTypeChange?: (type: string) => void;\n onAddDocumentType?: (id: string, documentType: string) => void;\n onRemoveDocumentType?: (id: string) => void;\n onAddProcessorApp?: (processorApp: ProcessorApp) => void;\n onRemoveProcessorApp?: (processorApp: ProcessorApp) => void;\n onConfirm?: () => void;\n}\n\nexport const ProcessorEditorForm: React.FC<ProcessorEditorFormProps> = ({\n processorName: initialProcessorName = \"\",\n processorType: initialProcessorType = \"\",\n documentTypes: initialDocumentTypes = [],\n processorApps: initialProcessorApps = [],\n status = \"DRAFT\",\n onNameChange,\n onTypeChange,\n onAddDocumentType,\n onRemoveDocumentType,\n onAddProcessorApp,\n onRemoveProcessorApp,\n onConfirm,\n}) => {\n const [processorName, setProcessorName] = useState(initialProcessorName);\n const [processorType, setProcessorType] = useState(initialProcessorType);\n const [documentTypes, setDocumentTypes] =\n useState<DocumentTypeItem[]>(initialDocumentTypes);\n const [selectedDocumentType, setSelectedDocumentType] = useState(\"\");\n const [processorApps, setProcessorApps] = useState(initialProcessorApps);\n const [isConfirmed, setIsConfirmed] = useState(false);\n\n // Get available document types from the hook (combines reactor and vetra drive)\n const availableDocumentTypes = useAvailableDocumentTypes();\n\n // Use the debounce hook for name and type changes\n useDebounce(processorName, onNameChange, 300);\n useDebounce(processorType, onTypeChange, 300);\n\n // Update local state when initial values change\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setProcessorName(initialProcessorName);\n }, [initialProcessorName]);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setProcessorType(initialProcessorType);\n }, [initialProcessorType]);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setDocumentTypes(initialDocumentTypes);\n }, [initialDocumentTypes]);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setProcessorApps(initialProcessorApps);\n }, [initialProcessorApps]);\n\n // Reset confirmation state if status changes back to DRAFT\n useEffect(() => {\n if (status === \"DRAFT\") {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setIsConfirmed(false);\n }\n }, [status]);\n\n // Check if form should be read-only\n const isReadOnly = isConfirmed || status === \"CONFIRMED\";\n\n const handleConfirm = () => {\n if (\n processorName.trim() &&\n processorType &&\n documentTypes.length > 0 &&\n processorApps.length > 0\n ) {\n setIsConfirmed(true); // Immediate UI update\n onConfirm?.();\n }\n };\n\n const handleRemoveDocumentType = (id: string) => {\n setDocumentTypes(documentTypes.filter((dt) => dt.id !== id));\n onRemoveDocumentType?.(id);\n };\n\n const canConfirm =\n !!processorName.trim() &&\n !!processorType &&\n documentTypes.length > 0 &&\n processorApps.length > 0;\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-lg font-medium text-foreground\">\n Processor Configuration\n </h2>\n <StatusPill\n status={status === \"CONFIRMED\" ? \"confirmed\" : \"draft\"}\n label={status === \"CONFIRMED\" ? \"Confirmed\" : \"Draft\"}\n />\n </div>\n\n {/* Processor Name Field */}\n <div>\n <label\n htmlFor=\"processor-name\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Processor Name\n </label>\n <input\n id=\"processor-name\"\n type=\"text\"\n value={processorName}\n onChange={(e) => setProcessorName(e.target.value)}\n disabled={isReadOnly}\n className={twMerge(\n \"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\",\n isReadOnly\n ? \"cursor-not-allowed bg-muted text-muted-foreground\"\n : \"\",\n )}\n placeholder=\"Enter processor name\"\n />\n </div>\n\n {/* Processor Type Dropdown */}\n <div>\n <label\n htmlFor=\"processor-type\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Type\n </label>\n <select\n id=\"processor-type\"\n value={processorType}\n onChange={(e) => setProcessorType(e.target.value)}\n disabled={isReadOnly}\n className={twMerge(\n \"w-full rounded-md border border-border px-3 py-2 text-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none\",\n isReadOnly ? \"cursor-not-allowed bg-muted\" : \"\",\n )}\n >\n <option value=\"\">Select type...</option>\n <option value=\"analytics\">Analytics</option>\n <option value=\"relational\">Relational Database</option>\n </select>\n </div>\n\n {/* Document Types Field */}\n <div>\n <label\n htmlFor=\"document-types\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Document Types\n </label>\n <div className=\"space-y-2\">\n {!isReadOnly && availableDocumentTypes.length > 0 && (\n <select\n id=\"document-types\"\n value={selectedDocumentType}\n onChange={(e) => {\n const selectedValue = e.target.value;\n if (\n selectedValue &&\n !documentTypes.some((dt) => dt.documentType === selectedValue)\n ) {\n const id = Date.now().toString();\n const newType: DocumentTypeItem = {\n id,\n documentType: selectedValue,\n };\n setDocumentTypes([...documentTypes, newType]);\n onAddDocumentType?.(id, selectedValue);\n }\n setSelectedDocumentType(\"\");\n }}\n className=\"w-full rounded-md border border-border px-3 py-2 text-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none\"\n >\n <option value=\"\">Select a document type to add</option>\n {availableDocumentTypes\n .filter(\n (docType) =>\n !documentTypes.some((dt) => dt.documentType === docType),\n )\n .map((docType) => (\n <option key={docType} value={docType}>\n {docType}\n </option>\n ))}\n </select>\n )}\n <div className=\"space-y-1\">\n {documentTypes.map((type) => (\n <div key={type.id} className=\"flex items-center py-1\">\n <span className=\"text-sm text-foreground\">\n {type.documentType}\n </span>\n {!isReadOnly && (\n <button\n onClick={() => handleRemoveDocumentType(type.id)}\n className=\"ml-2 text-muted-foreground hover:hover-effect focus:outline-none\"\n >\n ×\n </button>\n )}\n </div>\n ))}\n </div>\n </div>\n </div>\n {/* Processor Apps Field */}\n <div>\n <label\n htmlFor=\"processor-apps\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Processor Apps\n </label>\n <div className=\"space-y-2\">\n {!isReadOnly && (\n <>\n {PROCESSOR_APPS.map((processorApp) => (\n <div key={processorApp} className=\"flex gap-1\">\n <input\n type=\"checkbox\"\n name={processorApp}\n id={processorApp}\n checked={processorApps.includes(processorApp)}\n onChange={(event) => {\n const isChecked = event.target.checked;\n if (isChecked) {\n setProcessorApps((processorApps) => [\n ...new Set([...processorApps, processorApp]),\n ]);\n onAddProcessorApp?.(processorApp);\n } else {\n if (processorApps.length > 1) {\n setProcessorApps((processorApps) =>\n processorApps.filter((p) => p !== processorApp),\n );\n onRemoveProcessorApp?.(processorApp);\n }\n }\n }}\n />\n <label htmlFor={processorApp} className=\"text-foreground\">\n {processorApp}\n </label>\n </div>\n ))}\n </>\n )}\n <div className=\"space-y-1\">\n {isReadOnly &&\n processorApps.map((processorApp) => (\n <span key={processorApp} className=\"text-sm text-foreground\">\n {processorApp}\n </span>\n ))}\n </div>\n </div>\n </div>\n {/* Confirm Button - only show if not in read-only mode */}\n {!isReadOnly && (\n <div>\n <button\n onClick={handleConfirm}\n disabled={!canConfirm}\n className=\"rounded-md bg-primary px-4 py-2 text-primary-foreground hover:hover-effect focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-none disabled:disabled-effect\"\n >\n Confirm\n </button>\n </div>\n )}\n </div>\n );\n};\n","import type { PHDocumentEditorConfig } from \"@powerhousedao/reactor-browser\";\n\nexport const editorConfig: PHDocumentEditorConfig = {\n isExternalControlsEnabled: false,\n};\n","import { DocumentToolbar } from \"@powerhousedao/design-system/connect\";\nimport { useSetPHDocumentEditorConfig } from \"@powerhousedao/reactor-browser\";\nimport type {\n ProcessorApp,\n ProcessorApps,\n} from \"@powerhousedao/shared/processors\";\nimport { useCallback } from \"react\";\nimport {\n addDocumentType,\n addProcessorApp,\n removeDocumentType,\n removeProcessorApp,\n setProcessorName,\n setProcessorStatus,\n setProcessorType,\n} from \"../../document-models/processor-module/index.js\";\nimport { useSelectedProcessorModuleDocument } from \"../hooks/useVetraDocument.js\";\nimport { ProcessorEditorForm } from \"./components/ProcessorEditorForm.js\";\nimport { editorConfig } from \"./config.js\";\n\nexport default function Editor() {\n useSetPHDocumentEditorConfig(editorConfig);\n const [document, dispatch] = useSelectedProcessorModuleDocument();\n\n const onConfirm = useCallback(() => {\n // Dispatch all actions at once\n dispatch([setProcessorStatus({ status: \"CONFIRMED\" })]);\n }, [dispatch]);\n\n const onNameChange = useCallback(\n (name: string) => {\n if (name === document.state.global.name) return;\n dispatch(setProcessorName({ name }));\n },\n [document.state.global.name, dispatch],\n );\n\n const onTypeChange = useCallback(\n (type: string) => {\n if (type === document.state.global.type) return;\n dispatch(setProcessorType({ type }));\n },\n [document.state.global.type, dispatch],\n );\n\n const onAddDocumentType = useCallback(\n (id: string, documentType: string) => {\n dispatch(addDocumentType({ id, documentType }));\n },\n [dispatch],\n );\n\n const onRemoveDocumentType = useCallback(\n (id: string) => {\n dispatch(removeDocumentType({ id }));\n },\n [dispatch],\n );\n\n const onAddProcessorApp = useCallback(\n (processorApp: ProcessorApp) => {\n dispatch(addProcessorApp({ processorApp }));\n },\n [dispatch],\n );\n\n const onRemoveProcessorApp = useCallback(\n (processorApp: ProcessorApp) => {\n dispatch(removeProcessorApp({ processorApp }));\n },\n [dispatch],\n );\n\n return (\n <div className=\"bg-background p-6\">\n <DocumentToolbar />\n <ProcessorEditorForm\n onNameChange={onNameChange}\n onTypeChange={onTypeChange}\n onAddDocumentType={onAddDocumentType}\n onRemoveDocumentType={onRemoveDocumentType}\n onAddProcessorApp={onAddProcessorApp}\n onRemoveProcessorApp={onRemoveProcessorApp}\n status={document.state.global.status}\n processorName={document.state.global.name ?? \"\"}\n processorType={document.state.global.type ?? \"\"}\n documentTypes={document.state.global.documentTypes ?? []}\n processorApps={document.state.global.processorApps as ProcessorApps}\n onConfirm={onConfirm}\n />\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  import { b as setAppStatus, g as addDocumentType, h as setDragAndDropEnabled, v as removeDocumentType, x as setDocumentTypes, y as setAppName } from "./utils-B4KdjDnp.js";
2
2
  import { s as useSelectedAppModuleDocument } from "./app-module-dG7ug7Cm.js";
3
3
  import { StatusPill } from "./editors/components/index.js";
4
- import { t as useDebounce } from "./hooks-D_8Uwk1s.js";
4
+ import { t as useDebounce } from "./hooks-Btogj1f0.js";
5
5
  import { useDocumentTypesInSelectedDrive, useSetPHDocumentEditorConfig, useSupportedDocumentTypesInReactor } from "@powerhousedao/reactor-browser";
6
6
  import { useCallback, useEffect, useState } from "react";
7
7
  import { twMerge } from "tailwind-merge";
@@ -197,4 +197,4 @@ function Editor() {
197
197
  //#endregion
198
198
  export { Editor as default };
199
199
 
200
- //# sourceMappingURL=editor-bA5TTxfU.js.map
200
+ //# sourceMappingURL=editor-C3mtuH8G.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"editor-bA5TTxfU.js","names":[],"sources":["../editors/app-editor/components/AppEditorForm.tsx","../editors/app-editor/config.ts","../editors/app-editor/editor.tsx"],"sourcesContent":["import {\n useDocumentTypesInSelectedDrive,\n useSupportedDocumentTypesInReactor,\n} from \"@powerhousedao/reactor-browser\";\nimport {\n addDocumentType,\n removeDocumentType,\n setAppName,\n setAppStatus,\n setDocumentTypes,\n setDragAndDropEnabled,\n} from \"@powerhousedao/vetra/document-models/app-module\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { useSelectedAppModuleDocument } from \"../../../document-models/app-module/index.js\";\nimport { StatusPill } from \"../../components/index.js\";\nimport { useDebounce } from \"../../hooks/index.js\";\n\nconst ALL_IN_DRIVE = \"all-in-drive\";\nconst ALL_IN_REACTOR = \"all-in-reactor\";\nconst ALLOW_ANY = \"allow-any\";\n\nexport const AppEditorForm = () => {\n const [document, dispatch] = useSelectedAppModuleDocument();\n const documentName = document.state.global.name;\n const status = document.state.global.status;\n const isDragAndDropEnabled = document.state.global.isDragAndDropEnabled;\n const allowedDocumentTypes = document.state.global.allowedDocumentTypes;\n const [appName, handleSetAppName] = useState(documentName);\n const [isConfirmed, setIsConfirmed] = useState(status === \"CONFIRMED\");\n const documentTypesInSelectedDrive = useDocumentTypesInSelectedDrive();\n const supportedDocumentTypesInReactor = useSupportedDocumentTypesInReactor();\n const [selectedDocumentTypes, setSelectedDocumentTypes] = useState(\n allowedDocumentTypes ?? [],\n );\n\n // Use the debounce hook for name changes\n\n const onNameChange = useCallback(\n (name: string) => {\n if (name === documentName) return;\n console.log(\"onNameChange\", name);\n dispatch(setAppName({ name }));\n },\n [documentName, dispatch],\n );\n\n useDebounce(appName, onNameChange, 300);\n\n const onConfirm = () => {\n dispatch(setAppStatus({ status: \"CONFIRMED\" }));\n };\n\n const onDragAndDropToggle = (enabled: boolean) => {\n if (enabled === isDragAndDropEnabled) return;\n dispatch(setDragAndDropEnabled({ enabled }));\n };\n\n // Reset confirmation state if status changes back to DRAFT\n useEffect(() => {\n if (status === \"DRAFT\") {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setIsConfirmed(false);\n }\n }, [status]);\n\n // Check if form should be read-only\n const isReadOnly = isConfirmed || status === \"CONFIRMED\";\n\n const handleConfirm = () => {\n if (appName.trim()) {\n setIsConfirmed(true); // Immediate UI update\n onConfirm();\n }\n };\n\n const handleAddDocumentType = (documentType: string) => {\n if (!documentType || selectedDocumentTypes.includes(documentType)) return;\n setSelectedDocumentTypes([...selectedDocumentTypes, documentType]);\n dispatch(addDocumentType({ documentType }));\n };\n\n const handleRemoveDocumentType = (documentType: string) => {\n setSelectedDocumentTypes(\n selectedDocumentTypes.filter((dt) => dt !== documentType),\n );\n dispatch(removeDocumentType({ documentType }));\n };\n\n const handleAddAllDocumentTypesInDrive = () => {\n const newDocumentTypes = [\n ...new Set([\n ...selectedDocumentTypes,\n ...(documentTypesInSelectedDrive ?? []),\n ]),\n ];\n setSelectedDocumentTypes(newDocumentTypes);\n dispatch(setDocumentTypes({ documentTypes: newDocumentTypes }));\n };\n\n const handleAddAllDocumentTypesInReactor = () => {\n const newDocumentTypes = [\n ...new Set([\n ...selectedDocumentTypes,\n ...(supportedDocumentTypesInReactor ?? []),\n ]),\n ];\n setSelectedDocumentTypes(newDocumentTypes);\n dispatch(setDocumentTypes({ documentTypes: newDocumentTypes }));\n };\n\n const handleAllowAnyDocumentType = () => {\n setSelectedDocumentTypes([]);\n dispatch(setDocumentTypes({ documentTypes: [] }));\n };\n\n const handleDocumentTypeSelection = (selectedValue: string) => {\n if (selectedValue === ALL_IN_DRIVE) {\n handleAddAllDocumentTypesInDrive();\n } else if (selectedValue === ALL_IN_REACTOR) {\n handleAddAllDocumentTypesInReactor();\n } else if (selectedValue === ALLOW_ANY) {\n handleAllowAnyDocumentType();\n } else {\n handleAddDocumentType(selectedValue);\n }\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-lg font-medium text-foreground\">\n App Configuration\n </h2>\n <StatusPill\n status={status === \"CONFIRMED\" ? \"confirmed\" : \"draft\"}\n label={status === \"CONFIRMED\" ? \"Confirmed\" : \"Draft\"}\n />\n </div>\n\n {/* App Name Field */}\n <div>\n <label\n htmlFor=\"app-name\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n App Name\n </label>\n <input\n id=\"app-name\"\n type=\"text\"\n value={appName}\n onChange={(e) => handleSetAppName(e.target.value)}\n disabled={isReadOnly}\n className={twMerge(\n \"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\",\n isReadOnly ? \"cursor-not-allowed bg-muted\" : \"\",\n )}\n placeholder=\"Enter app name\"\n />\n </div>\n\n {/* Document Types Field */}\n <div>\n <label\n htmlFor=\"document-types\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Document Types\n </label>\n <div className=\"space-y-2\">\n {!isReadOnly && (\n <select\n onChange={(e) => handleDocumentTypeSelection(e.target.value)}\n className=\"w-full rounded-md border border-border px-3 py-2 text-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none\"\n >\n <option>Select a document type to add</option>\n <option>--- Vetra drive document types ---</option>\n <option value={ALL_IN_DRIVE}>\n Add all document types in Vetra drive\n </option>\n {documentTypesInSelectedDrive\n ?.filter((dt) => !selectedDocumentTypes.includes(dt))\n .map((docType) => (\n <option key={docType} value={docType}>\n {docType}\n </option>\n ))}\n <option>--- Reactor document types ---</option>\n <option value={ALL_IN_REACTOR}>\n Add all document types in Reactor\n </option>\n {supportedDocumentTypesInReactor\n ?.filter((dt) => !selectedDocumentTypes.includes(dt))\n .map((docType) => (\n <option key={docType} value={docType}>\n {docType}\n </option>\n ))}\n <option>--- Allow any document type ---</option>\n <option value={ALLOW_ANY}>Allow any document type</option>\n </select>\n )}\n <div className=\"space-y-1\">\n {selectedDocumentTypes.length > 0 ? (\n selectedDocumentTypes.map((type) => (\n <div key={type} className=\"flex items-center py-1\">\n <span className=\"text-sm text-foreground\">{type}</span>\n {!isReadOnly && (\n <button\n onClick={() => handleRemoveDocumentType(type)}\n className=\"ml-2 text-muted-foreground hover:hover-effect focus:outline-none\"\n >\n ×\n </button>\n )}\n </div>\n ))\n ) : (\n <span className=\"text-sm text-foreground\">All documents (*)</span>\n )}\n </div>\n </div>\n </div>\n\n {/* Drag and Drop Settings */}\n <div>\n <h3 className=\"mb-4 text-base font-medium text-foreground\">\n Drag and Drop Settings\n </h3>\n\n {/* Enable/Disable Switch */}\n <div className=\"mb-4\">\n <label htmlFor=\"drag-and-drop-enabled\" className=\"flex items-center\">\n <input\n id=\"drag-and-drop-enabled\"\n type=\"checkbox\"\n checked={isDragAndDropEnabled}\n onChange={(e) => onDragAndDropToggle(e.target.checked)}\n disabled={isReadOnly}\n className={twMerge(\n \"mr-2 size-4 rounded-sm border-border text-info focus:ring-ring\",\n isReadOnly ? \"cursor-not-allowed\" : \"\",\n )}\n />\n <span className=\"text-sm font-medium text-foreground\">\n Enable drag and drop\n </span>\n </label>\n </div>\n </div>\n\n {/* Confirm Button - only show if not in read-only mode */}\n {!isReadOnly && (\n <div>\n <button\n onClick={handleConfirm}\n disabled={!appName.trim()}\n className=\"rounded-md bg-primary px-4 py-2 text-primary-foreground hover:hover-effect focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-none disabled:disabled-effect\"\n >\n Confirm\n </button>\n </div>\n )}\n </div>\n );\n};\n","import type { PHDocumentEditorConfig } from \"@powerhousedao/reactor-browser\";\n\nexport const editorConfig: PHDocumentEditorConfig = {\n isExternalControlsEnabled: false,\n};\n","import { DocumentToolbar } from \"@powerhousedao/design-system/connect\";\nimport { useSetPHDocumentEditorConfig } from \"@powerhousedao/reactor-browser\";\nimport { AppEditorForm } from \"./components/AppEditorForm.js\";\nimport { editorConfig } from \"./config.js\";\n\nexport default function Editor() {\n useSetPHDocumentEditorConfig(editorConfig);\n\n return (\n <div className=\"bg-background p-6\">\n <DocumentToolbar />\n <AppEditorForm />\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"editor-C3mtuH8G.js","names":[],"sources":["../editors/app-editor/components/AppEditorForm.tsx","../editors/app-editor/config.ts","../editors/app-editor/editor.tsx"],"sourcesContent":["import {\n useDocumentTypesInSelectedDrive,\n useSupportedDocumentTypesInReactor,\n} from \"@powerhousedao/reactor-browser\";\nimport {\n addDocumentType,\n removeDocumentType,\n setAppName,\n setAppStatus,\n setDocumentTypes,\n setDragAndDropEnabled,\n} from \"@powerhousedao/vetra/document-models/app-module\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { useSelectedAppModuleDocument } from \"../../../document-models/app-module/index.js\";\nimport { StatusPill } from \"../../components/index.js\";\nimport { useDebounce } from \"../../hooks/index.js\";\n\nconst ALL_IN_DRIVE = \"all-in-drive\";\nconst ALL_IN_REACTOR = \"all-in-reactor\";\nconst ALLOW_ANY = \"allow-any\";\n\nexport const AppEditorForm = () => {\n const [document, dispatch] = useSelectedAppModuleDocument();\n const documentName = document.state.global.name;\n const status = document.state.global.status;\n const isDragAndDropEnabled = document.state.global.isDragAndDropEnabled;\n const allowedDocumentTypes = document.state.global.allowedDocumentTypes;\n const [appName, handleSetAppName] = useState(documentName);\n const [isConfirmed, setIsConfirmed] = useState(status === \"CONFIRMED\");\n const documentTypesInSelectedDrive = useDocumentTypesInSelectedDrive();\n const supportedDocumentTypesInReactor = useSupportedDocumentTypesInReactor();\n const [selectedDocumentTypes, setSelectedDocumentTypes] = useState(\n allowedDocumentTypes ?? [],\n );\n\n // Use the debounce hook for name changes\n\n const onNameChange = useCallback(\n (name: string) => {\n if (name === documentName) return;\n console.log(\"onNameChange\", name);\n dispatch(setAppName({ name }));\n },\n [documentName, dispatch],\n );\n\n useDebounce(appName, onNameChange, 300);\n\n const onConfirm = () => {\n dispatch(setAppStatus({ status: \"CONFIRMED\" }));\n };\n\n const onDragAndDropToggle = (enabled: boolean) => {\n if (enabled === isDragAndDropEnabled) return;\n dispatch(setDragAndDropEnabled({ enabled }));\n };\n\n // Reset confirmation state if status changes back to DRAFT\n useEffect(() => {\n if (status === \"DRAFT\") {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setIsConfirmed(false);\n }\n }, [status]);\n\n // Check if form should be read-only\n const isReadOnly = isConfirmed || status === \"CONFIRMED\";\n\n const handleConfirm = () => {\n if (appName.trim()) {\n setIsConfirmed(true); // Immediate UI update\n onConfirm();\n }\n };\n\n const handleAddDocumentType = (documentType: string) => {\n if (!documentType || selectedDocumentTypes.includes(documentType)) return;\n setSelectedDocumentTypes([...selectedDocumentTypes, documentType]);\n dispatch(addDocumentType({ documentType }));\n };\n\n const handleRemoveDocumentType = (documentType: string) => {\n setSelectedDocumentTypes(\n selectedDocumentTypes.filter((dt) => dt !== documentType),\n );\n dispatch(removeDocumentType({ documentType }));\n };\n\n const handleAddAllDocumentTypesInDrive = () => {\n const newDocumentTypes = [\n ...new Set([\n ...selectedDocumentTypes,\n ...(documentTypesInSelectedDrive ?? []),\n ]),\n ];\n setSelectedDocumentTypes(newDocumentTypes);\n dispatch(setDocumentTypes({ documentTypes: newDocumentTypes }));\n };\n\n const handleAddAllDocumentTypesInReactor = () => {\n const newDocumentTypes = [\n ...new Set([\n ...selectedDocumentTypes,\n ...(supportedDocumentTypesInReactor ?? []),\n ]),\n ];\n setSelectedDocumentTypes(newDocumentTypes);\n dispatch(setDocumentTypes({ documentTypes: newDocumentTypes }));\n };\n\n const handleAllowAnyDocumentType = () => {\n setSelectedDocumentTypes([]);\n dispatch(setDocumentTypes({ documentTypes: [] }));\n };\n\n const handleDocumentTypeSelection = (selectedValue: string) => {\n if (selectedValue === ALL_IN_DRIVE) {\n handleAddAllDocumentTypesInDrive();\n } else if (selectedValue === ALL_IN_REACTOR) {\n handleAddAllDocumentTypesInReactor();\n } else if (selectedValue === ALLOW_ANY) {\n handleAllowAnyDocumentType();\n } else {\n handleAddDocumentType(selectedValue);\n }\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-lg font-medium text-foreground\">\n App Configuration\n </h2>\n <StatusPill\n status={status === \"CONFIRMED\" ? \"confirmed\" : \"draft\"}\n label={status === \"CONFIRMED\" ? \"Confirmed\" : \"Draft\"}\n />\n </div>\n\n {/* App Name Field */}\n <div>\n <label\n htmlFor=\"app-name\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n App Name\n </label>\n <input\n id=\"app-name\"\n type=\"text\"\n value={appName}\n onChange={(e) => handleSetAppName(e.target.value)}\n disabled={isReadOnly}\n className={twMerge(\n \"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\",\n isReadOnly ? \"cursor-not-allowed bg-muted\" : \"\",\n )}\n placeholder=\"Enter app name\"\n />\n </div>\n\n {/* Document Types Field */}\n <div>\n <label\n htmlFor=\"document-types\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Document Types\n </label>\n <div className=\"space-y-2\">\n {!isReadOnly && (\n <select\n onChange={(e) => handleDocumentTypeSelection(e.target.value)}\n className=\"w-full rounded-md border border-border px-3 py-2 text-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none\"\n >\n <option>Select a document type to add</option>\n <option>--- Vetra drive document types ---</option>\n <option value={ALL_IN_DRIVE}>\n Add all document types in Vetra drive\n </option>\n {documentTypesInSelectedDrive\n ?.filter((dt) => !selectedDocumentTypes.includes(dt))\n .map((docType) => (\n <option key={docType} value={docType}>\n {docType}\n </option>\n ))}\n <option>--- Reactor document types ---</option>\n <option value={ALL_IN_REACTOR}>\n Add all document types in Reactor\n </option>\n {supportedDocumentTypesInReactor\n ?.filter((dt) => !selectedDocumentTypes.includes(dt))\n .map((docType) => (\n <option key={docType} value={docType}>\n {docType}\n </option>\n ))}\n <option>--- Allow any document type ---</option>\n <option value={ALLOW_ANY}>Allow any document type</option>\n </select>\n )}\n <div className=\"space-y-1\">\n {selectedDocumentTypes.length > 0 ? (\n selectedDocumentTypes.map((type) => (\n <div key={type} className=\"flex items-center py-1\">\n <span className=\"text-sm text-foreground\">{type}</span>\n {!isReadOnly && (\n <button\n onClick={() => handleRemoveDocumentType(type)}\n className=\"ml-2 text-muted-foreground hover:hover-effect focus:outline-none\"\n >\n ×\n </button>\n )}\n </div>\n ))\n ) : (\n <span className=\"text-sm text-foreground\">All documents (*)</span>\n )}\n </div>\n </div>\n </div>\n\n {/* Drag and Drop Settings */}\n <div>\n <h3 className=\"mb-4 text-base font-medium text-foreground\">\n Drag and Drop Settings\n </h3>\n\n {/* Enable/Disable Switch */}\n <div className=\"mb-4\">\n <label htmlFor=\"drag-and-drop-enabled\" className=\"flex items-center\">\n <input\n id=\"drag-and-drop-enabled\"\n type=\"checkbox\"\n checked={isDragAndDropEnabled}\n onChange={(e) => onDragAndDropToggle(e.target.checked)}\n disabled={isReadOnly}\n className={twMerge(\n \"mr-2 size-4 rounded-sm border-border text-info focus:ring-ring\",\n isReadOnly ? \"cursor-not-allowed\" : \"\",\n )}\n />\n <span className=\"text-sm font-medium text-foreground\">\n Enable drag and drop\n </span>\n </label>\n </div>\n </div>\n\n {/* Confirm Button - only show if not in read-only mode */}\n {!isReadOnly && (\n <div>\n <button\n onClick={handleConfirm}\n disabled={!appName.trim()}\n className=\"rounded-md bg-primary px-4 py-2 text-primary-foreground hover:hover-effect focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-none disabled:disabled-effect\"\n >\n Confirm\n </button>\n </div>\n )}\n </div>\n );\n};\n","import type { PHDocumentEditorConfig } from \"@powerhousedao/reactor-browser\";\n\nexport const editorConfig: PHDocumentEditorConfig = {\n isExternalControlsEnabled: false,\n};\n","import { DocumentToolbar } from \"@powerhousedao/design-system/connect\";\nimport { useSetPHDocumentEditorConfig } from \"@powerhousedao/reactor-browser\";\nimport { AppEditorForm } from \"./components/AppEditorForm.js\";\nimport { editorConfig } from \"./config.js\";\n\nexport default function Editor() {\n useSetPHDocumentEditorConfig(editorConfig);\n\n return (\n <div className=\"bg-background p-6\">\n <DocumentToolbar />\n <AppEditorForm />\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { C as setPackageCategory, D as setPackageNpmUrl, E as setPackageName, S as setPackageAuthorWebsite, T as setPackageGithubUrl, _ as addPackageKeyword, w as setPackageDescription, x as setPackageAuthorName, y as removePackageKeyword } from "./module-1hr_ne9w.js";
2
- import { t as useDebounce } from "./hooks-D_8Uwk1s.js";
2
+ import { t as useDebounce } from "./hooks-Btogj1f0.js";
3
3
  import { t as useSelectedDriveVetraPackage } from "./useVetraDocument-BpPD6DKR.js";
4
4
  import { useSetPHDocumentEditorConfig } from "@powerhousedao/reactor-browser";
5
5
  import { useCallback, useState } from "react";
@@ -304,4 +304,4 @@ function Editor(props) {
304
304
  //#endregion
305
305
  export { Editor as default };
306
306
 
307
- //# sourceMappingURL=editor-De5XaIXa.js.map
307
+ //# sourceMappingURL=editor-C7wFAvfQ.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"editor-De5XaIXa.js","names":[],"sources":["../editors/vetra-package/components/MetaForm.tsx","../editors/vetra-package/config.ts","../editors/vetra-package/editor.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport type { Keyword } from \"../../../document-models/vetra-package/index.js\";\nimport { useDebounce } from \"../../hooks/index.js\";\n\nexport interface MetaFormProps {\n name: string;\n description: string;\n category: string;\n publisher: string;\n publisherUrl: string;\n githubRepository: string;\n npmPackage: string;\n keywords: Keyword[];\n onNameChange?: (name: string) => void;\n onDescriptionChange?: (description: string) => void;\n onCategoryChange?: (category: string) => void;\n onPublisherChange?: (publisher: string) => void;\n onPublisherUrlChange?: (publisherUrl: string) => void;\n onGithubRepositoryChange?: (githubRepository: string) => void;\n onNpmPackageChange?: (npmPackage: string) => void;\n onAddKeyword?: (keyword: { id: string; label: string }) => void;\n onRemoveKeyword?: (id: string) => void;\n}\n\nexport const MetaForm: React.FC<MetaFormProps> = (props) => {\n const {\n name: initialName,\n description: initialDescription,\n category: initialCategory,\n publisher: initialPublisher,\n publisherUrl: initialPublisherUrl,\n githubRepository: initialGithubRepository,\n npmPackage: initialNpmPackage,\n keywords: initialKeywords,\n onNameChange,\n onDescriptionChange,\n onCategoryChange,\n onPublisherChange,\n onPublisherUrlChange,\n onGithubRepositoryChange,\n onNpmPackageChange,\n onAddKeyword,\n onRemoveKeyword,\n } = props;\n\n const [name, setName] = useState(initialName);\n const [description, setDescription] = useState(initialDescription);\n const [category, setCategory] = useState(initialCategory);\n const [publisher, setPublisher] = useState(initialPublisher);\n const [publisherUrl, setPublisherUrl] = useState(initialPublisherUrl);\n const [githubRepository, setGithubRepository] = useState(\n initialGithubRepository,\n );\n const [npmPackage, setNpmPackage] = useState(initialNpmPackage);\n\n // Keywords state\n const [keywords, setKeywords] = useState<Keyword[]>(initialKeywords);\n const [keywordInput, setKeywordInput] = useState(\"\");\n\n // Use the debounce hook with callbacks\n useDebounce(name, onNameChange, 300);\n useDebounce(description, onDescriptionChange, 300);\n useDebounce(publisher, onPublisherChange, 300);\n useDebounce(publisherUrl, onPublisherUrlChange, 300);\n useDebounce(githubRepository, onGithubRepositoryChange, 300);\n useDebounce(npmPackage, onNpmPackageChange, 300);\n\n return (\n <div className=\"grid grid-cols-1 gap-6 p-6 lg:grid-cols-3\">\n {/* Left Column */}\n <div className=\"space-y-6\">\n {/* Name Field */}\n <div>\n <label\n htmlFor=\"package-name\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Name\n </label>\n <input\n id=\"package-name\"\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n className=\"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\"\n />\n </div>\n\n {/* Description Field */}\n <div>\n <label\n htmlFor=\"package-description\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Description\n </label>\n <textarea\n id=\"package-description\"\n rows={6}\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n className=\"w-full resize-none rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\"\n />\n </div>\n </div>\n\n {/* Middle Column */}\n <div className=\"space-y-6\">\n {/* Category Field */}\n <div>\n <label\n htmlFor=\"package-category\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Category\n </label>\n <select\n id=\"package-category\"\n value={category}\n onChange={(e) => {\n const newValue = e.target.value;\n setCategory(newValue);\n onCategoryChange?.(newValue);\n }}\n className=\"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\"\n >\n <option value=\"\">Not selected</option>\n <option value=\"Productivity\">Productivity</option>\n <option value=\"Governance\">Governance</option>\n <option value=\"Project Management\">Project Management</option>\n <option value=\"Finance\">Finance</option>\n <option value=\"Legal\">Legal</option>\n <option value=\"People & Culture\">People & Culture</option>\n <option value=\"Engineering\">Engineering</option>\n </select>\n </div>\n\n {/* Publisher Field */}\n <div>\n <label\n htmlFor=\"package-publisher\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Publisher\n </label>\n <input\n id=\"package-publisher\"\n type=\"text\"\n value={publisher}\n onChange={(e) => setPublisher(e.target.value)}\n className=\"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\"\n />\n </div>\n\n {/* Publisher URL Field */}\n <div>\n <label\n htmlFor=\"package-publisher-url\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Publisher URL\n </label>\n <input\n id=\"package-publisher-url\"\n type=\"text\"\n value={publisherUrl}\n onChange={(e) => setPublisherUrl(e.target.value)}\n className=\"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\"\n />\n </div>\n\n {/* Keywords Field */}\n <div>\n <label\n htmlFor=\"package-keywords\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Keywords\n </label>\n <div className=\"space-y-2\">\n <input\n id=\"package-keywords\"\n type=\"text\"\n value={keywordInput}\n onChange={(e) => setKeywordInput(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && keywordInput.trim()) {\n e.preventDefault();\n const newKeyword = {\n id: Date.now().toString(), // Generate a unique ID\n label: keywordInput.trim(),\n };\n setKeywords([...keywords, newKeyword]);\n onAddKeyword?.(newKeyword);\n setKeywordInput(\"\");\n }\n }}\n placeholder=\"Type a keyword and press Enter\"\n className=\"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\"\n />\n <div className=\"flex min-h-[80px] flex-wrap gap-2 rounded-md border border-border p-3\">\n {keywords.map((keyword) => (\n <span\n key={keyword.id}\n className=\"inline-flex items-center rounded-sm border border-info bg-info/10 px-2 py-0.5 text-xs text-info\"\n >\n {keyword.label}\n <button\n onClick={() => {\n setKeywords(keywords.filter((k) => k.id !== keyword.id));\n onRemoveKeyword?.(keyword.id);\n }}\n className=\"ml-1 text-info hover:hover-effect focus:outline-none\"\n >\n ×\n </button>\n </span>\n ))}\n </div>\n </div>\n </div>\n </div>\n\n {/* Right Column */}\n <div className=\"space-y-6\">\n {/* Github Repository Field */}\n <div>\n <label\n htmlFor=\"package-github\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Github Repository\n </label>\n <input\n id=\"package-github\"\n type=\"text\"\n value={githubRepository}\n onChange={(e) => setGithubRepository(e.target.value)}\n className=\"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\"\n />\n </div>\n\n {/* NPM-package Field */}\n <div>\n <label\n htmlFor=\"package-npm\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n NPM-package\n </label>\n <input\n id=\"package-npm\"\n type=\"text\"\n value={npmPackage}\n onChange={(e) => setNpmPackage(e.target.value)}\n className=\"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\"\n />\n </div>\n\n {/* Version Field */}\n <div>\n <label\n htmlFor=\"package-version\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Version\n </label>\n <input\n id=\"package-version\"\n type=\"text\"\n placeholder=\"1.0.0-dev\"\n disabled\n className=\"w-full cursor-not-allowed rounded-md border border-border bg-background px-3 py-2 text-foreground placeholder:text-muted-foreground disabled:disabled-effect\"\n />\n </div>\n\n {/* License Field */}\n <div>\n <label\n htmlFor=\"package-license\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n License\n </label>\n <input\n id=\"package-license\"\n type=\"text\"\n placeholder=\"AGPL-3.0-only\"\n disabled\n className=\"w-full cursor-not-allowed rounded-md border border-border bg-background px-3 py-2 text-foreground placeholder:text-muted-foreground disabled:disabled-effect\"\n />\n </div>\n\n {/* Install with Field */}\n <div>\n <label\n htmlFor=\"package-install\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Install with:\n </label>\n <input\n id=\"package-install\"\n type=\"text\"\n placeholder=\"@powerhousedao/todo-demo-package\"\n disabled\n className=\"w-full cursor-not-allowed rounded-md border border-border bg-background px-3 py-2 text-foreground placeholder:text-muted-foreground disabled:disabled-effect\"\n />\n </div>\n </div>\n </div>\n );\n};\n","import type { PHDocumentEditorConfig } from \"@powerhousedao/reactor-browser\";\n\nexport const editorConfig: PHDocumentEditorConfig = {\n isExternalControlsEnabled: false,\n};\n","import { DocumentToolbar } from \"@powerhousedao/design-system/connect\";\nimport { useSetPHDocumentEditorConfig } from \"@powerhousedao/reactor-browser\";\nimport { useCallback } from \"react\";\nimport {\n addPackageKeyword,\n removePackageKeyword,\n setPackageAuthorName,\n setPackageAuthorWebsite,\n setPackageCategory,\n setPackageDescription,\n setPackageGithubUrl,\n setPackageName,\n setPackageNpmUrl,\n} from \"../../document-models/vetra-package/index.js\";\nimport { useSelectedDriveVetraPackage } from \"../hooks/useVetraDocument.js\";\nimport { MetaForm } from \"./components/MetaForm.js\";\nimport { editorConfig } from \"./config.js\";\n\nexport type EditorProps = {\n displayToolbar?: boolean;\n};\n\nexport default function Editor(props: EditorProps) {\n const { displayToolbar = true } = props;\n useSetPHDocumentEditorConfig(editorConfig);\n const [document, dispatch] = useSelectedDriveVetraPackage();\n\n const onNameChange = useCallback(\n (name: string) => {\n if (!document.state.global.name && !name) return;\n if (name === document.state.global.name) return;\n\n dispatch(setPackageName({ name }));\n },\n [document.state.global.name, dispatch],\n );\n\n const onDescriptionChange = useCallback(\n (description: string) => {\n if (!document.state.global.description && !description) return;\n if (description === document.state.global.description) return;\n\n dispatch(setPackageDescription({ description }));\n },\n [document.state.global.description, dispatch],\n );\n\n const onCategoryChange = useCallback(\n (category: string) => {\n if (!document.state.global.category && !category) return;\n if (category === document.state.global.category) return;\n\n dispatch(setPackageCategory({ category }));\n },\n [document.state.global.category, dispatch],\n );\n\n const onPublisherChange = useCallback(\n (name: string) => {\n if (!document.state.global.author.name && !name) return;\n if (name === document.state.global.author.name) return;\n\n dispatch(setPackageAuthorName({ name }));\n },\n [document.state.global.author.name, dispatch],\n );\n\n const onPublisherUrlChange = useCallback(\n (website: string) => {\n if (!document.state.global.author.website && !website) return;\n if (website === document.state.global.author.website) return;\n\n dispatch(setPackageAuthorWebsite({ website }));\n },\n [document.state.global.author.website, dispatch],\n );\n\n const onGithubRepositoryChange = useCallback(\n (url: string) => {\n if (!document.state.global.githubUrl && !url) return;\n if (url === document.state.global.githubUrl) return;\n\n dispatch(setPackageGithubUrl({ url }));\n },\n [document.state.global.githubUrl, dispatch],\n );\n\n const onNpmPackageChange = useCallback(\n (url: string) => {\n if (!document.state.global.npmUrl && !url) return;\n if (url === document.state.global.npmUrl) return;\n\n dispatch(setPackageNpmUrl({ url }));\n },\n [document.state.global.npmUrl, dispatch],\n );\n\n const onAddKeyword = useCallback(\n (keyword: { id: string; label: string }) => {\n dispatch(addPackageKeyword(keyword));\n },\n [dispatch],\n );\n\n const onRemoveKeyword = useCallback(\n (id: string) => {\n dispatch(removePackageKeyword({ id }));\n },\n [dispatch],\n );\n\n return (\n <div className=\"bg-background p-6\">\n {displayToolbar && <DocumentToolbar />}\n <MetaForm\n name={document.state.global.name ?? \"\"}\n description={document.state.global.description ?? \"\"}\n category={document.state.global.category ?? \"\"}\n publisher={document.state.global.author.name ?? \"\"}\n publisherUrl={document.state.global.author.website ?? \"\"}\n githubRepository={document.state.global.githubUrl ?? \"\"}\n npmPackage={document.state.global.npmUrl ?? \"\"}\n keywords={document.state.global.keywords}\n onNameChange={onNameChange}\n onDescriptionChange={onDescriptionChange}\n onCategoryChange={onCategoryChange}\n onPublisherChange={onPublisherChange}\n onPublisherUrlChange={onPublisherUrlChange}\n onGithubRepositoryChange={onGithubRepositoryChange}\n onNpmPackageChange={onNpmPackageChange}\n onAddKeyword={onAddKeyword}\n onRemoveKeyword={onRemoveKeyword}\n />\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"editor-C7wFAvfQ.js","names":[],"sources":["../editors/vetra-package/components/MetaForm.tsx","../editors/vetra-package/config.ts","../editors/vetra-package/editor.tsx"],"sourcesContent":["import { useState } from \"react\";\nimport type { Keyword } from \"../../../document-models/vetra-package/index.js\";\nimport { useDebounce } from \"../../hooks/index.js\";\n\nexport interface MetaFormProps {\n name: string;\n description: string;\n category: string;\n publisher: string;\n publisherUrl: string;\n githubRepository: string;\n npmPackage: string;\n keywords: Keyword[];\n onNameChange?: (name: string) => void;\n onDescriptionChange?: (description: string) => void;\n onCategoryChange?: (category: string) => void;\n onPublisherChange?: (publisher: string) => void;\n onPublisherUrlChange?: (publisherUrl: string) => void;\n onGithubRepositoryChange?: (githubRepository: string) => void;\n onNpmPackageChange?: (npmPackage: string) => void;\n onAddKeyword?: (keyword: { id: string; label: string }) => void;\n onRemoveKeyword?: (id: string) => void;\n}\n\nexport const MetaForm: React.FC<MetaFormProps> = (props) => {\n const {\n name: initialName,\n description: initialDescription,\n category: initialCategory,\n publisher: initialPublisher,\n publisherUrl: initialPublisherUrl,\n githubRepository: initialGithubRepository,\n npmPackage: initialNpmPackage,\n keywords: initialKeywords,\n onNameChange,\n onDescriptionChange,\n onCategoryChange,\n onPublisherChange,\n onPublisherUrlChange,\n onGithubRepositoryChange,\n onNpmPackageChange,\n onAddKeyword,\n onRemoveKeyword,\n } = props;\n\n const [name, setName] = useState(initialName);\n const [description, setDescription] = useState(initialDescription);\n const [category, setCategory] = useState(initialCategory);\n const [publisher, setPublisher] = useState(initialPublisher);\n const [publisherUrl, setPublisherUrl] = useState(initialPublisherUrl);\n const [githubRepository, setGithubRepository] = useState(\n initialGithubRepository,\n );\n const [npmPackage, setNpmPackage] = useState(initialNpmPackage);\n\n // Keywords state\n const [keywords, setKeywords] = useState<Keyword[]>(initialKeywords);\n const [keywordInput, setKeywordInput] = useState(\"\");\n\n // Use the debounce hook with callbacks\n useDebounce(name, onNameChange, 300);\n useDebounce(description, onDescriptionChange, 300);\n useDebounce(publisher, onPublisherChange, 300);\n useDebounce(publisherUrl, onPublisherUrlChange, 300);\n useDebounce(githubRepository, onGithubRepositoryChange, 300);\n useDebounce(npmPackage, onNpmPackageChange, 300);\n\n return (\n <div className=\"grid grid-cols-1 gap-6 p-6 lg:grid-cols-3\">\n {/* Left Column */}\n <div className=\"space-y-6\">\n {/* Name Field */}\n <div>\n <label\n htmlFor=\"package-name\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Name\n </label>\n <input\n id=\"package-name\"\n type=\"text\"\n value={name}\n onChange={(e) => setName(e.target.value)}\n className=\"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\"\n />\n </div>\n\n {/* Description Field */}\n <div>\n <label\n htmlFor=\"package-description\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Description\n </label>\n <textarea\n id=\"package-description\"\n rows={6}\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n className=\"w-full resize-none rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\"\n />\n </div>\n </div>\n\n {/* Middle Column */}\n <div className=\"space-y-6\">\n {/* Category Field */}\n <div>\n <label\n htmlFor=\"package-category\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Category\n </label>\n <select\n id=\"package-category\"\n value={category}\n onChange={(e) => {\n const newValue = e.target.value;\n setCategory(newValue);\n onCategoryChange?.(newValue);\n }}\n className=\"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\"\n >\n <option value=\"\">Not selected</option>\n <option value=\"Productivity\">Productivity</option>\n <option value=\"Governance\">Governance</option>\n <option value=\"Project Management\">Project Management</option>\n <option value=\"Finance\">Finance</option>\n <option value=\"Legal\">Legal</option>\n <option value=\"People & Culture\">People & Culture</option>\n <option value=\"Engineering\">Engineering</option>\n </select>\n </div>\n\n {/* Publisher Field */}\n <div>\n <label\n htmlFor=\"package-publisher\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Publisher\n </label>\n <input\n id=\"package-publisher\"\n type=\"text\"\n value={publisher}\n onChange={(e) => setPublisher(e.target.value)}\n className=\"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\"\n />\n </div>\n\n {/* Publisher URL Field */}\n <div>\n <label\n htmlFor=\"package-publisher-url\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Publisher URL\n </label>\n <input\n id=\"package-publisher-url\"\n type=\"text\"\n value={publisherUrl}\n onChange={(e) => setPublisherUrl(e.target.value)}\n className=\"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\"\n />\n </div>\n\n {/* Keywords Field */}\n <div>\n <label\n htmlFor=\"package-keywords\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Keywords\n </label>\n <div className=\"space-y-2\">\n <input\n id=\"package-keywords\"\n type=\"text\"\n value={keywordInput}\n onChange={(e) => setKeywordInput(e.target.value)}\n onKeyDown={(e) => {\n if (e.key === \"Enter\" && keywordInput.trim()) {\n e.preventDefault();\n const newKeyword = {\n id: Date.now().toString(), // Generate a unique ID\n label: keywordInput.trim(),\n };\n setKeywords([...keywords, newKeyword]);\n onAddKeyword?.(newKeyword);\n setKeywordInput(\"\");\n }\n }}\n placeholder=\"Type a keyword and press Enter\"\n className=\"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\"\n />\n <div className=\"flex min-h-[80px] flex-wrap gap-2 rounded-md border border-border p-3\">\n {keywords.map((keyword) => (\n <span\n key={keyword.id}\n className=\"inline-flex items-center rounded-sm border border-info bg-info/10 px-2 py-0.5 text-xs text-info\"\n >\n {keyword.label}\n <button\n onClick={() => {\n setKeywords(keywords.filter((k) => k.id !== keyword.id));\n onRemoveKeyword?.(keyword.id);\n }}\n className=\"ml-1 text-info hover:hover-effect focus:outline-none\"\n >\n ×\n </button>\n </span>\n ))}\n </div>\n </div>\n </div>\n </div>\n\n {/* Right Column */}\n <div className=\"space-y-6\">\n {/* Github Repository Field */}\n <div>\n <label\n htmlFor=\"package-github\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Github Repository\n </label>\n <input\n id=\"package-github\"\n type=\"text\"\n value={githubRepository}\n onChange={(e) => setGithubRepository(e.target.value)}\n className=\"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\"\n />\n </div>\n\n {/* NPM-package Field */}\n <div>\n <label\n htmlFor=\"package-npm\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n NPM-package\n </label>\n <input\n id=\"package-npm\"\n type=\"text\"\n value={npmPackage}\n onChange={(e) => setNpmPackage(e.target.value)}\n className=\"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\"\n />\n </div>\n\n {/* Version Field */}\n <div>\n <label\n htmlFor=\"package-version\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Version\n </label>\n <input\n id=\"package-version\"\n type=\"text\"\n placeholder=\"1.0.0-dev\"\n disabled\n className=\"w-full cursor-not-allowed rounded-md border border-border bg-background px-3 py-2 text-foreground placeholder:text-muted-foreground disabled:disabled-effect\"\n />\n </div>\n\n {/* License Field */}\n <div>\n <label\n htmlFor=\"package-license\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n License\n </label>\n <input\n id=\"package-license\"\n type=\"text\"\n placeholder=\"AGPL-3.0-only\"\n disabled\n className=\"w-full cursor-not-allowed rounded-md border border-border bg-background px-3 py-2 text-foreground placeholder:text-muted-foreground disabled:disabled-effect\"\n />\n </div>\n\n {/* Install with Field */}\n <div>\n <label\n htmlFor=\"package-install\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Install with:\n </label>\n <input\n id=\"package-install\"\n type=\"text\"\n placeholder=\"@powerhousedao/todo-demo-package\"\n disabled\n className=\"w-full cursor-not-allowed rounded-md border border-border bg-background px-3 py-2 text-foreground placeholder:text-muted-foreground disabled:disabled-effect\"\n />\n </div>\n </div>\n </div>\n );\n};\n","import type { PHDocumentEditorConfig } from \"@powerhousedao/reactor-browser\";\n\nexport const editorConfig: PHDocumentEditorConfig = {\n isExternalControlsEnabled: false,\n};\n","import { DocumentToolbar } from \"@powerhousedao/design-system/connect\";\nimport { useSetPHDocumentEditorConfig } from \"@powerhousedao/reactor-browser\";\nimport { useCallback } from \"react\";\nimport {\n addPackageKeyword,\n removePackageKeyword,\n setPackageAuthorName,\n setPackageAuthorWebsite,\n setPackageCategory,\n setPackageDescription,\n setPackageGithubUrl,\n setPackageName,\n setPackageNpmUrl,\n} from \"../../document-models/vetra-package/index.js\";\nimport { useSelectedDriveVetraPackage } from \"../hooks/useVetraDocument.js\";\nimport { MetaForm } from \"./components/MetaForm.js\";\nimport { editorConfig } from \"./config.js\";\n\nexport type EditorProps = {\n displayToolbar?: boolean;\n};\n\nexport default function Editor(props: EditorProps) {\n const { displayToolbar = true } = props;\n useSetPHDocumentEditorConfig(editorConfig);\n const [document, dispatch] = useSelectedDriveVetraPackage();\n\n const onNameChange = useCallback(\n (name: string) => {\n if (!document.state.global.name && !name) return;\n if (name === document.state.global.name) return;\n\n dispatch(setPackageName({ name }));\n },\n [document.state.global.name, dispatch],\n );\n\n const onDescriptionChange = useCallback(\n (description: string) => {\n if (!document.state.global.description && !description) return;\n if (description === document.state.global.description) return;\n\n dispatch(setPackageDescription({ description }));\n },\n [document.state.global.description, dispatch],\n );\n\n const onCategoryChange = useCallback(\n (category: string) => {\n if (!document.state.global.category && !category) return;\n if (category === document.state.global.category) return;\n\n dispatch(setPackageCategory({ category }));\n },\n [document.state.global.category, dispatch],\n );\n\n const onPublisherChange = useCallback(\n (name: string) => {\n if (!document.state.global.author.name && !name) return;\n if (name === document.state.global.author.name) return;\n\n dispatch(setPackageAuthorName({ name }));\n },\n [document.state.global.author.name, dispatch],\n );\n\n const onPublisherUrlChange = useCallback(\n (website: string) => {\n if (!document.state.global.author.website && !website) return;\n if (website === document.state.global.author.website) return;\n\n dispatch(setPackageAuthorWebsite({ website }));\n },\n [document.state.global.author.website, dispatch],\n );\n\n const onGithubRepositoryChange = useCallback(\n (url: string) => {\n if (!document.state.global.githubUrl && !url) return;\n if (url === document.state.global.githubUrl) return;\n\n dispatch(setPackageGithubUrl({ url }));\n },\n [document.state.global.githubUrl, dispatch],\n );\n\n const onNpmPackageChange = useCallback(\n (url: string) => {\n if (!document.state.global.npmUrl && !url) return;\n if (url === document.state.global.npmUrl) return;\n\n dispatch(setPackageNpmUrl({ url }));\n },\n [document.state.global.npmUrl, dispatch],\n );\n\n const onAddKeyword = useCallback(\n (keyword: { id: string; label: string }) => {\n dispatch(addPackageKeyword(keyword));\n },\n [dispatch],\n );\n\n const onRemoveKeyword = useCallback(\n (id: string) => {\n dispatch(removePackageKeyword({ id }));\n },\n [dispatch],\n );\n\n return (\n <div className=\"bg-background p-6\">\n {displayToolbar && <DocumentToolbar />}\n <MetaForm\n name={document.state.global.name ?? \"\"}\n description={document.state.global.description ?? \"\"}\n category={document.state.global.category ?? \"\"}\n publisher={document.state.global.author.name ?? \"\"}\n publisherUrl={document.state.global.author.website ?? \"\"}\n githubRepository={document.state.global.githubUrl ?? \"\"}\n npmPackage={document.state.global.npmUrl ?? \"\"}\n keywords={document.state.global.keywords}\n onNameChange={onNameChange}\n onDescriptionChange={onDescriptionChange}\n onCategoryChange={onCategoryChange}\n onPublisherChange={onPublisherChange}\n onPublisherUrlChange={onPublisherUrlChange}\n onGithubRepositoryChange={onGithubRepositoryChange}\n onNpmPackageChange={onNpmPackageChange}\n onAddKeyword={onAddKeyword}\n onRemoveKeyword={onRemoveKeyword}\n />\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { g as setSubgraphStatus, h as setSubgraphName } from "./utils-BiV3cs9Y.js";
2
2
  import { StatusPill } from "./editors/components/index.js";
3
- import { t as useDebounce } from "./hooks-D_8Uwk1s.js";
3
+ import { t as useDebounce } from "./hooks-Btogj1f0.js";
4
4
  import { r as useSelectedSubgraphModuleDocument } from "./useVetraDocument-BpPD6DKR.js";
5
5
  import { useSetPHDocumentEditorConfig } from "@powerhousedao/reactor-browser";
6
6
  import { useCallback, useEffect, useState } from "react";
@@ -88,4 +88,4 @@ function Editor() {
88
88
  //#endregion
89
89
  export { Editor as default };
90
90
 
91
- //# sourceMappingURL=editor-fNaLqnMc.js.map
91
+ //# sourceMappingURL=editor-CxRPBLK_.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"editor-fNaLqnMc.js","names":[],"sources":["../editors/subgraph-editor/components/SubgraphEditorForm.tsx","../editors/subgraph-editor/config.ts","../editors/subgraph-editor/editor.tsx"],"sourcesContent":["import { useEffect, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { StatusPill } from \"../../components/index.js\";\nimport { useDebounce } from \"../../hooks/index.js\";\n\nexport interface SubgraphEditorFormProps {\n subgraphName?: string;\n status?: string;\n onNameChange?: (name: string) => void;\n onConfirm?: () => void;\n}\n\nexport const SubgraphEditorForm: React.FC<SubgraphEditorFormProps> = ({\n subgraphName: initialSubgraphName = \"\",\n status = \"DRAFT\",\n onNameChange,\n onConfirm,\n}) => {\n const [subgraphName, setSubgraphName] = useState(initialSubgraphName);\n const [isConfirmed, setIsConfirmed] = useState(false);\n\n // Use the debounce hook for name changes\n useDebounce(subgraphName, onNameChange, 300);\n\n // Update local state when initialSubgraphName changes\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setSubgraphName(initialSubgraphName);\n }, [initialSubgraphName]);\n\n // Reset confirmation state if status changes back to DRAFT\n useEffect(() => {\n if (status === \"DRAFT\") {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setIsConfirmed(false);\n }\n }, [status]);\n\n // Check if form should be read-only\n const isReadOnly = isConfirmed || status === \"CONFIRMED\";\n\n const handleConfirm = () => {\n if (subgraphName.trim()) {\n setIsConfirmed(true); // Immediate UI update\n onConfirm?.();\n }\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-lg font-medium text-foreground\">\n Subgraph Configuration\n </h2>\n <StatusPill\n status={status === \"CONFIRMED\" ? \"confirmed\" : \"draft\"}\n label={status === \"CONFIRMED\" ? \"Confirmed\" : \"Draft\"}\n />\n </div>\n\n {/* Subgraph Name Field */}\n <div>\n <label\n htmlFor=\"subgraph-name\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Subgraph Name\n </label>\n <input\n id=\"subgraph-name\"\n type=\"text\"\n value={subgraphName}\n onChange={(e) => setSubgraphName(e.target.value)}\n disabled={isReadOnly}\n className={twMerge(\n \"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\",\n isReadOnly ? \"cursor-not-allowed bg-muted\" : \"\",\n )}\n placeholder=\"Enter subgraph name\"\n />\n </div>\n\n {/* Confirm Button - only show if not in read-only mode */}\n {!isReadOnly && (\n <div>\n <button\n onClick={handleConfirm}\n disabled={!subgraphName.trim()}\n className=\"rounded-md bg-primary px-4 py-2 text-primary-foreground hover:hover-effect focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-none disabled:disabled-effect\"\n >\n Confirm\n </button>\n </div>\n )}\n </div>\n );\n};\n","import type { PHDocumentEditorConfig } from \"@powerhousedao/reactor-browser\";\n\nexport const editorConfig: PHDocumentEditorConfig = {\n isExternalControlsEnabled: false,\n};\n","import { DocumentToolbar } from \"@powerhousedao/design-system/connect\";\nimport { useSetPHDocumentEditorConfig } from \"@powerhousedao/reactor-browser\";\nimport {\n setSubgraphName,\n setSubgraphStatus,\n} from \"@powerhousedao/vetra/document-models/subgraph-module\";\nimport { useCallback } from \"react\";\nimport { useSelectedSubgraphModuleDocument } from \"../hooks/useVetraDocument.js\";\nimport { SubgraphEditorForm } from \"./components/SubgraphEditorForm.js\";\nimport { editorConfig } from \"./config.js\";\n\nexport default function Editor() {\n useSetPHDocumentEditorConfig(editorConfig);\n const [document, dispatch] = useSelectedSubgraphModuleDocument();\n\n const onNameChange = useCallback(\n (name: string) => {\n if (name === document.state.global.name) return;\n dispatch(setSubgraphName({ name }));\n },\n [document.state.global.name, dispatch],\n );\n\n const onConfirm = useCallback(() => {\n dispatch(setSubgraphStatus({ status: \"CONFIRMED\" }));\n }, [dispatch]);\n\n return (\n <div className=\"bg-background p-6\">\n <DocumentToolbar />\n <SubgraphEditorForm\n subgraphName={document.state.global.name ?? \"\"}\n status={document.state.global.status}\n onNameChange={onNameChange}\n onConfirm={onConfirm}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;AAYA,MAAa,sBAAyD,EACpE,cAAc,sBAAsB,IACpC,SAAS,SACT,cACA,gBACI;CACJ,MAAM,CAAC,cAAc,mBAAmB,SAAS,oBAAoB;CACrE,MAAM,CAAC,aAAa,kBAAkB,SAAS,MAAM;AAGrD,aAAY,cAAc,cAAc,IAAI;AAG5C,iBAAgB;AAEd,kBAAgB,oBAAoB;IACnC,CAAC,oBAAoB,CAAC;AAGzB,iBAAgB;AACd,MAAI,WAAW,QAEb,gBAAe,MAAM;IAEtB,CAAC,OAAO,CAAC;CAGZ,MAAM,aAAa,eAAe,WAAW;CAE7C,MAAM,sBAAsB;AAC1B,MAAI,aAAa,MAAM,EAAE;AACvB,kBAAe,KAAK;AACpB,gBAAa;;;AAIjB,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf;GACE,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,oBAAC,MAAD;KAAI,WAAU;eAAsC;KAE/C,CAAA,EACL,oBAAC,YAAD;KACE,QAAQ,WAAW,cAAc,cAAc;KAC/C,OAAO,WAAW,cAAc,cAAc;KAC9C,CAAA,CACE;;GAGN,qBAAC,OAAD,EAAA,UAAA,CACE,oBAAC,SAAD;IACE,SAAQ;IACR,WAAU;cACX;IAEO,CAAA,EACR,oBAAC,SAAD;IACE,IAAG;IACH,MAAK;IACL,OAAO;IACP,WAAW,MAAM,gBAAgB,EAAE,OAAO,MAAM;IAChD,UAAU;IACV,WAAW,QACT,wMACA,aAAa,gCAAgC,GAC9C;IACD,aAAY;IACZ,CAAA,CACE,EAAA,CAAA;GAGL,CAAC,cACA,oBAAC,OAAD,EAAA,UACE,oBAAC,UAAD;IACE,SAAS;IACT,UAAU,CAAC,aAAa,MAAM;IAC9B,WAAU;cACX;IAEQ,CAAA,EACL,CAAA;GAEJ;;;;;AC5FV,MAAa,eAAuC,EAClD,2BAA2B,OAC5B;;;ACOD,SAAwB,SAAS;AAC/B,8BAA6B,aAAa;CAC1C,MAAM,CAAC,UAAU,YAAY,mCAAmC;CAEhE,MAAM,eAAe,aAClB,SAAiB;AAChB,MAAI,SAAS,SAAS,MAAM,OAAO,KAAM;AACzC,WAAS,gBAAgB,EAAE,MAAM,CAAC,CAAC;IAErC,CAAC,SAAS,MAAM,OAAO,MAAM,SAAS,CACvC;CAED,MAAM,YAAY,kBAAkB;AAClC,WAAS,kBAAkB,EAAE,QAAQ,aAAa,CAAC,CAAC;IACnD,CAAC,SAAS,CAAC;AAEd,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,oBAAC,iBAAD,EAAmB,CAAA,EACnB,oBAAC,oBAAD;GACE,cAAc,SAAS,MAAM,OAAO,QAAQ;GAC5C,QAAQ,SAAS,MAAM,OAAO;GAChB;GACH;GACX,CAAA,CACE"}
1
+ {"version":3,"file":"editor-CxRPBLK_.js","names":[],"sources":["../editors/subgraph-editor/components/SubgraphEditorForm.tsx","../editors/subgraph-editor/config.ts","../editors/subgraph-editor/editor.tsx"],"sourcesContent":["import { useEffect, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport { StatusPill } from \"../../components/index.js\";\nimport { useDebounce } from \"../../hooks/index.js\";\n\nexport interface SubgraphEditorFormProps {\n subgraphName?: string;\n status?: string;\n onNameChange?: (name: string) => void;\n onConfirm?: () => void;\n}\n\nexport const SubgraphEditorForm: React.FC<SubgraphEditorFormProps> = ({\n subgraphName: initialSubgraphName = \"\",\n status = \"DRAFT\",\n onNameChange,\n onConfirm,\n}) => {\n const [subgraphName, setSubgraphName] = useState(initialSubgraphName);\n const [isConfirmed, setIsConfirmed] = useState(false);\n\n // Use the debounce hook for name changes\n useDebounce(subgraphName, onNameChange, 300);\n\n // Update local state when initialSubgraphName changes\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setSubgraphName(initialSubgraphName);\n }, [initialSubgraphName]);\n\n // Reset confirmation state if status changes back to DRAFT\n useEffect(() => {\n if (status === \"DRAFT\") {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setIsConfirmed(false);\n }\n }, [status]);\n\n // Check if form should be read-only\n const isReadOnly = isConfirmed || status === \"CONFIRMED\";\n\n const handleConfirm = () => {\n if (subgraphName.trim()) {\n setIsConfirmed(true); // Immediate UI update\n onConfirm?.();\n }\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-lg font-medium text-foreground\">\n Subgraph Configuration\n </h2>\n <StatusPill\n status={status === \"CONFIRMED\" ? \"confirmed\" : \"draft\"}\n label={status === \"CONFIRMED\" ? \"Confirmed\" : \"Draft\"}\n />\n </div>\n\n {/* Subgraph Name Field */}\n <div>\n <label\n htmlFor=\"subgraph-name\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Subgraph Name\n </label>\n <input\n id=\"subgraph-name\"\n type=\"text\"\n value={subgraphName}\n onChange={(e) => setSubgraphName(e.target.value)}\n disabled={isReadOnly}\n className={twMerge(\n \"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\",\n isReadOnly ? \"cursor-not-allowed bg-muted\" : \"\",\n )}\n placeholder=\"Enter subgraph name\"\n />\n </div>\n\n {/* Confirm Button - only show if not in read-only mode */}\n {!isReadOnly && (\n <div>\n <button\n onClick={handleConfirm}\n disabled={!subgraphName.trim()}\n className=\"rounded-md bg-primary px-4 py-2 text-primary-foreground hover:hover-effect focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-none disabled:disabled-effect\"\n >\n Confirm\n </button>\n </div>\n )}\n </div>\n );\n};\n","import type { PHDocumentEditorConfig } from \"@powerhousedao/reactor-browser\";\n\nexport const editorConfig: PHDocumentEditorConfig = {\n isExternalControlsEnabled: false,\n};\n","import { DocumentToolbar } from \"@powerhousedao/design-system/connect\";\nimport { useSetPHDocumentEditorConfig } from \"@powerhousedao/reactor-browser\";\nimport {\n setSubgraphName,\n setSubgraphStatus,\n} from \"@powerhousedao/vetra/document-models/subgraph-module\";\nimport { useCallback } from \"react\";\nimport { useSelectedSubgraphModuleDocument } from \"../hooks/useVetraDocument.js\";\nimport { SubgraphEditorForm } from \"./components/SubgraphEditorForm.js\";\nimport { editorConfig } from \"./config.js\";\n\nexport default function Editor() {\n useSetPHDocumentEditorConfig(editorConfig);\n const [document, dispatch] = useSelectedSubgraphModuleDocument();\n\n const onNameChange = useCallback(\n (name: string) => {\n if (name === document.state.global.name) return;\n dispatch(setSubgraphName({ name }));\n },\n [document.state.global.name, dispatch],\n );\n\n const onConfirm = useCallback(() => {\n dispatch(setSubgraphStatus({ status: \"CONFIRMED\" }));\n }, [dispatch]);\n\n return (\n <div className=\"bg-background p-6\">\n <DocumentToolbar />\n <SubgraphEditorForm\n subgraphName={document.state.global.name ?? \"\"}\n status={document.state.global.status}\n onNameChange={onNameChange}\n onConfirm={onConfirm}\n />\n </div>\n );\n}\n"],"mappings":";;;;;;;;;;AAYA,MAAa,sBAAyD,EACpE,cAAc,sBAAsB,IACpC,SAAS,SACT,cACA,gBACI;CACJ,MAAM,CAAC,cAAc,mBAAmB,SAAS,oBAAoB;CACrE,MAAM,CAAC,aAAa,kBAAkB,SAAS,MAAM;AAGrD,aAAY,cAAc,cAAc,IAAI;AAG5C,iBAAgB;AAEd,kBAAgB,oBAAoB;IACnC,CAAC,oBAAoB,CAAC;AAGzB,iBAAgB;AACd,MAAI,WAAW,QAEb,gBAAe,MAAM;IAEtB,CAAC,OAAO,CAAC;CAGZ,MAAM,aAAa,eAAe,WAAW;CAE7C,MAAM,sBAAsB;AAC1B,MAAI,aAAa,MAAM,EAAE;AACvB,kBAAe,KAAK;AACpB,gBAAa;;;AAIjB,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf;GACE,qBAAC,OAAD;IAAK,WAAU;cAAf,CACE,oBAAC,MAAD;KAAI,WAAU;eAAsC;KAE/C,CAAA,EACL,oBAAC,YAAD;KACE,QAAQ,WAAW,cAAc,cAAc;KAC/C,OAAO,WAAW,cAAc,cAAc;KAC9C,CAAA,CACE;;GAGN,qBAAC,OAAD,EAAA,UAAA,CACE,oBAAC,SAAD;IACE,SAAQ;IACR,WAAU;cACX;IAEO,CAAA,EACR,oBAAC,SAAD;IACE,IAAG;IACH,MAAK;IACL,OAAO;IACP,WAAW,MAAM,gBAAgB,EAAE,OAAO,MAAM;IAChD,UAAU;IACV,WAAW,QACT,wMACA,aAAa,gCAAgC,GAC9C;IACD,aAAY;IACZ,CAAA,CACE,EAAA,CAAA;GAGL,CAAC,cACA,oBAAC,OAAD,EAAA,UACE,oBAAC,UAAD;IACE,SAAS;IACT,UAAU,CAAC,aAAa,MAAM;IAC9B,WAAU;cACX;IAEQ,CAAA,EACL,CAAA;GAEJ;;;;;AC5FV,MAAa,eAAuC,EAClD,2BAA2B,OAC5B;;;ACOD,SAAwB,SAAS;AAC/B,8BAA6B,aAAa;CAC1C,MAAM,CAAC,UAAU,YAAY,mCAAmC;CAEhE,MAAM,eAAe,aAClB,SAAiB;AAChB,MAAI,SAAS,SAAS,MAAM,OAAO,KAAM;AACzC,WAAS,gBAAgB,EAAE,MAAM,CAAC,CAAC;IAErC,CAAC,SAAS,MAAM,OAAO,MAAM,SAAS,CACvC;CAED,MAAM,YAAY,kBAAkB;AAClC,WAAS,kBAAkB,EAAE,QAAQ,aAAa,CAAC,CAAC;IACnD,CAAC,SAAS,CAAC;AAEd,QACE,qBAAC,OAAD;EAAK,WAAU;YAAf,CACE,oBAAC,iBAAD,EAAmB,CAAA,EACnB,oBAAC,oBAAD;GACE,cAAc,SAAS,MAAM,OAAO,QAAQ;GAC5C,QAAQ,SAAS,MAAM,OAAO;GAChB;GACH;GACX,CAAA,CACE"}
@@ -1,7 +1,7 @@
1
1
  import { _ as setEditorName, g as removeDocumentType, m as addDocumentType, v as setEditorStatus } from "./utils-D0ejTHeY.js";
2
2
  import { s as useSelectedDocumentEditorDocument } from "./document-editor-5gSBaTUM.js";
3
3
  import { StatusPill } from "./editors/components/index.js";
4
- import { n as useAvailableDocumentTypes, t as useDebounce } from "./hooks-D_8Uwk1s.js";
4
+ import { n as useAvailableDocumentTypes, t as useDebounce } from "./hooks-Btogj1f0.js";
5
5
  import { useSetPHDocumentEditorConfig } from "@powerhousedao/reactor-browser";
6
6
  import { Suspense, useCallback, useEffect, useState } from "react";
7
7
  import { twMerge } from "tailwind-merge";
@@ -172,4 +172,4 @@ function Editor() {
172
172
  //#endregion
173
173
  export { Editor as default };
174
174
 
175
- //# sourceMappingURL=editor-CtN1Sy88.js.map
175
+ //# sourceMappingURL=editor-wkoHTN7p.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"editor-CtN1Sy88.js","names":[],"sources":["../editors/document-editor/components/DocumentEditorForm.tsx","../editors/document-editor/config.ts","../editors/document-editor/editor.tsx"],"sourcesContent":["import { Suspense, useEffect, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport type {\n AddDocumentTypeInput,\n DocumentTypeItem,\n RemoveDocumentTypeInput,\n} from \"../../../document-models/document-editor/index.js\";\nimport { StatusPill } from \"../../components/index.js\";\nimport { useAvailableDocumentTypes, useDebounce } from \"../../hooks/index.js\";\n\nexport interface DocumentEditorFormProps {\n editorName?: string;\n documentTypes?: DocumentTypeItem[];\n status?: string;\n onEditorNameChange?: (name: string) => void;\n onAddDocumentType?: (input: AddDocumentTypeInput) => void;\n onRemoveDocumentType?: (input: RemoveDocumentTypeInput) => void;\n onConfirm?: () => void;\n}\n\nfunction DocumentTypeSelectUI(\n props: React.SelectHTMLAttributes<HTMLSelectElement>,\n) {\n return (\n <select\n id=\"supported-document-types\"\n className=\"w-full rounded-md border border-border px-3 py-2 text-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none\"\n {...props}\n >\n <option value=\"\">Select a document type</option>\n {props.children}\n </select>\n );\n}\n\nfunction DocumentTypeSelect({\n documentTypes,\n setDocumentTypes,\n onAddDocumentType,\n onRemoveDocumentType,\n}: {\n setDocumentTypes: (documentTypes: DocumentTypeItem[]) => void;\n} & Pick<\n DocumentEditorFormProps,\n \"documentTypes\" | \"onAddDocumentType\" | \"onRemoveDocumentType\"\n>) {\n // Get available document types from the hook (vetra drive only for document editor)\n const availableDocumentTypes = useAvailableDocumentTypes(true);\n const [selectedDocumentType, setSelectedDocumentType] = useState(\"\");\n\n return (\n <DocumentTypeSelectUI\n value={selectedDocumentType}\n onChange={(e) => {\n const selectedValue = e.target.value;\n if (selectedValue) {\n // Remove existing document type if any\n\n const existingType = documentTypes?.at(0);\n if (existingType) {\n onRemoveDocumentType?.({ id: existingType.id });\n }\n\n // Add the new document type\n const newTypeInput: AddDocumentTypeInput = {\n id: Date.now().toString(), // Generate a unique ID\n documentType: selectedValue,\n };\n const newType: DocumentTypeItem = {\n id: newTypeInput.id,\n documentType: newTypeInput.documentType,\n };\n setDocumentTypes([newType]); // Replace with single item array\n onAddDocumentType?.(newTypeInput);\n }\n setSelectedDocumentType(\"\");\n }}\n >\n {availableDocumentTypes.map((docType) => (\n <option key={docType} value={docType}>\n {docType}\n </option>\n ))}\n </DocumentTypeSelectUI>\n );\n}\n\nexport const DocumentEditorForm: React.FC<DocumentEditorFormProps> = ({\n editorName: initialEditorName = \"\",\n documentTypes: initialDocumentTypes = [],\n status = \"DRAFT\",\n onEditorNameChange,\n onAddDocumentType,\n onRemoveDocumentType,\n onConfirm,\n}) => {\n const [editorName, setEditorName] = useState(initialEditorName);\n const [documentTypes, setDocumentTypes] =\n useState<DocumentTypeItem[]>(initialDocumentTypes);\n const [isConfirmed, setIsConfirmed] = useState(false);\n\n // Use the debounce hook for name changes\n useDebounce(editorName, onEditorNameChange, 300);\n\n // Update local state when initial values change\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setEditorName(initialEditorName);\n }, [initialEditorName]);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setDocumentTypes(initialDocumentTypes);\n }, [initialDocumentTypes]);\n\n // Reset confirmation state if status changes back to DRAFT\n useEffect(() => {\n if (status === \"DRAFT\") {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setIsConfirmed(false);\n }\n }, [status]);\n\n // Check if form should be read-only\n const isReadOnly = isConfirmed || status === \"CONFIRMED\";\n\n const handleConfirm = () => {\n if (editorName.trim() && documentTypes.length > 0) {\n setIsConfirmed(true); // Immediate UI update\n onConfirm?.();\n }\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-lg font-medium text-foreground\">\n Editor Configuration\n </h2>\n <StatusPill\n status={status === \"CONFIRMED\" ? \"confirmed\" : \"draft\"}\n label={status === \"CONFIRMED\" ? \"Confirmed\" : \"Draft\"}\n />\n </div>\n\n {/* Editor Name Field */}\n <div>\n <label\n htmlFor=\"editor-name\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Editor Name\n </label>\n <input\n id=\"editor-name\"\n type=\"text\"\n value={editorName}\n onChange={(e) => setEditorName(e.target.value)}\n disabled={isReadOnly}\n className={twMerge(\n \"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\",\n isReadOnly ? \"cursor-not-allowed bg-muted\" : \"\",\n )}\n />\n </div>\n\n {/* Supported Document Types Field */}\n <div>\n <label\n htmlFor=\"supported-document-types\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Supported Document Types\n </label>\n <div className=\"space-y-2\">\n {!isReadOnly && (\n <Suspense fallback={<DocumentTypeSelectUI />}>\n <DocumentTypeSelect\n documentTypes={documentTypes}\n setDocumentTypes={setDocumentTypes}\n onAddDocumentType={onAddDocumentType}\n onRemoveDocumentType={onRemoveDocumentType}\n />\n </Suspense>\n )}\n <div className=\"space-y-1\">\n {documentTypes.map((type) => (\n <div key={type.id} className=\"flex items-center py-1\">\n <span className=\"text-sm text-foreground\">\n {type.documentType}\n </span>\n {!isReadOnly && (\n <button\n onClick={() => {\n setDocumentTypes([]);\n onRemoveDocumentType?.({ id: type.id });\n }}\n className=\"ml-2 text-muted-foreground hover:hover-effect focus:outline-none\"\n >\n ×\n </button>\n )}\n </div>\n ))}\n </div>\n </div>\n </div>\n\n {/* Confirm Button - only show if not in read-only mode */}\n {!isReadOnly && (\n <div>\n <button\n onClick={handleConfirm}\n disabled={!editorName.trim() || documentTypes.length === 0}\n className=\"rounded-md bg-primary px-4 py-2 text-primary-foreground hover:hover-effect focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-none disabled:disabled-effect\"\n >\n Confirm\n </button>\n </div>\n )}\n </div>\n );\n};\n","import type { PHDocumentEditorConfig } from \"@powerhousedao/reactor-browser\";\n\nexport const editorConfig: PHDocumentEditorConfig = {\n isExternalControlsEnabled: false,\n};\n","import { DocumentToolbar } from \"@powerhousedao/design-system/connect\";\nimport { useSetPHDocumentEditorConfig } from \"@powerhousedao/reactor-browser\";\nimport { useCallback } from \"react\";\nimport { useSelectedDocumentEditorDocument } from \"../../document-models/document-editor/index.js\";\nimport {\n addDocumentType,\n removeDocumentType,\n setEditorName,\n setEditorStatus,\n type AddDocumentTypeInput,\n type RemoveDocumentTypeInput,\n} from \"../../document-models/document-editor/index.js\";\nimport { DocumentEditorForm } from \"./components/DocumentEditorForm.js\";\nimport { editorConfig } from \"./config.js\";\n\nexport default function Editor() {\n useSetPHDocumentEditorConfig(editorConfig);\n const [document, dispatch] = useSelectedDocumentEditorDocument();\n\n const onEditorNameChange = useCallback(\n (name: string) => {\n if (!document.state.global.name && !name) return;\n if (name === document.state.global.name) return;\n\n dispatch(setEditorName({ name }));\n },\n [document.state.global.name, dispatch],\n );\n\n const onAddDocumentType = useCallback(\n (input: AddDocumentTypeInput) => {\n dispatch(addDocumentType(input));\n },\n [dispatch],\n );\n\n const onRemoveDocumentType = useCallback(\n (input: RemoveDocumentTypeInput) => {\n dispatch(removeDocumentType(input));\n },\n [dispatch],\n );\n\n const onConfirm = useCallback(() => {\n dispatch(setEditorStatus({ status: \"CONFIRMED\" }));\n }, [dispatch]);\n\n return (\n <div className=\"bg-background p-6\">\n <DocumentToolbar />\n <DocumentEditorForm\n status={document.state.global.status}\n editorName={document.state.global.name ?? \"\"}\n documentTypes={document.state.global.documentTypes}\n onEditorNameChange={onEditorNameChange}\n onAddDocumentType={onAddDocumentType}\n onRemoveDocumentType={onRemoveDocumentType}\n onConfirm={onConfirm}\n />\n </div>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"editor-wkoHTN7p.js","names":[],"sources":["../editors/document-editor/components/DocumentEditorForm.tsx","../editors/document-editor/config.ts","../editors/document-editor/editor.tsx"],"sourcesContent":["import { Suspense, useEffect, useState } from \"react\";\nimport { twMerge } from \"tailwind-merge\";\nimport type {\n AddDocumentTypeInput,\n DocumentTypeItem,\n RemoveDocumentTypeInput,\n} from \"../../../document-models/document-editor/index.js\";\nimport { StatusPill } from \"../../components/index.js\";\nimport { useAvailableDocumentTypes, useDebounce } from \"../../hooks/index.js\";\n\nexport interface DocumentEditorFormProps {\n editorName?: string;\n documentTypes?: DocumentTypeItem[];\n status?: string;\n onEditorNameChange?: (name: string) => void;\n onAddDocumentType?: (input: AddDocumentTypeInput) => void;\n onRemoveDocumentType?: (input: RemoveDocumentTypeInput) => void;\n onConfirm?: () => void;\n}\n\nfunction DocumentTypeSelectUI(\n props: React.SelectHTMLAttributes<HTMLSelectElement>,\n) {\n return (\n <select\n id=\"supported-document-types\"\n className=\"w-full rounded-md border border-border px-3 py-2 text-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none\"\n {...props}\n >\n <option value=\"\">Select a document type</option>\n {props.children}\n </select>\n );\n}\n\nfunction DocumentTypeSelect({\n documentTypes,\n setDocumentTypes,\n onAddDocumentType,\n onRemoveDocumentType,\n}: {\n setDocumentTypes: (documentTypes: DocumentTypeItem[]) => void;\n} & Pick<\n DocumentEditorFormProps,\n \"documentTypes\" | \"onAddDocumentType\" | \"onRemoveDocumentType\"\n>) {\n // Get available document types from the hook (vetra drive only for document editor)\n const availableDocumentTypes = useAvailableDocumentTypes(true);\n const [selectedDocumentType, setSelectedDocumentType] = useState(\"\");\n\n return (\n <DocumentTypeSelectUI\n value={selectedDocumentType}\n onChange={(e) => {\n const selectedValue = e.target.value;\n if (selectedValue) {\n // Remove existing document type if any\n\n const existingType = documentTypes?.at(0);\n if (existingType) {\n onRemoveDocumentType?.({ id: existingType.id });\n }\n\n // Add the new document type\n const newTypeInput: AddDocumentTypeInput = {\n id: Date.now().toString(), // Generate a unique ID\n documentType: selectedValue,\n };\n const newType: DocumentTypeItem = {\n id: newTypeInput.id,\n documentType: newTypeInput.documentType,\n };\n setDocumentTypes([newType]); // Replace with single item array\n onAddDocumentType?.(newTypeInput);\n }\n setSelectedDocumentType(\"\");\n }}\n >\n {availableDocumentTypes.map((docType) => (\n <option key={docType} value={docType}>\n {docType}\n </option>\n ))}\n </DocumentTypeSelectUI>\n );\n}\n\nexport const DocumentEditorForm: React.FC<DocumentEditorFormProps> = ({\n editorName: initialEditorName = \"\",\n documentTypes: initialDocumentTypes = [],\n status = \"DRAFT\",\n onEditorNameChange,\n onAddDocumentType,\n onRemoveDocumentType,\n onConfirm,\n}) => {\n const [editorName, setEditorName] = useState(initialEditorName);\n const [documentTypes, setDocumentTypes] =\n useState<DocumentTypeItem[]>(initialDocumentTypes);\n const [isConfirmed, setIsConfirmed] = useState(false);\n\n // Use the debounce hook for name changes\n useDebounce(editorName, onEditorNameChange, 300);\n\n // Update local state when initial values change\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setEditorName(initialEditorName);\n }, [initialEditorName]);\n\n useEffect(() => {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setDocumentTypes(initialDocumentTypes);\n }, [initialDocumentTypes]);\n\n // Reset confirmation state if status changes back to DRAFT\n useEffect(() => {\n if (status === \"DRAFT\") {\n // eslint-disable-next-line react-hooks/set-state-in-effect\n setIsConfirmed(false);\n }\n }, [status]);\n\n // Check if form should be read-only\n const isReadOnly = isConfirmed || status === \"CONFIRMED\";\n\n const handleConfirm = () => {\n if (editorName.trim() && documentTypes.length > 0) {\n setIsConfirmed(true); // Immediate UI update\n onConfirm?.();\n }\n };\n\n return (\n <div className=\"space-y-6 p-6\">\n <div className=\"flex items-center justify-between\">\n <h2 className=\"text-lg font-medium text-foreground\">\n Editor Configuration\n </h2>\n <StatusPill\n status={status === \"CONFIRMED\" ? \"confirmed\" : \"draft\"}\n label={status === \"CONFIRMED\" ? \"Confirmed\" : \"Draft\"}\n />\n </div>\n\n {/* Editor Name Field */}\n <div>\n <label\n htmlFor=\"editor-name\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Editor Name\n </label>\n <input\n id=\"editor-name\"\n type=\"text\"\n value={editorName}\n onChange={(e) => setEditorName(e.target.value)}\n disabled={isReadOnly}\n className={twMerge(\n \"w-full rounded-md border border-border px-3 py-2 text-foreground placeholder:text-muted-foreground focus:border-transparent focus:ring-2 focus:ring-ring focus:outline-none disabled:disabled-effect\",\n isReadOnly ? \"cursor-not-allowed bg-muted\" : \"\",\n )}\n />\n </div>\n\n {/* Supported Document Types Field */}\n <div>\n <label\n htmlFor=\"supported-document-types\"\n className=\"mb-2 block text-sm font-medium text-foreground\"\n >\n Supported Document Types\n </label>\n <div className=\"space-y-2\">\n {!isReadOnly && (\n <Suspense fallback={<DocumentTypeSelectUI />}>\n <DocumentTypeSelect\n documentTypes={documentTypes}\n setDocumentTypes={setDocumentTypes}\n onAddDocumentType={onAddDocumentType}\n onRemoveDocumentType={onRemoveDocumentType}\n />\n </Suspense>\n )}\n <div className=\"space-y-1\">\n {documentTypes.map((type) => (\n <div key={type.id} className=\"flex items-center py-1\">\n <span className=\"text-sm text-foreground\">\n {type.documentType}\n </span>\n {!isReadOnly && (\n <button\n onClick={() => {\n setDocumentTypes([]);\n onRemoveDocumentType?.({ id: type.id });\n }}\n className=\"ml-2 text-muted-foreground hover:hover-effect focus:outline-none\"\n >\n ×\n </button>\n )}\n </div>\n ))}\n </div>\n </div>\n </div>\n\n {/* Confirm Button - only show if not in read-only mode */}\n {!isReadOnly && (\n <div>\n <button\n onClick={handleConfirm}\n disabled={!editorName.trim() || documentTypes.length === 0}\n className=\"rounded-md bg-primary px-4 py-2 text-primary-foreground hover:hover-effect focus:ring-2 focus:ring-ring focus:ring-offset-2 focus:outline-none disabled:disabled-effect\"\n >\n Confirm\n </button>\n </div>\n )}\n </div>\n );\n};\n","import type { PHDocumentEditorConfig } from \"@powerhousedao/reactor-browser\";\n\nexport const editorConfig: PHDocumentEditorConfig = {\n isExternalControlsEnabled: false,\n};\n","import { DocumentToolbar } from \"@powerhousedao/design-system/connect\";\nimport { useSetPHDocumentEditorConfig } from \"@powerhousedao/reactor-browser\";\nimport { useCallback } from \"react\";\nimport { useSelectedDocumentEditorDocument } from \"../../document-models/document-editor/index.js\";\nimport {\n addDocumentType,\n removeDocumentType,\n setEditorName,\n setEditorStatus,\n type AddDocumentTypeInput,\n type RemoveDocumentTypeInput,\n} from \"../../document-models/document-editor/index.js\";\nimport { DocumentEditorForm } from \"./components/DocumentEditorForm.js\";\nimport { editorConfig } from \"./config.js\";\n\nexport default function Editor() {\n useSetPHDocumentEditorConfig(editorConfig);\n const [document, dispatch] = useSelectedDocumentEditorDocument();\n\n const onEditorNameChange = useCallback(\n (name: string) => {\n if (!document.state.global.name && !name) return;\n if (name === document.state.global.name) return;\n\n dispatch(setEditorName({ name }));\n },\n [document.state.global.name, dispatch],\n );\n\n const onAddDocumentType = useCallback(\n (input: AddDocumentTypeInput) => {\n dispatch(addDocumentType(input));\n },\n [dispatch],\n );\n\n const onRemoveDocumentType = useCallback(\n (input: RemoveDocumentTypeInput) => {\n dispatch(removeDocumentType(input));\n },\n [dispatch],\n );\n\n const onConfirm = useCallback(() => {\n dispatch(setEditorStatus({ status: \"CONFIRMED\" }));\n }, [dispatch]);\n\n return (\n <div className=\"bg-background p-6\">\n <DocumentToolbar />\n <DocumentEditorForm\n status={document.state.global.status}\n editorName={document.state.global.name ?? \"\"}\n documentTypes={document.state.global.documentTypes}\n onEditorNameChange={onEditorNameChange}\n onAddDocumentType={onAddDocumentType}\n onRemoveDocumentType={onRemoveDocumentType}\n onConfirm={onConfirm}\n />\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { n as useAvailableDocumentTypes, t as useDebounce } from "../../hooks-D_8Uwk1s.js";
1
+ import { n as useAvailableDocumentTypes, t as useDebounce } from "../../hooks-Btogj1f0.js";
2
2
  export { useAvailableDocumentTypes, useDebounce };
@@ -1,2 +1,2 @@
1
- import { a as DocumentEditorEditor, i as ProcessorModuleEditor, n as VetraDriveApp, o as AppEditor, r as SubgraphModuleEditor, t as VetraPackageEditor } from "../module-BhsG8kkn.js";
1
+ import { a as DocumentEditorEditor, i as ProcessorModuleEditor, n as VetraDriveApp, o as AppEditor, r as SubgraphModuleEditor, t as VetraPackageEditor } from "../module-D-awATbo.js";
2
2
  export { AppEditor, DocumentEditorEditor, ProcessorModuleEditor, SubgraphModuleEditor, VetraDriveApp, VetraPackageEditor };
@@ -36,4 +36,4 @@ function useDebounce(value, callback, delay) {
36
36
  //#endregion
37
37
  export { useAvailableDocumentTypes as n, useDebounce as t };
38
38
 
39
- //# sourceMappingURL=hooks-D_8Uwk1s.js.map
39
+ //# sourceMappingURL=hooks-Btogj1f0.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"hooks-D_8Uwk1s.js","names":[],"sources":["../editors/hooks/useAvailableDocumentTypes.ts","../editors/hooks/useDebounce.ts"],"sourcesContent":["import {\n useDocumentsInSelectedDrive,\n useSupportedDocumentTypesInReactor,\n} from \"@powerhousedao/reactor-browser\";\nimport type {\n DocumentModelDocument,\n PHDocument,\n} from \"@powerhousedao/shared/document-model\";\n\nfunction isDocumentModelDocument(\n document: PHDocument,\n): document is DocumentModelDocument {\n return document.header.documentType === \"powerhouse/document-model\";\n}\n\nexport function useAvailableDocumentTypes(\n onlyDocumentTypesFromDriveDocuments = false,\n): string[] {\n const supportedDocumentTypes = useSupportedDocumentTypesInReactor() ?? [];\n const documents = useDocumentsInSelectedDrive() ?? [];\n const documentModelDocumentsInSelectedDrive = documents.filter(\n isDocumentModelDocument,\n );\n const documentTypesFromDocumentModelDocuments =\n documentModelDocumentsInSelectedDrive.map((doc) => doc.state.global.id);\n\n if (onlyDocumentTypesFromDriveDocuments)\n return [...new Set(documentTypesFromDocumentModelDocuments)];\n\n return [\n ...new Set([\n ...supportedDocumentTypes,\n ...documentTypesFromDocumentModelDocuments,\n ]),\n ];\n}\n","import { useEffect } from \"react\";\n\n/**\n * Reusable debounce hook that calls a callback function after a specified delay\n * when the value changes. Useful for API calls, search inputs, etc.\n *\n * @param value - The value to debounce\n * @param callback - Function to call with the debounced value (optional)\n * @param delay - Delay in milliseconds\n */\nexport function useDebounce<T>(\n value: T,\n callback: ((value: T) => void) | undefined,\n delay: number,\n) {\n useEffect(() => {\n if (!callback) return;\n\n const timer = setTimeout(() => {\n callback(value);\n }, delay);\n\n return () => clearTimeout(timer);\n }, [value, callback, delay]);\n}\n"],"mappings":";;;AASA,SAAS,wBACP,UACmC;AACnC,QAAO,SAAS,OAAO,iBAAiB;;AAG1C,SAAgB,0BACd,sCAAsC,OAC5B;CACV,MAAM,yBAAyB,oCAAoC,IAAI,EAAE;CAKzE,MAAM,2CAJY,6BAA6B,IAAI,EAAE,EACG,OACtD,wBACD,CAEuC,KAAK,QAAQ,IAAI,MAAM,OAAO,GAAG;AAEzE,KAAI,oCACF,QAAO,CAAC,GAAG,IAAI,IAAI,wCAAwC,CAAC;AAE9D,QAAO,CACL,GAAG,IAAI,IAAI,CACT,GAAG,wBACH,GAAG,wCACJ,CAAC,CACH;;;;;;;;;;;;ACxBH,SAAgB,YACd,OACA,UACA,OACA;AACA,iBAAgB;AACd,MAAI,CAAC,SAAU;EAEf,MAAM,QAAQ,iBAAiB;AAC7B,YAAS,MAAM;KACd,MAAM;AAET,eAAa,aAAa,MAAM;IAC/B;EAAC;EAAO;EAAU;EAAM,CAAC"}
1
+ {"version":3,"file":"hooks-Btogj1f0.js","names":[],"sources":["../editors/hooks/useAvailableDocumentTypes.ts","../editors/hooks/useDebounce.ts"],"sourcesContent":["import {\n useDocumentsInSelectedDrive,\n useSupportedDocumentTypesInReactor,\n} from \"@powerhousedao/reactor-browser\";\nimport type {\n DocumentModelDocument,\n PHDocument,\n} from \"@powerhousedao/shared/document-model\";\n\nfunction isDocumentModelDocument(\n document: PHDocument,\n): document is DocumentModelDocument {\n return document.header.documentType === \"powerhouse/document-model\";\n}\n\nexport function useAvailableDocumentTypes(\n onlyDocumentTypesFromDriveDocuments = false,\n): string[] {\n const supportedDocumentTypes = useSupportedDocumentTypesInReactor() ?? [];\n const documents = useDocumentsInSelectedDrive() ?? [];\n const documentModelDocumentsInSelectedDrive = documents.filter(\n isDocumentModelDocument,\n );\n const documentTypesFromDocumentModelDocuments =\n documentModelDocumentsInSelectedDrive.map((doc) => doc.state.global.id);\n\n if (onlyDocumentTypesFromDriveDocuments)\n return [...new Set(documentTypesFromDocumentModelDocuments)];\n\n return [\n ...new Set([\n ...supportedDocumentTypes,\n ...documentTypesFromDocumentModelDocuments,\n ]),\n ];\n}\n","import { useEffect } from \"react\";\n\n/**\n * Reusable debounce hook that calls a callback function after a specified delay\n * when the value changes. Useful for API calls, search inputs, etc.\n *\n * @param value - The value to debounce\n * @param callback - Function to call with the debounced value (optional)\n * @param delay - Delay in milliseconds\n */\nexport function useDebounce<T>(\n value: T,\n callback: ((value: T) => void) | undefined,\n delay: number,\n) {\n useEffect(() => {\n if (!callback) return;\n\n const timer = setTimeout(() => {\n callback(value);\n }, delay);\n\n return () => clearTimeout(timer);\n }, [value, callback, delay]);\n}\n"],"mappings":";;;AASA,SAAS,wBACP,UACmC;AACnC,QAAO,SAAS,OAAO,iBAAiB;;AAG1C,SAAgB,0BACd,sCAAsC,OAC5B;CACV,MAAM,yBAAyB,oCAAoC,IAAI,EAAE;CAKzE,MAAM,2CAJY,6BAA6B,IAAI,EAAE,EACG,OACtD,wBACD,CAEuC,KAAK,QAAQ,IAAI,MAAM,OAAO,GAAG;AAEzE,KAAI,oCACF,QAAO,CAAC,GAAG,IAAI,IAAI,wCAAwC,CAAC;AAE9D,QAAO,CACL,GAAG,IAAI,IAAI,CACT,GAAG,wBACH,GAAG,wCACJ,CAAC,CACH;;;;;;;;;;;;ACxBH,SAAgB,YACd,OACA,UACA,OACA;AACA,iBAAgB;AACd,MAAI,CAAC,SAAU;EAEf,MAAM,QAAQ,iBAAiB;AAC7B,YAAS,MAAM;KACd,MAAM;AAET,eAAa,aAAa,MAAM;IAC/B;EAAC;EAAO;EAAU;EAAM,CAAC"}
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import { t as DocumentEditor } from "./module-DP3bVbak.js";
4
4
  import { t as ProcessorModule } from "./module-mtR8W4L4.js";
5
5
  import { t as SubgraphModule } from "./module-C0jUPu9F.js";
6
6
  import { t as VetraPackage } from "./module-1hr_ne9w.js";
7
- import { a as DocumentEditorEditor, i as ProcessorModuleEditor, n as VetraDriveApp, o as AppEditor, r as SubgraphModuleEditor, t as VetraPackageEditor } from "./module-BhsG8kkn.js";
7
+ import { a as DocumentEditorEditor, i as ProcessorModuleEditor, n as VetraDriveApp, o as AppEditor, r as SubgraphModuleEditor, t as VetraPackageEditor } from "./module-D-awATbo.js";
8
8
  //#region document-models/document-models.ts
9
9
  /**
10
10
  * WARNING: DO NOT EDIT
@@ -2,7 +2,7 @@ import { lazy } from "react";
2
2
  //#region editors/app-editor/module.ts
3
3
  /** Document editor module for the "powerhouse/app" document type */
4
4
  const AppEditor = {
5
- Component: lazy(() => import("./editor-bA5TTxfU.js")),
5
+ Component: lazy(() => import("./editor-C3mtuH8G.js")),
6
6
  documentTypes: ["powerhouse/app"],
7
7
  config: {
8
8
  id: "app-editor",
@@ -13,7 +13,7 @@ const AppEditor = {
13
13
  //#region editors/document-editor/module.ts
14
14
  /** Document editor module for the "powerhouse/document-editor" document type */
15
15
  const DocumentEditorEditor = {
16
- Component: lazy(() => import("./editor-CtN1Sy88.js")),
16
+ Component: lazy(() => import("./editor-wkoHTN7p.js")),
17
17
  documentTypes: ["powerhouse/document-editor"],
18
18
  config: {
19
19
  id: "document-editor-editor",
@@ -24,7 +24,7 @@ const DocumentEditorEditor = {
24
24
  //#region editors/processor-editor/module.ts
25
25
  /** Document editor module for the "powerhouse/processor" document type */
26
26
  const ProcessorModuleEditor = {
27
- Component: lazy(() => import("./editor-saGUzfCl.js")),
27
+ Component: lazy(() => import("./editor-0Boxg7qN.js")),
28
28
  documentTypes: ["powerhouse/processor"],
29
29
  config: {
30
30
  id: "processor-module-editor",
@@ -35,7 +35,7 @@ const ProcessorModuleEditor = {
35
35
  //#region editors/subgraph-editor/module.ts
36
36
  /** Document editor module for the "powerhouse/subgraph" document type */
37
37
  const SubgraphModuleEditor = {
38
- Component: lazy(() => import("./editor-fNaLqnMc.js")),
38
+ Component: lazy(() => import("./editor-CxRPBLK_.js")),
39
39
  documentTypes: ["powerhouse/subgraph"],
40
40
  config: {
41
41
  id: "subgraph-module-editor",
@@ -56,7 +56,7 @@ const VetraDriveApp = {
56
56
  //#region editors/vetra-package/module.ts
57
57
  /** Document editor module for the "powerhouse/package" document type */
58
58
  const VetraPackageEditor = {
59
- Component: lazy(() => import("./editor-De5XaIXa.js")),
59
+ Component: lazy(() => import("./editor-C7wFAvfQ.js")),
60
60
  documentTypes: ["powerhouse/package"],
61
61
  config: {
62
62
  id: "vetra-package-editor",
@@ -66,4 +66,4 @@ const VetraPackageEditor = {
66
66
  //#endregion
67
67
  export { DocumentEditorEditor as a, ProcessorModuleEditor as i, VetraDriveApp as n, AppEditor as o, SubgraphModuleEditor as r, VetraPackageEditor as t };
68
68
 
69
- //# sourceMappingURL=module-BhsG8kkn.js.map
69
+ //# sourceMappingURL=module-D-awATbo.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"module-BhsG8kkn.js","names":[],"sources":["../editors/app-editor/module.ts","../editors/document-editor/module.ts","../editors/processor-editor/module.ts","../editors/subgraph-editor/module.ts","../editors/vetra-drive-app/module.ts","../editors/vetra-package/module.ts"],"sourcesContent":["/**\n * WARNING: DO NOT EDIT\n * This file is auto-generated and updated by codegen\n */\nimport type { EditorModule } from \"document-model\";\nimport { lazy } from \"react\";\n\n/** Document editor module for the \"powerhouse/app\" document type */\nexport const AppEditor: EditorModule = {\n Component: lazy(() => import(\"./editor.js\")),\n documentTypes: [\"powerhouse/app\"],\n config: {\n id: \"app-editor\",\n name: \"AppEditor\",\n },\n};\n","/**\n * WARNING: DO NOT EDIT\n * This file is auto-generated and updated by codegen\n */\nimport type { EditorModule } from \"document-model\";\nimport { lazy } from \"react\";\n\n/** Document editor module for the \"powerhouse/document-editor\" document type */\nexport const DocumentEditorEditor: EditorModule = {\n Component: lazy(() => import(\"./editor.js\")),\n documentTypes: [\"powerhouse/document-editor\"],\n config: {\n id: \"document-editor-editor\",\n name: \"Document Editor Editor\",\n },\n};\n","/**\n * WARNING: DO NOT EDIT\n * This file is auto-generated and updated by codegen\n */\nimport type { EditorModule } from \"document-model\";\nimport { lazy } from \"react\";\n\n/** Document editor module for the \"powerhouse/processor\" document type */\nexport const ProcessorModuleEditor: EditorModule = {\n Component: lazy(() => import(\"./editor.js\")),\n documentTypes: [\"powerhouse/processor\"],\n config: {\n id: \"processor-module-editor\",\n name: \"Processor Module Editor\",\n },\n};\n","/**\n * WARNING: DO NOT EDIT\n * This file is auto-generated and updated by codegen\n */\nimport type { EditorModule } from \"document-model\";\nimport { lazy } from \"react\";\n\n/** Document editor module for the \"powerhouse/subgraph\" document type */\nexport const SubgraphModuleEditor: EditorModule = {\n Component: lazy(() => import(\"./editor.js\")),\n documentTypes: [\"powerhouse/subgraph\"],\n config: {\n id: \"subgraph-module-editor\",\n name: \"Subgraph Module Editor\",\n },\n};\n","import type { EditorModule } from \"@powerhousedao/shared/document-model\";\nimport { lazy } from \"react\";\n\nexport const VetraDriveApp: EditorModule = {\n Component: lazy(() => import(\"./editor.js\")),\n documentTypes: [\"powerhouse/document-drive\"],\n config: {\n id: \"vetra-drive-app\",\n name: \"Vetra Drive App\",\n },\n};\n","/**\n * WARNING: DO NOT EDIT\n * This file is auto-generated and updated by codegen\n */\nimport type { EditorModule } from \"document-model\";\nimport { lazy } from \"react\";\n\n/** Document editor module for the \"powerhouse/package\" document type */\nexport const VetraPackageEditor: EditorModule = {\n Component: lazy(() => import(\"./editor.js\")),\n documentTypes: [\"powerhouse/package\"],\n config: {\n id: \"vetra-package-editor\",\n name: \"Vetra Package Editor\",\n },\n};\n"],"mappings":";;;AAQA,MAAa,YAA0B;CACrC,WAAW,WAAW,OAAO,wBAAe;CAC5C,eAAe,CAAC,iBAAiB;CACjC,QAAQ;EACN,IAAI;EACJ,MAAM;EACP;CACF;;;;ACPD,MAAa,uBAAqC;CAChD,WAAW,WAAW,OAAO,wBAAe;CAC5C,eAAe,CAAC,6BAA6B;CAC7C,QAAQ;EACN,IAAI;EACJ,MAAM;EACP;CACF;;;;ACPD,MAAa,wBAAsC;CACjD,WAAW,WAAW,OAAO,wBAAe;CAC5C,eAAe,CAAC,uBAAuB;CACvC,QAAQ;EACN,IAAI;EACJ,MAAM;EACP;CACF;;;;ACPD,MAAa,uBAAqC;CAChD,WAAW,WAAW,OAAO,wBAAe;CAC5C,eAAe,CAAC,sBAAsB;CACtC,QAAQ;EACN,IAAI;EACJ,MAAM;EACP;CACF;;;ACZD,MAAa,gBAA8B;CACzC,WAAW,WAAW,OAAO,wBAAe;CAC5C,eAAe,CAAC,4BAA4B;CAC5C,QAAQ;EACN,IAAI;EACJ,MAAM;EACP;CACF;;;;ACFD,MAAa,qBAAmC;CAC9C,WAAW,WAAW,OAAO,wBAAe;CAC5C,eAAe,CAAC,qBAAqB;CACrC,QAAQ;EACN,IAAI;EACJ,MAAM;EACP;CACF"}
1
+ {"version":3,"file":"module-D-awATbo.js","names":[],"sources":["../editors/app-editor/module.ts","../editors/document-editor/module.ts","../editors/processor-editor/module.ts","../editors/subgraph-editor/module.ts","../editors/vetra-drive-app/module.ts","../editors/vetra-package/module.ts"],"sourcesContent":["/**\n * WARNING: DO NOT EDIT\n * This file is auto-generated and updated by codegen\n */\nimport type { EditorModule } from \"document-model\";\nimport { lazy } from \"react\";\n\n/** Document editor module for the \"powerhouse/app\" document type */\nexport const AppEditor: EditorModule = {\n Component: lazy(() => import(\"./editor.js\")),\n documentTypes: [\"powerhouse/app\"],\n config: {\n id: \"app-editor\",\n name: \"AppEditor\",\n },\n};\n","/**\n * WARNING: DO NOT EDIT\n * This file is auto-generated and updated by codegen\n */\nimport type { EditorModule } from \"document-model\";\nimport { lazy } from \"react\";\n\n/** Document editor module for the \"powerhouse/document-editor\" document type */\nexport const DocumentEditorEditor: EditorModule = {\n Component: lazy(() => import(\"./editor.js\")),\n documentTypes: [\"powerhouse/document-editor\"],\n config: {\n id: \"document-editor-editor\",\n name: \"Document Editor Editor\",\n },\n};\n","/**\n * WARNING: DO NOT EDIT\n * This file is auto-generated and updated by codegen\n */\nimport type { EditorModule } from \"document-model\";\nimport { lazy } from \"react\";\n\n/** Document editor module for the \"powerhouse/processor\" document type */\nexport const ProcessorModuleEditor: EditorModule = {\n Component: lazy(() => import(\"./editor.js\")),\n documentTypes: [\"powerhouse/processor\"],\n config: {\n id: \"processor-module-editor\",\n name: \"Processor Module Editor\",\n },\n};\n","/**\n * WARNING: DO NOT EDIT\n * This file is auto-generated and updated by codegen\n */\nimport type { EditorModule } from \"document-model\";\nimport { lazy } from \"react\";\n\n/** Document editor module for the \"powerhouse/subgraph\" document type */\nexport const SubgraphModuleEditor: EditorModule = {\n Component: lazy(() => import(\"./editor.js\")),\n documentTypes: [\"powerhouse/subgraph\"],\n config: {\n id: \"subgraph-module-editor\",\n name: \"Subgraph Module Editor\",\n },\n};\n","import type { EditorModule } from \"@powerhousedao/shared/document-model\";\nimport { lazy } from \"react\";\n\nexport const VetraDriveApp: EditorModule = {\n Component: lazy(() => import(\"./editor.js\")),\n documentTypes: [\"powerhouse/document-drive\"],\n config: {\n id: \"vetra-drive-app\",\n name: \"Vetra Drive App\",\n },\n};\n","/**\n * WARNING: DO NOT EDIT\n * This file is auto-generated and updated by codegen\n */\nimport type { EditorModule } from \"document-model\";\nimport { lazy } from \"react\";\n\n/** Document editor module for the \"powerhouse/package\" document type */\nexport const VetraPackageEditor: EditorModule = {\n Component: lazy(() => import(\"./editor.js\")),\n documentTypes: [\"powerhouse/package\"],\n config: {\n id: \"vetra-package-editor\",\n name: \"Vetra Package Editor\",\n },\n};\n"],"mappings":";;;AAQA,MAAa,YAA0B;CACrC,WAAW,WAAW,OAAO,wBAAe;CAC5C,eAAe,CAAC,iBAAiB;CACjC,QAAQ;EACN,IAAI;EACJ,MAAM;EACP;CACF;;;;ACPD,MAAa,uBAAqC;CAChD,WAAW,WAAW,OAAO,wBAAe;CAC5C,eAAe,CAAC,6BAA6B;CAC7C,QAAQ;EACN,IAAI;EACJ,MAAM;EACP;CACF;;;;ACPD,MAAa,wBAAsC;CACjD,WAAW,WAAW,OAAO,wBAAe;CAC5C,eAAe,CAAC,uBAAuB;CACvC,QAAQ;EACN,IAAI;EACJ,MAAM;EACP;CACF;;;;ACPD,MAAa,uBAAqC;CAChD,WAAW,WAAW,OAAO,wBAAe;CAC5C,eAAe,CAAC,sBAAsB;CACtC,QAAQ;EACN,IAAI;EACJ,MAAM;EACP;CACF;;;ACZD,MAAa,gBAA8B;CACzC,WAAW,WAAW,OAAO,wBAAe;CAC5C,eAAe,CAAC,4BAA4B;CAC5C,QAAQ;EACN,IAAI;EACJ,MAAM;EACP;CACF;;;;ACFD,MAAa,qBAAmC;CAC9C,WAAW,WAAW,OAAO,wBAAe;CAC5C,eAAe,CAAC,qBAAqB;CACrC,QAAQ;EACN,IAAI;EACJ,MAAM;EACP;CACF"}
@@ -637,4 +637,4 @@ function pathSubdir(filePath) {
637
637
  //#endregion
638
638
  export { getDocument as a, getDocuments as c, getSpecEntry as d, listSpecDocumentTypes as f, stripLeadingDot as g, specPath as h, deleteDocument as i, validateActions as l, specDir as m, addActionsAndSave as n, getDocumentModelSchema as o, saveSpec as p, createDocument as r, getDocumentModels as s, addActions as t, SPECS_DIRNAME as u };
639
639
 
640
- //# sourceMappingURL=spec-api-CT1DqmgF.js.map
640
+ //# sourceMappingURL=spec-api-D2QObgjc.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"spec-api-CT1DqmgF.js","names":["documentEditorReducer","documentEditorUtils","documentEditorActions","documentEditorSpec","processorModuleReducer","processorModuleUtils","processorModuleActions","processorModuleSpec","subgraphModuleReducer","subgraphModuleUtils","subgraphModuleActions","subgraphModuleSpec","appModuleReducer","appModuleUtils","appModuleActions","appModuleSpec"],"sources":["../document-models/app-module/app-module.json","../document-models/document-editor/document-editor.json","../document-models/processor-module/processor-module.json","../document-models/subgraph-module/subgraph-module.json","../codegen/specs.ts","../codegen/spec-api.ts"],"sourcesContent":["","","","","import type {\n Action,\n DocumentModelGlobalState,\n PHDocument,\n Reducer,\n} from \"@powerhousedao/shared/document-model\";\nimport { kebabCase } from \"change-case\";\nimport { documentModelDocumentModelModule } from \"document-model\";\nimport { baseSaveToFile } from \"document-model/node\";\nimport { mkdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\n/* Import from gen/ + actions.ts directly (not the top-level barrel) so we\n * don't pull in `hooks.ts`, which depends on `@powerhousedao/reactor-browser`\n * (a browser-only module that breaks Node-side spec tooling). */\nimport appModuleSpec from \"../document-models/app-module/app-module.json\" with { type: \"json\" };\nimport { actions as appModuleActions } from \"../document-models/app-module/v1/actions.js\";\nimport {\n appModuleDocumentType,\n createAppModuleDocument,\n reducer as appModuleReducer,\n utils as appModuleUtils,\n} from \"../document-models/app-module/v1/gen/index.js\";\nimport documentEditorSpec from \"../document-models/document-editor/document-editor.json\" with { type: \"json\" };\nimport { actions as documentEditorActions } from \"../document-models/document-editor/v1/actions.js\";\nimport {\n createDocumentEditorDocument,\n documentEditorDocumentType,\n reducer as documentEditorReducer,\n utils as documentEditorUtils,\n} from \"../document-models/document-editor/v1/gen/index.js\";\nimport processorModuleSpec from \"../document-models/processor-module/processor-module.json\" with { type: \"json\" };\nimport { actions as processorModuleActions } from \"../document-models/processor-module/v1/actions.js\";\nimport {\n createProcessorModuleDocument,\n processorModuleDocumentType,\n reducer as processorModuleReducer,\n utils as processorModuleUtils,\n} from \"../document-models/processor-module/v1/gen/index.js\";\nimport subgraphModuleSpec from \"../document-models/subgraph-module/subgraph-module.json\" with { type: \"json\" };\nimport { actions as subgraphModuleActions } from \"../document-models/subgraph-module/v1/actions.js\";\nimport {\n createSubgraphModuleDocument,\n subgraphModuleDocumentType,\n reducer as subgraphModuleReducer,\n utils as subgraphModuleUtils,\n} from \"../document-models/subgraph-module/v1/gen/index.js\";\n\nexport const SPECS_DIRNAME = \"specs\";\n\nconst documentModelDocumentType = \"powerhouse/document-model\";\n\ntype ActionsModule = Record<string, (input?: any) => Action>;\n\ntype SpecEntry = {\n documentType: string;\n subdir: string;\n reducer: Reducer<any>;\n utils: { fileExtension: string };\n actions: ActionsModule;\n createDocument: (state?: any) => PHDocument;\n jsonSpec: DocumentModelGlobalState;\n};\n\nconst SPECS: Record<string, SpecEntry> = {\n [documentModelDocumentType]: {\n documentType: documentModelDocumentType,\n subdir: \"document-models\",\n reducer: documentModelDocumentModelModule.reducer,\n utils: documentModelDocumentModelModule.utils,\n actions: documentModelDocumentModelModule.actions as ActionsModule,\n createDocument: documentModelDocumentModelModule.utils.createDocument,\n jsonSpec: documentModelDocumentModelModule.documentModel\n .global as DocumentModelGlobalState,\n },\n [documentEditorDocumentType]: {\n documentType: documentEditorDocumentType,\n subdir: \"editors\",\n reducer: documentEditorReducer as Reducer<any>,\n utils: documentEditorUtils,\n actions: documentEditorActions as unknown as ActionsModule,\n createDocument: createDocumentEditorDocument as (state?: any) => PHDocument,\n jsonSpec: documentEditorSpec as unknown as DocumentModelGlobalState,\n },\n [processorModuleDocumentType]: {\n documentType: processorModuleDocumentType,\n subdir: \"processors\",\n reducer: processorModuleReducer as Reducer<any>,\n utils: processorModuleUtils,\n actions: processorModuleActions as unknown as ActionsModule,\n createDocument: createProcessorModuleDocument as (\n state?: any,\n ) => PHDocument,\n jsonSpec: processorModuleSpec as unknown as DocumentModelGlobalState,\n },\n [subgraphModuleDocumentType]: {\n documentType: subgraphModuleDocumentType,\n subdir: \"subgraphs\",\n reducer: subgraphModuleReducer as Reducer<any>,\n utils: subgraphModuleUtils,\n actions: subgraphModuleActions as unknown as ActionsModule,\n createDocument: createSubgraphModuleDocument as (state?: any) => PHDocument,\n jsonSpec: subgraphModuleSpec as unknown as DocumentModelGlobalState,\n },\n [appModuleDocumentType]: {\n documentType: appModuleDocumentType,\n subdir: \"apps\",\n reducer: appModuleReducer as Reducer<any>,\n utils: appModuleUtils,\n actions: appModuleActions as unknown as ActionsModule,\n createDocument: createAppModuleDocument as (state?: any) => PHDocument,\n jsonSpec: appModuleSpec as unknown as DocumentModelGlobalState,\n },\n};\n\nexport function getSpecEntry(documentType: string): SpecEntry {\n const entry = SPECS[documentType];\n if (!entry) {\n throw new Error(`No spec handler registered for \"${documentType}\"`);\n }\n return entry;\n}\n\nexport function listSpecDocumentTypes(): string[] {\n return Object.keys(SPECS);\n}\n\n/** Returns the directory that holds specs for a given document type. */\nexport function specDir(projectDir: string, documentType: string): string {\n return join(projectDir, SPECS_DIRNAME, getSpecEntry(documentType).subdir);\n}\n\n/**\n * Deterministic path for a doc-type + display name.\n * Format: `<projectDir>/<specsDir>/<subdir>/<kebab-name>.<ext>.phd`.\n */\nexport function specPath(\n projectDir: string,\n documentType: string,\n name: string,\n): string {\n const entry = getSpecEntry(documentType);\n const baseName = kebabCase(name);\n const ext = stripLeadingDot(entry.utils.fileExtension);\n return join(specDir(projectDir, documentType), `${baseName}.${ext}.phd`);\n}\n\n/* baseSaveToFile expects the extension WITHOUT a leading dot (\"phdm\"), while the\n * document-model utils export it WITH one (\".phdm\"). Normalize so we can pass\n * either through. */\nexport function stripLeadingDot(ext: string): string {\n return ext.startsWith(\".\") ? ext.slice(1) : ext;\n}\n\n/** Saves a document into `<projectDir>/specs/<subdir>/<kebab-name>.<ext>.phd`. */\nexport async function saveSpec(\n doc: PHDocument,\n projectDir: string,\n): Promise<string> {\n const entry = getSpecEntry(doc.header.documentType);\n const dir = specDir(projectDir, doc.header.documentType);\n await mkdir(dir, { recursive: true });\n const name = kebabCase(doc.header.name || \"untitled\");\n return baseSaveToFile(\n doc,\n dir,\n stripLeadingDot(entry.utils.fileExtension),\n name,\n );\n}\n","/**\n * File-backed mirror of reactor-mcp's tool surface. Same function names and\n * input shapes — same agent code works whether it's targeting a live reactor\n * or a `specs/` folder on disk. The \"drive id\" is the project directory;\n * \"document id\" is the file path of the spec.\n *\n * See `packages/reactor-mcp/src/tools/reactor.ts` for the canonical schema.\n */\nimport type {\n Action,\n DocumentModelGlobalState,\n OperationSpecification,\n PHDocument,\n} from \"@powerhousedao/shared/document-model\";\nimport { camelCase } from \"change-case\";\nimport { baseLoadFromFile } from \"document-model/node\";\nimport { readdir, rm, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport {\n getSpecEntry,\n listSpecDocumentTypes,\n saveSpec,\n specDir,\n SPECS_DIRNAME,\n} from \"./specs.js\";\n\nexport type DocumentModelInfo = {\n name: string;\n type: string;\n description: string;\n extension: string;\n authorName: string;\n authorWebsite: string;\n};\n\n/** Mirrors reactor-mcp `getDocumentModels`. */\nexport function getDocumentModels(): DocumentModelInfo[] {\n return listSpecDocumentTypes().map((documentType) => {\n const { jsonSpec } = getSpecEntry(documentType);\n return {\n name: jsonSpec.name,\n type: jsonSpec.id,\n description: jsonSpec.description ?? \"\",\n extension: jsonSpec.extension ?? \"\",\n authorName: jsonSpec.author?.name ?? \"\",\n authorWebsite: jsonSpec.author?.website ?? \"\",\n };\n });\n}\n\n/** Mirrors reactor-mcp `getDocumentModelSchema`. Returns the full\n * `DocumentModelGlobalState` (schema + operations + errors), same payload\n * shape reactor-mcp serves. */\nexport function getDocumentModelSchema(\n documentType: string,\n): DocumentModelGlobalState {\n return getSpecEntry(documentType).jsonSpec;\n}\n\n/** Mirrors reactor-mcp `getDocument`. Path = file location on disk. */\nexport async function getDocument(path: string): Promise<PHDocument> {\n // We don't know the documentType ahead of time, so try each registered\n // reducer until one loads cleanly. baseLoadFromFile validates against the\n // reducer; the wrong reducer rejects. Try the path's parent directory first\n // as a fast hint (matches our `specs/<subdir>/` convention).\n const subdir = pathSubdir(path);\n const hint = subdir\n ? listSpecDocumentTypes().find((t) => getSpecEntry(t).subdir === subdir)\n : undefined;\n const order = hint\n ? [hint, ...listSpecDocumentTypes().filter((t) => t !== hint)]\n : listSpecDocumentTypes();\n\n let lastError: unknown;\n for (const documentType of order) {\n const { reducer } = getSpecEntry(documentType);\n try {\n return await baseLoadFromFile(path, reducer);\n } catch (err) {\n lastError = err;\n }\n }\n throw new Error(\n `Failed to load spec at \"${path}\": no registered reducer accepted it. Last error: ${String(lastError)}`,\n );\n}\n\n/** Mirrors reactor-mcp `getDocuments`. `parentId` is the project directory\n * containing `specs/`. */\nexport async function getDocuments(\n projectDir: string,\n opts: { documentType?: string } = {},\n): Promise<PHDocument[]> {\n const documentTypes = opts.documentType\n ? [opts.documentType]\n : listSpecDocumentTypes();\n\n const results: PHDocument[] = [];\n for (const documentType of documentTypes) {\n const dir = specDir(projectDir, documentType);\n const exists = await stat(dir).then(\n (s) => s.isDirectory(),\n () => false,\n );\n if (!exists) continue;\n const entries = await readdir(dir);\n for (const entry of entries) {\n if (!entry.endsWith(\".phd\")) continue;\n results.push(await getDocument(join(dir, entry)));\n }\n }\n return results;\n}\n\n/** Mirrors reactor-mcp `createDocument`. Returns an in-memory document; the\n * caller persists with `saveSpec`. */\nexport function createDocument(\n documentType: string,\n opts: {\n name?: string;\n initialState?: { global?: unknown; local?: unknown };\n } = {},\n): PHDocument {\n const entry = getSpecEntry(documentType);\n const doc = entry.createDocument(opts.initialState);\n if (opts.name) doc.header.name = opts.name;\n return doc;\n}\n\nexport type ActionInput = {\n type: string;\n input?: unknown;\n scope?: string;\n};\n\n/** Mirrors reactor-mcp `addActions`. Validates every action up front against\n * the document model's latest specification, then applies them in order via\n * the reducer. If any action is invalid, throws an aggregated error and\n * leaves `doc` untouched. */\nexport function addActions(\n doc: PHDocument,\n actions: ActionInput[],\n): PHDocument {\n const entry = getSpecEntry(doc.header.documentType);\n const built = validateAndBuildActions(entry, actions);\n let current = doc;\n for (let i = 0; i < built.length; i++) {\n const action = built[i];\n current = entry.reducer(current, action);\n /* The base reducer wraps custom reducers in try/catch and records any\n * throw as `operation.error` instead of propagating. For an atomic\n * batch apply that's the wrong shape — surface the error so callers\n * (and `saveSpec`) bail out before persisting a half-applied doc. */\n const scope = action.scope ?? \"global\";\n const ops = current.operations[scope];\n const last = ops?.[ops.length - 1];\n if (last?.error) {\n const failures: ActionValidationError[] = [\n {\n index: i,\n type: actions[i].type ?? \"<missing>\",\n errors: [`Reducer error: ${last.error}`],\n },\n ];\n throw formatValidationError(failures);\n }\n }\n return current;\n}\n\nexport type ActionValidationError = {\n /** Position in the input array. */\n index: number;\n /** The action's `type` field (or `<missing>` when not a string). */\n type: string;\n /** Human-readable reasons the action was rejected. */\n errors: string[];\n};\n\n/** Validate a list of actions without applying them. Returns one entry per\n * invalid action with all of its problems aggregated. Used by `addActions`\n * and exposed for callers that want a dry-run check. */\nexport function validateActions(\n documentType: string,\n actions: ActionInput[],\n): ActionValidationError[] {\n const entry = getSpecEntry(documentType);\n const failures: ActionValidationError[] = [];\n for (let i = 0; i < actions.length; i++) {\n const errors = collectActionErrors(entry, actions[i]);\n if (errors.length > 0) {\n failures.push({ index: i, type: actions[i].type ?? \"<missing>\", errors });\n }\n }\n return failures;\n}\n\n/** Run validateActions across the batch and, on success, materialize the\n * built Action objects. On any failure throws with every action's errors\n * aggregated — the caller never sees a partial apply. */\nfunction validateAndBuildActions(\n entry: ReturnType<typeof getSpecEntry>,\n actions: ActionInput[],\n): Action[] {\n const built: Action[] = [];\n const failures: ActionValidationError[] = [];\n for (let i = 0; i < actions.length; i++) {\n const item = actions[i];\n const errors = collectActionErrors(entry, item);\n if (errors.length > 0) {\n failures.push({ index: i, type: item.type ?? \"<missing>\", errors });\n continue;\n }\n built.push(buildAction(entry.actions, item));\n }\n if (failures.length > 0) throw formatValidationError(failures);\n return built;\n}\n\n/* Mirrors reactor-mcp's `validateDocumentModelAction`: confirms the operation\n * is declared in the latest spec, looks up the action creator, runs the\n * creator's own input validation, and checks scope. */\nfunction collectActionErrors(\n entry: ReturnType<typeof getSpecEntry>,\n item: ActionInput,\n): string[] {\n const errors: string[] = [];\n if (typeof item.type !== \"string\" || item.type.length === 0) {\n errors.push(\"Missing `type` field\");\n return errors;\n }\n const specs = entry.jsonSpec.specifications;\n if (!specs || specs.length === 0) {\n errors.push(\"Document model has no specifications\");\n return errors;\n }\n const latest = specs[specs.length - 1];\n let operation: OperationSpecification | undefined;\n for (const module of latest.modules ?? []) {\n const found = (module.operations ?? []).find((op) => op.name === item.type);\n if (found) {\n operation = found;\n break;\n }\n }\n if (!operation) {\n errors.push(\n `Operation \"${item.type}\" is not defined in any module of the document model`,\n );\n }\n const creatorName = camelCase(item.type);\n const creator = entry.actions[creatorName];\n if (!creator) {\n errors.push(`No action creator found.`);\n } else {\n try {\n creator(item.input);\n } catch (err) {\n errors.push(\n `Input validation error: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n if (operation?.scope && item.scope && item.scope !== operation.scope) {\n errors.push(\n `Scope \"${item.scope}\" does not match operation scope \"${operation.scope}\"`,\n );\n }\n return errors;\n}\n\nfunction formatValidationError(failures: ActionValidationError[]): Error {\n const lines = failures.map(\n (f) => ` [${f.index}] ${f.type}: ${f.errors.join(\"; \")}`,\n );\n const header =\n failures.length === 1\n ? \"1 action failed validation:\"\n : `${failures.length} actions failed validation:`;\n const err = new Error([header, ...lines].join(\"\\n\")) as Error & {\n failures: ActionValidationError[];\n };\n err.failures = failures;\n return err;\n}\n\nfunction buildAction(\n actionsModule: Record<string, (input?: any) => Action>,\n item: ActionInput,\n): Action {\n const creatorName = camelCase(item.type);\n const creator = actionsModule[creatorName];\n if (!creator) {\n throw new Error(\n `No action creator found for \"${item.type}\" (looked up as \"${creatorName}\")`,\n );\n }\n const action = creator(item.input);\n // Caller may override the scope (creator picks a default).\n if (item.scope) action.scope = item.scope;\n return action;\n}\n\n/** Mirrors reactor-mcp `deleteDocument`. Removes the spec file from disk. */\nexport async function deleteDocument(\n path: string,\n): Promise<{ success: boolean }> {\n try {\n await rm(path);\n return { success: true };\n } catch {\n return { success: false };\n }\n}\n\n/* Convenience: persist after applying actions. Matches the typical agent\n * loop `getDocument → addActions → saveSpec` from the plan. */\nexport async function addActionsAndSave(\n path: string,\n projectDir: string,\n actions: ActionInput[],\n): Promise<{ doc: PHDocument; savedPath: string }> {\n const doc = await getDocument(path);\n const next = addActions(doc, actions);\n const savedPath = await saveSpec(next, projectDir);\n return { doc: next, savedPath };\n}\n\nfunction pathSubdir(filePath: string): string | undefined {\n const parts = filePath.split(/[/\\\\]/);\n const i = parts.lastIndexOf(SPECS_DIRNAME);\n if (i < 0 || i + 1 >= parts.length) return undefined;\n return parts[i + 1];\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"spec-api-D2QObgjc.js","names":["documentEditorReducer","documentEditorUtils","documentEditorActions","documentEditorSpec","processorModuleReducer","processorModuleUtils","processorModuleActions","processorModuleSpec","subgraphModuleReducer","subgraphModuleUtils","subgraphModuleActions","subgraphModuleSpec","appModuleReducer","appModuleUtils","appModuleActions","appModuleSpec"],"sources":["../document-models/app-module/app-module.json","../document-models/document-editor/document-editor.json","../document-models/processor-module/processor-module.json","../document-models/subgraph-module/subgraph-module.json","../codegen/specs.ts","../codegen/spec-api.ts"],"sourcesContent":["","","","","import type {\n Action,\n DocumentModelGlobalState,\n PHDocument,\n Reducer,\n} from \"@powerhousedao/shared/document-model\";\nimport { kebabCase } from \"change-case\";\nimport { documentModelDocumentModelModule } from \"document-model\";\nimport { baseSaveToFile } from \"document-model/node\";\nimport { mkdir } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\n/* Import from gen/ + actions.ts directly (not the top-level barrel) so we\n * don't pull in `hooks.ts`, which depends on `@powerhousedao/reactor-browser`\n * (a browser-only module that breaks Node-side spec tooling). */\nimport appModuleSpec from \"../document-models/app-module/app-module.json\" with { type: \"json\" };\nimport { actions as appModuleActions } from \"../document-models/app-module/v1/actions.js\";\nimport {\n appModuleDocumentType,\n createAppModuleDocument,\n reducer as appModuleReducer,\n utils as appModuleUtils,\n} from \"../document-models/app-module/v1/gen/index.js\";\nimport documentEditorSpec from \"../document-models/document-editor/document-editor.json\" with { type: \"json\" };\nimport { actions as documentEditorActions } from \"../document-models/document-editor/v1/actions.js\";\nimport {\n createDocumentEditorDocument,\n documentEditorDocumentType,\n reducer as documentEditorReducer,\n utils as documentEditorUtils,\n} from \"../document-models/document-editor/v1/gen/index.js\";\nimport processorModuleSpec from \"../document-models/processor-module/processor-module.json\" with { type: \"json\" };\nimport { actions as processorModuleActions } from \"../document-models/processor-module/v1/actions.js\";\nimport {\n createProcessorModuleDocument,\n processorModuleDocumentType,\n reducer as processorModuleReducer,\n utils as processorModuleUtils,\n} from \"../document-models/processor-module/v1/gen/index.js\";\nimport subgraphModuleSpec from \"../document-models/subgraph-module/subgraph-module.json\" with { type: \"json\" };\nimport { actions as subgraphModuleActions } from \"../document-models/subgraph-module/v1/actions.js\";\nimport {\n createSubgraphModuleDocument,\n subgraphModuleDocumentType,\n reducer as subgraphModuleReducer,\n utils as subgraphModuleUtils,\n} from \"../document-models/subgraph-module/v1/gen/index.js\";\n\nexport const SPECS_DIRNAME = \"specs\";\n\nconst documentModelDocumentType = \"powerhouse/document-model\";\n\ntype ActionsModule = Record<string, (input?: any) => Action>;\n\ntype SpecEntry = {\n documentType: string;\n subdir: string;\n reducer: Reducer<any>;\n utils: { fileExtension: string };\n actions: ActionsModule;\n createDocument: (state?: any) => PHDocument;\n jsonSpec: DocumentModelGlobalState;\n};\n\nconst SPECS: Record<string, SpecEntry> = {\n [documentModelDocumentType]: {\n documentType: documentModelDocumentType,\n subdir: \"document-models\",\n reducer: documentModelDocumentModelModule.reducer,\n utils: documentModelDocumentModelModule.utils,\n actions: documentModelDocumentModelModule.actions as ActionsModule,\n createDocument: documentModelDocumentModelModule.utils.createDocument,\n jsonSpec: documentModelDocumentModelModule.documentModel\n .global as DocumentModelGlobalState,\n },\n [documentEditorDocumentType]: {\n documentType: documentEditorDocumentType,\n subdir: \"editors\",\n reducer: documentEditorReducer as Reducer<any>,\n utils: documentEditorUtils,\n actions: documentEditorActions as unknown as ActionsModule,\n createDocument: createDocumentEditorDocument as (state?: any) => PHDocument,\n jsonSpec: documentEditorSpec as unknown as DocumentModelGlobalState,\n },\n [processorModuleDocumentType]: {\n documentType: processorModuleDocumentType,\n subdir: \"processors\",\n reducer: processorModuleReducer as Reducer<any>,\n utils: processorModuleUtils,\n actions: processorModuleActions as unknown as ActionsModule,\n createDocument: createProcessorModuleDocument as (\n state?: any,\n ) => PHDocument,\n jsonSpec: processorModuleSpec as unknown as DocumentModelGlobalState,\n },\n [subgraphModuleDocumentType]: {\n documentType: subgraphModuleDocumentType,\n subdir: \"subgraphs\",\n reducer: subgraphModuleReducer as Reducer<any>,\n utils: subgraphModuleUtils,\n actions: subgraphModuleActions as unknown as ActionsModule,\n createDocument: createSubgraphModuleDocument as (state?: any) => PHDocument,\n jsonSpec: subgraphModuleSpec as unknown as DocumentModelGlobalState,\n },\n [appModuleDocumentType]: {\n documentType: appModuleDocumentType,\n subdir: \"apps\",\n reducer: appModuleReducer as Reducer<any>,\n utils: appModuleUtils,\n actions: appModuleActions as unknown as ActionsModule,\n createDocument: createAppModuleDocument as (state?: any) => PHDocument,\n jsonSpec: appModuleSpec as unknown as DocumentModelGlobalState,\n },\n};\n\nexport function getSpecEntry(documentType: string): SpecEntry {\n const entry = SPECS[documentType];\n if (!entry) {\n throw new Error(`No spec handler registered for \"${documentType}\"`);\n }\n return entry;\n}\n\nexport function listSpecDocumentTypes(): string[] {\n return Object.keys(SPECS);\n}\n\n/** Returns the directory that holds specs for a given document type. */\nexport function specDir(projectDir: string, documentType: string): string {\n return join(projectDir, SPECS_DIRNAME, getSpecEntry(documentType).subdir);\n}\n\n/**\n * Deterministic path for a doc-type + display name.\n * Format: `<projectDir>/<specsDir>/<subdir>/<kebab-name>.<ext>.phd`.\n */\nexport function specPath(\n projectDir: string,\n documentType: string,\n name: string,\n): string {\n const entry = getSpecEntry(documentType);\n const baseName = kebabCase(name);\n const ext = stripLeadingDot(entry.utils.fileExtension);\n return join(specDir(projectDir, documentType), `${baseName}.${ext}.phd`);\n}\n\n/* baseSaveToFile expects the extension WITHOUT a leading dot (\"phdm\"), while the\n * document-model utils export it WITH one (\".phdm\"). Normalize so we can pass\n * either through. */\nexport function stripLeadingDot(ext: string): string {\n return ext.startsWith(\".\") ? ext.slice(1) : ext;\n}\n\n/** Saves a document into `<projectDir>/specs/<subdir>/<kebab-name>.<ext>.phd`. */\nexport async function saveSpec(\n doc: PHDocument,\n projectDir: string,\n): Promise<string> {\n const entry = getSpecEntry(doc.header.documentType);\n const dir = specDir(projectDir, doc.header.documentType);\n await mkdir(dir, { recursive: true });\n const name = kebabCase(doc.header.name || \"untitled\");\n return baseSaveToFile(\n doc,\n dir,\n stripLeadingDot(entry.utils.fileExtension),\n name,\n );\n}\n","/**\n * File-backed mirror of reactor-mcp's tool surface. Same function names and\n * input shapes — same agent code works whether it's targeting a live reactor\n * or a `specs/` folder on disk. The \"drive id\" is the project directory;\n * \"document id\" is the file path of the spec.\n *\n * See `packages/reactor-mcp/src/tools/reactor.ts` for the canonical schema.\n */\nimport type {\n Action,\n DocumentModelGlobalState,\n OperationSpecification,\n PHDocument,\n} from \"@powerhousedao/shared/document-model\";\nimport { camelCase } from \"change-case\";\nimport { baseLoadFromFile } from \"document-model/node\";\nimport { readdir, rm, stat } from \"node:fs/promises\";\nimport { join } from \"node:path\";\n\nimport {\n getSpecEntry,\n listSpecDocumentTypes,\n saveSpec,\n specDir,\n SPECS_DIRNAME,\n} from \"./specs.js\";\n\nexport type DocumentModelInfo = {\n name: string;\n type: string;\n description: string;\n extension: string;\n authorName: string;\n authorWebsite: string;\n};\n\n/** Mirrors reactor-mcp `getDocumentModels`. */\nexport function getDocumentModels(): DocumentModelInfo[] {\n return listSpecDocumentTypes().map((documentType) => {\n const { jsonSpec } = getSpecEntry(documentType);\n return {\n name: jsonSpec.name,\n type: jsonSpec.id,\n description: jsonSpec.description ?? \"\",\n extension: jsonSpec.extension ?? \"\",\n authorName: jsonSpec.author?.name ?? \"\",\n authorWebsite: jsonSpec.author?.website ?? \"\",\n };\n });\n}\n\n/** Mirrors reactor-mcp `getDocumentModelSchema`. Returns the full\n * `DocumentModelGlobalState` (schema + operations + errors), same payload\n * shape reactor-mcp serves. */\nexport function getDocumentModelSchema(\n documentType: string,\n): DocumentModelGlobalState {\n return getSpecEntry(documentType).jsonSpec;\n}\n\n/** Mirrors reactor-mcp `getDocument`. Path = file location on disk. */\nexport async function getDocument(path: string): Promise<PHDocument> {\n // We don't know the documentType ahead of time, so try each registered\n // reducer until one loads cleanly. baseLoadFromFile validates against the\n // reducer; the wrong reducer rejects. Try the path's parent directory first\n // as a fast hint (matches our `specs/<subdir>/` convention).\n const subdir = pathSubdir(path);\n const hint = subdir\n ? listSpecDocumentTypes().find((t) => getSpecEntry(t).subdir === subdir)\n : undefined;\n const order = hint\n ? [hint, ...listSpecDocumentTypes().filter((t) => t !== hint)]\n : listSpecDocumentTypes();\n\n let lastError: unknown;\n for (const documentType of order) {\n const { reducer } = getSpecEntry(documentType);\n try {\n return await baseLoadFromFile(path, reducer);\n } catch (err) {\n lastError = err;\n }\n }\n throw new Error(\n `Failed to load spec at \"${path}\": no registered reducer accepted it. Last error: ${String(lastError)}`,\n );\n}\n\n/** Mirrors reactor-mcp `getDocuments`. `parentId` is the project directory\n * containing `specs/`. */\nexport async function getDocuments(\n projectDir: string,\n opts: { documentType?: string } = {},\n): Promise<PHDocument[]> {\n const documentTypes = opts.documentType\n ? [opts.documentType]\n : listSpecDocumentTypes();\n\n const results: PHDocument[] = [];\n for (const documentType of documentTypes) {\n const dir = specDir(projectDir, documentType);\n const exists = await stat(dir).then(\n (s) => s.isDirectory(),\n () => false,\n );\n if (!exists) continue;\n const entries = await readdir(dir);\n for (const entry of entries) {\n if (!entry.endsWith(\".phd\")) continue;\n results.push(await getDocument(join(dir, entry)));\n }\n }\n return results;\n}\n\n/** Mirrors reactor-mcp `createDocument`. Returns an in-memory document; the\n * caller persists with `saveSpec`. */\nexport function createDocument(\n documentType: string,\n opts: {\n name?: string;\n initialState?: { global?: unknown; local?: unknown };\n } = {},\n): PHDocument {\n const entry = getSpecEntry(documentType);\n const doc = entry.createDocument(opts.initialState);\n if (opts.name) doc.header.name = opts.name;\n return doc;\n}\n\nexport type ActionInput = {\n type: string;\n input?: unknown;\n scope?: string;\n};\n\n/** Mirrors reactor-mcp `addActions`. Validates every action up front against\n * the document model's latest specification, then applies them in order via\n * the reducer. If any action is invalid, throws an aggregated error and\n * leaves `doc` untouched. */\nexport function addActions(\n doc: PHDocument,\n actions: ActionInput[],\n): PHDocument {\n const entry = getSpecEntry(doc.header.documentType);\n const built = validateAndBuildActions(entry, actions);\n let current = doc;\n for (let i = 0; i < built.length; i++) {\n const action = built[i];\n current = entry.reducer(current, action);\n /* The base reducer wraps custom reducers in try/catch and records any\n * throw as `operation.error` instead of propagating. For an atomic\n * batch apply that's the wrong shape — surface the error so callers\n * (and `saveSpec`) bail out before persisting a half-applied doc. */\n const scope = action.scope ?? \"global\";\n const ops = current.operations[scope];\n const last = ops?.[ops.length - 1];\n if (last?.error) {\n const failures: ActionValidationError[] = [\n {\n index: i,\n type: actions[i].type ?? \"<missing>\",\n errors: [`Reducer error: ${last.error}`],\n },\n ];\n throw formatValidationError(failures);\n }\n }\n return current;\n}\n\nexport type ActionValidationError = {\n /** Position in the input array. */\n index: number;\n /** The action's `type` field (or `<missing>` when not a string). */\n type: string;\n /** Human-readable reasons the action was rejected. */\n errors: string[];\n};\n\n/** Validate a list of actions without applying them. Returns one entry per\n * invalid action with all of its problems aggregated. Used by `addActions`\n * and exposed for callers that want a dry-run check. */\nexport function validateActions(\n documentType: string,\n actions: ActionInput[],\n): ActionValidationError[] {\n const entry = getSpecEntry(documentType);\n const failures: ActionValidationError[] = [];\n for (let i = 0; i < actions.length; i++) {\n const errors = collectActionErrors(entry, actions[i]);\n if (errors.length > 0) {\n failures.push({ index: i, type: actions[i].type ?? \"<missing>\", errors });\n }\n }\n return failures;\n}\n\n/** Run validateActions across the batch and, on success, materialize the\n * built Action objects. On any failure throws with every action's errors\n * aggregated — the caller never sees a partial apply. */\nfunction validateAndBuildActions(\n entry: ReturnType<typeof getSpecEntry>,\n actions: ActionInput[],\n): Action[] {\n const built: Action[] = [];\n const failures: ActionValidationError[] = [];\n for (let i = 0; i < actions.length; i++) {\n const item = actions[i];\n const errors = collectActionErrors(entry, item);\n if (errors.length > 0) {\n failures.push({ index: i, type: item.type ?? \"<missing>\", errors });\n continue;\n }\n built.push(buildAction(entry.actions, item));\n }\n if (failures.length > 0) throw formatValidationError(failures);\n return built;\n}\n\n/* Mirrors reactor-mcp's `validateDocumentModelAction`: confirms the operation\n * is declared in the latest spec, looks up the action creator, runs the\n * creator's own input validation, and checks scope. */\nfunction collectActionErrors(\n entry: ReturnType<typeof getSpecEntry>,\n item: ActionInput,\n): string[] {\n const errors: string[] = [];\n if (typeof item.type !== \"string\" || item.type.length === 0) {\n errors.push(\"Missing `type` field\");\n return errors;\n }\n const specs = entry.jsonSpec.specifications;\n if (!specs || specs.length === 0) {\n errors.push(\"Document model has no specifications\");\n return errors;\n }\n const latest = specs[specs.length - 1];\n let operation: OperationSpecification | undefined;\n for (const module of latest.modules ?? []) {\n const found = (module.operations ?? []).find((op) => op.name === item.type);\n if (found) {\n operation = found;\n break;\n }\n }\n if (!operation) {\n errors.push(\n `Operation \"${item.type}\" is not defined in any module of the document model`,\n );\n }\n const creatorName = camelCase(item.type);\n const creator = entry.actions[creatorName];\n if (!creator) {\n errors.push(`No action creator found.`);\n } else {\n try {\n creator(item.input);\n } catch (err) {\n errors.push(\n `Input validation error: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n }\n if (operation?.scope && item.scope && item.scope !== operation.scope) {\n errors.push(\n `Scope \"${item.scope}\" does not match operation scope \"${operation.scope}\"`,\n );\n }\n return errors;\n}\n\nfunction formatValidationError(failures: ActionValidationError[]): Error {\n const lines = failures.map(\n (f) => ` [${f.index}] ${f.type}: ${f.errors.join(\"; \")}`,\n );\n const header =\n failures.length === 1\n ? \"1 action failed validation:\"\n : `${failures.length} actions failed validation:`;\n const err = new Error([header, ...lines].join(\"\\n\")) as Error & {\n failures: ActionValidationError[];\n };\n err.failures = failures;\n return err;\n}\n\nfunction buildAction(\n actionsModule: Record<string, (input?: any) => Action>,\n item: ActionInput,\n): Action {\n const creatorName = camelCase(item.type);\n const creator = actionsModule[creatorName];\n if (!creator) {\n throw new Error(\n `No action creator found for \"${item.type}\" (looked up as \"${creatorName}\")`,\n );\n }\n const action = creator(item.input);\n // Caller may override the scope (creator picks a default).\n if (item.scope) action.scope = item.scope;\n return action;\n}\n\n/** Mirrors reactor-mcp `deleteDocument`. Removes the spec file from disk. */\nexport async function deleteDocument(\n path: string,\n): Promise<{ success: boolean }> {\n try {\n await rm(path);\n return { success: true };\n } catch {\n return { success: false };\n }\n}\n\n/* Convenience: persist after applying actions. Matches the typical agent\n * loop `getDocument → addActions → saveSpec` from the plan. */\nexport async function addActionsAndSave(\n path: string,\n projectDir: string,\n actions: ActionInput[],\n): Promise<{ doc: PHDocument; savedPath: string }> {\n const doc = await getDocument(path);\n const next = addActions(doc, actions);\n const savedPath = await saveSpec(next, projectDir);\n return { doc: next, savedPath };\n}\n\nfunction pathSubdir(filePath: string): string | undefined {\n const parts = filePath.split(/[/\\\\]/);\n const i = parts.lastIndexOf(SPECS_DIRNAME);\n if (i < 0 || i + 1 >= parts.length) return undefined;\n return parts[i + 1];\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@powerhousedao/vetra",
3
- "version": "6.2.1-dev.1",
3
+ "version": "6.2.1-dev.3",
4
4
  "license": "AGPL-3.0-only",
5
5
  "type": "module",
6
6
  "sideEffects": false,
@@ -65,12 +65,12 @@
65
65
  "react": "19.2.6",
66
66
  "zod": "4.3.6",
67
67
  "tailwind-merge": "3.4.0",
68
- "@powerhousedao/config": "6.2.1-dev.1",
69
- "@powerhousedao/codegen": "6.2.1-dev.1",
70
- "@powerhousedao/design-system": "6.2.1-dev.1",
71
- "@powerhousedao/reactor-browser": "6.2.1-dev.1",
72
- "@powerhousedao/shared": "6.2.1-dev.1",
73
- "document-model": "6.2.1-dev.1"
68
+ "@powerhousedao/codegen": "6.2.1-dev.3",
69
+ "@powerhousedao/config": "6.2.1-dev.3",
70
+ "@powerhousedao/design-system": "6.2.1-dev.3",
71
+ "@powerhousedao/reactor-browser": "6.2.1-dev.3",
72
+ "@powerhousedao/shared": "6.2.1-dev.3",
73
+ "document-model": "6.2.1-dev.3"
74
74
  },
75
75
  "devDependencies": {
76
76
  "@tailwindcss/cli": "4.2.2",
@@ -89,7 +89,7 @@
89
89
  "vite": "8.0.10",
90
90
  "vite-tsconfig-paths": "6.1.1",
91
91
  "vitest": "4.1.1",
92
- "@powerhousedao/builder-tools": "6.2.1-dev.1"
92
+ "@powerhousedao/builder-tools": "6.2.1-dev.3"
93
93
  },
94
94
  "description": "Vetra — the agent-first builder platform for the Powerhouse ecosystem. Spec-driven and AI-native development of open-source, decentralized back-ends.",
95
95
  "keywords": [