{"_id":"@alexguha/rplib-editor","_rev":"4-46299ee0a649c17cc7f146d4423f3e12","name":"@alexguha/rplib-editor","dist-tags":{"latest":"0.3.0"},"versions":{"0.1.0":{"name":"@alexguha/rplib-editor","version":"0.1.0","keywords":["diagram","editor","rplib","svg","d3","visualization","dsl","codemirror"],"license":"ISC","_id":"@alexguha/rplib-editor@0.1.0","maintainers":[{"name":"alexguha","email":"alexandersguha@gmail.com"}],"homepage":"https://github.com/Alex-Guha/rplib#readme","bugs":{"url":"https://github.com/Alex-Guha/rplib/issues"},"dist":{"shasum":"f6e5407a32e15f6050b4a950ce2be7a7d6415ef8","tarball":"https://registry.npmjs.org/@alexguha/rplib-editor/-/rplib-editor-0.1.0.tgz","fileCount":39,"integrity":"sha512-/ck3uOQnBRgt4k1dZZu+0R6iMo6fuvqEzhCab4g0Zcfo+fl7XPAPYVjvcb7AZX91SQVJ3TrENSTqszE8zgmTVw==","signatures":[{"sig":"MEUCICTDN1KVTDZElLsz7sHAc7yycIG6vIshFh2Eav8p9LqrAiEA4z54R+VH/kndV9s9Ybs26D0vHMmHJRpcNxIolIGRXQo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":212361},"main":"index.js","type":"module","engines":{"node":">=18"},"exports":{".":"./index.js","./styles.css":"./styles.css"},"gitHead":"649560143b4ef431e8d7dd7875cc7b5696e58def","scripts":{"test":"node --test"},"_npmUser":{"name":"alexguha","email":"alexandersguha@gmail.com"},"repository":{"url":"git+https://github.com/Alex-Guha/rplib.git","type":"git","directory":"editor"},"_npmVersion":"11.11.1","description":"Generic diagram-editor UI built on top of rplib.","directories":{},"_nodeVersion":"25.8.2","dependencies":{"codemirror":"^6.0.2","@codemirror/lint":"^6.9.6","@codemirror/view":"^6.43.0","@lezer/highlight":"^1.2.3","@codemirror/state":"^6.6.0","@codemirror/search":"^6.7.0","@codemirror/commands":"^6.10.3","@codemirror/language":"^6.12.3","@codemirror/autocomplete":"^6.20.2"},"_hasShrinkwrap":false,"peerDependencies":{"d3":"^7.0.0","katex":"^0.16.0","@alexguha/rplib":"^0.1.0"},"_npmOperationalInternal":{"tmp":"tmp/rplib-editor_0.1.0_1779992888809_0.22584390128695886","host":"s3://npm-registry-packages-npm-production"}},"0.1.1":{"name":"@alexguha/rplib-editor","version":"0.1.1","keywords":["diagram","editor","rplib","svg","d3","visualization","dsl","codemirror"],"license":"ISC","_id":"@alexguha/rplib-editor@0.1.1","maintainers":[{"name":"alexguha","email":"alexandersguha@gmail.com"}],"homepage":"https://github.com/Alex-Guha/rplib#readme","bugs":{"url":"https://github.com/Alex-Guha/rplib/issues"},"dist":{"shasum":"c944a36e9ebbe7fa44cf5f7e2750bca7563cc119","tarball":"https://registry.npmjs.org/@alexguha/rplib-editor/-/rplib-editor-0.1.1.tgz","fileCount":41,"integrity":"sha512-aLf8B/wYcjFuNxQT9udcCBvxxYctouUWqYmdR+JOp/m+YFbyd8mvxFLqXlLkdJoKRvMAXYwmdbhbh1IEH2W6aw==","signatures":[{"sig":"MEYCIQCC8SbzPUBEeHXeQOvlCWtWMy55+chutJQNCtU8QDMrWQIhALMTwJcO28nDKCQ0VfSrLssYxF7A2EPrNfBLdWApHTIK","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":235402},"main":"index.js","type":"module","engines":{"node":">=18"},"exports":{".":"./index.js","./styles.css":"./styles.css"},"gitHead":"d4a23729c4a075fb70a98a61ef1fefaa363f2d56","scripts":{"test":"node --test"},"_npmUser":{"name":"alexguha","email":"alexandersguha@gmail.com"},"repository":{"url":"git+https://github.com/Alex-Guha/rplib.git","type":"git","directory":"editor"},"_npmVersion":"10.8.2","description":"Generic diagram-editor UI built on top of rplib.","directories":{},"_nodeVersion":"18.20.8","dependencies":{"codemirror":"^6.0.2","@codemirror/lint":"^6.9.6","@codemirror/view":"^6.43.0","@lezer/highlight":"^1.2.3","@codemirror/state":"^6.6.0","@codemirror/search":"^6.7.0","@codemirror/commands":"^6.10.3","@codemirror/language":"^6.12.3","@codemirror/autocomplete":"^6.20.2"},"_hasShrinkwrap":false,"peerDependencies":{"d3":"^7.0.0","katex":"^0.16.0","@alexguha/rplib":"^0.1.0"},"_npmOperationalInternal":{"tmp":"tmp/rplib-editor_0.1.1_1779995769866_0.36212999733151774","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@alexguha/rplib-editor","version":"0.2.0","keywords":["diagram","editor","rplib","svg","d3","visualization","dsl","codemirror"],"license":"ISC","_id":"@alexguha/rplib-editor@0.2.0","maintainers":[{"name":"alexguha","email":"alexandersguha@gmail.com"}],"homepage":"https://github.com/Alex-Guha/rplib#readme","bugs":{"url":"https://github.com/Alex-Guha/rplib/issues"},"dist":{"shasum":"ac8a4390456bd564157db58720e987a790b7f07a","tarball":"https://registry.npmjs.org/@alexguha/rplib-editor/-/rplib-editor-0.2.0.tgz","fileCount":41,"integrity":"sha512-JSrBiIp1CPFiBNZTvWHqWXZHyWL425fjSPPZilUntM98ChzNuaWUPsPiUBVnyC/wIqNNfQYLFsoGuG0gcwQTxA==","signatures":[{"sig":"MEQCID+orxEjdWNmKeWRTlAjhZrsSCcfvNHL1W98W3jgvgMnAiAD46dmeM/OtyLQCyQHz5RlZn/5MmX/kB29V+8QPclFjQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":253206},"main":"index.js","type":"module","engines":{"node":">=18"},"exports":{".":"./index.js","./styles.css":"./styles.css"},"gitHead":"ee63f535efad9995192b16e65f5e34ff4e139224","scripts":{"test":"node --test"},"_npmUser":{"name":"alexguha","email":"alexandersguha@gmail.com"},"repository":{"url":"git+https://github.com/Alex-Guha/rplib.git","type":"git","directory":"editor"},"_npmVersion":"10.8.2","description":"Generic diagram-editor UI built on top of rplib.","directories":{},"_nodeVersion":"18.20.8","dependencies":{"codemirror":"^6.0.2","@codemirror/lint":"^6.9.6","@codemirror/view":"^6.43.0","@lezer/highlight":"^1.2.3","@codemirror/state":"^6.6.0","@codemirror/search":"^6.7.0","@codemirror/commands":"^6.10.3","@codemirror/language":"^6.12.3","@codemirror/autocomplete":"^6.20.2"},"_hasShrinkwrap":false,"peerDependencies":{"d3":"^7.0.0","katex":"^0.16.0","@alexguha/rplib":"^0.2.0"},"_npmOperationalInternal":{"tmp":"tmp/rplib-editor_0.2.0_1780869584537_0.9797703669811324","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"@alexguha/rplib-editor","version":"0.3.0","description":"Generic diagram-editor UI built on top of rplib.","type":"module","main":"index.js","scripts":{"test":"node --test"},"exports":{".":"./index.js","./styles.css":"./styles.css"},"keywords":["diagram","editor","rplib","svg","d3","visualization","dsl","codemirror"],"repository":{"type":"git","url":"git+https://github.com/Alex-Guha/rplib.git","directory":"editor"},"homepage":"https://github.com/Alex-Guha/rplib#readme","bugs":{"url":"https://github.com/Alex-Guha/rplib/issues"},"engines":{"node":">=18"},"peerDependencies":{"d3":"^7.0.0","katex":"^0.16.0","@alexguha/rplib":"^0.3.0"},"license":"ISC","dependencies":{"@codemirror/autocomplete":"^6.20.2","@codemirror/commands":"^6.10.3","@codemirror/language":"^6.12.3","@codemirror/lint":"^6.9.6","@codemirror/search":"^6.7.0","@codemirror/state":"^6.6.0","@codemirror/view":"^6.43.0","@lezer/highlight":"^1.2.3","codemirror":"^6.0.2"},"gitHead":"3a15d9c28c2d74c5ce41012b5da76dfc567b503e","_id":"@alexguha/rplib-editor@0.3.0","_nodeVersion":"25.8.2","_npmVersion":"11.11.1","dist":{"integrity":"sha512-u4mywcSkhUGLYrSz4EXxl+ujIom5EL86S5j+ZEkGgqT/Hf0azt6BhK5RX9a+wV1/F5Yptmp8uF6qiwH9A+bH+A==","shasum":"bba5bb18027515379dfd7b10e02b1368e472d83e","tarball":"https://registry.npmjs.org/@alexguha/rplib-editor/-/rplib-editor-0.3.0.tgz","fileCount":41,"unpackedSize":259398,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCSK24NlQWPU7R1Yc9dyt0k4izDlSaC6M4HignWDJFTlwIhAMQca9i5EbSTO2Ga5QLeuuBaceHLRt26VnyRsEIioYqH"}]},"_npmUser":{"name":"alexguha","email":"alexandersguha@gmail.com"},"directories":{},"maintainers":[{"name":"alexguha","email":"alexandersguha@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/rplib-editor_0.3.0_1780963133733_0.3111328359227523"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-28T18:28:08.670Z","modified":"2026-06-08T23:58:53.967Z","0.1.0":"2026-05-28T18:28:08.937Z","0.1.1":"2026-05-28T19:16:10.010Z","0.2.0":"2026-06-07T21:59:44.684Z","0.3.0":"2026-06-08T23:58:53.870Z"},"bugs":{"url":"https://github.com/Alex-Guha/rplib/issues"},"license":"ISC","homepage":"https://github.com/Alex-Guha/rplib#readme","keywords":["diagram","editor","rplib","svg","d3","visualization","dsl","codemirror"],"repository":{"type":"git","url":"git+https://github.com/Alex-Guha/rplib.git","directory":"editor"},"description":"Generic diagram-editor UI built on top of rplib.","maintainers":[{"name":"alexguha","email":"alexandersguha@gmail.com"}],"readme":"# @alexguha/rplib-editor\n\nA generic diagram-editor UI built on top of [`@alexguha/rplib`](../core/). You supply a `data/` directory containing components (visual building blocks) and rplib-DSL abstract definitions (see [DSL.md](./DSL.md)); the editor handles canvas wiring, sidebar, navigation, theme switching, and settings persistence to `localStorage`.\n\nThe editor knows nothing about your domain. Labels, theme palettes, and storage are all overridable.\n\n## Install\n\n```sh\nnpm install @alexguha/rplib @alexguha/rplib-editor d3 katex\n```\n\n`@alexguha/rplib`, `d3`, and `katex` are peer dependencies.\n\n## Quickstart\n\nLay out your data as:\n\n```\ndata/\n  abstracts/   # any number of *.txt files (rplib-DSL), any names\n  components/  # any number of *.json / *.js files, nested freely\n```\n\nBefore serving the app, generate the manifest the runtime fetches:\n\n```sh\nnpx rplib-build-data ./data\n```\n\nThe recommended wiring is an npm script:\n\n```json\n{\n  \"scripts\": {\n    \"build:data\": \"rplib-build-data ./data\",\n    \"prestart\": \"npm run build:data\",\n    \"predev\": \"npm run build:data\"\n  }\n}\n```\n\nThen boot:\n\n```js\nimport { createEditor } from '@alexguha/rplib-editor';\n\nconst manager = await createEditor({\n  dataDir: './data',\n  labels: {\n    abstract: { singular: 'Architecture', plural: 'Architectures' },\n  },\n});\n\nmanager.restoreView('default_view');         // fallback if no saved view in localStorage\n```\n\nBundler users (Vite's `import.meta.glob`, webpack `require.context`) can skip the CLI and pass pre-aggregated input instead — see [`data` escape hatch](#pre-aggregated-data-escape-hatch) below.\n\nThe consumer also needs to:\n\n1. Load `@alexguha/rplib-editor/styles.css` somewhere in the page (`<link>` or bundler).\n2. Provide an `#svg` element and a `#sidebar` container holding an `#info` and a `#panels` child — the editor mounts into these by id. (`#info` is the description pane; `#panels` is the configurable panel region.)\n3. If running directly in the browser (no bundler), declare an importmap so bare specifiers resolve:\n\n   ```html\n   <script type=\"importmap\">\n   {\n     \"imports\": {\n       \"d3\": \"./node_modules/d3/.../d3.js\",\n       \"katex\": \"./node_modules/katex/dist/katex.mjs\",\n       \"@alexguha/rplib\": \"./node_modules/@alexguha/rplib/index.js\",\n       \"@alexguha/rplib/\": \"./node_modules/@alexguha/rplib/\",\n       \"@alexguha/rplib-editor\": \"./node_modules/@alexguha/rplib-editor/index.js\",\n       \"@alexguha/rplib-editor/\": \"./node_modules/@alexguha/rplib-editor/\"\n     }\n   }\n   </script>\n   ```\n\nSee [Neural-Atlas](https://github.com/Alex-Guha/Neural-Atlas) for a complete consumer example.\n\n## `createEditor(config)`\n\nExactly one of `dataDir` or `data` is required.\n\n| Field | Type | Required | Description |\n| --- | --- | --- | --- |\n| `dataDir` | string | one of | URL/path to a `data/` directory containing `abstracts/`, `components/`, and a `manifest.json` produced by `rplib-build-data`. Resolved relative to the page. |\n| `data` | object | one of | Pre-aggregated `{ abstractDefinitions, components }`. Escape hatch for bundler users who aggregate their own way. |\n| `labels` | object | no | Terminology overrides, e.g. `{ abstract: { singular: 'Architecture', plural: 'Architectures' } }`. Affects sidebar copy. |\n| `themes` | object | no | Extra named theme palettes merged on top of the editor's built-ins. Host-supplied themes win on name collision. |\n| `repoUrl` | string | no | URL the lower-left GitHub button links to. Omitted → button is rendered but inert. Reassign at runtime via `manager.setRepoUrl(url)`. |\n| `storage` | object | no | `{ getItem, setItem, removeItem }` adapter. Defaults to `localStorage` when available. |\n| `reporter` | object | no | `{ error, warn }` diagnostics sink. Defaults to `console`. |\n| `panels` | array | no | Ordered [panel definitions](#panels) rendered into the sidebar content region. Defaults to `[]` (empty region). **References is no longer built in** — supply a references panel to render it. |\n\nReturns a promise resolving to the `AppManager` instance.\n\n## Panels\n\nThe sidebar content region (the box below `#info`) renders an ordered array of\n**panel** definitions you supply via `panels`. References is no longer special —\nit's just a panel keyed to the `references` property. Panels are built from\n[`@alexguha/rplib/panel`](../core/README.md#panels-alexguharplibpanel); each owns\nits display, its editor (in the component editor), and its data key.\n\nOmit `panels` (or pass `[]`) and the region is empty; errors and confirmation\ndialogs still work (they take over the region transiently).\n\n### Getting references back (canonical recipe)\n\n```js\nimport { definePanel } from '@alexguha/rplib/panel';\nimport { createEditor } from '@alexguha/rplib-editor';\n\nconst referencesPanel = definePanel({\n  name: 'references',\n  title: 'References',\n  property: 'references',                 // → ctx.resolveProperty('references')\n  showWhen: (data) => !!data && Object.keys(data).length > 0,\n\n  // Editability: references is stored as an object keyed by title, so the\n  // component editor renders a list whose `title` field doubles as that key.\n  itemKey: 'title',\n  itemFields: { title: 'text', link: 'text', info: 'textarea', authors: 'list', refType: 'text' },\n\n  render(container, refs, ctx) {\n    const list = document.createElement('ul');\n    list.id = 'references-list';\n    Object.entries(refs).forEach(([title, ref]) => {\n      const a = document.createElement('a');\n      a.href = ref.link || '#';\n      a.target = '_blank';\n      a.textContent = title + (ref.refType ? ` (${ref.refType})` : '');\n      a.dataset.info =\n        (ref.title   ? `**Reference Name:** ${ref.title}\\n\\n` : '') +\n        (ref.info    ? `**Description:** ${ref.info}\\n\\n` : '') +\n        (ref.authors?.length ? `**Authors:**\\n${ref.authors.map(x => `• ${x}`).join('\\n')}\\n\\n` : '') +\n        (ref.refType ? `**Link type:** ${ref.refType}\\n\\n` : '');\n      ctx.attachHoverPreview(a);\n      const li = document.createElement('li'); li.appendChild(a);\n      list.appendChild(li);\n    });\n    container.appendChild(list);\n  },\n});\n\nconst manager = await createEditor({ dataDir: './data', panels: [referencesPanel] });\n```\n\nThe `references:` DSL data and your data files need no edits — the renderer just\ncalls `ctx.resolveProperty('references')`. A panel that declares neither\n`itemFields` nor `renderEditor` is edited as raw JSON in the component editor.\n\n### Theming\n\nPanels without a `theme` use `PANEL_BACKGROUND` (`--panel-background-color`). A\npanel may declare `theme: { background: '<THEME_KEY>' }` to use a different key —\nthe key must exist in every active theme palette (supply your own via the\n`themes` option). The sidebar content region is the host-supplied `#panels`\nelement (a bare flex layout region); the card styling lives on `.rplib-panel`.\n\n### Pre-aggregated `data` escape hatch\n\n```js\nimport * as componentsA from './data/components/foo.js';\nimport componentsB from './data/components/bar.json' with { type: 'json' };\nimport { parseAbstractContent } from '@alexguha/rplib/parser';\nimport abstractsRaw from './data/abstracts/main.txt?raw';\n\nconst manager = await createEditor({\n  data: {\n    abstractDefinitions: parseAbstractContent(abstractsRaw),\n    components: { ...componentsA, ...componentsB },\n  },\n});\n```\n\n### Data directory layout\n\n`rplib-build-data <dataDir>` walks `<dataDir>/abstracts/**.txt` and\n`<dataDir>/components/**.{json,js}` and writes `<dataDir>/manifest.json`. File\nand folder names inside `abstracts/` and `components/` are arbitrary — the\nruntime aggregates everything listed in the manifest. The manifest is meant to\nbe regenerated on every dev/build (gitignore it). On duplicate component keys\nacross files, later files override earlier ones and a warning is emitted via\n`reporter.warn`.\n\n`.js` component files must be ESM (`export const name = …` or a default\nexport of `{ [name]: … }`) and served with a `text/javascript`/`application/javascript`\ncontent type — they're loaded via dynamic `import()`.\n\n### `AppManager`\n\n| Property / method | Description |\n| --- | --- |\n| `manager.canvas` | The underlying [`RPCanvas`](../core/README.md) instance. Use this for any direct rplib operation. |\n| `manager.labels` | Resolved labels (defaults merged with overrides). |\n| `manager.themes` | Resolved theme map (built-ins + extras). |\n| `manager.restoreView(fallback)` | Load the last saved root view from `localStorage`, falling back to `fallback` if none. |\n| `manager.setRepoUrl(url)` | Update (or clear, with `null`) the GitHub button's link target after boot. |\n\nFor lower-level needs (programmatic edits, custom navigation), reach through `manager.canvas` — that's the full rplib API surface.\n\n## Persistence\n\nThe editor reads from and writes to `localStorage` for:\n\n- The current root view name (so reloading restores the user's last position)\n- User-saved abstract definitions on top of the bundled `dataDir`\n- Settings (theme choice, rendering delay, etc.)\n\nIf you need a non-`localStorage` storage backend, use rplib's storage adapter API directly via `manager.canvas` — but at that point you may want to bypass `createEditor` and wire your own UI.\n\n## What's in the editor vs. what's in rplib core\n\n| In `@alexguha/rplib` core | In `@alexguha/rplib-editor` |\n| --- | --- |\n| Resolved-view rendering, layout, theme application | Sidebar, settings menu, edit menu, view-picker, navigation breadcrumbs |\n| DSL parser, serializer, view structures | Theme palette catalog, settings persistence |\n| Mutation API (`updateItem`, `addItem`, …) and edit history | UI bindings that call the mutation API in response to user actions |\n\nIf you want a headless rplib (no UI), depend on `@alexguha/rplib` alone and bring your own view layer.\n","readmeFilename":"README.md"}