@01.works/visual-review 0.9.1 → 0.9.2
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 +9 -10
- package/THIRD_PARTY_NOTICES.md +32 -2
- package/dist/hosted-runtime-D1xY3Jtw.js +13 -0
- package/dist/index.js +1 -1
- package/dist/install-RHVUfLTU.js +1 -0
- package/dist/react.js +1 -1
- package/dist/src-CtuDVE7s.js +1467 -0
- package/package.json +1 -1
- package/dist/hosted-runtime-Bf6OQ7hX.js +0 -13
- package/dist/install-by7IEqS6.js +0 -1
- package/dist/src-Dtk1yQCG.js +0 -1278
package/README.md
CHANGED
|
@@ -157,11 +157,10 @@ npm run preview
|
|
|
157
157
|
<VisualReview collaboration={{ cursors: true, chat: true }} />
|
|
158
158
|
```
|
|
159
159
|
|
|
160
|
-
`cursors
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
쓰지 않으며, 채팅만 켜면 cursor room에 참여하지 않습니다. 둘 모두 유효한
|
|
160
|
+
`cursors`와 `chat`은 저장하지 않는 presence를 사용합니다. `chat`을 켜면 일반 입력
|
|
161
|
+
요소 밖에서 `/`를 눌러 현재 cursor room의 ephemeral 채팅을 열 수 있습니다.
|
|
162
|
+
따라서 저장되는 page chat은 없고, legacy `reviewMessages`는 read-only 호환 data로만
|
|
163
|
+
남습니다. 둘 모두 유효한
|
|
165
164
|
invitation과 같은 deny-by-default project 권한을 전제로 하며 browser flag 자체는
|
|
166
165
|
권한을 부여하지 않습니다.
|
|
167
166
|
|
|
@@ -190,11 +189,11 @@ namespaced storage 확인 뒤 DOM, history listener, auth, dynamic runtime impor
|
|
|
190
189
|
bootstrap을 시작하지 않습니다. `enabled={false}`는 긴급 kill switch입니다.
|
|
191
190
|
|
|
192
191
|
처음에는 `#visual-review=<invitation-id>` 초대 링크로 접근합니다. hosted service가
|
|
193
|
-
project에 연결된 exact Origin 목록과 현재 pathname을 activation gate로
|
|
194
|
-
|
|
195
|
-
등록됩니다. bootstrap 응답은 public Instant App ID만 반환하며 reviewer session이나
|
|
192
|
+
project에 연결된 exact Origin 목록과 현재 pathname을 읽기 전용 activation gate로
|
|
193
|
+
확인합니다. bootstrap 응답은 public Instant App ID만 반환하며 reviewer session이나
|
|
196
194
|
이메일을 포함하지 않습니다. 이후 magic-code login을 완료한 browser가 accept
|
|
197
|
-
endpoint에 refresh token을
|
|
195
|
+
endpoint에 refresh token을 보내고, 인증된 `/v1/pages/resolve`가 아직 등록되지 않은
|
|
196
|
+
pathname을 자동 등록합니다. Server는
|
|
198
197
|
`db.asUser({ token })`으로 user-scoped claim을 실행하며 완료된 뒤에만 client가
|
|
199
198
|
정확한 page를 선택해 Instant subscription과 overlay를 mount합니다. `revokedAt`,
|
|
200
199
|
expiry와 claim 시 membership/project mismatch는 fail closed합니다.
|
|
@@ -206,7 +205,7 @@ reviewer membership은 claim 검증과 comment/reply author identity에 사용
|
|
|
206
205
|
접근 철회는 invitation revoke로 수행합니다. admin token은 browser로 전달되지
|
|
207
206
|
않습니다.
|
|
208
207
|
|
|
209
|
-
정식 default service는 `https://
|
|
208
|
+
정식 default service는 `https://review.01.works`입니다. local/self-hosted
|
|
210
209
|
integration에서는 명시적으로 service URL을 바꿀 수 있습니다.
|
|
211
210
|
|
|
212
211
|
```tsx
|
package/THIRD_PARTY_NOTICES.md
CHANGED
|
@@ -41,14 +41,18 @@ SOFTWARE.
|
|
|
41
41
|
## React Grab
|
|
42
42
|
|
|
43
43
|
The bundled selection engine uses `react-grab/primitives`, and the widget UI
|
|
44
|
-
adapts interface elements from the
|
|
44
|
+
adapts interface elements from the initial UI snapshot below. The bundled
|
|
45
|
+
dock adapts drag thresholds, edge-snap geometry, velocity projection, and
|
|
46
|
+
orientation from the newer dock snapshot below.
|
|
45
47
|
An explicitly enabled developer tool also uses React Grab's context and
|
|
46
48
|
clipboard primitives on first use for code context copying without initializing
|
|
47
49
|
another toolbar, shortcut, or telemetry surface.
|
|
48
50
|
|
|
49
51
|
- Repository: https://github.com/aidenybai/react-grab
|
|
50
52
|
- Version first integrated: `0.1.50`
|
|
51
|
-
-
|
|
53
|
+
- Initial UI snapshot commit: `2a39bc29e5f8bdbd69095cf1d33d91634576cd20`
|
|
54
|
+
- Dock snapshot version: `0.2.0`
|
|
55
|
+
- Dock snapshot commit: `bc0c7d0dbcf24bf245abb0f1c55ad38429351cfd`
|
|
52
56
|
- License: MIT
|
|
53
57
|
|
|
54
58
|
### MIT License
|
|
@@ -161,3 +165,29 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
161
165
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
162
166
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
163
167
|
SOFTWARE.
|
|
168
|
+
|
|
169
|
+
## html-to-image
|
|
170
|
+
|
|
171
|
+
- Repository: https://github.com/bubkoo/html-to-image
|
|
172
|
+
- Version bundled: `1.11.13`
|
|
173
|
+
- License: MIT
|
|
174
|
+
|
|
175
|
+
Copyright (c) 2017-2025 W.Y.
|
|
176
|
+
|
|
177
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
178
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
179
|
+
in the Software without restriction, including without limitation the rights
|
|
180
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
181
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
182
|
+
furnished to do so, subject to the following conditions:
|
|
183
|
+
|
|
184
|
+
The above copyright notice and this permission notice shall be included in all
|
|
185
|
+
copies or substantial portions of the Software.
|
|
186
|
+
|
|
187
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
188
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
189
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
190
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
191
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
192
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
193
|
+
SOFTWARE.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import{r as e}from"./install-RHVUfLTU.js";import{t}from"./embedded-source-DSDHbbeU.js";import{i as n,init as r}from"@instantdb/core";const i=131072,a=32768,o=4096,s=1e3;var c=class extends Error{constructor(e,t){super(e,t),this.name=`InstantCaptureIntegrityError`}};function l(e){let t=_(e,`comment target`,!0),n={kind:t.kind,anchor:le(t.anchor),region:fe(t.region),elements:t.elements.map(e=>({selector:e.selector,tagName:e.tagName,textPreview:e.textPreview,rect:fe(e.rect),source:null,componentStack:[]})),pageUrl:t.pageUrl,pageTitle:t.pageTitle,capturedAt:t.capturedAt,...t.environment?{environment:ne(t.environment)}:{}},r={elements:t.elements.map(e=>({selector:e.selector,source:e.source?pe(e.source):null,componentStack:e.componentStack.map(pe)})),...t.sourceProvenance?{sourceProvenance:me(t.sourceProvenance)}:{}};T(n,i,`Public target`);let a=xe(r,65536,`Source context`);return{publicTarget:n,commentFields:f(n),targetElements:n.elements.map(p),sourceContextJson:a}}function u(e,t,n){let r=b(e,n),i={selector:x(r.anchorSelector,`${n} anchor selector`,o),offsetX:w(r.anchorOffsetX,`${n} anchor offsetX`),offsetY:w(r.anchorOffsetY,`${n} anchor offsetY`),viewportX:w(r.anchorViewportX,`${n} anchor viewportX`),viewportY:w(r.anchorViewportY,`${n} anchor viewportY`)},a=h({kind:r.targetKind,anchor:i,region:{pageX:r.targetPageX,pageY:r.targetPageY,width:r.targetWidth,height:r.targetHeight,viewportX:r.targetViewportX,viewportY:r.targetViewportY,viewportWidth:r.targetViewportWidth,viewportHeight:r.targetViewportHeight},elements:[],pageUrl:de({origin:S(r.targetPageOrigin,`${n} page origin`,1024),pathname:S(r.targetPagePathname,`${n} page pathname`,4096),search:x(r.targetPageSearch,`${n} page search`,1024),hash:x(r.targetPageHash,`${n} page hash`,1024)}),pageTitle:r.targetPageTitle,capturedAt:r.targetCapturedAt,...te(r,n)},n),s=m(t,`${n} elements`),c=a;for(let e of s)try{c=h({...a,elements:[...c.elements,e]},n)}catch{}return c}function d(e){if(!Array.isArray(e)||e.length===0)return;let t=[...e].map(e=>{try{let t=b(e,`Comment scope entry`);return{row:t,ordinal:_e(t.ordinal,`Comment scope entry ordinal`,0,19),id:typeof t.id==`string`?t.id:``}}catch{return null}}).filter(e=>e!==null).sort((e,t)=>e.ordinal-t.ordinal||e.id.localeCompare(t.id)),n={},r=new Set;for(let{row:e,ordinal:i}of t)if(!r.has(i)){r.add(i);try{let t=S(e.key,`Comment scope key`,256);if(Object.hasOwn(n,t))continue;switch(e.valueType){case`string`:n[t]=x(e.stringValue,`Comment scope ${t}`,s);break;case`number`:n[t]=C(e.numberValue,`Comment scope ${t}`);break;case`boolean`:if(typeof e.booleanValue!=`boolean`)throw E(`Comment scope ${t} is invalid`);n[t]=e.booleanValue;break;case`null`:n[t]=null;break;default:throw E(`Comment scope ${t} is invalid`)}}catch{}}if(Object.keys(n).length!==0)try{return T(n,a,`Comment scope`),n}catch{return}}function f(e){let t=new URL(e.pageUrl);return{anchorSelector:e.anchor.selector,anchorOffsetX:e.anchor.offsetX,anchorOffsetY:e.anchor.offsetY,anchorViewportX:e.anchor.viewportX,anchorViewportY:e.anchor.viewportY,targetKind:e.kind,targetPageX:e.region.pageX,targetPageY:e.region.pageY,targetWidth:e.region.width,targetHeight:e.region.height,targetViewportX:e.region.viewportX,targetViewportY:e.region.viewportY,targetViewportWidth:e.region.viewportWidth,targetViewportHeight:e.region.viewportHeight,targetPageOrigin:t.origin,targetPagePathname:ue(t.pathname),targetPageSearch:t.search.slice(1),targetPageHash:t.hash.slice(1),targetPageTitle:e.pageTitle,targetCapturedAt:e.capturedAt,...e.environment?{environmentBrowser:e.environment.browser,environmentOperatingSystem:e.environment.operatingSystem,environmentDeviceType:e.environment.deviceType,environmentScreenWidth:e.environment.screenWidth,environmentScreenHeight:e.environment.screenHeight,environmentDevicePixelRatio:e.environment.devicePixelRatio}:{}}}function p(e,t){return{ordinal:t,selector:e.selector,tagName:e.tagName,textPreview:e.textPreview,pageX:e.rect.pageX,pageY:e.rect.pageY,width:e.rect.width,height:e.rect.height,viewportX:e.rect.viewportX,viewportY:e.rect.viewportY,viewportWidth:e.rect.viewportWidth,viewportHeight:e.rect.viewportHeight}}function m(e,t){if(!Array.isArray(e)||e.length===0)return[];let n=[...e].map(e=>{try{let n=b(e,t);return{row:n,ordinal:_e(n.ordinal,`${t} ordinal`,0,7),id:typeof n.id==`string`?n.id:``}}catch{return null}}).filter(e=>e!==null).sort((e,t)=>e.ordinal-t.ordinal||e.id.localeCompare(t.id)),r=[],i=new Set;for(let{row:e,ordinal:a}of n)if(!i.has(a)){i.add(a);try{r.push(ie({selector:e.selector,tagName:e.tagName,textPreview:e.textPreview,rect:{pageX:e.pageX,pageY:e.pageY,width:e.width,height:e.height,viewportX:e.viewportX,viewportY:e.viewportY,viewportWidth:e.viewportWidth,viewportHeight:e.viewportHeight},source:null,componentStack:[]},`${t}[${a}]`,!1))}catch{}}return r}function h(e,t){return _(e,t,!1)}function g(e,t=`Comment body`){return S(e,t,2e4)}function ee(e){if(e==null)return;let t=b(e,`Comment scope`);if(Object.keys(t).length>20)throw E(`Comment scope has too many fields`);let n={};for(let[e,r]of Object.entries(t)){if(!e.trim()||e.length>256)throw E(`Comment scope has an invalid key`);if(typeof r==`string`){if(r.length>s)throw E(`Comment scope ${e} is too long`);n[e]=r}else if(typeof r==`number`)n[e]=C(r,`Comment scope ${e}`);else if(typeof r==`boolean`||r===null)n[e]=r;else throw E(`Comment scope ${e} is invalid`)}return T(n,a,`Comment scope`),n}function _(e,t,n){let r=y(e,t,[`kind`,`anchor`,`region`,`elements`,`pageUrl`,`pageTitle`,`capturedAt`,`environment`,`sourceProvenance`],[`environment`,`sourceProvenance`]),a=r.kind;if(a!==`element`&&a!==`region`&&a!==`viewport`)throw E(`${t} kind is invalid`);let o=he(r.elements,`${t} elements`);if(o.length>8)throw E(`${t} contains too many elements`);if(!n&&r.sourceProvenance!=null)throw E(`${t} exposes source provenance`);let c=S(r.pageUrl,`${t} pageUrl`,8192);be(c,`${t} pageUrl`);let l={kind:a,anchor:ae(r.anchor,`${t} anchor`),region:oe(r.region,`${t} region`),elements:o.map((e,r)=>ie(e,`${t} elements[${r}]`,n)),pageUrl:c,pageTitle:x(r.pageTitle,`${t} pageTitle`,s),capturedAt:ve(r.capturedAt,`${t} capturedAt`),...r.environment==null?{}:{environment:v(r.environment,`${t} environment`)},...n&&r.sourceProvenance!=null?{sourceProvenance:ce(r.sourceProvenance,`${t} provenance`)}:{}};return T(l,n?196608:i,t),l}function v(e,t){let n=y(e,t,[`browser`,`operatingSystem`,`deviceType`,`screenWidth`,`screenHeight`,`devicePixelRatio`]),r=n.deviceType;if(r!==`desktop`&&r!==`tablet`&&r!==`mobile`&&r!==`unknown`)throw E(`${t} deviceType is invalid`);return{browser:S(n.browser,`${t} browser`,120),operatingSystem:S(n.operatingSystem,`${t} operatingSystem`,120),deviceType:r,screenWidth:re(n.screenWidth,`${t} screenWidth`,1e5),screenHeight:re(n.screenHeight,`${t} screenHeight`,1e5),devicePixelRatio:re(n.devicePixelRatio,`${t} devicePixelRatio`,100)}}function te(e,t){if([e.environmentBrowser,e.environmentOperatingSystem,e.environmentDeviceType,e.environmentScreenWidth,e.environmentScreenHeight,e.environmentDevicePixelRatio].every(e=>e==null))return{};try{return{environment:v({browser:e.environmentBrowser,operatingSystem:e.environmentOperatingSystem,deviceType:e.environmentDeviceType,screenWidth:e.environmentScreenWidth,screenHeight:e.environmentScreenHeight,devicePixelRatio:e.environmentDevicePixelRatio},`${t} environment`)}}catch{return{}}}function ne(e){return{...e}}function re(e,t,n){let r=C(e,t);if(r<=0||r>n)throw E(`${t} is invalid`);return r}function ie(e,t,n){let r=y(e,t,[`selector`,`tagName`,`textPreview`,`rect`,`source`,`componentStack`]),i=he(r.componentStack,`${t} componentStack`);if(i.length>32)throw E(`${t} componentStack is too large`);if(!n&&(r.source!=null||i.length>0))throw E(`${t} exposes source metadata`);return{selector:S(r.selector,`${t} selector`,o),tagName:S(r.tagName,`${t} tagName`,128),textPreview:x(r.textPreview,`${t} textPreview`,s),rect:oe(r.rect,`${t} rect`),source:n&&r.source!=null?se(r.source,`${t} source`):null,componentStack:n?i.map((e,n)=>se(e,`${t} stack[${n}]`)):[]}}function ae(e,t){let n=y(e,t,[`selector`,`offsetX`,`offsetY`,`viewportX`,`viewportY`]);return{selector:x(n.selector,`${t} selector`,o),offsetX:w(n.offsetX,`${t} offsetX`),offsetY:w(n.offsetY,`${t} offsetY`),viewportX:w(n.viewportX,`${t} viewportX`),viewportY:w(n.viewportY,`${t} viewportY`)}}function oe(e,t){let n=y(e,t,[`pageX`,`pageY`,`width`,`height`,`viewportX`,`viewportY`,`viewportWidth`,`viewportHeight`]),r={pageX:C(n.pageX,`${t} pageX`),pageY:C(n.pageY,`${t} pageY`),width:C(n.width,`${t} width`),height:C(n.height,`${t} height`),viewportX:C(n.viewportX,`${t} viewportX`),viewportY:C(n.viewportY,`${t} viewportY`),viewportWidth:C(n.viewportWidth,`${t} viewportWidth`),viewportHeight:C(n.viewportHeight,`${t} viewportHeight`)};if(r.width<0||r.height<0||r.viewportWidth<0||r.viewportHeight<0)throw E(`${t} has a negative dimension`);return r}function se(e,n){let r=y(e,n,[`filePath`,`lineNumber`,`columnNumber`,`componentName`,`origin`,`generated`],[`generated`]),i=r.origin;if(i!==`app`&&i!==`shared-ui`&&i!==`dependency`&&i!==`generated`&&i!==`unknown`)throw E(`${n} origin is invalid`);let a=S(r.filePath,`${n} filePath`,o);return{filePath:a,lineNumber:ye(r.lineNumber,`${n} lineNumber`),columnNumber:ye(r.columnNumber,`${n} columnNumber`),componentName:r.componentName==null?null:S(r.componentName,`${n} componentName`,512),origin:t(a)}}function ce(e,t){let n=y(e,t,[`provider`,`build`,`resolvedAt`]),r=n.provider;if(r!==`react-grab`&&r!==`embedded`&&r!==`custom`)throw E(`${t} provider is invalid`);let i=y(n.build,`${t} build`,[`buildId`,`gitCommit`,`generatedAt`,`mode`],[`generatedAt`]),a=i.mode;if(a!==`development`&&a!==`preview`&&a!==`production`)throw E(`${t} build mode is invalid`);return{provider:r,build:{buildId:S(i.buildId,`${t} buildId`,512),gitCommit:i.gitCommit==null?null:S(i.gitCommit,`${t} gitCommit`,256),...i.generatedAt==null?{}:{generatedAt:ve(i.generatedAt,`${t} generatedAt`)},mode:a},resolvedAt:ve(n.resolvedAt,`${t} resolvedAt`)}}function le(e){return{...e}}function ue(e){return e.replace(/\/+$/,``)||`/`}function de(e){return`${e.origin}${e.pathname}${e.search?`?${e.search}`:``}${e.hash?`#${e.hash}`:``}`}function fe(e){return{...e}}function pe(e){return{...e}}function me(e){return{...e,build:{...e.build}}}function y(e,t,n,r=[]){let i=b(e,t);if(Object.keys(i).some(e=>!n.includes(e)))throw E(`${t} contains unknown fields`);for(let e of n)if(!r.includes(e)&&!Object.hasOwn(i,e))throw E(`${t} is missing ${e}`);return i}function b(e,t){if(!e||typeof e!=`object`||Array.isArray(e))throw E(`${t} is missing or invalid`);return e}function he(e,t){if(!Array.isArray(e))throw E(`${t} is missing or invalid`);return e}function x(e,t,n){if(typeof e!=`string`||ge(e,n)>n)throw E(`${t} is invalid or too long`);return e}function ge(e,t){let n=0;for(let r of e)if(n+=1,n>t)return n;return n}function S(e,t,n){let r=x(e,t,n);if(!r.trim())throw E(`${t} is empty`);return r}function C(e,t){if(typeof e!=`number`||!Number.isFinite(e))throw E(`${t} is invalid`);return e}function _e(e,t,n,r){if(typeof e!=`number`||!Number.isSafeInteger(e)||e<n||e>r)throw E(`${t} is invalid`);return e}function w(e,t){let n=C(e,t);if(n<0||n>1)throw E(`${t} is outside 0..1`);return n}function ve(e,t){if(typeof e!=`number`||!Number.isSafeInteger(e)||e<0||e>0xe677d21fdbff)throw E(`${t} is invalid`);return e}function ye(e,t){if(e===null)return null;if(typeof e!=`number`||!Number.isSafeInteger(e)||e<0)throw E(`${t} is invalid`);return e}function be(e,t){let n;try{n=new URL(e)}catch(e){throw E(`${t} is invalid`,e)}if(n.protocol!==`http:`&&n.protocol!==`https:`)throw E(`${t} must use HTTP or HTTPS`)}function T(e,t,n){xe(e,t,n)}function xe(e,t,n){let r;try{r=JSON.stringify(e)}catch(e){throw E(`${n} cannot be serialized`,e)}if(r.length>t)throw E(`${n} is too large`);return r}function E(e,t){return new c(e,{cause:t instanceof Error?t:void 0})}new Uint8Array([107,167,184,17,157,173,17,209,128,180,0,192,79,212,48,200]);const Se=n.schema({entities:{$files:n.entity({path:n.string().unique().indexed(),url:n.string()}),$users:n.entity({email:n.string().unique().indexed()}),projects:n.entity({name:n.string(),slug:n.string().unique().indexed(),allowedOrigin:n.string().optional(),originDisconnectedAt:n.number().optional(),originModelVersion:n.number().optional(),createdAt:n.number().indexed(),updatedAt:n.number()}),projectOrigins:n.entity({projectId:n.string().indexed(),originKey:n.string().unique().indexed(),origin:n.string().indexed(),label:n.string().optional(),createdAt:n.number().indexed(),updatedAt:n.number()}),reviewPages:n.entity({projectId:n.string().indexed(),autoRegistrationSlot:n.string().unique().indexed().optional(),name:n.string(),pathname:n.string(),stagingOrigin:n.string(),createdAt:n.number().indexed(),updatedAt:n.number()}),reviewPageBuilds:n.entity({projectId:n.string().indexed(),pageId:n.string().unique().indexed(),buildId:n.string(),gitCommit:n.string().optional(),generatedAt:n.number().optional(),mode:n.string(),updatedAt:n.number().indexed()}),reviewers:n.entity({authUserId:n.string().indexed(),projectId:n.string().indexed(),email:n.string().indexed(),displayName:n.string(),role:n.string(),createdAt:n.number()}),reviewerIdentityClaims:n.entity({reviewerId:n.string().unique().indexed(),projectId:n.string().indexed(),authUserId:n.string().indexed(),email:n.string(),displayName:n.string(),role:n.string(),createdAt:n.number()}),invitations:n.entity({projectId:n.string().indexed(),reviewerId:n.string().indexed().optional(),email:n.string().indexed(),status:n.string().indexed(),claimRevision:n.number(),claimedByAuthUserId:n.string().indexed().optional(),expiresAt:n.number().indexed(),createdAt:n.number(),acceptedAt:n.number().optional(),revokedAt:n.number().optional()}),comments:n.entity({pageId:n.string().indexed(),pageNumber:n.number().optional(),authorId:n.string().indexed(),authorAuthUserId:n.string().indexed(),authorName:n.string(),body:n.string(),bodyContentMarker:n.string().optional(),anchorSelector:n.string().optional(),anchorOffsetX:n.number().optional(),anchorOffsetY:n.number().optional(),anchorViewportX:n.number().optional(),anchorViewportY:n.number().optional(),targetKind:n.string().optional(),targetPageX:n.number().optional(),targetPageY:n.number().optional(),targetWidth:n.number().optional(),targetHeight:n.number().optional(),targetViewportX:n.number().optional(),targetViewportY:n.number().optional(),targetViewportWidth:n.number().optional(),targetViewportHeight:n.number().optional(),targetPageOrigin:n.string().optional(),targetPagePathname:n.string().optional(),targetPageSearch:n.string().optional(),targetPageHash:n.string().optional(),targetPageTitle:n.string().optional(),targetCapturedAt:n.number().optional(),environmentBrowser:n.string().optional(),environmentOperatingSystem:n.string().optional(),environmentDeviceType:n.string().optional(),environmentScreenWidth:n.number().optional(),environmentScreenHeight:n.number().optional(),environmentDevicePixelRatio:n.number().optional(),status:n.string().indexed(),workflowRevision:n.number(),createdAt:n.number().indexed(),updatedAt:n.number().indexed(),resolvedAt:n.number().optional(),resolvedById:n.string().optional(),deletingAt:n.number().optional()}),commentWorkflowClaims:n.entity({claimKey:n.string().unique().indexed(),commentId:n.string().indexed(),expectedWorkflowRevision:n.number(),createdAt:n.number().indexed()}),commentPageNumberClaims:n.entity({claimKey:n.string().unique().indexed(),pageId:n.string().indexed(),pageNumber:n.number(),commentId:n.string().indexed(),createdAt:n.number().indexed()}),commentTargetElements:n.entity({commentId:n.string().indexed(),slotKey:n.string().unique().indexed().optional(),ordinal:n.number(),selector:n.string(),tagName:n.string(),textPreview:n.string(),pageX:n.number(),pageY:n.number(),width:n.number(),height:n.number(),viewportX:n.number(),viewportY:n.number(),viewportWidth:n.number(),viewportHeight:n.number(),authorAuthUserId:n.string().indexed()}),commentScopeEntries:n.entity({commentId:n.string().indexed(),slotKey:n.string().unique().indexed().optional(),ordinal:n.number(),key:n.string(),valueType:n.string(),stringValue:n.string().optional(),numberValue:n.number().optional(),booleanValue:n.boolean().optional(),authorAuthUserId:n.string().indexed()}),commentSourceContexts:n.entity({commentId:n.string().unique().indexed(),pageId:n.string().indexed(),authorAuthUserId:n.string().indexed(),contextJson:n.string(),createdAt:n.number().indexed()}),replies:n.entity({pageId:n.string().indexed(),commentId:n.string().indexed(),authorId:n.string().indexed(),authorAuthUserId:n.string().indexed(),authorName:n.string(),body:n.string(),bodyContentMarker:n.string().optional(),createdAt:n.number().indexed(),updatedAt:n.number().indexed()}),reviewMessages:n.entity({pageId:n.string().indexed(),pathname:n.string().indexed(),authorId:n.string().indexed(),authorAuthUserId:n.string().indexed(),authorName:n.string(),body:n.string(),bodyContentMarker:n.string(),createdAt:n.number().indexed(),updatedAt:n.number().indexed()})},links:{projectOwners:{forward:{on:`projects`,has:`many`,label:`owners`},reverse:{on:`$users`,has:`many`,label:`ownedProjects`}},projectPages:{forward:{on:`projects`,has:`many`,label:`pages`},reverse:{on:`reviewPages`,has:`one`,label:`project`}},projectOriginProject:{forward:{on:`projects`,has:`many`,label:`origins`},reverse:{on:`projectOrigins`,has:`one`,label:`project`}},pageCurrentBuild:{forward:{on:`reviewPageBuilds`,has:`one`,label:`page`,required:!0,onDelete:`cascade`},reverse:{on:`reviewPages`,has:`one`,label:`currentBuild`}},projectReviewers:{forward:{on:`projects`,has:`many`,label:`reviewers`},reverse:{on:`reviewers`,has:`one`,label:`project`}},reviewerUser:{forward:{on:`reviewers`,has:`one`,label:`$user`},reverse:{on:`$users`,has:`many`,label:`reviewerMemberships`}},projectInvitations:{forward:{on:`projects`,has:`many`,label:`invitations`},reverse:{on:`invitations`,has:`one`,label:`project`}},invitationReviewer:{forward:{on:`invitations`,has:`one`,label:`reviewer`},reverse:{on:`reviewers`,has:`many`,label:`acceptedInvitations`}},invitationActiveUser:{forward:{on:`invitations`,has:`one`,label:`activeUser`},reverse:{on:`$users`,has:`many`,label:`activeReviewInvitations`}},pageComments:{forward:{on:`reviewPages`,has:`many`,label:`comments`},reverse:{on:`comments`,has:`one`,label:`page`}},pageReviewMessages:{forward:{on:`reviewPages`,has:`many`,label:`reviewMessages`},reverse:{on:`reviewMessages`,has:`one`,label:`page`}},commentReplies:{forward:{on:`comments`,has:`many`,label:`replies`},reverse:{on:`replies`,has:`one`,label:`comment`,required:!0,onDelete:`cascade`}},commentTargetElements:{forward:{on:`commentTargetElements`,has:`one`,label:`comment`,required:!0,onDelete:`cascade`},reverse:{on:`comments`,has:`many`,label:`targetElements`}},commentScopeEntries:{forward:{on:`commentScopeEntries`,has:`one`,label:`comment`,required:!0,onDelete:`cascade`},reverse:{on:`comments`,has:`many`,label:`scopeEntries`}},commentSourceContext:{forward:{on:`commentSourceContexts`,has:`one`,label:`comment`,required:!0,onDelete:`cascade`},reverse:{on:`comments`,has:`one`,label:`sourceContext`}},pageSourceContexts:{forward:{on:`commentSourceContexts`,has:`one`,label:`page`,required:!0},reverse:{on:`reviewPages`,has:`many`,label:`sourceContexts`}},sourceContextAuthor:{forward:{on:`commentSourceContexts`,has:`one`,label:`author`,required:!0},reverse:{on:`reviewers`,has:`many`,label:`sourceContexts`}},commentAuthor:{forward:{on:`comments`,has:`one`,label:`author`},reverse:{on:`reviewers`,has:`many`,label:`comments`}},replyAuthor:{forward:{on:`replies`,has:`one`,label:`author`},reverse:{on:`reviewers`,has:`many`,label:`replies`}},reviewMessageAuthor:{forward:{on:`reviewMessages`,has:`one`,label:`author`},reverse:{on:`reviewers`,has:`many`,label:`reviewMessages`}}},rooms:{visualReview:{presence:n.entity({reviewerId:n.string(),displayName:n.string(),color:n.string(),active:n.boolean(),pathname:n.string().optional(),cursorX:n.number().optional(),cursorY:n.number().optional(),viewportWidth:n.number().optional(),viewportHeight:n.number().optional(),cursorChat:n.string().optional()})}}}),D={$default:`false`},O={$default:`false`},k=`$user.activeReviewInvitations`,A=`${k}.project.id`;function j(e){return[`auth.id != null`,`size(auth.ref('${k}.id')) > 0`,`size(auth.ref('${A}')) == size(auth.ref('${k}.id'))`,`size(auth.ref('${k}.status')) == size(auth.ref('${k}.id'))`,`size(auth.ref('${k}.expiresAt')) == size(auth.ref('${k}.id'))`,`size(auth.ref('${k}.revokedAt')) == 0`,`auth.ref('${k}.status').all(status, status == 'accepted')`,`auth.ref('${k}.expiresAt').all(expiresAt, request.time < timestamp(expiresAt))`,e].join(` && `)}function M(...e){return e.map(e=>`(${e})`).join(` && `)}function N(...e){return e.map(e=>`(${e})`).join(` || `)}function P(e){let t=`data.ref('${e}project.origins.origin')`,n=`data.ref('${e}project.allowedOrigin')`,r=`data.ref('${e}project.originModelVersion')`;return N(`request.origin in ${t}`,M(`size(${r}) == 0`,`request.origin in ${n}`))}j(`data.ref('project.id')[0] in auth.ref('${A}')`),N(`request.origin in data.ref('project.origins.origin')`,M(`size(data.ref('project.originModelVersion')) == 0`,`request.origin in data.ref('project.allowedOrigin')`)),N(`request.origin in data.ref('origins.origin')`,M(`size(data.ref('originModelVersion')) == 0`,`request.origin in data.ref('allowedOrigin')`)),j(`data.ref('page.project.id')[0] in auth.ref('${A}')`),P(`page.`),N(`auth.id != null && auth.id in data.ref('comment.page.project.owners.id')`,M(j(`data.ref('comment.page.project.id')[0] in auth.ref('${A}')`),P(`comment.page.`))),j(`data.ref('comment.page.project.id')[0] in auth.ref('${A}')`),P(`comment.page.`),j(`data.ref('page.project.id')[0] in auth.ref('${A}')`),P(`page.`),P(``);const Ce=M(`data.reviewerId != null`,`data.projectId in data.ref('project.id')`,`data.reviewerId in data.ref('reviewer.id')`,`data.projectId in data.ref('reviewer.project.id')`,`auth.id in data.ref('reviewer.$user.id')`,`auth.email in data.ref('reviewer.email')`);M(`auth.id != null`,`data.revokedAt == null`,`data.status in ['pending', 'accepted']`,`data.status == 'pending' || data.claimedByAuthUserId == auth.id`,`request.time < timestamp(data.expiresAt)`,`request.modifiedFields.all(field, field in ['status', 'claimedByAuthUserId', 'acceptedAt', 'claimRevision', 'activeUser'])`,`'status' in request.modifiedFields`,`'claimedByAuthUserId' in request.modifiedFields`,`'acceptedAt' in request.modifiedFields`,`'claimRevision' in request.modifiedFields`,`'activeUser' in request.modifiedFields`,`newData.status == 'accepted'`,`newData.claimedByAuthUserId == auth.id`,`newData.claimRevision == data.claimRevision + 1`,`math.abs((request.time - timestamp(newData.acceptedAt)).getMinutes()) <= 1`,Ce),M(`actions.data == 'update'`,`actions.linkedData == 'update'`,`auth.id != null`,`auth.email != null`,`linkedData.id == auth.id`,`linkedData.email == auth.email`,`data.email == auth.email`,`data.revokedAt == null`,`data.status in ['pending', 'accepted']`,`data.status == 'pending' || data.claimedByAuthUserId == auth.id`,`request.time < timestamp(data.expiresAt)`,`newData.status == 'accepted'`,`newData.claimedByAuthUserId == auth.id`,`newData.claimRevision == data.claimRevision + 1`,`math.abs((request.time - timestamp(newData.acceptedAt)).getMinutes()) <= 1`,Ce),M(`actions.data == 'update'`,`actions.linkedData == 'update'`,`auth.id != null`,`auth.email != null`,`data.id == auth.id`,`data.email == auth.email`,`linkedData.email == auth.email`,`linkedData.revokedAt == null`,`linkedData.status == 'accepted'`,`linkedData.claimedByAuthUserId == auth.id`,`request.time < timestamp(linkedData.expiresAt)`,`math.abs((request.time - timestamp(linkedData.acceptedAt)).getMinutes()) <= 1`,`linkedData.projectId in linkedData.ref('project.id')`,`linkedData.reviewerId in linkedData.ref('reviewer.id')`,`linkedData.projectId in linkedData.ref('reviewer.project.id')`,`auth.id in linkedData.ref('reviewer.$user.id')`,`auth.email in linkedData.ref('reviewer.email')`),M(`auth.id != null`,`auth.email != null`,`linkedData.id == auth.id`,`linkedData.email == auth.email`,`data.email == auth.email`,`data.claimedByAuthUserId == auth.id`,`auth.id in data.ref('activeUser.id')`),M(`auth.id != null`,`auth.email != null`,`data.id == auth.id`,`data.email == auth.email`,`linkedData.email == auth.email`,`linkedData.claimedByAuthUserId == auth.id`,`auth.id in linkedData.ref('activeUser.id')`),{...D},{...D},{...O},{...O},j(`data.id in auth.ref('${A}')`),{...D},{...O},{...D},{...D},{...O},{...D},{...O},j(`data.ref('project.id')[0] in auth.ref('${A}')`),{...D},{...O},{...D},{...D},{...O},{...O},{...D},{...O},{...D},{...D},{...D},{...D},{...D},{...D},{...D};function we(e){if(!e.trim())throw Error(`InstantDB app ID is required`);return r({appId:e,schema:Se,devtool:!1})}var Te=class{db;session;#e;attachScreenshot;constructor(e,t,n={}){this.db=e,this.session=t,this.#e=n.commentTransport,this.#e&&(this.attachScreenshot=(e,t,n)=>this.#e.uploadScreenshot({pageId:e,commentId:t,screenshot:n}))}async getSnapshot(e){let{data:t}=await this.db.queryOnce(Ee(e,this.session.authUserId));return Oe(e,t.comments,t.replies)}async getProjectSnapshot(e){this.#t(e);let{data:t}=await this.db.queryOnce(De(e,this.session.authUserId));return ke(e,t.comments,t.replies)}subscribe(e,t,n){return this.db.subscribeQuery(Ee(e,this.session.authUserId),r=>{if(r.error){n?.(Ie(r.error));return}if(r.data)try{t(Oe(e,r.data.comments,r.data.replies))}catch{n?.({type:`error`,code:`data-integrity`,recovery:`retry`,clearSnapshot:!0})}})}subscribeProject(e,t,n){return this.#t(e),this.db.subscribeQuery(De(e,this.session.authUserId),r=>{if(r.error){n?.(Ie(r.error));return}if(r.data)try{t(ke(e,r.data.comments,r.data.replies))}catch{n?.({type:`error`,code:`data-integrity`,recovery:`retry`,clearSnapshot:!0})}})}async mutate(e,t){switch(t.type){case`comment.upsert`:{if(t.comment.pageId!==e)throw Error(`Comment page mismatch`);let n=t.comment;if(n.authorId!==this.session.reviewerId)throw Error(`Comment author mismatch`);let r=g(n.body).trim(),i=z(n.createdAt,`Comment createdAt`);if(z(n.updatedAt,`Comment updatedAt`)<i)throw new c(`Comment updatedAt precedes createdAt`);if(n.createdAt!==n.updatedAt)throw new c(`Comment edits must go through the review service`);if(n.status!==`open`||n.resolvedAt!==void 0||n.resolvedById!==void 0)throw new c(`New comments must start open`);let a=l(n.target);if(!Pe(n.anchor,a.publicTarget.anchor))throw new c(`Comment anchor does not match its target`);if(!this.#e)throw new c(`Comment creation requires the review service transport`);await this.#e.createComment({pageId:e,commentId:n.id,body:r,target:n.target,...n.scope===void 0?{}:{scope:n.scope}});return}case`comment.delete`:throw new c(`Comment deletion must go through the review service`);case`reply.upsert`:{let e=t.reply;if(e.authorId!==this.session.reviewerId)throw Error(`Reply author mismatch`);let n=g(e.body,`Reply body`).trim(),r=z(e.createdAt,`Reply createdAt`);if(z(e.updatedAt,`Reply updatedAt`)<r)throw new c(`Reply updatedAt precedes createdAt`);if(e.createdAt!==e.updatedAt)throw new c(`Reply edits must go through the review service`);if(!this.#e)throw new c(`Reply creation requires the review service transport`);await this.#e.createReply({commentId:e.commentId,replyId:e.id,body:n});return}case`reply.delete`:throw new c(`Reply deletion must go through the review service`)}}#t(e){if(!e.trim()||e!==this.session.projectId)throw Error(`Project does not belong to the reviewer session`)}};function Ee(e,t){return{comments:{$:{where:{pageId:e},order:{createdAt:`asc`}},targetElements:{},scopeEntries:{}},replies:{$:{where:{pageId:e},order:{createdAt:`asc`}}},$users:{$:{where:{id:t}},activeReviewInvitations:{project:{}}}}}function De(e,t){return{comments:{$:{where:{"page.project.id":e},order:{createdAt:`asc`}},page:{project:{}},targetElements:{},scopeEntries:{}},replies:{$:{where:{"comment.page.project.id":e},order:{createdAt:`asc`}},comment:{page:{project:{}}}},$users:{$:{where:{id:t}},activeReviewInvitations:{project:{}}}}}function Oe(e,t,n){let r=t.map(t=>je(t,e));F(r,`comment`);let i=new Set(r.map(({id:e})=>e)),a=n.map(t=>Me(t,e));F(a,`reply`);for(let e of a)if(!i.has(e.commentId))throw new c(`Reply ${e.id} references a comment outside the page snapshot`);return{pageId:e,comments:r,replies:a}}function ke(e,t,n){let r=new Map,i=t.map(t=>{let n=L(t.pageId,`comment pageId`);Ae(t.page,n,e,`comment ${String(t.id)}`);let i=I(t.page,`comment ${String(t.id)} page`),a=je(t,n),o=`/`;try{o=new URL(a.target.pageUrl).pathname||`/`}catch{}return r.set(n,{id:n,name:typeof i.name==`string`&&i.name.trim()?i.name.trim():a.target.pageTitle.trim()||o,pathname:typeof i.pathname==`string`&&i.pathname.trim()?i.pathname.trim():o}),a});F(i,`comment`);let a=new Map(i.map(e=>[e.id,e])),o=n.map(t=>{let n=L(t.pageId,`reply pageId`),r=I(t.comment,`reply ${String(t.id)} comment`),i=L(t.commentId,`reply ${String(t.id)} commentId`);if(L(r.id,`reply ${String(t.id)} comment relation id`)!==i)throw new c(`Reply ${String(t.id)} has an inconsistent comment relation`);Ae(r.page,n,e,`reply ${String(t.id)}`);let o=Me(t,n),s=a.get(o.commentId);if(!s||s.pageId!==n)throw new c(`Reply ${o.id} references a comment outside the project snapshot`);return o});return F(o,`reply`),{projectId:e,pages:[...r.values()].sort((e,t)=>e.pathname.localeCompare(t.pathname)||e.id.localeCompare(t.id)),comments:i,replies:o}}function Ae(e,t,n,r){let i=I(e,`${r} page`);if(L(i.id,`${r} page id`)!==t)throw new c(`${r} escaped its page relation`);if(L(I(i.project,`${r} project`).id,`${r} project id`)!==n)throw new c(`${r} escaped its project scope`)}function je(e,t){let n=I(e,`comment`),r=L(n.id,`comment id`);if(L(n.pageId,`comment ${r} pageId`)!==t)throw new c(`Comment ${r} escaped its page scope`);L(n.authorAuthUserId,`comment ${r} authorAuthUserId`);let i=!(Object.hasOwn(n,`anchor`)&&Object.hasOwn(n,`target`)),a=i?u(n,n.targetElements,`comment ${r} target`):h(n.target,`comment ${r} target`),o=i?{...a.anchor}:Ne(n.anchor,`comment ${r} anchor`);if(!Pe(o,a.anchor))throw new c(`Comment ${r} has inconsistent anchors`);let s=n.status;if(s!==`open`&&s!==`resolved`)throw new c(`Comment ${r} has an invalid status`);let l=z(n.createdAt,`comment ${r} createdAt`),f=z(n.updatedAt,`comment ${r} updatedAt`);if(f<l)throw new c(`Comment ${r} updatedAt precedes createdAt`);let p=Be(n.resolvedAt,`comment ${r} resolvedAt`),m=Ve(n.resolvedById,`comment ${r} resolvedById`);if(s===`open`&&(p!==void 0||m!==void 0))throw new c(`Open comment ${r} contains resolution metadata`);if(s===`resolved`&&(p===void 0||m===void 0||p!==f))throw new c(`Resolved comment ${r} has invalid workflow metadata`);return{id:r,pageId:t,...He(n.pageNumber,`comment ${r} pageNumber`),authorId:L(n.authorId,`comment ${r} authorId`),authorName:L(n.authorName,`comment ${r} authorName`),body:g(n.body,`comment ${r} body`),anchor:o,target:a,...i?Fe(d(n.scopeEntries)):n.scope==null?{}:{scope:ee(n.scope)},status:s,workflowRevision:ze(n.workflowRevision,`comment ${r} workflowRevision`),createdAt:l,updatedAt:f,...p===void 0?{}:{resolvedAt:p},...m===void 0?{}:{resolvedById:m}}}function Me(e,t){let n=I(e,`reply`),r=L(n.id,`reply id`);if(L(n.pageId,`reply ${r} pageId`)!==t)throw new c(`Reply ${r} escaped its page scope`);L(n.authorAuthUserId,`reply ${r} authorAuthUserId`);let i=z(n.createdAt,`reply ${r} createdAt`),a=z(n.updatedAt,`reply ${r} updatedAt`);if(a<i)throw new c(`Reply ${r} updatedAt precedes createdAt`);return{id:r,commentId:L(n.commentId,`reply ${r} commentId`),authorId:L(n.authorId,`reply ${r} authorId`),authorName:L(n.authorName,`reply ${r} authorName`),body:g(n.body,`reply ${r} body`),createdAt:i,updatedAt:a}}function Ne(e,t){let n=I(e,t);if(Object.keys(n).length!==5||!Object.hasOwn(n,`selector`)||!Object.hasOwn(n,`offsetX`)||!Object.hasOwn(n,`offsetY`)||!Object.hasOwn(n,`viewportX`)||!Object.hasOwn(n,`viewportY`))throw new c(`${t} has invalid fields`);return{selector:Re(n.selector,`${t} selector`),offsetX:R(n.offsetX,`${t} offsetX`),offsetY:R(n.offsetY,`${t} offsetY`),viewportX:R(n.viewportX,`${t} viewportX`),viewportY:R(n.viewportY,`${t} viewportY`)}}function Pe(e,t){return e.selector===t.selector&&e.offsetX===t.offsetX&&e.offsetY===t.offsetY&&e.viewportX===t.viewportX&&e.viewportY===t.viewportY}function Fe(e){return e===void 0?{}:{scope:e}}function F(e,t){let n=new Set;for(let r of e){if(n.has(r.id))throw new c(`Duplicate ${t} ${r.id}`);n.add(r.id)}}function Ie(e){let t=Le(e).toLowerCase();return t.includes(`expired`)||t.includes(`token`)?{type:`access-lost`,code:`session-expired`,recovery:`reauthenticate`,clearSnapshot:!0}:t.includes(`permission`)||t.includes(`forbidden`)||t.includes(`unauthorized`)?{type:`access-lost`,code:`permission-denied`,recovery:`reauthenticate`,clearSnapshot:!0}:{type:`error`,code:`transport`,recovery:`retry`,clearSnapshot:!0}}function Le(e){return e instanceof Error?e.message:e&&typeof e==`object`&&`message`in e?String(e.message):``}function I(e,t){if(!e||typeof e!=`object`||Array.isArray(e))throw new c(`${t} is missing or invalid`);return e}function Re(e,t){if(typeof e!=`string`)throw new c(`${t} is invalid`);return e}function L(e,t){let n=Re(e,t);if(!n.trim())throw new c(`${t} is empty`);return n}function R(e,t){if(typeof e!=`number`||!Number.isFinite(e)||e<0||e>1)throw new c(`${t} is invalid`);return e}function z(e,t){if(!Number.isSafeInteger(e)||e<0||e>0xe677d21fdbff)throw new c(`${t} is invalid`);return e}function ze(e,t){if(!Number.isSafeInteger(e)||e<0)throw new c(`${t} is invalid`);return e}function Be(e,t){return e==null?void 0:z(e,t)}function Ve(e,t){return e==null?void 0:L(e,t)}function He(e,t){if(e==null)return{};let n=ze(e,t);if(n<1)throw new c(`${t} is invalid`);return{pageNumber:n}}Object.freeze({field:`createdAt`,direction:`desc`,tieBreaker:`id`,tieDirection:`desc`}),Object.freeze({comments:200,replies:1e3,sourceContexts:200});var Ue=class{db;session;roomCredential;#e=new Map;constructor(e,t,n){this.db=e,this.session=t,this.roomCredential=n}subscribe(e,t,n,r){let i=[],a=[],o=!1,s=[],c=()=>{o||n({pageId:e,peers:structuredClone(i),messages:structuredClone(a)})};if(t.cursors){let n=tt(e,t.roomId),a,l,u=this.roomCredential?.id===t.roomId?this.roomCredential:void 0,d=u??{id:t.roomId,expiresAt:2**53-1,refresh:async()=>void 0},f=t=>{let o=this.db.joinRoom(`visualReview`,t),s=o.subscribePresence({},e=>{if(e.error){r?.(rt(e.error));return}i=Object.values(e.peers).map(e=>Ge(e)).filter(e=>e!==null).sort((e,t)=>e.displayName.localeCompare(t.displayName)||e.peerId.localeCompare(t.peerId)),c()}),l=a;a=()=>{s(),o.leaveRoom()},this.#e.set(n,{pageId:e,roomId:t,publishPresence:e=>o.publishPresence(e)}),l?.()},p=()=>{if(!u||o)return;let e=Math.max(1e3,d.expiresAt-Date.now()+250);l=setTimeout(()=>{m()},e)},m=async()=>{try{let e=await d.refresh();if(o||!e)return;d={...e,refresh:d.refresh},u&&(u.id=e.id,u.expiresAt=e.expiresAt),f(e.id),p()}catch(e){if(o)return;r?.(rt(e)),o||(l=setTimeout(()=>{m()},5e3))}};f(d.id),p(),s.push(()=>{l&&clearTimeout(l),this.#e.delete(n),a?.()})}return t.chat&&s.push(this.db.subscribeQuery(We(e,this.session.authUserId),t=>{if(t.error){r?.(rt(t.error));return}if(t.data)try{a=t.data.reviewMessages.map(t=>Je(t,e)).sort(nt),c()}catch{r?.({type:`error`,code:`data-integrity`,recovery:`retry`,clearSnapshot:!0})}})),queueMicrotask(c),()=>{if(!o){o=!0;for(let e of s.reverse())try{e()}catch{}}}}publishPresence(e,t,n){let r=this.#e.get(tt(e,t));r&&r.publishPresence({reviewerId:this.session.reviewerId,displayName:this.session.displayName,color:n.color,active:n.active,pathname:qe(n.pathname),...n.cursorX===void 0?{}:{cursorX:n.cursorX},...n.cursorY===void 0?{}:{cursorY:n.cursorY},...n.viewportWidth===void 0?{}:{viewportWidth:n.viewportWidth},...n.viewportHeight===void 0?{}:{viewportHeight:n.viewportHeight},cursorChat:Ke(n.cursorChat)})}async sendMessage(e,t){throw Error(`Persisted review messages are no longer supported`)}};function We(e,t){return{reviewMessages:{$:{where:{pageId:e},order:{createdAt:`desc`},limit:200}},$users:{$:{where:{id:t}},activeReviewInvitations:{project:{}}}}}function Ge(e){let t=Ze(e.reviewerId,128),n=Ze(e.displayName,512),r=typeof e.color==`string`&&/^#[0-9a-f]{6}$/iu.test(e.color)?e.color:null;if(!t||!n||!r||typeof e.active!=`boolean`)return null;let i=Qe(e.cursorX),a=Qe(e.cursorY),o=$e(e.viewportWidth),s=$e(e.viewportHeight),c=Ke(e.cursorChat),l=qe(e.pathname);return{peerId:e.peerId,reviewerId:t,displayName:n,color:r,active:e.active,pathname:l,...i===void 0?{}:{cursorX:i},...a===void 0?{}:{cursorY:a},...o===void 0?{}:{viewportWidth:o},...s===void 0?{}:{viewportHeight:s},...c?{cursorChat:c}:{}}}function Ke(e){return typeof e==`string`?e.trim().slice(0,280):``}function qe(e){if(typeof e!=`string`)return`/`;let t=e.trim();return t.startsWith(`/`)?t.slice(0,2e3):`/`}function Je(e,t){let n=B(e.id,`Review message id`,128);if(B(e.pageId,`Review message pageId`,128)!==t)throw Error(`Review message page mismatch`);return{id:n,pageId:t,pathname:Xe(e.pathname),authorId:B(e.authorId,`Review message authorId`,128),authorName:B(e.authorName,`Review message authorName`,512),body:Ye(e.body),createdAt:et(e.createdAt,`Review message createdAt`),updatedAt:et(e.updatedAt,`Review message updatedAt`)}}function Ye(e){return B(e,`Review message body`,4e3)}function Xe(e){let t=B(e,`Review message pathname`,2e3);if(!t.startsWith(`/`))throw Error(`Review message pathname is invalid`);return t}function B(e,t,n){if(typeof e!=`string`)throw Error(`${t} is invalid`);let r=e.trim();if(!r||r.length>n)throw Error(`${t} is invalid`);return r}function Ze(e,t){if(typeof e!=`string`)return null;let n=e.trim();return n&&n.length<=t?n:null}function Qe(e){return typeof e==`number`&&Number.isFinite(e)?e:void 0}function $e(e){let t=Qe(e);return t!==void 0&&t>0?t:void 0}function et(e,t){if(!Number.isSafeInteger(e)||e<0)throw Error(`${t} is invalid`);return e}function tt(e,t){return JSON.stringify([e,t])}function nt(e,t){return e.createdAt-t.createdAt||e.id.localeCompare(t.id)}function rt(e){let t=e&&typeof e==`object`&&`code`in e?String(e.code):``;if(/^INVITATION_(?:EXPIRED|NOT_FOUND|REQUIRED|REVOKED)$/u.test(t))return{type:`access-lost`,code:t===`INVITATION_EXPIRED`?`session-expired`:`membership-revoked`,recovery:`reauthenticate`,clearSnapshot:!0};let n=String(e instanceof Error||e&&typeof e==`object`&&`message`in e?e.message:e).toLowerCase();return n.includes(`expired`)||n.includes(`token`)?{type:`access-lost`,code:`session-expired`,recovery:`reauthenticate`,clearSnapshot:!0}:n.includes(`permission`)||n.includes(`forbidden`)||n.includes(`unauthorized`)?{type:`access-lost`,code:`permission-denied`,recovery:`reauthenticate`,clearSnapshot:!0}:{type:`error`,code:`transport`,recovery:`retry`,clearSnapshot:!0}}Object.freeze({field:`createdAt`,direction:`desc`,tieBreaker:`id`,tieDirection:`desc`});var V=class extends Error{code;constructor(e,t){super(t),this.code=e,this.name=`ReviewerCommentSaveError`}};function it(e,t){let n=e.replace(/\/+$/,``),r=async(e,r)=>{let i=await t();if(!i)throw new V(`AUTH_REQUIRED`,`로그인 세션이 만료되었습니다. 새로고침 후 다시 시도해 주세요.`);let a;try{a=await fetch(`${n}${e}`,{method:`POST`,headers:{authorization:`Bearer ${i}`,"content-type":`application/json`},body:JSON.stringify(r)})}catch{throw new V(`NETWORK`,`리뷰 서버에 연결하지 못했습니다. 연결을 확인하고 다시 시도해 주세요.`)}if(!a.ok)throw new V(...await ot(a))};return{createComment:({target:e,...t})=>{let{environment:n,...i}=e;return r(`/v1/comments`,{...t,target:i,...n?{environment:n}:{}})},createReply:e=>r(`/v1/replies`,e),uploadScreenshot:async({pageId:e,commentId:r,screenshot:i})=>{let a=await t();if(!a)throw new V(`AUTH_REQUIRED`,`로그인 세션이 만료되어 위치 캡처를 저장하지 못했습니다.`);let o;try{o=await fetch(`${n}/v1/comments/${encodeURIComponent(r)}/screenshot`,{method:`PUT`,headers:{authorization:`Bearer ${a}`,"content-type":i.contentType,"x-review-page-id":e,"x-review-image-width":String(i.width),"x-review-image-height":String(i.height)},body:at(i.bytes)})}catch{throw new V(`NETWORK`,`리뷰 서버에 연결하지 못해 위치 캡처를 저장하지 못했습니다.`)}if(!o.ok)throw new V(...await ot(o))}}}function at(e){let t=new Uint8Array(e.byteLength);return t.set(e),t.buffer}async function ot(e){let t=e.status>=500?`리뷰 서버가 코멘트를 저장하지 못했습니다. 잠시 후 다시 시도해 주세요.`:`코멘트를 저장하지 못했습니다.`;try{let n=await e.json();if(!n||typeof n!=`object`)return[`UNKNOWN`,t];let r=n;return[typeof r.error==`string`?r.error:`UNKNOWN`,typeof r.message==`string`&&r.message.trim()?r.message:t]}catch{return[`UNKNOWN`,t]}}var H=class extends Error{code;constructor(e,t){super(t),this.code=e,this.name=`ReviewBootstrapError`}};const U=new Map;function st(e,t={}){let n=e.trim();if(!n)throw Error(`InstantDB app ID is required`);return{async resolve(e){let r=(t.databaseFactory??we)(n),i=await dt(n,r,e.authHost,e.signal,e.styleNonce);for(;;)try{await ct(t.acceptInvitation,{refreshToken:i.refresh_token,invitationId:e.invitationId,suggestedDisplayName:wt(i.email),authHost:e.authHost,signal:e.signal,styleNonce:e.styleNonce});break}catch(t){if(!q(t,`INVITATION_EMAIL_MISMATCH`))throw t;await _t(e.authHost,e.signal,e.styleNonce),i=await ft(n,r,i,e.authHost,e.signal,e.styleNonce)}t.resolveReviewPage&&await t.resolveReviewPage({refreshToken:i.refresh_token,invitationId:e.invitationId,origin:e.location.origin,pathname:e.location.pathname,signal:e.signal});let{data:a}=await r.queryOnce({reviewers:{$:{where:{authUserId:i.id}}},reviewPages:{},invitations:{}}),o=lt(a.invitations,a.reviewers,a.reviewPages,{invitationId:e.invitationId,authUserId:i.id,email:i.email??``,location:e.location,now:Date.now()});if(!o.ok)throw new H(o.code,X(o.code));let s={authUserId:i.id,reviewerId:o.reviewer.id,projectId:o.reviewer.projectId,invitationId:e.invitationId,email:o.reviewer.email||i.email||``,displayName:o.reviewer.displayName||i.email||`Reviewer`,role:o.reviewer.role===`agency`?`agency`:`reviewer`},c=o.page.id,l=e.collaboration?.scopeId,u=(e.collaboration?.cursors===!0||e.collaboration?.chat===!0)&&t.resolveCollaborationRoom?await t.resolveCollaborationRoom({refreshToken:i.refresh_token,invitationId:e.invitationId,pageId:o.page.id,scopeId:e.collaboration.scopeId,signal:e.signal}):void 0,d=u&&t.resolveCollaborationRoom?{...u,refresh:async()=>{let n=await r.getAuth();if(!(!n?.refresh_token||l===void 0))return t.resolveCollaborationRoom?.({refreshToken:n.refresh_token,invitationId:e.invitationId,pageId:c,scopeId:l,signal:new AbortController().signal})}}:void 0,f=0;return{pageId:o.page.id,resolvePage:async n=>{let i=++f,a=()=>i!==f||n.signal.aborted,o=(e,t,n)=>({pageId:e,...n&&d?{collaborationRoomId:n.id}:{},commit:()=>{a()||(c=e,t!==void 0&&(l=t),!(!n||!d)&&(d.id=n.id,d.expiresAt=n.expiresAt))}});if(n.location.origin!==e.location.origin)throw new H(`PAGE_NOT_FOUND`,X(`PAGE_NOT_FOUND`));let{data:u}=await r.queryOnce({reviewPages:{$:{where:{projectId:s.projectId}}}});if(a())throw J();let p=Et(n.location.pathname),m=ut(u.reviewPages,s.projectId,n.location.origin,p);if(!m&&t.resolveReviewPage){let i=await r.getAuth();if(a())throw J();if(!i?.refresh_token)throw Error(`리뷰 세션이 만료되어 페이지를 등록할 수 없습니다.`);if(await t.resolveReviewPage({refreshToken:i.refresh_token,invitationId:e.invitationId,origin:n.location.origin,pathname:p,signal:n.signal}),a()||({data:u}=await r.queryOnce({reviewPages:{$:{where:{projectId:s.projectId}}}}),a()))throw J();m=ut(u.reviewPages,s.projectId,n.location.origin,p)}if(!m)throw new H(`PAGE_NOT_FOUND`,X(`PAGE_NOT_FOUND`));if(n.collaboration?.cursors!==!0&&n.collaboration?.chat!==!0||d===void 0||t.resolveCollaborationRoom===void 0||!n.collaboration)return o(m.id,n.collaboration?.scopeId);let h=await r.getAuth();if(a())throw J();if(!h?.refresh_token)throw Error(`리뷰 세션이 만료되어 실시간 협업 연결을 갱신할 수 없습니다.`);let g=await t.resolveCollaborationRoom({refreshToken:h.refresh_token,invitationId:e.invitationId,pageId:m.id,scopeId:n.collaboration.scopeId,signal:n.signal});if(a())throw J();return o(m.id,n.collaboration.scopeId,g)},session:s,repository:new Te(r,s,{...t.serviceUrl===void 0?{}:{commentTransport:it(t.serviceUrl,async()=>(await r.getAuth())?.refresh_token??null)}}),...e.collaboration?.cursors===!0||e.collaboration?.chat===!0?{collaborationRepository:new Ue(r,s,d)}:{},...(e.collaboration?.cursors===!0||e.collaboration?.chat===!0)&&d?{collaborationRoomId:d.id}:{},allowedStagingHosts:[e.location.hostname]}}}}async function ct(e,t){if(!e)return;let n={refreshToken:t.refreshToken,invitationId:t.invitationId,signal:t.signal};try{await e(n);return}catch(e){if(!q(e,`DISPLAY_NAME_REQUIRED`))throw e}let r=await gt(t.authHost,t.signal,t.suggestedDisplayName,t.styleNonce);await e({...n,displayName:r})}function lt(e,t,n,r){let i=e.find(({id:e})=>e===r.invitationId);if(!i||Dt(i.email)!==Dt(r.email))return{ok:!1,code:`INVITATION_REQUIRED`};if(i.status===`revoked`)return{ok:!1,code:`INVITATION_REVOKED`};if(i.status===`expired`||i.expiresAt<=r.now)return{ok:!1,code:`INVITATION_EXPIRED`};if(i.status!==`accepted`)return{ok:!1,code:`INVITATION_NOT_ACCEPTED`};let a=t.find(e=>e.authUserId===r.authUserId&&e.projectId===i.projectId);if(!a)return{ok:!1,code:`MEMBERSHIP_REQUIRED`};let o=Et(r.location.pathname),s=ut(n,i.projectId,r.location.origin,o);return s?{ok:!0,invitation:i,reviewer:a,page:s}:{ok:!1,code:`PAGE_NOT_FOUND`}}function ut(e,t,n,r){let i=e.filter(e=>e.projectId===t&&Et(e.pathname)===r),a=i.filter(({stagingOrigin:e})=>e===n);return(a.length>0?a:i).sort((e,t)=>(e.createdAt??2**53-1)-(t.createdAt??2**53-1)||e.id.localeCompare(t.id))[0]}async function dt(e,t,n,r,i){let a=await W(r,()=>t.getAuth());if(a)return a;let o=await pt(e,r);try{return await W(r,()=>t.getAuth())||await ht(t,n,r,i)}finally{o()}}async function ft(e,t,n,r,i,a){G(i);let o=await pt(e,i);try{let e=await W(i,()=>t.getAuth());return e&&e.id!==n.id?e:(e&&await W(i,async()=>{await t.auth.signOut()}),G(i),await ht(t,r,i,a))}finally{o()}}async function pt(e,t){G(t);let n=U.get(e);return n||(n={held:!1,waiters:[]},U.set(e,n)),n.held?new Promise((e,r)=>{let i,a=()=>{let e=n.waiters.indexOf(i);e<0||(n.waiters.splice(e,1),t.removeEventListener(`abort`,a),r(Y()))};i={signal:t,resolve:e,reject:r,abort:a},n.waiters.push(i),t.addEventListener(`abort`,a,{once:!0}),t.aborted&&a()}):(n.held=!0,mt(e,n))}function mt(e,t){let n=!1;return()=>{if(!n){for(n=!0;t.waiters.length>0;){let n=t.waiters.shift();if(n.signal.removeEventListener(`abort`,n.abort),n.signal.aborted){n.reject(Y());continue}n.resolve(mt(e,t));return}t.held=!1,U.get(e)===t&&U.delete(e)}}}async function W(e,t){G(e);let n=await t();return G(e),n}function G(e){if(e.aborted)throw Y()}function ht(e,t,n,r){try{G(n)}catch(e){return Promise.reject(e)}let i=yt(t);i.replaceChildren(bt(i,r),xt(i));let a=i.querySelector(`form`),o=i.querySelector(`h2`),s=i.querySelector(`.description`),c=a.elements.namedItem(`email`),l=a.elements.namedItem(`code`),u=i.querySelector(`.code`),d=i.querySelector(`button`),f=i.querySelector(`.error`),p=!1;return new Promise((t,r)=>{let m=!1,h=!1,g=!1,ee=()=>{n.removeEventListener(`abort`,v),i.removeEventListener(`keydown`,te),a.removeEventListener(`submit`,ne)},_=e=>{m||(m=!0,ee(),e())},v=()=>{m||(g=!0,ee(),h||_(()=>r(Y())))},te=e=>{let t=e;t.key===`Escape`?(t.preventDefault(),v()):t.key===`Tab`&&Tt(i,t)},ne=async i=>{if(i.preventDefault(),!(m||h)){h=!0,f.textContent=``,d.disabled=!0,a.setAttribute(`aria-busy`,`true`);try{if(G(n),!p){let t=c.value.trim();await W(n,async()=>{await e.auth.sendMagicCode({email:t})}),p=!0,c.readOnly=!0,u.hidden=!1,l.required=!0,o.textContent=`인증 코드`,s.textContent=`${t}로 보낸 코드를 입력하세요.`,d.textContent=`확인`,l.focus();return}await W(n,async()=>{await e.auth.signInWithMagicCode({email:c.value.trim(),code:l.value.trim()})});let r=await W(n,()=>e.getAuth());if(!r)throw Error(`인증 세션을 확인할 수 없습니다.`);_(()=>t(r))}catch(e){if(m||n.aborted||q(e,`AUTH_CANCELLED`))return;f.textContent=vt(e)}finally{h=!1,!m&&(g||n.aborted)?_(()=>r(Y())):m||(d.disabled=!1,a.removeAttribute(`aria-busy`))}}};n.addEventListener(`abort`,v,{once:!0}),i.addEventListener(`keydown`,te),a.addEventListener(`submit`,ne)})}function gt(e,t,n=``,r){if(t.aborted)return Promise.reject(Y());let i=yt(e);i.replaceChildren(bt(i,r),St(i));let a=i.querySelector(`form`),o=a.elements.namedItem(`displayName`),s=i.querySelector(`button`),c=i.querySelector(`.error`);return o.value=n.trim().slice(0,120),o.focus(),o.select(),new Promise((e,n)=>{let r=!1,l=e=>{r||(r=!0,t.removeEventListener(`abort`,u),i.removeEventListener(`keydown`,p),a.removeEventListener(`submit`,f),e())},u=()=>l(()=>n(Y())),d=()=>{let t=o.value.trim();if(!t){c.textContent=`이름을 입력해 주세요.`,o.focus();return}if(t.length>120){c.textContent=`이름은 120자 이하여야 합니다.`,o.focus();return}c.textContent=``,s.disabled=!0,a.setAttribute(`aria-busy`,`true`),l(()=>e(t))},f=e=>{e.preventDefault(),d()},p=e=>{let t=e;if(t.key===`Escape`){t.preventDefault(),u();return}if(t.key===`Tab`){Tt(i,t);return}t.key===`Enter`&&!t.isComposing&&t.target===o&&(t.preventDefault(),d())};t.addEventListener(`abort`,u,{once:!0}),i.addEventListener(`keydown`,p),a.addEventListener(`submit`,f)})}function _t(e,t,n){if(t.aborted)return Promise.reject(Y());let r=yt(e);r.replaceChildren(bt(r,n),Ct(r));let i=r.querySelector(`form`),a=r.querySelector(`button`);return a.focus(),new Promise((e,n)=>{let o=!1,s=e=>{o||(o=!0,t.removeEventListener(`abort`,c),r.removeEventListener(`keydown`,u),i.removeEventListener(`submit`,l),e())},c=()=>s(()=>n(Y())),l=t=>{t.preventDefault(),a.disabled=!0,i.setAttribute(`aria-busy`,`true`),s(e)},u=e=>{let t=e;t.key===`Escape`?(t.preventDefault(),c()):t.key===`Tab`&&Tt(r,t)};t.addEventListener(`abort`,c,{once:!0}),r.addEventListener(`keydown`,u),i.addEventListener(`submit`,l)})}function vt(e){if(e&&typeof e==`object`&&`body`in e){let t=e.body;if(t?.message)return t.message}return e instanceof Error?e.message:`로그인에 실패했습니다. 다시 시도해 주세요.`}function yt(e){return e.shadowRoot??e.attachShadow({mode:`open`})}function bt(e,t){let n=e.ownerDocument.createElement(`style`);return t&&(n.nonce=t),n.textContent=Ot,n}function xt(e){let t=e.ownerDocument,n=t.createElement(`form`);n.setAttribute(`role`,`dialog`),n.setAttribute(`aria-modal`,`true`),n.setAttribute(`aria-labelledby`,`visual-review-login-title`),n.setAttribute(`aria-describedby`,`visual-review-login-description`);let r=K(t,`p`,`01.works`,`eyebrow`),i=K(t,`h2`,`Visual Review`);i.id=`visual-review-login-title`;let a=K(t,`p`,`초대받은 이메일로 계속하세요.`,`description`);a.id=`visual-review-login-description`;let o=t.createElement(`label`);o.append(`이메일`);let s=t.createElement(`input`);s.name=`email`,s.type=`email`,s.autocomplete=`email`,s.required=!0,o.append(s);let c=t.createElement(`label`);c.className=`code`,c.hidden=!0,c.append(`인증 코드`);let l=t.createElement(`input`);l.name=`code`,l.inputMode=`numeric`,l.autocomplete=`one-time-code`,c.append(l);let u=K(t,`p`,``,`error`);u.setAttribute(`role`,`alert`);let d=K(t,`button`,`코드 받기`);return d.type=`submit`,n.append(r,i,a,o,c,u,d),n}function St(e){let t=e.ownerDocument,n=t.createElement(`form`);n.setAttribute(`role`,`dialog`),n.setAttribute(`aria-modal`,`true`),n.setAttribute(`aria-labelledby`,`visual-review-name-title`),n.setAttribute(`aria-describedby`,`visual-review-name-description`);let r=K(t,`p`,`01.works`,`eyebrow`),i=K(t,`h2`,`표시 이름`);i.id=`visual-review-name-title`;let a=K(t,`p`,`피드백에 이 이름이 표시됩니다.`,`description`);a.id=`visual-review-name-description`;let o=K(t,`label`,`이름`);o.htmlFor=`visual-review-display-name`;let s=t.createElement(`input`);s.id=`visual-review-display-name`,s.name=`displayName`,s.autocomplete=`name`,s.maxLength=120,s.required=!0;let c=K(t,`p`,``,`error`);c.setAttribute(`role`,`alert`);let l=K(t,`button`,`리뷰 시작`);return l.type=`submit`,n.append(r,i,a,o,s,c,l),n}function Ct(e){let t=e.ownerDocument,n=t.createElement(`form`);n.setAttribute(`role`,`dialog`),n.setAttribute(`aria-modal`,`true`),n.setAttribute(`aria-labelledby`,`visual-review-account-title`),n.setAttribute(`aria-describedby`,`visual-review-account-description`);let r=K(t,`p`,`01.works`,`eyebrow`),i=K(t,`h2`,`계정 확인`);i.id=`visual-review-account-title`;let a=K(t,`p`,`이 초대는 현재 로그인한 계정과 일치하지 않습니다.`,`description`);a.id=`visual-review-account-description`;let o=K(t,`button`,`다른 계정으로 계속`);return o.type=`submit`,n.append(r,i,a,o),n}function K(e,t,n,r){let i=e.createElement(t);return i.textContent=n,r&&(i.className=r),i}function wt(e){return e?.split(`@`)[0]?.trim().slice(0,120)??``}function q(e,t){return!!(e&&typeof e==`object`&&`code`in e&&e.code===t)}function J(){return new DOMException(`Aborted`,`AbortError`)}function Y(){return new H(`AUTH_CANCELLED`,`리뷰 로그인이 취소되었습니다.`)}function Tt(e,t){let n=Array.from(e.querySelectorAll(`input:not([disabled]),button:not([disabled])`)).filter(e=>!e.closest(`[hidden]`));if(n.length===0)return;let r=n[0],i=n.at(-1);t.shiftKey&&e.activeElement===r?(t.preventDefault(),i.focus()):!t.shiftKey&&e.activeElement===i&&(t.preventDefault(),r.focus())}function Et(e){return e.replace(/\/+$/,``)||`/`}function Dt(e){return e.trim().toLowerCase()}function X(e){switch(e){case`INVITATION_REQUIRED`:return`현재 계정과 일치하는 리뷰 초대를 찾을 수 없습니다.`;case`INVITATION_NOT_ACCEPTED`:return`아직 수락되지 않은 리뷰 초대입니다.`;case`INVITATION_REVOKED`:return`취소된 리뷰 초대입니다. 계속 검토하려면 담당자에게 다시 요청하세요.`;case`INVITATION_EXPIRED`:return`만료된 리뷰 초대입니다. 담당자에게 새 링크를 요청하세요.`;case`MEMBERSHIP_REQUIRED`:return`이 프로젝트의 reviewer membership이 없습니다.`;case`PAGE_NOT_FOUND`:return`이 페이지는 아직 리뷰 대상이 아닙니다. 담당자에게 문의하세요.`}}const Ot=`
|
|
2
|
+
:host{all:initial;--vr-panel:#fff;--vr-text:#161616;--vr-muted:#707070;--vr-label:#3f3f3f;--vr-control:#fff;--vr-border:#d9d9d9;--vr-action:#161616;--vr-action-text:#fff;position:fixed;inset:0;z-index:2147483646;display:grid;place-items:center;overflow:auto;padding:8px;box-sizing:border-box;background:rgba(15,15,15,.34);font-family:Inter,ui-sans-serif,system-ui,sans-serif;color:var(--vr-text)}
|
|
3
|
+
form{box-sizing:border-box;width:min(320px,calc(100vw - 16px));padding:20px;border:0;border-radius:14px;background:var(--vr-panel);box-shadow:0 18px 56px rgba(0,0,0,.18)}
|
|
4
|
+
.eyebrow{margin:0 0 10px;color:var(--vr-muted);font-size:10px;font-weight:700;letter-spacing:.09em;text-transform:uppercase}
|
|
5
|
+
h2{margin:0 0 5px;font-size:16px;line-height:1.3;letter-spacing:-.01em}.description{margin:0 0 18px;color:var(--vr-muted);font-size:13px;line-height:1.45}
|
|
6
|
+
label{display:grid;gap:6px;margin-top:12px;color:var(--vr-label);font-size:12px;font-weight:600}input{box-sizing:border-box;width:100%;height:40px;margin-top:6px;padding:0 11px;border:1px solid var(--vr-border);border-radius:9px;background:var(--vr-control);color:var(--vr-text);font:400 13px/1 Inter,ui-sans-serif,system-ui,sans-serif}
|
|
7
|
+
label input{margin-top:0}input:focus{border-color:#999;outline:0;box-shadow:0 0 0 3px rgba(127,127,127,.16)}.error{min-height:17px;margin:8px 0 0;color:#d92d20;font-size:11px;line-height:1.45}
|
|
8
|
+
button{width:100%;height:40px;margin-top:7px;border:0;border-radius:9px;background:var(--vr-action);color:var(--vr-action-text);font:650 13px/1 Inter,ui-sans-serif,system-ui,sans-serif;cursor:pointer}button:focus-visible{outline:2px solid var(--vr-action);outline-offset:2px}button:disabled{opacity:.55;cursor:wait}
|
|
9
|
+
@media (prefers-color-scheme:dark){:host{--vr-panel:#161616;--vr-text:#fff;--vr-muted:#a7a7a7;--vr-label:#d6d6d6;--vr-control:#222;--vr-border:#3a3a3a;--vr-action:#fff;--vr-action-text:#171717}}
|
|
10
|
+
@media (pointer:coarse){input,button{height:44px}}
|
|
11
|
+
@media (max-width:480px){form{padding:18px}input{font-size:16px}}
|
|
12
|
+
@media (prefers-reduced-motion:reduce){*,*::before,*::after{scroll-behavior:auto!important;transition:none!important;animation:none!important}}
|
|
13
|
+
`;var Z=class extends Error{code;status;constructor(e,t,n){super(t),this.code=e,this.status=n,this.name=`HostedBootstrapError`}};function kt(e={}){return At(e)}function At(t={},n={}){let r=e(t.serviceUrl??`https://review.01.works`),i=t.fetch??globalThis.fetch,a=n.instantRuntimeFactory??st,o=n.now??Date.now;if(typeof i!=`function`)throw Error(`Visual Review bootstrap requires the Fetch API`);return{async resolve(e){let t=jt(e),n=await Pt(r,i,t,e.signal),s=o(),c=await a(n.instantAppId,{serviceUrl:r,acceptInvitation:async e=>{let t=await i(`${r}/v1/invitations/accept`,{method:`POST`,headers:{accept:`application/json`,authorization:`Bearer ${e.refreshToken}`,"content-type":`application/json`},body:JSON.stringify({invitationId:e.invitationId,...e.displayName===void 0?{}:{displayName:e.displayName}}),cache:`no-store`,credentials:`omit`,signal:e.signal}),n=await Q(t);if(!t.ok)throw new Z($(n,`error`)??`INVITATION_ACCEPT_FAILED`,$(n,`message`)??`리뷰 초대 수락에 실패했습니다.`,t.status)},resolveReviewPage:e=>Nt(r,i,e),...e.collaboration?.cursors===!0||e.collaboration?.chat===!0?{resolveCollaborationRoom:e=>Mt(r,i,e)}:{}}).resolve(e),l=c.resolvePage;if(!l)return c;let u=async t=>{await Pt(r,i,{invitationId:e.invitationId,origin:t.location.origin,pathname:t.location.pathname},t.signal),s=o()};return{...c,resolvePage:async e=>(o()-s>=3e5&&await u(e),l(e))}}}}function jt(e){return{invitationId:e.invitationId,origin:e.location.origin,pathname:e.location.pathname}}async function Mt(e,t,n){let r=await t(`${e}/v1/collaboration/room`,{method:`POST`,headers:{accept:`application/json`,authorization:`Bearer ${n.refreshToken}`,"content-type":`application/json`},body:JSON.stringify({invitationId:n.invitationId,pageId:n.pageId,scopeId:n.scopeId}),cache:`no-store`,credentials:`omit`,signal:n.signal}),i=await Q(r);if(!r.ok)throw new Z($(i,`error`)??`COLLABORATION_ROOM_FAILED`,$(i,`message`)??`실시간 협업 연결에 실패했습니다.`,r.status);if(!i||typeof i!=`object`||Array.isArray(i))throw new Z(`INVALID_COLLABORATION_ROOM`,`잘못된 협업 응답입니다.`,502);let a=i,o=$(a,`id`);if(!o||!/^vr_[A-Za-z0-9_-]{43}$/u.test(o)||!Number.isSafeInteger(a.expiresAt))throw new Z(`INVALID_COLLABORATION_ROOM`,`잘못된 협업 응답입니다.`,502);return{id:o,expiresAt:a.expiresAt}}async function Nt(e,t,n){let r=await t(`${e}/v1/pages/resolve`,{method:`POST`,headers:{accept:`application/json`,authorization:`Bearer ${n.refreshToken}`,"content-type":`application/json`},body:JSON.stringify({invitationId:n.invitationId,origin:n.origin,pathname:n.pathname}),cache:`no-store`,credentials:`omit`,signal:n.signal});if(r.ok)return;let i=await Q(r);throw new Z($(i,`error`)??`PAGE_RESOLVE_FAILED`,$(i,`message`)??`리뷰 페이지를 준비하지 못했습니다.`,r.status)}async function Pt(e,t,n,r){let i=await t(`${e}/v1/bootstrap`,{method:`POST`,headers:{accept:`application/json`,"content-type":`application/json`},body:JSON.stringify(n),cache:`no-store`,credentials:`omit`,signal:r}),a=await Q(i);if(!i.ok)throw new Z($(a,`error`)??`BOOTSTRAP_FAILED`,$(a,`message`)??`Visual Review bootstrap에 실패했습니다.`,i.status);return Ft(a)}function Ft(e){if(!e||typeof e!=`object`||Array.isArray(e))throw new Z(`INVALID_BOOTSTRAP_RESPONSE`,`잘못된 bootstrap 응답입니다.`,502);let t=e;if(typeof t.apiVersion==`number`&&t.apiVersion!==1)throw new Z(`UNSUPPORTED_SERVICE_VERSION`,`이 Visual Review 위젯 버전은 더 이상 지원되지 않습니다. 사이트의 @01.works/visual-review를 업데이트해 주세요.`,502);let n=$(t,`instantAppId`);if(t.apiVersion!==1||!n||!It(n))throw new Z(`INVALID_BOOTSTRAP_RESPONSE`,`잘못된 bootstrap 응답입니다.`,502);return{apiVersion:1,instantAppId:n}}async function Q(e){try{return await e.json()}catch{throw new Z(`INVALID_BOOTSTRAP_RESPONSE`,`JSON bootstrap 응답이 필요합니다.`,502)}}function $(e,t){if(!e||typeof e!=`object`||Array.isArray(e))return null;let n=e[t];return typeof n==`string`&&n.trim()?n.trim():null}function It(e){return/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(e)}export{kt as createHostedReviewRuntime};
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./install-
|
|
1
|
+
import{t as e}from"./install-RHVUfLTU.js";export{e as installVisualReview};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=`https://review.01.works`;function t(e){let t=new URL(e),n=t.hostname===`localhost`||t.hostname===`127.0.0.1`||t.hostname.endsWith(`.test`)||t.hostname.endsWith(`.local`);if(t.protocol!==`https:`&&!(n&&t.protocol===`http:`))throw Error(`Visual Review serviceUrl must use HTTPS outside local development`);if(t.username||t.password||t.search||t.hash)throw Error(`Visual Review serviceUrl must be a plain origin or base path`);return t.toString().replace(/\/+$/,``)}const n=()=>{let e=Promise.resolve(null);return{ready:e,refresh:()=>e,dispose(){}}},r=new Map,i=6e4,a=1e4;function o(e={}){if(e.enabled===!1||typeof window>`u`||typeof document>`u`)return n();let r=!1,i=0,a=null,o=null,m=null,h=null,_=!1,v=null,y=null,C=t(e.serviceUrl??`https://review.01.works`),D=e.activationParam??`visual-review`,A=K(window),N=x(window.location);if(!(O(C,D,N,A,e.runtime!==void 0)??S(w(C,N.origin))))return n();let P=document.baseURI,F=new WeakMap,I=new Map,L=ne(e.styleNonce,document),R=b(window.location,D),z=g(window,e=>{let t=b(e,D);if(t===R)return;let n=k(D,e.href);n&&I.set(e.origin,n),R=t,V(e)}),B=e=>{if(!(r||!h||e.target!==h)){if((e instanceof CustomEvent&&e.detail&&typeof e.detail==`object`&&`code`in e.detail?e.detail.code:void 0)===`membership-revoked`){let e=x(window.location),t=I.get(e.origin);t&&(E(C,e.origin,t),I.delete(e.origin),q(C,e.origin,A,t));return}R=b(window.location,D),G()}};return window.addEventListener(`visual-review:reauthenticate-required`,B),{ready:G(),refresh(){return r?Promise.resolve(null):(R=b(window.location,D),V(x(window.location),!0))},dispose(){r||(r=!0,i+=1,U(),h?.remove(),h=null,y=null,v?.remove(),v=null,I.clear(),z.unsubscribe(),window.removeEventListener(`visual-review:reauthenticate-required`,B))}};function V(e,t=!1){return!h||!y||y.origin!==e.origin||k(D,e.href)?G():H(h,y,e,t)}function H(t,n,r,c){let l=++i;a!==o&&a?.abort();let u=new AbortController;a=u;let d=s(e.build,r),f=(async()=>{try{let i=await M(n.resolvePage({location:r,signal:u.signal,collaboration:{cursors:e.collaboration?.cursors===!0,chat:e.collaboration?.chat===!0,scopeId:d}}),u.signal);return Q(l,u)?(i.commit?.(),t.setPage({pageId:i.pageId,collaboration:{roomId:i.collaborationRoomId,scopeId:d}},{reload:c}),t.isConnected||document.body?.append(t),t):$(l)}catch{return Q(l,u)?G():$(l)}})();return m=f,f}function U(){a?.abort(),o?.abort(),a=null,o=null}function G(){let t=++i;U(),h?.remove(),h=null,y=null,v?.remove();let n=new AbortController,r=document.createElement(`div`);r.dataset.agencyReviewRoot=``,a=n,o=n,v=r;let s=J(t,n,r);return m=s,s.then(r=>{r&&Q(t,n)&&h===r&&e.onReady?.(r)}),s}async function J(t,n,i){try{let e=document.body??await te(document,n.signal);if(!Q(t,n))return $(t);e.append(i);let r=await Y(t,n,i);return Q(t,n)?r:(i.remove(),$(t))}catch(a){if(!Q(t,n))return i.remove(),$(t);if(d(a,`AUTH_CANCELLED`))return i.remove(),v===i&&(v=null),null;let o=F.get(i)?.[3];Z(a,i);let s=X(a,F.get(i)?.[2]);if(o!==`storage`||_||!f(a)){let{renderBootstrapError:e}=await import(`./bootstrap-error-X9PqxFnS.js`);if(!Q(t,n))return i.remove(),$(t);let o=p(a)?void 0:()=>{r||v!==i||(R=b(window.location,D),G())};e(i,s.message,L,o)}else i.remove(),v===i&&(v=null);return e.onError?.(s),window.dispatchEvent(new CustomEvent(`visual-review:error`,{detail:s})),null}}async function Y(t,n,r){let i=x(window.location),a=O(C,D,i,A,e.runtime!==void 0),o=ee(I.get(i.origin)),d=S(w(C,i.origin)),f=a?.source===`url`?a:o??d??a;if(!f)return F.delete(r),r.remove(),v===r&&(v=null),null;let p=f.invitationId;F.set(r,[C,i.origin,p,f.source]),f.source===`url`?(q(C,i.origin,A),I.set(i.origin,p),T(C,i.origin,p),z.suppress(()=>j(D))):f.source===`handoff`&&I.set(i.origin,p),R=b(window.location,D);let m=await M((e.runtime??await c(C)).resolve({invitationId:p,location:i,signal:n.signal,authHost:r,styleNonce:L,collaboration:{cursors:e.collaboration?.cursors===!0,chat:e.collaboration?.chat===!0,scopeId:s(e.build,i)}}),n.signal);if(!Q(t,n))return null;E(C,i.origin,p),W(C,p,i,A),I.set(i.origin,p);let g=e.sourceContextResolver??await u(e.build,P,n.signal,L);if(!Q(t,n))return null;let{mountReviewWidget:k}=await l(n.signal);return Q(t,n)?(h=k({...m,collaboration:{cursors:e.collaboration?.cursors===!0&&!!(m.collaborationRepository&&m.collaborationRoomId),chat:e.collaboration?.chat===!0&&!!m.collaborationRepository,repository:m.collaborationRepository,roomId:m.collaborationRoomId,scopeId:s(e.build,i)},developerTools:e.developerTools?.codeContextCopy===!0||e.developerTools?.reactGrab===!0?{codeContextCopy:!0}:void 0,offset:e.offset,onNavigateToFeedback:async t=>{let n=new URL(t,window.location.href);if(n.origin!==window.location.origin)throw Error(`Visual Review route navigation must stay on the staging origin`);if(e.navigateToFeedback){await e.navigateToFeedback(n.href);return}window.location.assign(n.href)},sourceContextResolver:g,styleNonce:L,position:e.position}),y=m.resolvePage?{origin:i.origin,resolvePage:e=>m.resolvePage(e)}:null,r.remove(),v===r&&(v=null),_=!0,window.dispatchEvent(new CustomEvent(`visual-review:ready`,{detail:h})),h):null}function Z(e,t){if(!f(e))return;let n=F.get(t);if(!n)return;let[r,i,a]=n;E(r,i,a),I.get(i)===a&&I.delete(i),q(r,i,A,a)}function Q(e,t){return!r&&i===e&&a===t&&!t.signal.aborted}function $(e){return!r&&i!==e?m:null}}function s(e,t){return JSON.stringify([P(e).buildId,t.pathname,t.search])}async function c(e){let{createHostedReviewRuntime:t}=await import(`./hosted-runtime-D1xY3Jtw.js`);return t({serviceUrl:e})}async function l(e){return N(import(`./src-CtuDVE7s.js`),e,a,`리뷰 위젯을 불러오는 시간이 초과되었습니다. 다시 시도해 주세요.`)}async function u(e,t,n,r){let i=P(e),{createGeneratedSourceContextResolver:o}=await N(import(`./generated-source-context-D59o5CKS.js`),n,a,`리뷰 소스 정보를 불러오는 시간이 초과되었습니다. 다시 시도해 주세요.`);return o({build:i})}function d(e,t){return e instanceof Error&&`code`in e&&e.code===t}function f(e){let t=m(e);return typeof t==`string`&&/^INVITATION_(?:EXPIRED|NOT_FOUND|REVOKED)$/.test(t)}function p(e){return f(e)||m(e)===`UNSUPPORTED_SERVICE_VERSION`}function m(e){return e instanceof Error&&`code`in e?e.code:void 0}const h=new WeakMap;function g(e,t){let n=h.get(e);if(!n){let t=e.history,r=t.pushState,i=t.replaceState,a=new Set;n={history:t,originalPushStateDescriptor:Object.getOwnPropertyDescriptor(t,`pushState`),originalReplaceStateDescriptor:Object.getOwnPropertyDescriptor(t,`replaceState`),patchedPushState:function(t,n,i){r.call(this,t,n,i),_(e)},patchedReplaceState:function(t,n,r){i.call(this,t,n,r),_(e)},popstateListener:()=>_(e),subscribers:a,suppressionDepth:0},h.set(e,n),v(t,`pushState`,n.patchedPushState),v(t,`replaceState`,n.patchedReplaceState),e.addEventListener(`popstate`,n.popstateListener)}n.subscribers.add(t);let r=!0;return{suppress(e){n.suppressionDepth+=1;try{return e()}finally{--n.suppressionDepth}},unsubscribe(){r&&(r=!1,n.subscribers.delete(t),!(n.subscribers.size>0)&&(e.removeEventListener(`popstate`,n.popstateListener),y(n.history,`pushState`,n.patchedPushState,n.originalPushStateDescriptor),y(n.history,`replaceState`,n.patchedReplaceState,n.originalReplaceStateDescriptor),h.delete(e)))}}}function _(e){let t=h.get(e);if(!t||t.suppressionDepth>0)return;let n=x(e.location);[...t.subscribers].forEach(e=>e(n))}function v(e,t,n){Object.defineProperty(e,t,{configurable:!0,enumerable:!1,writable:!0,value:n})}function y(e,t,n,r){if(Object.getOwnPropertyDescriptor(e,t)?.value===n){if(r){Object.defineProperty(e,t,r);return}delete e[t]}}function b(e,t){return`${e.origin}\n${e.pathname}\n${k(t,e.href)??``}`}function x(e){return new URL(e.href)}function ee(e){return e?{invitationId:e,source:`memory`}:null}function S(e){return e?{invitationId:e,source:`handoff`}:null}function C(e,t){return JSON.stringify([e,t])}function w(e,t,n=Date.now()){let i=C(e,t),a=r.get(i);if(a){if(a.expiresAt>n)return a.invitationId;clearTimeout(a.timeout),r.delete(i)}}function T(e,t,n,a=Date.now()){D(a);let o=C(e,t),s=r.get(o);for(s&&(clearTimeout(s.timeout),r.delete(o));r.size>=32;){let e=r.keys().next().value;if(!e)break;let t=r.get(e);t&&clearTimeout(t.timeout),r.delete(e)}let c=a+i,l=setTimeout(()=>{r.get(o)?.expiresAt===c&&r.delete(o)},i);r.set(o,{invitationId:n,expiresAt:c,timeout:l})}function E(e,t,n){let i=C(e,t),a=r.get(i);a?.invitationId===n&&(clearTimeout(a.timeout),r.delete(i))}function D(e){for(let[t,n]of r)n.expiresAt>e||(clearTimeout(n.timeout),r.delete(t))}function O(e,t,n,r,i){let a=k(t,n.href);if(a)return{invitationId:a,source:`url`};let o=G(r,J(e,n.origin));return o?{invitationId:o,source:`storage`}:i&&Y(n.hostname)?{invitationId:`local-preview`,source:`local-preview`}:null}function k(e,t){let n=new URL(t),r=A(n.hash);return(r?.get(e)??r?.get(`visual-review`)??r?.get(`agency-review`)??r?.get(`agency-review-invite`)??n.searchParams.get(e)??n.searchParams.get(`agency-review`)??n.searchParams.get(`agency-review-invite`))?.trim()||null}function A(e){let t=e.startsWith(`#`)?e.slice(1):e,n=t.startsWith(`?`)?t.slice(1):t;return n.includes(`=`)?new URLSearchParams(n):null}function j(e){let t=new URL(window.location.href),n=new Set([e,`visual-review`,`agency-review`,`agency-review-invite`]),r=!1;n.forEach(e=>{t.searchParams.has(e)&&(t.searchParams.delete(e),r=!0)});let i=A(t.hash);if(i){n.forEach(e=>{i.has(e)&&(i.delete(e),r=!0)});let e=i.toString();t.hash=e?`#${e}`:``}r&&window.history.replaceState(window.history.state,``,`${t.pathname}${t.search}${t.hash}`)}function M(e,t){return new Promise((n,r)=>{let i=()=>r(new DOMException(`Aborted`,`AbortError`));if(t.aborted){i();return}t.addEventListener(`abort`,i,{once:!0}),e.then(e=>{t.removeEventListener(`abort`,i),n(e)},e=>{t.removeEventListener(`abort`,i),r(e)})})}function N(e,t,n,r){return new Promise((i,a)=>{let o=!1,s=e=>{o||(o=!0,clearTimeout(l),t.removeEventListener(`abort`,c),e())},c=()=>{s(()=>a(new DOMException(`Aborted`,`AbortError`)))},l=setTimeout(()=>{s(()=>a(Error(r)))},n);if(t.aborted){c();return}t.addEventListener(`abort`,c,{once:!0}),e.then(e=>s(()=>i(e)),e=>s(()=>a(e)))})}function te(e,t){return e.body?Promise.resolve(e.body):t.aborted?Promise.reject(new DOMException(`Aborted`,`AbortError`)):new Promise((n,r)=>{let i=!1,a=new MutationObserver(()=>c()),o=()=>{e.removeEventListener(`DOMContentLoaded`,c),t.removeEventListener(`abort`,l),a.disconnect()},s=e=>{i||(i=!0,o(),e())},c=()=>{let t=e.body;t&&s(()=>n(t))},l=()=>{s(()=>r(new DOMException(`Aborted`,`AbortError`)))};e.addEventListener(`DOMContentLoaded`,c),t.addEventListener(`abort`,l,{once:!0}),a.observe(e,{childList:!0,subtree:!0}),c()})}function P(e){let t=document.querySelector(`meta[name="visual-review-build"]`),n=document.querySelector(`meta[name="visual-review-commit"]`),r=U(L()),i=U(R());return{buildId:H(e?.buildId)??V(t)??r??`unversioned`,gitCommit:z(e,n,i),generatedAt:e?.generatedAt,mode:e?.mode??I(F())??(Y(window.location.hostname)?`development`:`production`)}}function F(){try{return process.env.VISUAL_REVIEW_PUBLIC_BUILD_MODE}catch{return}}function I(e){return e===`development`||e===`preview`||e===`production`?e:void 0}function L(){try{return process.env.VISUAL_REVIEW_PUBLIC_BUILD_ID}catch{return}}function R(){try{return process.env.VISUAL_REVIEW_PUBLIC_GIT_COMMIT}catch{return}}function z(e,t,n){return e?.gitCommit===null?null:typeof e?.gitCommit==`string`?B(e.gitCommit):B(t?.content)??B(n)}function B(e){if(typeof e!=`string`)return null;let t=e.trim().toLowerCase();return/^(?:[0-9a-f]{40}|[0-9a-f]{64})$/.test(t)?t:null}function V(e){return U(e?.content)}function H(e){let t=typeof e==`string`?e.trim():``;return t.length>0?t:null}function U(e){return typeof e==`string`&&e.length>0?e:null}function W(e,t,n,r){try{r?.setItem(J(e,n.origin),t)}catch{}}function G(e,t){try{return e?.getItem(t)??null}catch{return null}}function K(e){try{return e.localStorage}catch{return null}}function q(e,t,n,r){try{if(!n)return;let i=J(e,t),a=n.getItem(i);if(a===null||r!==void 0&&a!==r)return;n.removeItem(i)}catch{}}function J(e,t){return`visual-review:${e}:${t}:invitation`}function Y(e){return e===`localhost`||e===`127.0.0.1`||e.endsWith(`.test`)||e.endsWith(`.local`)}function X(e,t){let n=e instanceof Error?e.message:String(e),r=Error(Z(n,t));if(e&&typeof e==`object`){let n=`code`in e?e.code:void 0,i=`status`in e?e.status:void 0;typeof n==`string`&&Object.defineProperty(r,"code",{configurable:!0,enumerable:!0,value:Z(n,t)}),typeof i==`number`&&Number.isFinite(i)&&Object.defineProperty(r,"status",{configurable:!0,enumerable:!0,value:i})}return r}function Z(e,t){if(!t)return e;let n=new Set([t,encodeURIComponent(t)]),r=e;for(let e of n)e&&(r=r.split(e).join(`[redacted]`));return r}function ne(e,t){if(e!==void 0)return $(e);let n=t.currentScript,r=n?Q(n):void 0;if(r)return r;try{for(let e of t.querySelectorAll(`script[nonce],style[nonce]`)){let t=Q(e);if(t)return t}}catch{}}function Q(e){let t=`nonce`in e?e.nonce:void 0;return typeof t==`string`?$(t):void 0}function $(e){return e.trim()||void 0}export{e as n,t as r,o as t};
|
package/dist/react.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{t as e}from"./install-
|
|
1
|
+
import{t as e}from"./install-RHVUfLTU.js";import{useEffect as t,useRef as n}from"react";function r({activationParam:r,build:i,collaboration:a,developerTools:o,enabled:s,navigateToFeedback:c,offset:l,onError:u,onReady:d,position:f,runtime:p,serviceUrl:m,sourceContextResolver:h,styleNonce:g}){let _=n(u),v=n(d),y=i?.buildId,b=i?.gitCommit,x=i?.generatedAt,S=i?.mode,C=o?.codeContextCopy===!0||o?.reactGrab===!0,w=a?.cursors===!0,T=a?.chat===!0;return _.current=u,v.current=d,t(()=>{if(s===!1)return;let t=e({activationParam:r,build:y===void 0&&b===void 0&&x===void 0&&S===void 0?void 0:{buildId:y,gitCommit:b,generatedAt:x,mode:S},collaboration:w||T?{cursors:w,chat:T}:void 0,developerTools:C?{codeContextCopy:!0}:void 0,enabled:s,navigateToFeedback:c,offset:l,onError:e=>_.current?.(e),onReady:e=>v.current?.(e),runtime:p,position:f,serviceUrl:m,sourceContextResolver:h,styleNonce:g});return()=>t.dispose()},[r,y,S,T,w,C,s,x,b,c,l?.x,l?.y,f,p,m,h,g]),null}r.displayName=`VisualReview`;export{r as VisualReview};
|