|
| 1 | +# SDUI Demo Development Workflow |
| 2 | + |
| 3 | +This guide explains the local dependency chain, what to rebuild after upstream changes, and |
| 4 | +how to avoid stale-cache pitfalls. |
| 5 | + |
| 6 | +## Dependency chain |
| 7 | + |
| 8 | +``` |
| 9 | +v2/lib (agnosticui-core — web components, Vue/React wrappers) |
| 10 | + └── v2/sdui/schema (@agnosticui/schema — AgNode type definitions) |
| 11 | + └── v2/sdui/renderers/react (@agnosticui/render-react) |
| 12 | + └── v2/sdui/renderers/vue (@agnosticui/render-vue) |
| 13 | + └── v2/sdui/renderers/lit (@agnosticui/render-lit) |
| 14 | + └── v2/sdui/demo (React demo app) |
| 15 | + └── v2/sdui/demo-vue (Vue demo app) |
| 16 | + └── v2/sdui/demo-lit (Lit demo app) |
| 17 | +``` |
| 18 | + |
| 19 | +Each arrow is a `file:` dependency in `package.json`. npm installs these as **symlinks** in |
| 20 | +`node_modules`, so demos always resolve to the local source. However, all packages under |
| 21 | +`v2/lib` and `v2/sdui/renderers/*` are **TypeScript projects that must be compiled to `dist/` |
| 22 | +before their consumers can see changes.** |
| 23 | + |
| 24 | +## When to rebuild what |
| 25 | + |
| 26 | +| You changed... | Rebuild command | Then... | |
| 27 | +|---|---|---| |
| 28 | +| `v2/lib/src/**` (core components, Vue/React wrappers) | `cd v2/lib && npm run build` | Restart the affected demo dev server | |
| 29 | +| `v2/sdui/schema/src/**` | `cd v2/sdui/schema && npm run build` | Rebuild any affected renderer (see below) | |
| 30 | +| `v2/sdui/renderers/vue/src/**` | `cd v2/sdui/renderers/vue && npm run build` | Restart demo-vue dev server | |
| 31 | +| `v2/sdui/renderers/lit/src/**` | `cd v2/sdui/renderers/lit && npm run build` | Restart demo-lit dev server | |
| 32 | +| `v2/sdui/renderers/react/src/**` | `cd v2/sdui/renderers/react && npm run build` | Restart demo (React) dev server | |
| 33 | +| Fixture files in `v2/sdui/demo/src/fixtures/**` | None — imported as raw TypeScript by all three demos | Just save; Vite HMR picks it up | |
| 34 | + |
| 35 | +### Rebuilding everything from scratch |
| 36 | + |
| 37 | +```bash |
| 38 | +# From the repo root (v2/) |
| 39 | +cd lib && npm run build && cd .. |
| 40 | +cd sdui/schema && npm run build && cd ../.. |
| 41 | +cd sdui/renderers/react && npm run build && cd ../../.. |
| 42 | +cd sdui/renderers/vue && npm run build && cd ../../.. |
| 43 | +cd sdui/renderers/lit && npm run build && cd ../../.. |
| 44 | +``` |
| 45 | + |
| 46 | +## First-time setup for a demo app |
| 47 | + |
| 48 | +If a demo's `node_modules` folder does not exist yet (e.g. after a fresh clone or after |
| 49 | +deleting it), run `npm install` inside the demo directory. npm resolves all `file:` deps as |
| 50 | +symlinks automatically. |
| 51 | + |
| 52 | +```bash |
| 53 | +# Example for demo-lit (which ships without node_modules committed) |
| 54 | +cd v2/sdui/demo-lit && npm install && npm run dev |
| 55 | +``` |
| 56 | + |
| 57 | +## The Vite pre-bundle cache (`.vite/deps`) |
| 58 | + |
| 59 | +Vite pre-bundles certain dependencies into `.vite/deps/` for faster startup. The demos use |
| 60 | +`optimizeDeps.noDiscovery: true` plus an explicit `include` list, so **`agnosticui-core` and |
| 61 | +the SDUI renderers are NOT pre-bundled** — they are served directly from the symlinked `dist/` |
| 62 | +folders on disk. |
| 63 | + |
| 64 | +The only package currently pre-bundled in demo-vue is `vue` itself. You should not need to |
| 65 | +clear the Vite cache after a normal upstream rebuild. |
| 66 | + |
| 67 | +**However**, if you ever see a demo serving unmistakably stale code after a rebuild and dev |
| 68 | +server restart, clear the cache: |
| 69 | + |
| 70 | +```bash |
| 71 | +# Stop the dev server first, then: |
| 72 | +rm -rf v2/sdui/demo-vue/node_modules/.vite |
| 73 | +rm -rf v2/sdui/demo-lit/node_modules/.vite |
| 74 | +rm -rf v2/sdui/demo/node_modules/.vite |
| 75 | +# Then restart: npm run dev |
| 76 | +``` |
| 77 | + |
| 78 | +## Convenience scripts (add to each demo's `package.json`) |
| 79 | + |
| 80 | +You can add the following scripts to each demo app to make the rebuild loop faster. These are |
| 81 | +intentionally not committed by default because they encode absolute paths; adjust for your |
| 82 | +machine. |
| 83 | + |
| 84 | +```jsonc |
| 85 | +// v2/sdui/demo-vue/package.json (example) |
| 86 | +"scripts": { |
| 87 | + "dev": "vite", |
| 88 | + "build": "vue-tsc -b && vite build", |
| 89 | + "preview": "vite preview", |
| 90 | + "rebuild:lib": "npm run build --prefix ../../lib", |
| 91 | + "rebuild:renderer": "npm run build --prefix ../renderers/vue", |
| 92 | + "rebuild:all": "npm run rebuild:lib && npm run rebuild:renderer", |
| 93 | + "fresh": "npm run rebuild:all && rm -rf node_modules/.vite && npm run dev" |
| 94 | +} |
| 95 | +``` |
| 96 | + |
| 97 | +Run `npm run fresh` after any upstream change: it rebuilds both lib and the renderer, clears |
| 98 | +the Vite pre-bundle cache, then starts the dev server. |
| 99 | + |
| 100 | +## Common pitfalls |
| 101 | + |
| 102 | +### Symptom: a prop (e.g. `min`, `max`) is passed in the fixture but has no effect in the UI |
| 103 | + |
| 104 | +**Cause:** The renderer dist is stale — the prop is in the renderer's TypeScript source but |
| 105 | +was added after the last `npm run build`. |
| 106 | + |
| 107 | +**Fix:** Rebuild the affected renderer. |
| 108 | + |
| 109 | +```bash |
| 110 | +cd v2/sdui/renderers/vue && npm run build |
| 111 | +# or |
| 112 | +cd v2/sdui/renderers/lit && npm run build |
| 113 | +``` |
| 114 | + |
| 115 | +### Symptom: an event (e.g. `@change`) fires in React but not in Vue or Lit |
| 116 | + |
| 117 | +**Cause:** Native DOM events like `change` are `composed: false` by default, so they stop at |
| 118 | +the shadow root of a LitElement and never reach outside listeners. Only `input` and `click` |
| 119 | +are `composed: true` natively. |
| 120 | + |
| 121 | +**Fix:** In the web component's event handler, re-dispatch a composed `CustomEvent` (or a |
| 122 | +plain `Event` with `composed: true`) from the host element so external listeners receive it. |
| 123 | +All AgnosticUI form components should do this; if one is missing it, add it to the |
| 124 | +component's `_handle*` method in `v2/lib/src/`. |
| 125 | + |
| 126 | +### Symptom: Vue `@change` on `ag-input` never fires |
| 127 | + |
| 128 | +Same root cause as above. The fix is in `v2/lib/src/components/Input/core/_Input.ts`: |
| 129 | +`_handleChange` must dispatch `new Event('change', { bubbles: true, composed: true })` from |
| 130 | +`this` (the host element) after handling the native event. |
| 131 | + |
| 132 | +### Symptom: a Vue wrapper prop (e.g. `min`, `labelPosition`) is declared but silently ignored |
| 133 | + |
| 134 | +**Cause:** Vue 3 `defineProps` removes declared props from `$attrs`. If a prop is declared in |
| 135 | +`withDefaults(defineProps<...>(), {...})` but is NOT explicitly bound in the template, Vue |
| 136 | +will not forward it to the underlying web component. |
| 137 | + |
| 138 | +**Fix:** Add the binding to the wrapper template. Example in `VueInput.vue`: |
| 139 | + |
| 140 | +```html |
| 141 | +:min="min" |
| 142 | +:max="max" |
| 143 | +:labelPosition="labelPosition" |
| 144 | +``` |
| 145 | + |
| 146 | +React is not affected (all props are forwarded automatically via `@lit/react` `createComponent`). |
| 147 | +Lit is not affected (direct property binding in the renderer template). |
| 148 | + |
| 149 | +## Summary checklist after an upstream change |
| 150 | + |
| 151 | +- [ ] `cd v2/lib && npm run build` if any core component or Vue/React wrapper changed |
| 152 | +- [ ] `cd v2/sdui/renderers/[vue|lit|react] && npm run build` if the corresponding renderer changed |
| 153 | +- [ ] `cd v2/sdui/schema && npm run build` if the schema types changed |
| 154 | +- [ ] Restart the demo dev server |
| 155 | +- [ ] If something still looks stale: `rm -rf node_modules/.vite` in the demo, then restart |
0 commit comments