@bud.sh/app 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +41 -31
- package/dist/client/assets/bud/design.js +1 -1
- package/dist/client/assets/canvas-Bih9EdKJ.js +1 -0
- package/dist/client/assets/difference-worker-Bzg-rizy.js +8 -0
- package/dist/client/assets/dist-CdE5wBkg.js +5 -0
- package/dist/client/assets/files-1dLuoM2f.js +1 -0
- package/dist/client/assets/i18n-CkO6VFI0.js +1 -0
- package/dist/client/assets/index-Cn2mxroU.css +2 -0
- package/dist/client/assets/{index-ChANGtl-.js → index-DtISWZp9.js} +2 -2
- package/dist/client/assets/pages-BJ-tNJ4J.js +1 -0
- package/dist/client/assets/{project-branches-DO897zM6.js → project-branches-Ce3rXrkc.js} +1 -1
- package/dist/client/assets/project-comments-CPUONfs8.js +1 -0
- package/dist/client/assets/project-thread-links-C-TGkq59.js +1 -0
- package/dist/client/assets/{project-threads-Lay351p4.js → project-threads-Bv7IDBgi.js} +105 -105
- package/dist/client/assets/project-work-DAE9-olg.js +1 -0
- package/dist/client/assets/{task-design-Avb2RO4w.js → task-design-CwySIAOl.js} +3 -3
- package/dist/client/assets/tasks-KWsCLi_h.js +3 -0
- package/dist/client/assets/wasm-inline-DSUyFn1L.js +1 -0
- package/dist/client/assets/workspace-CVdcfaaB.js +2 -0
- package/dist/client/index.html +3 -3
- package/dist/hosted/assets/{canvas-V36732ER.js → canvas-AII16n9i.js} +97 -6
- package/dist/hosted/assets/{comment-data-CF2ZV_3k.js → comment-data-BXfMElfx.js} +2004 -402
- package/dist/hosted/assets/dist-BCSTeNf4.js +4785 -0
- package/dist/hosted/assets/{files-DjSCjfU7.js → files-D_1yeAVO.js} +10 -5
- package/dist/hosted/assets/{pages-BzjzeuPu.js → pages-CN_SbKWA.js} +3 -3
- package/dist/hosted/assets/{project-branches-BT97J9i7.js → project-branches-Bxp0DCwg.js} +1 -1
- package/dist/hosted/assets/{project-thread-links-BRLgByEe.js → project-thread-links-KqQoKBLE.js} +76 -4
- package/dist/{node-host/assets/screen-CZXWJEds.js → hosted/assets/screen-DpAcDUKR.js} +29 -1
- package/dist/hosted/assets/tasks-D66LlwxM.js +1423 -0
- package/dist/hosted/assets/wasm-inline-Dl9tqabx.js +4 -0
- package/dist/hosted/hosted.js +7885 -6219
- package/dist/node/assets/Stream-CAm1eJ2n.js +16604 -0
- package/dist/{server/assets/bridge-B_Blt55E.js → node/assets/bridge-DQSBYHmw.js} +124 -290
- package/dist/node/assets/config-9_jWwNBh.js +1067 -0
- package/dist/node/assets/load-config.server-CMVtRVmO.js +261 -0
- package/dist/node/assets/module-3GgtT4Xs.js +308 -0
- package/dist/node/assets/server-DTQFuoX2.js +846 -0
- package/dist/node/assets/src-D-kG1GxB.js +2 -0
- package/dist/node/assets/{src-CerrKjID.js → src-Dwe9APUx.js} +93 -3
- package/dist/node/assets/src-DysjfbM8.js +8592 -0
- package/dist/node/bridge.js +1 -845
- package/dist/node/cli.js +206 -0
- package/dist/node/design.js +811 -13
- package/dist/node/index.js +2 -739
- package/dist/node/plugins.js +5711 -0
- package/dist/node/server.js +1 -6746
- package/dist/node/vite.js +121 -0
- package/dist/{server/assets/canvas-Dc1mYCwQ.js → node-host/assets/canvas-BeDoufy1.js} +97 -7
- package/dist/node-host/assets/{comment-data-DyIZNpfG.js → comment-data-DE2T9yTj.js} +1980 -376
- package/dist/node-host/assets/dist-BCSTeNf4.js +4785 -0
- package/dist/node-host/assets/{files-Dh2TiQZq.js → files-Dl-PTS09.js} +11 -6
- package/dist/node-host/assets/{pages-BxpjbYhs.js → pages-DL2sk6_U.js} +3 -3
- package/dist/node-host/assets/{project-branches-B7HUGiVK.js → project-branches-DGp5ELct.js} +1 -1
- package/dist/{server/assets/project-thread-links-CBOpf6zk.js → node-host/assets/project-thread-links-CgBV3Jcm.js} +76 -5
- package/dist/{hosted/assets/screen-CKp2C7kx.js → node-host/assets/screen-B55yyVfb.js} +29 -1
- package/dist/node-host/assets/tasks-DZRNkoxe.js +1425 -0
- package/dist/node-host/assets/wasm-inline-Dl9tqabx.js +4 -0
- package/dist/node-host/node-host.js +6127 -4438
- package/dist/server/assets/{branch-previews-ClkoJ0lM.js → branch-previews-DedrpnVR.js} +1555 -673
- package/dist/{node-host/assets/canvas-TRUfxfL5.js → server/assets/canvas-CJWQ-jjv.js} +98 -6
- package/dist/server/assets/{comment-data-CsjukwAW.js → comment-data-Rg42ToTW.js} +1666 -47
- package/dist/server/assets/dist-BCSTeNf4.js +4785 -0
- package/dist/server/assets/{events-iHpLGr3k.js → events-BH_rAu7O.js} +155 -20
- package/dist/server/assets/{files-E9mSFeoc.js → files-CPJqKeMo.js} +12 -7
- package/dist/server/assets/{listener-DN5TyOjJ.js → listener-D61O6PzF.js} +708 -12
- package/dist/server/assets/{pages-BBBXyJWV.js → pages-KJY_Ba92.js} +4 -4
- package/dist/server/assets/{project-branches-B0YIK6Ur.js → project-branches-qG9ACZvo.js} +2 -2
- package/dist/{node-host/assets/project-thread-links-CauJF0Cz.js → server/assets/project-thread-links-CqK0lqCF.js} +77 -4
- package/dist/{node-host/assets/tasks-request-ZWmbc8fE.js → server/assets/project-work-DoIwxWMm.js} +87 -2
- package/dist/server/assets/run-BJ8r5jSh.js +572 -0
- package/dist/server/assets/{screen-BIQA2mr4.js → screen-CBrHPFug.js} +30 -2
- package/dist/server/assets/{server-DxK-UB_Z.js → server-Dkbp5stG.js} +1521 -793
- package/dist/server/assets/{services-BRrgXYlT.js → services-BTfig8A8.js} +234 -997
- package/dist/server/assets/tasks-Bgu5Lg9Y.js +1427 -0
- package/dist/server/assets/wasm-inline-Dl9tqabx.js +4 -0
- package/dist/server/capture.js +1 -2
- package/dist/server/migration.js +569 -12
- package/dist/server/runtime.js +7 -5
- package/dist/server/server.js +3 -3
- package/dist/types/assets/{config-DIC2cf_S.d.ts → config-CvcYmE2s.d.ts} +188 -50
- package/dist/types/assets/{contract-CAT-XFNq.d.ts → contract-B7yuuqSn.d.ts} +44 -2
- package/dist/types/assets/{items-CaVkByHk.d.ts → items-BQdaVksf.d.ts} +12 -1
- package/dist/types/assets/memory-state-BBW-FAVA.d.ts +236 -0
- package/dist/types/assets/picker-Be5Gx4WR.d.ts +9 -0
- package/dist/types/assets/{task-design-xJOhRNWh.d.ts → task-design-BDHKFHpp.d.ts} +3 -1
- package/dist/types/bridge.d.ts +1 -1
- package/dist/types/companion.d.ts +3 -3
- package/dist/types/design.d.ts +2 -2
- package/dist/types/hosted.d.ts +3 -3
- package/dist/types/index.d.ts +2 -2
- package/dist/types/node-host.d.ts +2 -2
- package/dist/types/plugins.d.ts +445 -0
- package/dist/types/screen.d.ts +2 -2
- package/dist/types/server.d.ts +2 -228
- package/dist/types/vite.d.ts +16 -0
- package/package.json +19 -3
- package/dist/client/assets/canvas-Cu6R6xxT.js +0 -1
- package/dist/client/assets/difference-worker-jfTSn-Tw.js +0 -8
- package/dist/client/assets/files-js6ElfkU.js +0 -1
- package/dist/client/assets/i18n-DxqFr2mi.js +0 -1
- package/dist/client/assets/index-CFFxP0gS.css +0 -2
- package/dist/client/assets/pages-6_lhiQmz.js +0 -1
- package/dist/client/assets/project-comments-DFFKVpia.js +0 -1
- package/dist/client/assets/project-thread-links-NLFWQRD2.js +0 -1
- package/dist/client/assets/project-work-du0Y-L5Y.js +0 -1
- package/dist/client/assets/tasks-CA-E8bbK.js +0 -1
- package/dist/client/assets/tasks-request-C55IeuiP.js +0 -1
- package/dist/client/assets/workspace-Cw5HvX5d.js +0 -2
- package/dist/hosted/assets/tasks-Dj7AyBJB.js +0 -649
- package/dist/hosted/assets/tasks-request-DZob623r.js +0 -113
- package/dist/node-host/assets/tasks-Bs1IOpeU.js +0 -651
- package/dist/server/assets/project-work-qSKFO5yj.js +0 -88
- package/dist/server/assets/tasks-CiXodsLN.js +0 -652
- package/dist/server/assets/tasks-request-DhwCzpRi.js +0 -115
- package/dist/types/assets/picker-D1Bw3ndx.d.ts +0 -14
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @bud.sh/app
|
|
2
2
|
|
|
3
|
-
Bud is a local companion for reviewing a web project: the app itself, its config, screen, design and adapter APIs, and the companion server a host starts.
|
|
3
|
+
Bud is a local companion for reviewing a web project: the app itself, its config, screen, design and adapter APIs, and the companion server a host starts. Its Vite plugin, `@bud.sh/app/vite`, hosts it beside your Vite dev server, and the package's `bud` CLI runs it without Vite. Bud browses your live pages, shows your routes side by side on a canvas, lets you browse, edit and review files, and keeps discussions on pages, code and tasks through your selected storage adapters. The interface uses Remix 3; your project can use any framework that runs on Vite.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
@@ -16,14 +16,19 @@ Bud is a local companion for reviewing a web project: the app itself, its config
|
|
|
16
16
|
|
|
17
17
|
## Installation
|
|
18
18
|
|
|
19
|
-
|
|
19
|
+
One package holds the app, its Vite plugin and the `bud` CLI:
|
|
20
20
|
|
|
21
21
|
```sh
|
|
22
|
-
|
|
22
|
+
npm install -D @bud.sh/app
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
To try this repository's version instead, build and pack it:
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
pnpm --filter @bud.sh/app build
|
|
23
29
|
pnpm --filter @bud.sh/app pack --out /tmp/bud-app.tgz
|
|
24
|
-
pnpm --filter @bud.sh/app-vite-plugin pack --out /tmp/bud-vite.tgz
|
|
25
30
|
# In your project
|
|
26
|
-
npm install -D /tmp/bud-app.tgz
|
|
31
|
+
npm install -D /tmp/bud-app.tgz
|
|
27
32
|
```
|
|
28
33
|
|
|
29
34
|
Node 26.12 or newer is required.
|
|
@@ -34,7 +39,7 @@ Add the Vite plugin:
|
|
|
34
39
|
|
|
35
40
|
```ts
|
|
36
41
|
// vite.config.ts
|
|
37
|
-
import { bud } from '@bud.sh/app
|
|
42
|
+
import { bud } from '@bud.sh/app/vite'
|
|
38
43
|
|
|
39
44
|
export default {
|
|
40
45
|
plugins: [bud()],
|
|
@@ -53,38 +58,44 @@ export default defineConfig({
|
|
|
53
58
|
// port: 4000, // Bud's own port; omit to pick a free one
|
|
54
59
|
// target: { port: 3000 }, // detected from Vite by default
|
|
55
60
|
// comments: { remote: 'origin' },
|
|
56
|
-
//
|
|
61
|
+
// plugins: [reactGrab()], // from @bud.sh/app/plugins; Bud's DOM picker by default
|
|
57
62
|
})
|
|
58
63
|
```
|
|
59
64
|
|
|
60
|
-
Run your usual Vite dev command and open the printed **Bud** URL. The plugin only runs in development, and config changes restart it.
|
|
65
|
+
Run your usual Vite dev command and open the printed **Bud** URL. The plugin only runs in development, and config changes restart it. It starts Bud's companion when Vite starts listening, finds your dev server's address, refreshes previews on hot updates and adds the small dev bridge Pages uses to follow your live pages; the bridge does nothing outside Bud's frames.
|
|
61
66
|
|
|
62
|
-
###
|
|
67
|
+
### Plugins, storage and designs
|
|
63
68
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
`
|
|
67
|
-
|
|
68
|
-
|
|
69
|
+
Stores, the picker, the task design, extra screens and the factory's sandboxes come from
|
|
70
|
+
plugins, which `@bud.sh/app/plugins` exports: `beads()`, `gitComments()`, `memory()`,
|
|
71
|
+
`reactGrab()`, `react()`, `picker()`, `taskDesign()`, `local()`, `boat()` and `definePlugin`
|
|
72
|
+
for your own. Tasks and discussions are Beads' unless a plugin provides one;
|
|
73
|
+
`storage: { work: false }` or `{ threads: false }` turns one off. `designs.pages` sets how the
|
|
74
|
+
Pages sidebar names pages: by `path` (the default) or by `title` with the path beside it.
|
|
69
75
|
|
|
70
76
|
```ts
|
|
77
|
+
import { defineConfig } from '@bud.sh/app'
|
|
78
|
+
import { definePlugin, gitComments, taskDesign } from '@bud.sh/app/plugins'
|
|
79
|
+
import { tracker } from './bud/tracker.server.ts'
|
|
80
|
+
|
|
71
81
|
export default defineConfig({
|
|
72
82
|
routes: ['/'],
|
|
73
|
-
|
|
74
|
-
|
|
83
|
+
plugins: [
|
|
84
|
+
definePlugin({ name: 'tracker', label: 'Tracker', work: tracker }),
|
|
85
|
+
gitComments(),
|
|
86
|
+
taskDesign('./bud/tasks.tsx'),
|
|
87
|
+
],
|
|
75
88
|
})
|
|
76
89
|
```
|
|
77
90
|
|
|
78
|
-
|
|
79
|
-
`@bud.sh/app/server
|
|
80
|
-
`
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
Only each store's public identity and connection state
|
|
87
|
-
reach screens through `project.storage`; module paths and server configuration stay private.
|
|
91
|
+
A plugin's store is a fully provided Effect layer using the `WorkAdapter` or `ThreadAdapter`
|
|
92
|
+
service from `@bud.sh/app/server`, or a function making one for `{ project }`;
|
|
93
|
+
`memoryAdapterLayer({ schema })` supplies both for fixtures. A shared layer is acquired once,
|
|
94
|
+
and its resources close with the companion. Task designs are browser modules ending in `.ts`,
|
|
95
|
+
`.tsx`, `.js` or `.jsx` inside the project, outside `node_modules`; Bud checks their paths
|
|
96
|
+
before listening and their exports when opened. Only each store's public identity and
|
|
97
|
+
connection state reach screens through `project.storage`; plugins and server configuration
|
|
98
|
+
stay private.
|
|
88
99
|
|
|
89
100
|
Task designs default-export `defineTaskDesign` from `@bud.sh/app/design`. Its optional
|
|
90
101
|
`card`, `page`, `properties`, `actions`, `sections` and `column` slots are Remix components.
|
|
@@ -164,10 +175,11 @@ Opened screens also stay mounted while hidden. `context.active` tells a screen w
|
|
|
164
175
|
### Without Vite
|
|
165
176
|
|
|
166
177
|
```sh
|
|
167
|
-
bud [project-directory]
|
|
178
|
+
npx bud [project-directory] # standalone, needs target.origin or target.port
|
|
179
|
+
npx bud comments migrate [project-directory] [--to bud:beads] [--dry-run]
|
|
168
180
|
```
|
|
169
181
|
|
|
170
|
-
The
|
|
182
|
+
The `bud` command comes with `@bud.sh/app` and needs `target.origin` or `target.port` in the config to serve. Previews opened this way can't be commented on; use the Vite plugin for that. `bud capture` is what a hosted Bud's builder runs.
|
|
171
183
|
|
|
172
184
|
### Task links
|
|
173
185
|
|
|
@@ -185,8 +197,7 @@ Writes use the discussion revision you last read. Conflicts retain the draft for
|
|
|
185
197
|
uncertain writes require checking the stored discussion before retrying. **Sync** is explicit
|
|
186
198
|
and uses the selected adapter's existing remote configuration.
|
|
187
199
|
|
|
188
|
-
With `
|
|
189
|
-
branch. Writes preserve your source branch, index and working files. Sync validates and
|
|
200
|
+
With `gitComments()`, discussions use the compatible `bud/comments` branch. Writes preserve your source branch, index and working files. Sync validates and
|
|
190
201
|
merges fetched records, then pushes the exact validated commit without forcing. No other
|
|
191
202
|
application storage selection writes this ref.
|
|
192
203
|
|
|
@@ -249,7 +260,6 @@ See [AGENTS.md](AGENTS.md) for the app's structure.
|
|
|
249
260
|
|
|
250
261
|
## Related Packages
|
|
251
262
|
|
|
252
|
-
- [`@bud.sh/app-vite-plugin`](../app-vite-plugin/README.md) - Hosts the app beside Vite, and the `bud` CLI
|
|
253
263
|
- [`@bud.sh/project`](../project/README.md) - Config contract and loading
|
|
254
264
|
- [`@bud.sh/ui`](../ui/README.md) - Components
|
|
255
265
|
- [`@bud.sh/comments`](../comments/README.md), [`@bud.sh/files`](../files/README.md), [`@bud.sh/beads`](../beads/README.md) - Domain services
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{r as ActionsDefault,i as ColumnDefault,t as PropertiesDefault,a as SectionsDefault,
|
|
1
|
+
export{r as ActionsDefault,i as ColumnDefault,t as PropertiesDefault,a as SectionsDefault,ct as TaskCardDefault,it as TaskField,n as TaskPageDefault,tt as defineTaskDesign,Hn as fieldByRole,at as taskFieldRenderers,Bn as valueByRole}from"../task-design-CwySIAOl.js";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{r as e}from"./i18n-CkO6VFI0.js";import{t}from"./jsx-B4XNFIzB.js";import{t as n}from"./component-DWct-Tq6.js";import{n as r}from"./on-mixin-iWnqUzq5.js";import{n as i}from"./attrs-mixin-CmlG_FtV.js";import{c as a,l as o,t as s}from"./loader-Q6-HPKft.js";import{t as c}from"./screen-Dfvzj6n2.js";import{At as l,I as u,T as d,_ as f,v as p,w as m}from"./task-design-CwySIAOl.js";import{G as h,Mt as g,Nt as _,W as v,lt as y,q as b,s as x}from"./project-threads-Bv7IDBgi.js";import{i as S,n as C,t as w}from"./project-comments-CPUONfs8.js";import{i as T,n as E,t as D}from"./project-branches-Ce3rXrkc.js";import{n as O,t as k}from"./project-thread-links-C-TGkq59.js";var A=760,j=r(`pointerdown`,e=>e.stopPropagation());function M(e,t,n){let r=e.capture.width*t,i=e.capture.thumbnails.map(e=>e.width),a=e=>{let t=i.findIndex(t=>r<=t*e);return t<0?`slices`:t},o=e=>e===`slices`?i.length:e,s=a(1);return n===void 0||o(s)>=o(n)||o(a(.85))<o(n)?s:n}function N(e,t){return e?.get(t)??{visible:!0,top:0,bottom:1/0,density:1}}function P(e,t){let n=0;return e.capture.tiles.map((r,i)=>{let a={tile:r,index:i,top:n,src:e.srcs[i]};return n+=r.height,{...a,shownTo:Math.min(n,t)}})}function ee(n){let{route:i,previews:c}=n.props,u=i.pageId??i.id,d=()=>T(n.props.theme,n.props.size),f=``,p,m,g=``;function _(e){return n.props.topOnly?e.capture.tiles[0]?.height??e.capture.height:e.capture.height}function v(){let{preview:e,images:t}=c.get(u),r=t[d()]??m,i=r?_(r):e?.captures[0]?.height??(e?.state===`failed`?A:0);if(!e||!i)return;let a=`${i}:${e.path}:${r?.capture.hash??``}`;f!==a&&(f=a,n.props.onLayout({height:i,path:e.path,pins:r?.capture.pins}))}function y(e){let t=N(n.props.viewport,i.id);if(!t.visible||p===void 0)return{thumbnail:void 0,slices:[]};if(p===`slices`&&e.srcs.length){let n=Math.min(t.bottom,_(e));return{thumbnail:e.thumbnails.at(-1),slices:P(e,n).filter(({src:e,top:n,shownTo:r})=>e&&n<r&&r>t.top)}}let r=p===`slices`?e.thumbnails.length-1:p;return{thumbnail:e.thumbnails[r]??e.thumbnails.at(-1),slices:[]}}function b(){let e=c.get(u).images[d()];if(!e||e===m)return;if(!m||m.capture.hash===e.capture.hash){m=e;return}if(p===`slices`&&!e.srcs.length){c.slices(u,n.props.theme,n.props.size);return}let t=`${e.capture.hash}:${p}`;if(g===t)return;g=t;let r=e,{thumbnail:i,slices:a}=y(r);Promise.all([i,...a.map(({src:e})=>e)].flatMap(e=>{if(!e)return[];let t=new Image;return t.src=e,[t.decode().catch(()=>{})]})).then(()=>{g!==t||n.signal.aborted||(g=``,m=c.get(u).images[d()]??r,v(),n.update())})}let x=c.watch(u,()=>{b(),v(),n.update()}),S=n.props.viewport?.watch(i.id,()=>void n.update());return n.signal.addEventListener(`abort`,()=>{x(),S?.()},{once:!0}),()=>{let{mode:d,origin:f,theme:g,viewport:x,size:S}=n.props,{preview:C,images:w,refreshing:E,error:D}=c.get(u);n.queueTask(()=>{c.show(u,g,S),v()});let O=w[T(g,S)]??w[T(g===`dark`?`light`:`dark`,S)];O&&(!m||m.capture.theme!==O.capture.theme)?m=O:b();let k=m,A=D||(C?.captures.length?null:C?.error),P=new URL(i.path,f).href;if(k){let a=N(x,i.id);if(p=M(k,a.density,p),a.visible&&p===`slices`&&!k.srcs.length){let{theme:e}=k.capture;n.queueTask(()=>c.slices(u,e,S))}let o=_(k),{width:s}=k.capture,{thumbnail:l,slices:f}=y(k);return t(`div`,{role:`img`,"aria-label":e(`app.client.previewImage.preview`,{title:i.title}),"data-detail":a.visible?f.length?`slices`:l?`thumbnail`:`pending`:`hidden`,class:`relative select-none overflow-hidden ${d===`comment`?`cursor-crosshair`:``}`,style:{height:o},mix:[r(`pointerdown`,e=>{d!==`pan`&&e.stopPropagation()}),r(`click`,e=>{if(d!==`comment`||C?.path!==i.path)return;e.stopPropagation();let t=e.currentTarget.getBoundingClientRect(),r={x:(e.clientX-t.left)*s/t.width,y:(e.clientY-t.top)*o/t.height};n.props.onPick({element:null,path:i.path,...h(r,s),found:c.describe(u,k.capture,r.x,r.y)})})],children:[l?t(`img`,{src:l,alt:``,decoding:`async`,draggable:!1,class:`absolute inset-x-0 top-0 block w-full max-w-none`,style:{height:k.capture.height}}):null,f.map(({tile:e,index:n,top:r,src:i})=>t(`img`,{src:i,alt:``,decoding:`async`,draggable:!1,class:`absolute inset-x-0 block w-full max-w-none`,style:{top:r,height:e.height+ +(n<k.capture.tiles.length-1)}},e.hash))]})}return C?.state===`failed`||A&&!E?t(`div`,{class:`absolute inset-0 flex flex-col items-center justify-center gap-3 p-12 text-center`,role:`status`,children:[t(l,{name:`circle-alert`,size:24,class:`text-muted`}),t(o,{variant:`title`,weight:`semibold`,class:`text-ink`,children:e(`app.client.previewImage.captureFailed`,{title:i.title})}),A?t(o,{variant:`ui`,class:`max-w-md text-muted`,children:A}):null,t(`div`,{class:`mt-2 flex gap-2`,children:[t(a,{variant:`secondary`,disabled:E,mix:[j,r(`click`,()=>void c.refresh(u))],children:t(o,{variant:`ui`,children:e(`app.client.previewImage.tryAgain`)})}),t(`a`,{href:P,target:`_blank`,rel:`noreferrer`,class:`bud-interaction bud-control flex h-control items-center rounded-lg px-3 text-ink`,mix:j,children:t(o,{variant:`ui`,children:e(`app.client.previewImage.openPage`)})})]})]}):t(`div`,{class:`absolute inset-0 flex items-center justify-center`,children:t(s,{label:e(`app.client.previewImage.capturing`,{title:i.title})})})}}function te(i){let{route:a,previews:o}=i.props,s=a.pageId??a.id,c=o.watch(s,()=>void i.update());return i.signal.addEventListener(`abort`,c,{once:!0}),()=>{let{preview:i,refreshing:c}=o.get(s),u=c||!!i?.updating,f=i?.state===`ready`?i.error:null;return t(n,{children:[f?t(d,{label:f,children:t(`span`,{tabIndex:0,role:`img`,"aria-label":f,class:`pointer-events-auto ms-1 inline-flex text-amber-500`,mix:j,children:t(l,{name:`circle-alert`,size:13})})}):null,t(m,{icon:`sync`,label:e(`app.client.previewImage.refresh`,{title:a.title}),tooltip:!0,size:`small`,iconSize:13,disabled:c,"aria-busy":u?`true`:void 0,class:`pointer-events-auto ms-0.5 text-muted hover:text-ink ${u?`[&_svg]:animate-spin`:``}`,mix:[j,r(`click`,()=>void o.refresh(s))]})]})}}var F={width:1200,height:800},I=.82;async function ne(e,t,n){let r=t.anchor;if(!r||`type`in r)return;let i=n.find(e=>e.width===r.viewport)??n[0];if(!i)return;let a=await e.picture(r.pageId,`light`,i);if(!a)return;let{capture:o,images:s}=a,c=o.pins?.find(e=>e.id===t.id&&e.x!==null),l=c&&c.x!==null&&c.y!==null?{x:c.x,y:c.y}:{x:r.offsetX*o.width,y:r.offsetY},[u,d]=await Promise.all([L(o,s,l).catch(()=>void 0),e.describe(r.pageId,o,l.x,l.y).catch(()=>null)]);return{...u?{image:u}:{},element:d,point:l}}async function L(e,t,n){let r=Math.min(F.width,e.width),i=Math.min(F.height,e.height),a=Math.max(0,Math.min(e.width-r,Math.round(n.x-r/2))),o=Math.max(0,Math.min(e.height-i,Math.round(n.y-i/2))),s=new OffscreenCanvas(r,i),c=s.getContext(`2d`);if(!c)throw Error(`No canvas.`);c.fillStyle=`#fff`,c.fillRect(0,0,r,i);let l=0;for(let[n,s]of e.tiles.entries()){let u=l+s.height,d=Math.max(o,l),f=Math.min(o+i,u);if(f>d&&t[n]){let i=await createImageBitmap(t[n]);c.drawImage(i,a*e.scale,(d-l)*e.scale,r*e.scale,(f-d)*e.scale,0,d-o,r,f-d),i.close()}l=u}let u=n.x-a,d=n.y-o;c.lineWidth=6,c.strokeStyle=`#fff`,c.beginPath(),c.arc(u,d,18,0,Math.PI*2),c.stroke(),c.lineWidth=3,c.strokeStyle=`#ef4444`,c.stroke();let f=await s.convertToBlob({type:`image/jpeg`,quality:I}),p=new Uint8Array(await f.arrayBuffer()),m=``;for(let e=0;e<p.length;e+=32768)m+=String.fromCharCode(...p.subarray(e,e+32768));return btoa(m)}var R=new Map;function z(){return new Worker(new URL(`/assets/difference-worker-Bzg-rizy.js`,``+import.meta.url),{type:`module`})}function B(t){let{routes:n,before:r,after:i,theme:a,signal:o}=t,s=new Map,c={get:e=>s.get(e)??{state:`pending`,regions:[]},progress:{compared:0,total:n.length},done:n.length===0},l,u=0,d=new Map;function f(e){l??=z(),l.onmessage=e=>{d.get(e.data.id)?.(e.data),d.delete(e.data.id)};let t=u++;return new Promise(n=>{d.set(t,n),l.postMessage({...e,id:t})})}o.addEventListener(`abort`,()=>l?.terminate(),{once:!0});async function p(e,t){let[n,o]=await Promise.all([r.picture(e,a,t),i.picture(e,a,t)]);if(!n||!o)return{state:`missing`,regions:[],before:n?.capture,after:o?.capture};let s={before:n.capture,after:o.capture};if(n.capture.hash===o.capture.hash)return{state:`same`,regions:[],...s};let c=`${n.capture.hash}\0${o.capture.hash}`,l=R.get(c);if(!l){let e=e=>({images:e.images,heights:e.capture.tiles.map(e=>e.height),scale:e.capture.scale}),t=await f({width:n.capture.width,before:e(n),after:e(o)});if(`error`in t)return{state:`failed`,regions:[],error:t.error,...s};l=t.regions,R.set(c,l)}return{state:l.length?`different`:`same`,regions:l,...s}}return(async()=>{for(let r of n){if(o.aborted)return;let i=await p(r.page,r.size).catch(t=>({state:`failed`,regions:[],error:t instanceof Error?t.message:e(`app.client.projectDifferences.comparisonFailed`)}));if(o.aborted)return;s.set(r.id,i),c.progress={compared:c.progress.compared+1,total:n.length},t.onChange(r.id)}c.done=!0,l?.terminate(),l=void 0,t.onChange(null)})(),c}var V=40,H=48;function U(e){let t=0;return{slots:e.map(e=>{let n={top:t,height:V+Math.max(e.before.height,e.after.height,1)};return t+=n.height+H,n}),height:Math.max(1,t-H)}}function W(t){return e(t===`changed`?`app.client.differenceView.changed`:t===`added`?`app.client.differenceView.added`:`app.client.differenceView.removed`)}function G(e){let t=new Map;return e.addEventListener(`abort`,()=>{for(let e of t.values())URL.revokeObjectURL(e)},{once:!0}),e=>{let n=t.get(e);return n||t.set(e,n=URL.createObjectURL(e)),n}}function re(n){let r=G(n.signal),i=0;return()=>{let{route:a,side:s,label:c,regions:l,viewport:u}=n.props,{slots:d,height:f}=U(l);i!==f&&(i=f,n.queueTask(()=>n.props.onLayout({height:f,path:a.path})));let p=u?.get(a.id)?.visible??!0;return t(`div`,{role:`img`,"aria-label":e(`app.client.differenceView.artboardLabel`,{title:a.title,label:c}),"data-difference":s,"data-changes":l.length,class:`relative select-none bg-[var(--bud-main)]`,style:{height:`${f}px`},children:l.map((n,i)=>{let a=n[s],l=n.crops[s],u=d[i];return t(`div`,{"data-kind":n.kind,"data-span":`${a.y} ${a.height}`,class:`absolute inset-x-0`,style:{top:`${u.top}px`,height:`${u.height}px`},children:[t(`div`,{class:`flex items-center gap-2 px-1`,style:{height:`${V}px`},children:[t(o,{variant:`ui`,weight:`medium`,children:e(`app.client.differenceView.changeNumber`,{count:i+1})}),t(o,{variant:`ui`,tone:`muted`,children:W(n.kind)})]}),l&&a.height>0?t(`div`,{class:`relative overflow-hidden`,style:{height:`${a.height}px`},children:[p?t(`img`,{alt:``,src:r(l),draggable:!1,class:`block h-full w-full`}):null,n.kind===`changed`?t(`div`,{"aria-hidden":`true`,class:`pointer-events-none absolute inset-y-0 rounded-sm outline-2 outline-red-500/70`,style:{left:`${n.x}px`,width:`${Math.max(2,n.width)}px`}}):null]}):t(`div`,{class:`grid h-24 place-items-center rounded-lg border border-dashed border-line`,children:t(o,{variant:`ui`,tone:`muted`,children:e(`app.client.differenceView.notIn`,{label:c})})})]},i)})})}}function ie(n){let a=G(n.signal),s=e=>{let{slides:t,index:r}=n.props;t.length&&n.props.onIndex((r+e+t.length)%t.length)};return()=>{let{slides:c,index:l,beforeLabel:u,afterLabel:d}=n.props,f=c[Math.min(l,c.length-1)],p=(n,r)=>{let i=f?.region.crops[n];return t(`figure`,{class:`m-0 flex min-w-0 flex-col gap-2`,children:[t(`figcaption`,{children:t(o,{variant:`ui`,tone:`muted`,children:r})}),i&&f.region[n].height>0?t(`div`,{class:`relative`,children:[t(`img`,{alt:e(`app.client.differenceView.artboardLabel`,{title:f.route.title,label:r}),src:a(i),class:`block w-full rounded-lg ring-1 ring-line`}),f.region.kind===`changed`?t(`div`,{"aria-hidden":`true`,class:`pointer-events-none absolute inset-y-0 rounded-sm outline-2 outline-red-500/70`,style:{left:`${f.region.x/f.width*100}%`,width:`max(2px, ${f.region.width/f.width*100}%)`}}):null]}):t(`div`,{class:`grid h-32 place-items-center rounded-lg border border-dashed border-line`,children:t(o,{variant:`ui`,tone:`muted`,children:e(`app.client.differenceView.notIn`,{label:r})})})]})};return t(`section`,{role:`dialog`,"aria-label":e(`app.client.differenceView.slideshowLabel`),class:`bud-surface absolute inset-0 z-40 flex flex-col bg-[var(--bud-main)]`,mix:i((e,t)=>{e.focus(),e.ownerDocument.addEventListener(`keydown`,e=>{if(e.key===`ArrowRight`)s(1);else if(e.key===`ArrowLeft`)s(-1);else if(e.key===`Escape`)n.props.onClose();else return;e.preventDefault()},{signal:t})}),tabindex:-1,children:[t(`header`,{class:`flex h-12 shrink-0 items-center gap-2 border-b border-line ps-4 pe-2`,children:[t(`div`,{class:`flex min-w-0 flex-1 items-baseline gap-2`,children:[t(o,{variant:`ui`,weight:`medium`,class:`truncate`,children:f?.route.title??e(`app.client.differenceView.noDifferences`)}),f?t(o,{variant:`ui`,tone:`muted`,class:`shrink-0 tabular-nums`,role:`status`,children:e(`app.client.differenceView.slideStatus`,{kind:W(f.region.kind),change:f.index+1,count:f.count,index:l+1,total:c.length})}):null]}),t(m,{tooltip:!0,icon:`chevron-left`,label:e(`app.client.differenceView.previousChange`),disabled:c.length<2,mix:r(`click`,()=>s(-1))}),t(m,{tooltip:!0,icon:`chevron-right`,label:e(`app.client.differenceView.nextChange`),disabled:c.length<2,mix:r(`click`,()=>s(1))}),t(m,{tooltip:!0,icon:`close`,label:e(`app.client.differenceView.closeSlideshow`),shortcut:`escape`,mix:r(`click`,()=>n.props.onClose())})]}),t(`div`,{class:`min-h-0 flex-1 overflow-auto p-4`,children:f?t(`div`,{class:`grid gap-4 md:grid-cols-2`,children:[p(`before`,u),p(`after`,d)]}):null})]})}}function K(e){return!(!e.anchor||`type`in e.anchor)}function ae(e,t){let{themes:n}=e.previews,r=g(t),i=document.documentElement.dataset.theme;return n.find(e=>e===r)??n.find(e=>e===i)??n[0]}function q(i){let a=i.props.project,o,c=w({store:x(a),token:a.token,signal:i.signal,initial:i.props.comments,onChange:()=>{i.update()}});i.props.comments.stored&&c.load();let l=a.workingTree?null:a.main??`main`,d=`bud:canvas-branch:${a.id}`,h=g(d),C=typeof h==`string`?h:l,T=!0,A=!1,j=D({project:a,signal:i.signal,onChange:()=>{C&&C!==l&&j.loaded&&!j.list.branches.some(e=>e.name===C&&e.active)?P(l):i.update()}}),M=new AbortController;i.signal.addEventListener(`abort`,()=>M.abort(),{once:!0});let N=E({project:a,signal:M.signal,branch:C});function P(e){if(A=!1,e===C)return void i.update();C=e,_(d,e),M.abort(),M=new AbortController,N=E({project:a,signal:M.signal,branch:e}),i.update()}let F=`bud:preview-theme:${a.id}`,I=ae(a,F),L=`bud:preview-top-only:${a.id}`,R=g(L)===!0,z=a.previews.viewports,V=z.length>1,H=`bud:canvas-viewport:${a.id}`,U=g(H),W=V&&typeof U==`string`&&(U===`all`||z.some(e=>e.id===U))?U:V?`all`:z[0].id;function G(e){e!==W&&(W=e,_(H,e),i.update())}function q(){let e=W===`all`?z:z.filter(e=>e.id===W);return a.routes.flatMap(t=>e.map(e=>({route:t,size:e,artboard:V?{...t,id:`${t.id}@${e.id}`,pageId:t.id,width:e.width,caption:String(e.width)}:t})))}let J=`bud:canvas-compare:${a.id}`,Y=null,X,Z;function Q(){let t=a.workingTree?[{value:``,label:e(`app.client.projectCanvas.workingTree`)}]:[];for(let e of j.list.branches)e.active&&e.captured&&t.push({value:e.name,label:e.name});return t.filter(e=>e.value!==(C??``))}function oe(t){return t||e(`app.client.projectCanvas.workingTree`)}function se(){let e=Q(),t=g(J);Y=e.find(e=>e.value===t)?.value??e.find(e=>e.value===(j.list.main??`main`))?.value??e[0]?.value??null,Z=void 0,i.update()}function ce(){Y=null,Z=void 0,X?.controller.abort(),X=void 0,i.update()}function le(e){if(Y===null||(Q().some(e=>e.value===Y)||(Y=Q()[0]?.value??null),Y===null))return;let t=`${Y}\0${C??``}\0${I}\0${W}`;if(X?.key===t)return X.result;X?.controller.abort();let n=new AbortController;i.signal.addEventListener(`abort`,()=>n.abort(),{once:!0});let r=E({project:a,signal:n.signal,branch:Y||null}),o=B({routes:q().map(({route:e,size:t,artboard:n})=>({id:n.id,page:e.id,size:t})),before:r,after:e,theme:I,signal:n.signal,onChange:()=>{i.update()}});return X={key:t,controller:n,result:o},o}function $(e){return!V||W===`all`||(z.find(t=>t.width===e.anchor.viewport)??z[0]).id===W}function ue(e){return e.filter(K).filter(e=>(e.anchor.branch??l)===C).filter($)}return()=>{if(o!==i.props.threadId){o=i.props.threadId;let e=o;e&&i.queueTask(()=>{c.loadThread(e)})}if(!j.loaded&&!j.error)return t(s,{label:e(`app.client.projectCanvas.loadingBranches`)});let l=`${a.id}:${a.targetOrigin}:${a.routes.map(e=>e.path).join(`|`)}`,d={...c.snapshot,threads:ue(c.snapshot.threads)},h=q(),g=new Map(h.map(({artboard:e,size:t})=>[e.id,t])),x=le(N),w=oe(Y),E=oe(C),D=x?h.map(({artboard:e})=>e).filter(e=>x.get(e.id).state===`different`):[],M=new Map,B=D.flatMap(e=>[`before`,`after`].map(t=>{let n=`${e.id}#${t}`;return M.set(n,{route:e,side:t}),{id:n,path:e.path,title:e.title,width:e.width,caption:e.caption,compare:{groupId:e.id,groupTitle:e.title,versionLabel:t===`before`?w:E}}})),H=D.flatMap(e=>{let{regions:t,after:n}=x.get(e.id),r=n?.width??e.width??z[0].width;return t.map((n,i)=>({route:e,region:n,index:i,count:t.length,width:r}))}),U=``;if(x){let{compared:t,total:n}=x.progress,r=h.filter(({artboard:e})=>x.get(e.id).state===`missing`).length;U=x.done?D.length?r?e(`app.client.projectCanvas.differentPagesWithMissing`,{changed:D.length,count:n,name:w,missing:r}):e(`app.client.projectCanvas.differentPages`,{changed:D.length,count:n,name:w}):r?e(`app.client.projectCanvas.noDifferencesWithMissing`,{name:w,count:r}):e(`app.client.projectCanvas.noDifferences`,{name:w}):e(`app.client.projectCanvas.comparingPages`,{name:w,done:t,count:n})}let K=Q(),ae=e=>e.mobile||e.width<600?`mobile`:e.width<1100?`tablet`:`desktop`,$=t(n,{children:[V?t(n,{children:[z.map(n=>t(m,{tooltip:!0,icon:ae(n),label:e(`app.client.projectCanvas.showViewport`,{name:n.name,width:n.width}),active:W===n.id,mix:r(`click`,()=>G(n.id))})),t(m,{tooltip:!0,icon:`columns`,label:e(`app.client.projectCanvas.showEveryViewport`),active:W===`all`,mix:r(`click`,()=>G(`all`))}),t(f,{})]}):null,t(m,{tooltip:!0,icon:`compare`,label:e(x?`app.client.projectCanvas.stopComparing`:`app.client.projectCanvas.showDifferences`),active:!!x,disabled:!x&&!K.length,mix:r(`click`,()=>x?ce():se())}),x?t(n,{children:[t(u,{label:e(`app.client.projectCanvas.compareWith`),value:Y??``,options:K,class:`max-w-48`,onChange:e=>{Y=e,Z=void 0,_(J,e),i.update()}}),t(m,{tooltip:!0,icon:`play`,label:e(`app.client.projectCanvas.stepThroughDifferences`),disabled:!H.length,mix:r(`click`,()=>{Z=0,i.update()})})]}):null]});return t(p,{class:`h-full min-h-0`,sidebarLabel:e(`app.client.projectCanvas.branches`),mainLabel:e(`app.client.projectCanvas.canvas`),drawerOpen:A,onDrawerOpenChange:e=>{A=e,i.update()},onWideChange:e=>{T!==e&&(T=e,i.update())},sidebar:t(b,{working:j.list.working,workingTree:a.workingTree,branches:j.list.branches,selected:C,busy:j.busy||!j.loaded,loaded:j.loaded,error:j.error,mobile:!T,onSelect:P,onActivate:(e,t)=>{j.activate(e,t)},onCapture:e=>{j.capture(e)},onClose:()=>{A=!1,i.update()}}),children:t(v,{artboards:x?B:h.map(({artboard:e})=>e),width:z[0].width,storageKey:x?`bud:camera:${l}:differences:${W}`:`bud:camera:${l}:${V?W:z[0].width}`,tools:$,overlay:x&&Z!==void 0?t(ie,{slides:H,index:Z,beforeLabel:w,afterLabel:E,onIndex:e=>{Z=e,i.update()},onClose:()=>{Z=void 0,i.update()}}):null,snapshot:d,capabilities:c.snapshot.capabilities,commentsUnavailable:x?U:(c.loaded?!c.ready:a.storage.threads?.state!==`ready`)?S:void 0,onLoadThread:c.loadThread,renderThreadLinks:e=>t(O,{part:`links`,project:a,thread:e,canLink:c.snapshot.capabilities.link,busy:c.busy,onChange:async()=>{await c.load(),await c.loadThread(e.id,!0)}}),renderThreadActions:e=>t(n,{children:[t(k,{thread:e,canMake:c.snapshot.capabilities.link&&a.storage.work?.state===`ready`,busy:c.busy,onMake:async t=>c.makeTask(t,await ne(N,e,z).catch(()=>void 0))}),t(O,{part:`action`,project:a,thread:e,canLink:c.snapshot.capabilities.link,busy:c.busy,onChange:async()=>{await c.load(),await c.loadThread(e.id,!0)}})]}),initialThreadId:o,loaded:c.loaded,busy:c.busy,error:c.error,now:c.now,onWrite:async e=>{let t=await c.write(e);return{...t,threads:ue(t.threads)}},onSync:()=>c.sync().catch(()=>{}),onReload:c.load,viewerId:c.viewer?.id,onDeleteComment:(e,t)=>c.remove(e,t),onCopyThreadLink:e=>navigator.clipboard.writeText(new URL(y(e.id),window.location.origin).href),interactive:!1,branch:C,theme:I,onThemeChange:a.previews.themes.length>1?e=>{I=e,_(F,e),i.update()}:void 0,topOnly:R,onTopOnlyChange:x?void 0:e=>{R=e,_(L,e),i.update()},onShowSidebar:T?void 0:()=>{A=!0,i.update()},sidebarLabel:e(`app.client.projectCanvas.branches`),renderArtboard:(e,n)=>{let r=M.get(e.id);return r?t(re,{route:e,side:r.side,label:r.side===`before`?w:E,regions:x.get(r.route.id).regions,...n},`${X?.key??``}\0${e.id}`):t(ee,{route:e,origin:a.targetOrigin,theme:I,size:g.get(e.id)??z[0],topOnly:R,previews:N,...n},`${C??``}\0${e.id}`)},renderArtboardActions:e=>C||x?null:t(te,{route:e,previews:N})},`${x?`${l}:differences`:l}:${W}`)})}}var J=c({load:({project:e,signal:t})=>C(e,t),render:(e,{project:n,conversation:r})=>t(q,{project:n,comments:e,threadId:r?.id})});export{J as default};
|