@ideascol/flow-editor
v0.1.13
Published
Visual flow editor for ebook page layout and PDF export
Downloads
1,552
Readme
@ideascol/flow-editor
Visual flow editor for ebook page layout and PDF export.
Two ways to use it:
- Standalone CLI — run a local dev server with browser-side storage. Good for trying it out or authoring ebooks without a backend.
- Embedded library — mount
<FlowEditor />inside another React/Next.js app and wire it to your own auth, persistence, chat, and AI.
1. Standalone CLI
Setup (saves Gemini API key, encrypted)
npx @ideascol/flow-editor@latest setupYou'll be prompted for:
- Gemini API key — get one at https://aistudio.google.com/apikey
- Passphrase — used to encrypt the key on disk (
~/.cli-maker/flow-editor-config.json)
Run the editor
npx @ideascol/flow-editor@latest dev --ai geminiPrompts for the same passphrase you set in setup to decrypt the Gemini key. Editor opens at http://localhost:4242 with local browser storage (IndexedDB) — no backend needed.
Flags:
| Flag | Description |
|------|-------------|
| --port <n> | Port (default 4242) |
| --file <path> | Load an ebook JSON file on start |
| --ai <provider> | none (default) or gemini |
Skip the passphrase prompt by exporting GEMINI_API_KEY instead:
GEMINI_API_KEY=... npx @ideascol/flow-editor@latest dev --ai geminiOther commands:
npx @ideascol/flow-editor@latest show-config # show masked saved key2. Embedded in another app
Use the package as a React library. Host app supplies auth, persistence, toast, optional chat panel, and optional header actions. Reference integration: personal/ebook — src/components/flow-editor/FlowProviders.tsx.
Install
npm install @ideascol/flow-editorPeer deps required in the host: react 19, react-dom 19, @base-ui/react, @tiptap/react + @tiptap/starter-kit + @tiptap/pm + @tiptap/extension-placeholder, pdf-lib, @pdf-lib/fontkit, lucide-react, @chenglou/pretext.
Mount
"use client";
import {
FlowEditor,
FlowEditorProvider,
type EbookData,
type FlowLocale,
type FlowToast,
type FlowPersistence,
} from "@ideascol/flow-editor";
import { toast } from "sonner";
const flowToast: FlowToast = {
success: (m, o) => toast.success(m, o),
error: (m, o) => toast.error(m, o),
loading: (m) => toast.loading(m),
};
const flowPersistence: FlowPersistence = {
// load/save ebook + run edits against your backend (Firestore, Postgres, etc.)
// see ebook reference impl: src/lib/flow/persistence.ts
};
export function FlowEditorMount({
ebook,
ebookId,
canEdit,
user,
authLoading,
locale,
}: {
ebook: EbookData;
ebookId: string;
canEdit: boolean;
user: { uid: string } | null;
authLoading: boolean;
locale: FlowLocale;
}) {
return (
<FlowEditorProvider
user={user}
canEdit={canEdit}
authLoading={authLoading}
locale={locale}
persistence={flowPersistence}
toast={flowToast}
renderChatPanel={({ open, onClose, onChangesApplied }) => (
<YourChatPanel
ebookId={ebookId}
open={open}
onClose={onClose}
onChangesApplied={onChangesApplied}
/>
)}
renderHeaderActions={({ ebook, refetchEbook, jumpToChapter }) => (
<YourHeaderActions
ebook={ebook}
onApplied={refetchEbook}
onSelectChapter={jumpToChapter}
/>
)}
>
<FlowEditor ebook={ebook} />
</FlowEditorProvider>
);
}Read-only preview
import { FlowPreview } from "@ideascol/flow-editor";
<FlowEditorProvider /* ...same provider, canEdit={false}... */>
<FlowPreview ebook={ebook} />
</FlowEditorProvider>Pagination snapshot (server-side AI redesign, etc.)
import { flattenEbook, paginate, type PageLayout } from "@ideascol/flow-editor";
const lines = flattenEbook(ebook);
const pages: PageLayout[] = paginate(lines, layoutOpts);Provider contracts
persistence: FlowPersistence— load/save ebook, persist run edits, list catalog/user images.toast: FlowToast—success/error/loading.renderChatPanel?— your AI chat UI; receives{ open, onClose, onChangesApplied }.renderHeaderActions?— extra buttons in the editor header; receives{ ebook, refetchEbook, jumpToChapter }.locale: "en" | "es"— built-in messages; override viamessagesprop.
See src/index.ts for the full public API.
License
MIT
