@weaverse/next 1.0.1 → 1.1.0-beta.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/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/utils.ts","../src/loader.ts","../src/request-info.ts","../src/revalidate-item.ts","../src/seo.ts","../src/studio-router.ts","../src/studio-script-src.ts","../src/theme-settings-store.ts","../src/translate.ts","../src/translation-store.ts"],"names":["PageTypeSchema"],"mappings":";;;;;;;;AAWO,SAAS,uBACd,MAAA,EACyB;AACzB,EAAA,IAAI,OAAgC,EAAC;AACrC,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI,MAAA,GACD,MAAA,CAAO,QAAA,IAGP,MAAA,CAAyC,aAC1C,EAAC;AAEH,EAAA,KAAA,IAAS,SAAS,MAAA,EAAQ;AACxB,IAAA,KAAA,IAAS,KAAA,IAAS,KAAA,EAAO,MAAA,IAAU,EAAC,EAAG;AACrC,MAAA,IAAI,EAAE,IAAA,EAAM,YAAA,EAAa,GAAI,KAAA;AAC7B,MAAA,IAAI,IAAA,IAAQ,YAAA,KAAiB,IAAA,IAAQ,YAAA,KAAiB,MAAA,EAAW;AAC/D,QAAA,IAAA,CAAK,IAAI,CAAA,GAAI,YAAA;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAEA,EAAA,OAAO,IAAA;AACT;AASO,IAAI,SAAA,GAAY,OAAO,MAAA,KAAW;AAGlC,IAAI,QAAA,GAAW,SAAA,IAAa,MAAA,CAAO,GAAA,KAAQ,MAAA,CAAO;;;AC1BzD,SAAS,WAAW,IAAA,EAAkD;AACpE,EAAA,OACE,OAAO,IAAA,KAAS,QAAA,IAChB,SAAS,IAAA,IACT,OAAQ,KAAmC,IAAA,KAAS,QAAA;AAExD;AAEA,SAAS,UAAU,IAAA,EAA4D;AAC7E,EAAA,OAAO;AAAA,IACL,GAAG,IAAA;AAAA,IACH,UAAU,KAAA,CAAM,OAAA,CAAQ,KAAK,QAAQ,CAAA,GACjC,KAAK,QAAA,CAAS,GAAA;AAAA,MAAI,CAAC,KAAA,KACjB,UAAA,CAAW,KAAK,CAAA,GAAI,UAAU,KAAK,CAAA,GAAI,EAAE,GAAG,KAAA;AAAM,QAEpD,IAAA,CAAK;AAAA,GACX;AACF;AAaA,eAAsB,4BACpB,IAAA,EACwC;AACxC,EAAA,IAAI,EAAE,MAAA,EAAQ,OAAA,EAAS,QAAA,EAAS,GAAI,IAAA;AACpC,EAAA,IAAI,UAAA,GAAa,IAAA,CAAK,IAAA,IAAQ,MAAA,CAAO,IAAA;AACrC,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI,CAAC,UAAA,CAAW,IAAA,CAAK,KAAA,CAAM,MAAA,EAAQ;AACjC,IAAA,OAAO,UAAA;AAAA,EACT;AAEA,EAAA,IAAI,IAAA,GAA+B;AAAA,IACjC,GAAG,UAAA;AAAA,IACH,IAAA,EAAM;AAAA,MACJ,GAAG,UAAA,CAAW,IAAA;AAAA,MACd,KAAA,EAAO,UAAA,CAAW,IAAA,CAAK,KAAA,CAAM,IAAI,SAAS;AAAA;AAC5C,GACF;AACA,EAAA,IAAI,KAAA,GAAQ,KAAK,IAAA,CAAK,KAAA;AAEtB,EAAA,IAAI,YAAA,uBAAmB,GAAA,EAAmC;AAC1D,EAAA,KAAA,IAAS,SAAA,IAAa,OAAO,UAAA,EAAY;AACvC,IAAA,IAAI,SAAA,EAAW,QAAQ,IAAA,EAAM;AAC3B,MAAA,YAAA,CAAa,GAAA,CAAI,SAAA,CAAU,MAAA,CAAO,IAAA,EAAM,SAAS,CAAA;AAAA,IACnD;AAAA,EACF;AAEA,EAAA,IAAI,OAAA,uBAAc,GAAA,EAAY;AAC9B,EAAA,IAAI,eAAA,GAAkB,WAAW,MAAA,CAAO,cAAA;AACxC,EAAA,IAAI,gBAAA,GAAmB,YAAY,MAAA,CAAO,QAAA;AAQ1C,EAAA,IAAI,gBAAA,GACF,gBAAA,KAAqB,MAAA,CAAO,QAAA,GACxB,MAAA,GACA;AAAA,IACE,GAAG,MAAA;AAAA,IACH,QAAA,EAAU,gBAAA;AAAA,IACV,YAAY,gBAAA,EAAkB;AAAA,GAChC;AAEN,EAAA,eAAe,KAAK,KAAA,EAAoC;AACtD,IAAA,KAAA,IAAS,QAAQ,KAAA,EAAO;AACtB,MAAA,IAAI,CAAC,IAAA,IAAQ,OAAA,CAAQ,GAAA,CAAI,IAAA,CAAK,EAAE,CAAA,EAAG;AACjC,QAAA;AAAA,MACF;AACA,MAAA,OAAA,CAAQ,GAAA,CAAI,KAAK,EAAE,CAAA;AAEnB,MAAA,IAAI,SAAA,GAAY,YAAA,CAAa,GAAA,CAAI,IAAA,CAAK,IAAI,CAAA;AAC1C,MAAA,IAAI,WAAW,MAAA,EAAQ;AACrB,QAAA,IAAI;AACF,UAAA,IAAA,CAAK,UAAA,GAAa,MAAM,SAAA,CAAU,MAAA,CAAO;AAAA,YACvC,IAAA,EAAM,EAAE,GAAG,sBAAA,CAAuB,UAAU,MAAM,CAAA,EAAG,GAAG,IAAA,CAAK,IAAA,EAAK;AAAA,YAClE,QAAA,EAAU,gBAAA;AAAA,YACV,OAAA,EAAS,eAAA;AAAA,YACT,QAAA,EAAU;AAAA,WACX,CAAA;AAAA,QACH,SAAS,KAAA,EAAO;AACd,UAAA,OAAA,CAAQ,KAAK,gCAAA,EAA6B,IAAA,CAAK,IAAA,EAAM,IAAA,CAAK,IAAI,KAAK,CAAA;AAAA,QACrE;AAAA,MACF;AAEA,MAAA,IAAI,WAAW,IAAA,CAAK,QAAA;AACpB,MAAA,IAAI,KAAA,CAAM,OAAA,CAAQ,QAAQ,CAAA,EAAG;AAC3B,QAAA,IAAI,iBAAiB,QAAA,CAAS,MAAA;AAAA,UAC5B;AAAA,SACF;AACA,QAAA,IAAI,eAAe,MAAA,EAAQ;AACzB,UAAA,MAAM,KAAK,cAAc,CAAA;AAAA,QAC3B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,EAAA,MAAM,KAAK,KAAK,CAAA;AAChB,EAAA,OAAO,IAAA;AACT;;;ACjIA,SAAS,MAAM,KAAA,EAA0B;AACvC,EAAA,OAAO,OAAO,KAAA,KAAU,QAAA,GAAW,IAAI,GAAA,CAAI,KAAA,EAAO,kBAAkB,CAAA,GAAI,KAAA;AAC1E;AAEA,SAAS,2BACP,OAAA,EACiB;AACjB,EAAA,IAAI,SAAS,YAAA,EAAc;AACzB,IAAA,OAAO,IAAI,eAAA,CAAgB,OAAA,CAAQ,YAAY,CAAA;AAAA,EACjD;AAEA,EAAA,IAAI,SAAS,GAAA,EAAK;AAChB,IAAA,IAAI,GAAA,GAAM,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA;AAC3B,IAAA,OAAO,IAAI,eAAA,CAAgB,GAAA,CAAI,YAAY,CAAA;AAAA,EAC7C;AAEA,EAAA,OAAO,IAAI,eAAA,EAAgB;AAC7B;AAYO,SAAS,cAAA,CACd,UACA,IAAA,EACQ;AACR,EAAA,IAAI,MAAM,OAAO,IAAA,EAAM,UAAA,KAAe,QAAA,GAAW,KAAK,UAAA,GAAa,EAAA;AAGnE,EAAA,IAAI,WAAW,GAAA,CAAI,KAAA,CAAM,GAAG,CAAA,CAAE,OAAO,OAAO,CAAA;AAC5C,EAAA,IAAI,MAAA,GAAS,SAAS,MAAA,GAAS,CAAA,GAAI,IAAI,QAAA,CAAS,IAAA,CAAK,GAAG,CAAC,CAAA,CAAA,GAAK,EAAA;AAC9D,EAAA,IACE,MAAA,KAAW,MACX,QAAA,KAAa,MAAA,IACb,SAAS,UAAA,CAAW,CAAA,EAAG,MAAM,CAAA,CAAA,CAAG,CAAA,EAChC;AACA,IAAA,OAAO,QAAA;AAAA,EACT;AACA,EAAA,OAAO,aAAa,GAAA,GAAM,MAAA,GAAS,CAAA,EAAG,MAAM,GAAG,QAAQ,CAAA,CAAA;AACzD;AAEA,SAAS,uBAAuB,OAAA,EAA8C;AAC5E,EAAA,IAAI,SAAS,QAAA,EAAU;AACrB,IAAA,OAAO,cAAA,CAAe,OAAA,CAAQ,QAAA,EAAU,OAAA,CAAQ,IAAI,CAAA;AAAA,EACtD;AAEA,EAAA,IAAI,SAAS,GAAA,EAAK;AAChB,IAAA,IAAI,GAAA,GAAM,KAAA,CAAM,OAAA,CAAQ,GAAG,CAAA;AAC3B,IAAA,OAAO,cAAA,CAAe,GAAA,CAAI,QAAA,IAAY,GAAA,EAAK,QAAQ,IAAI,CAAA;AAAA,EACzD;AAEA,EAAA,OAAO,GAAA;AACT;AAEA,SAAS,iBAAiB,KAAA,EAAiC;AACzD,EAAA,IAAI,UAAU,MAAA,EAAQ;AACpB,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI,UAAU,OAAA,EAAS;AACrB,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,OAAO,KAAA;AACT;AAEA,SAAS,cACP,YAAA,EACkC;AAClC,EAAA,IAAI,UAA4C,EAAC;AACjD,EAAA,KAAA,IAAS,CAAC,GAAA,EAAK,KAAK,CAAA,IAAK,YAAA,CAAa,SAAQ,EAAG;AAC/C,IAAA,OAAA,CAAQ,GAAG,CAAA,GAAI,gBAAA,CAAiB,KAAK,CAAA;AAAA,EACvC;AACA,EAAA,OAAO,OAAA;AACT;AAEA,IAAM,uBAAA,uBAA8B,GAAA,CAAI;AAAA,EACtC,mBAAA;AAAA;AAAA;AAAA;AAAA,EAIA;AACF,CAAC,CAAA;AAED,SAAS,2BACP,OAAA,EACiB;AACjB,EAAA,IAAI,YAAA,GAAe,IAAI,eAAA,CAAgB,0BAAA,CAA2B,OAAO,CAAC,CAAA;AAC1E,EAAA,KAAA,IAAS,OAAO,uBAAA,EAAyB;AACvC,IAAA,YAAA,CAAa,OAAO,GAAG,CAAA;AAAA,EACzB;AACA,EAAA,OAAO,YAAA;AACT;AAOO,SAAS,6BACd,OAAA,EACyB;AACzB,EAAA,IAAI,YAAA,GAAe,2BAA2B,OAAO,CAAA;AACrD,EAAA,IAAI,MAAA,GAAS,aAAa,QAAA,EAAS;AAEnC,EAAA,OAAO;AAAA,IACL,QAAA,EAAU,uBAAuB,OAAO,CAAA;AAAA,IACxC,MAAA,EAAQ,MAAA,GAAS,CAAA,CAAA,EAAI,MAAM,CAAA,CAAA,GAAK,EAAA;AAAA,IAChC,OAAA,EAAS,cAAc,YAAY,CAAA;AAAA,IACnC,GAAI,SAAS,IAAA,GAAO,EAAE,MAAM,OAAA,CAAQ,IAAA,KAAS,EAAC;AAAA,IAC9C,GAAI,SAAS,QAAA,GAAW,EAAE,UAAU,OAAA,CAAQ,QAAA,KAAa,EAAC;AAAA,IAC1D,GAAI,SAAS,MAAA,GAAS,EAAE,QAAQ,OAAA,CAAQ,MAAA,KAAW;AAAC,GACtD;AACF;AClHO,IAAM,2BAAA,GAA8B;AAE3C,IAAM,+BAAA,GAAkC,GAAA;AAajC,IAAM,2BAAA,GAA8B;AAAA,EACzC,mBAAA;AAAA,EACA,cAAA;AAAA,EACA,gBAAA;AAAA,EACA,iBAAA;AAAA,EACA,uBAAA;AAAA,EACA,iBAAA;AAAA,EACA,WAAA;AAAA,EACA,mBAAA;AAAA,EACA,qBAAA;AAAA,EACA;AACF,CAAA;AAGO,IAAM,uBAAA,GAA0B;AAAA,EACrC,SAAA;AAAA,EACA,OAAA;AAAA,EACA,UAAA;AAAA,EACA,QAAA;AAAA,EACA;AACF,CAAA;AAmDO,SAAS,2BAA2B,MAAA,EAAwB;AACjE,EAAA,IAAI,MAAA,GAAS,IAAI,eAAA,CAAgB,MAAM,CAAA;AACvC,EAAA,IAAI,MAAA,GAAS,IAAI,GAAA,CAAI,2BAA2B,CAAA;AAChD,EAAA,KAAA,IAAS,GAAA,IAAO,CAAC,GAAG,IAAI,IAAI,MAAA,CAAO,IAAA,EAAM,CAAC,CAAA,EAAG;AAC3C,IAAA,IAAI,MAAA,CAAO,GAAA,CAAI,GAAA,CAAI,WAAA,EAAa,CAAA,EAAG;AACjC,MAAA,MAAA,CAAO,OAAO,GAAG,CAAA;AAAA,IACnB;AAAA,EACF;AACA,EAAA,IAAI,UAAA,GAAa,OAAO,QAAA,EAAS;AACjC,EAAA,OAAO,UAAA,GAAa,CAAA,CAAA,EAAI,UAAU,CAAA,CAAA,GAAK,EAAA;AACzC;AAQO,SAAS,wCACd,WAAA,EACgD;AAChD,EAAA,IACE,CAAC,eACD,OAAO,WAAA,CAAY,aAAa,QAAA,IAChC,CAAC,YAAY,QAAA,EACb;AACA,IAAA;AAAA,EACF;AAEA,EAAA,IAAI,YAAA,GAAmD;AAAA,IACrD,UAAU,WAAA,CAAY,QAAA;AAAA,IACtB,MAAA,EAAQ,0BAAA,CAA2B,WAAA,CAAY,MAAA,IAAU,EAAE;AAAA,GAC7D;AAEA,EAAA,IAAI,EAAE,MAAK,GAAI,WAAA;AACf,EAAA,IAAI,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,EAAU;AACpC,IAAA,IAAI,SAAiC,EAAC;AACtC,IAAA,KAAA,IAAS,OAAO,uBAAA,EAAyB;AACvC,MAAA,IAAI,KAAA,GAAQ,KAAK,GAAG,CAAA;AACpB,MAAA,IAAI,OAAO,UAAU,QAAA,EAAU;AAC7B,QAAA,MAAA,CAAO,GAAG,CAAA,GAAI,KAAA;AAAA,MAChB;AAAA,IACF;AACA,IAAA,IAAI,MAAA,CAAO,IAAA,CAAK,MAAM,CAAA,CAAE,MAAA,EAAQ;AAC9B,MAAA,YAAA,CAAa,IAAA,GAAO,MAAA;AAAA,IACtB;AAAA,EACF;AAEA,EAAA,IACE,YAAY,QAAA,IACZA,qBAAA,CAAe,UAAU,WAAA,CAAY,QAAQ,EAAE,OAAA,EAC/C;AACA,IAAA,YAAA,CAAa,WAAW,WAAA,CAAY,QAAA;AAAA,EACtC;AAEA,EAAA,IACE,OAAO,YAAY,MAAA,KAAW,QAAA,IAC9B,YAAY,MAAA,IACZ,WAAA,CAAY,MAAA,CAAO,MAAA,IAAU,+BAAA,EAC7B;AACA,IAAA,YAAA,CAAa,SAAS,WAAA,CAAY,MAAA;AAAA,EACpC;AAEA,EAAA,OAAO,YAAA;AACT;AAeA,eAAsB,0BAAA,CACpB,OAAA,EACA,SAAA,EACA,QAAA,GAAmB,2BAAA,EACJ;AACf,EAAA,IAAI,QAAA,GAAW,OAAA,CAAQ,aAAA,CAAc,GAAA,CAAI,UAAU,EAAE,CAAA;AACrD,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,2CAAA,EAA8C,UAAU,EAAE,CAAA,EAAA;AAAA,KAC5D;AAAA,EACF;AAIA,EAAA,IAAI,YAAA,GAAe,uCAAA;AAAA,IACjB,OAAA,CAAQ;AAAA,GACV;AACA,EAAA,IAAI,OAAO,YAAA,GAAe,EAAE,WAAW,YAAA,EAAa,GAAI,EAAE,SAAA,EAAU;AAEpE,EAAA,IAAI,QAAA,GAAW,MAAM,KAAA,CAAM,QAAA,EAAU;AAAA,IACnC,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,IAC9C,IAAA,EAAM,IAAA,CAAK,SAAA,CAAU,IAAI;AAAA,GAC1B,CAAA;AACD,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,CAAA,8CAAA,EAAiD,SAAS,MAAM,CAAA,CAAA;AAAA,KAClE;AAAA,EACF;AAEA,EAAA,IAAI,EAAE,UAAA,EAAW,GAAK,MAAM,SAAS,IAAA,EAAK;AAK1C,EAAA,QAAA,CAAS,OAAA,CAAQ,EAAE,UAAA,EAAY,UAAA,IAAc,MAAM,CAAA;AACrD;;;AC7JA,SAAS,oBAAoB,GAAA,EAAwC;AACnE,EAAA,OAAO,OAAA,CAAQ,KAAK,KAAA,IAAS,GAAA,EAAK,eAAe,GAAA,EAAK,KAAA,IAAS,KAAK,IAAI,CAAA;AAC1E;AAEA,SAAS,kBAAkB,GAAA,EAAsC;AAC/D,EAAA,OAAO,OAAA,CAAQ,KAAK,KAAA,IAAS,GAAA,EAAK,eAAe,GAAA,EAAK,KAAA,IAAS,KAAK,QAAQ,CAAA;AAC9E;AAEA,SAAS,qBACP,QAAA,EACmC;AACnC,EAAA,OAAO,QAAA,KAAa,wBAAwB,qBAAA,GAAwB,SAAA;AACtE;AAQA,SAAS,uBACP,IAAA,EACmD;AACnD,EAAA,IAAI,IAAA,KAAS,SAAA,IAAa,IAAA,KAAS,SAAA,IAAa,SAAS,aAAA,EAAe;AACtE,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,SAAA;AACT;AAQO,SAAS,8BACd,GAAA,EACyB;AACzB,EAAA,IAAI,KAAA,GAAQ,GAAA,EAAK,MAAA,EAAQ,KAAA,KAAU,KAAA;AACnC,EAAA,IAAI,MAAA,GAAS,GAAA,EAAK,MAAA,EAAQ,MAAA,KAAW,KAAA;AACrC,EAAA,IAAI,QAAA,GAAoC;AAAA,IACtC,MAAA,EAAQ,EAAE,KAAA,EAAO,MAAA;AAAO,GAC1B;AAEA,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,OAAO,QAAA;AAAA,EACT;AAEA,EAAA,IAAI,IAAI,KAAA,EAAO;AACb,IAAA,QAAA,CAAS,QAAQ,GAAA,CAAI,KAAA;AAAA,EACvB;AACA,EAAA,IAAI,IAAI,WAAA,EAAa;AACnB,IAAA,QAAA,CAAS,cAAc,GAAA,CAAI,WAAA;AAAA,EAC7B;AACA,EAAA,IAAI,IAAI,QAAA,EAAU;AAChB,IAAA,QAAA,CAAS,WAAW,GAAA,CAAI,QAAA;AAAA,EAC1B;AACA,EAAA,IAAI,IAAI,YAAA,EAAc;AACpB,IAAA,QAAA,CAAS,UAAA,GAAa,EAAE,SAAA,EAAW,GAAA,CAAI,YAAA,EAAa;AAAA,EACtD;AAEA,EAAA,IAAI,YAAY,GAAA,CAAI,SAAA;AACpB,EAAA,IAAI,mBAAA,CAAoB,SAAS,CAAA,EAAG;AAClC,IAAA,QAAA,CAAS,SAAA,GAAY;AAAA,MACnB,OAAO,SAAA,EAAW,KAAA;AAAA,MAClB,aAAa,SAAA,EAAW,WAAA;AAAA,MACxB,QAAQ,SAAA,EAAW,KAAA,GAAQ,CAAC,SAAA,CAAU,KAAK,CAAA,GAAI,MAAA;AAAA,MAC/C,IAAA,EAAM,sBAAA,CAAuB,SAAA,EAAW,IAAI;AAAA,KAC9C;AAAA,EACF;AAEA,EAAA,IAAI,UAAU,GAAA,CAAI,OAAA;AAClB,EAAA,IAAI,iBAAA,CAAkB,OAAO,CAAA,EAAG;AAK9B,IAAA,QAAA,CAAS,OAAA,GAAU;AAAA,MACjB,IAAA,EAAM,oBAAA,CAAqB,OAAA,EAAS,QAAQ,CAAA;AAAA,MAC5C,OAAO,OAAA,EAAS,KAAA;AAAA,MAChB,aAAa,OAAA,EAAS,WAAA;AAAA,MACtB,QAAQ,OAAA,EAAS,KAAA,GAAQ,CAAC,OAAA,CAAQ,KAAK,CAAA,GAAI;AAAA,KAC7C;AAAA,EACF;AAEA,EAAA,OAAO,QAAA;AACT;AAMO,SAAS,2BACd,IAAA,EACyB;AACzB,EAAA,IAAI,CAAC,IAAA,EAAM;AACT,IAAA,OAAO,8BAA8B,IAAI,CAAA;AAAA,EAC3C;AACA,EAAA,IAAI,OACF,OAAA,IAAW,IAAA,IAAQ,QAAQ,IAAA,GACtB,IAAA,GACC,KAAsC,IAAA,IAAQ,IAAA;AACtD,EAAA,OAAO,6BAAA,CAA8B,IAAA,EAAM,GAAA,IAAO,IAAI,CAAA;AACxD;;;AChHA,SAAS,kBACP,OAAA,EACS;AACT,EAAA,IAAI,CAAC,OAAA,IAAW,OAAO,OAAA,KAAY,QAAA,EAAU;AAC3C,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,CAAE,OAAA,CAA6C,kBAAA;AACxD;AAgBO,SAAS,iCAAA,CACd,MAAA,EACA,OAAA,GAAoD,EAAC,EACxB;AAC7B,EAAA,OAAO;AAAA,IACL,QAAA,EAAU,CAAC,EAAA,EAAI,eAAA,KAAoB;AACjC,MAAA,IAAI,MAAA,GAAS,kBAAkB,eAAe,CAAA;AAC9C,MAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,QAAA,MAAA,CAAO,OAAA,CAAQ,EAAA,EAAI,EAAE,MAAA,EAAQ,CAAA;AAAA,MAC/B,CAAA,MAAO;AACL,QAAA,MAAA,CAAO,IAAA,CAAK,EAAA,EAAI,EAAE,MAAA,EAAQ,CAAA;AAAA,MAC5B;AAAA,IACF,CAAA;AAAA,IACA,YAAY,MAAM;AAChB,MAAA,MAAA,CAAO,OAAA,EAAQ;AAAA,IACjB;AAAA,GACF;AACF;;;AC7EA,IAAM,sBAAA,GAAyB,CAAC,aAAA,EAAe,cAAc,CAAA;AAE7D,SAAS,mBAAmB,QAAA,EAA2B;AACrD,EAAA,OACE,aAAa,WAAA,IACb,QAAA,KAAa,WAAA,IACb,QAAA,CAAS,SAAS,YAAY,CAAA;AAElC;AAEA,SAAS,gBAAgB,KAAA,EAAqC;AAC5D,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI;AACF,IAAA,OAAO,IAAI,GAAA,CAAI,KAAK,CAAA,CAAE,MAAA;AAAA,EACxB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAUA,SAAS,qBAAA,CACP,QACA,kBAAA,EACS;AACT,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI;AACF,IAAA,MAAA,GAAS,IAAI,IAAI,MAAM,CAAA;AAAA,EACzB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,IAAI,EAAE,QAAA,EAAU,QAAA,EAAS,GAAI,MAAA;AAC7B,EAAA,IAAI,kBAAA,CAAmB,kBAAkB,CAAA,IAAK,kBAAA,CAAmB,QAAQ,CAAA,EAAG;AAC1E,IAAA,OAAO,QAAA,KAAa,WAAW,QAAA,KAAa,QAAA;AAAA,EAC9C;AAEA,EAAA,IAAI,aAAa,QAAA,EAAU;AACzB,IAAA,OAAO,KAAA;AAAA,EACT;AAEA,EAAA,OAAO,sBAAA,CAAuB,IAAA;AAAA,IAC5B,CAAC,WAAW,QAAA,KAAa,MAAA,IAAU,SAAS,QAAA,CAAS,CAAA,CAAA,EAAI,MAAM,CAAA,CAAE;AAAA,GACnE;AACF;AAEA,SAAS,eAAe,OAAA,EAAuD;AAC7E,EAAA,IAAI,SAAS,YAAA,EAAc;AACzB,IAAA,OAAO,IAAI,eAAA,CAAgB,OAAA,CAAQ,YAAY,CAAA;AAAA,EACjD;AAEA,EAAA,IAAI,SAAS,GAAA,EAAK;AAChB,IAAA,IAAI,GAAA,GACF,OAAO,OAAA,CAAQ,GAAA,KAAQ,QAAA,GACnB,IAAI,GAAA,CAAI,OAAA,CAAQ,GAAA,EAAK,kBAAkB,CAAA,GACvC,OAAA,CAAQ,GAAA;AACd,IAAA,OAAO,IAAI,eAAA,CAAgB,GAAA,CAAI,YAAY,CAAA;AAAA,EAC7C;AAEA,EAAA,OAAO,IAAI,eAAA,EAAgB;AAC7B;AAEA,SAAS,IAAA,CAAK,cAA+B,GAAA,EAA4B;AACvE,EAAA,IAAI,MAAA,GAAS,YAAA,CAAa,MAAA,CAAO,GAAG,CAAA;AACpC,EAAA,OAAO,OAAO,MAAA,GAAU,MAAA,CAAO,EAAA,CAAG,EAAE,KAAK,IAAA,GAAQ,IAAA;AACnD;AAYO,SAAS,kCAAA,CACd,OAAA,EACA,OAAA,GAAqD,EAAC,EACvC;AACf,EAAA,IAAI,YAAA,GAAe,eAAe,OAAO,CAAA;AAEzC,EAAA,IAAI,eACF,OAAA,EAAS,YAAA,IAAgB,IAAA,CAAK,YAAA,EAAc,cAAc,CAAA,KAAM,MAAA;AAClE,EAAA,IAAI,gBACF,OAAA,EAAS,aAAA,IAAiB,IAAA,CAAK,YAAA,EAAc,eAAe,CAAA,KAAM,MAAA;AACpE,EAAA,IAAI,oBACF,OAAA,EAAS,iBAAA,IAAqB,QAAQ,IAAA,CAAK,YAAA,EAAc,cAAc,CAAC,CAAA;AAE1E,EAAA,IAAI,EAAE,YAAA,IAAgB,aAAA,IAAiB,iBAAA,CAAA,EAAoB;AACzD,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI,MAAA,GAAS,eAAA,CAAgB,IAAA,CAAK,YAAA,EAAc,cAAc,CAAC,CAAA;AAC/D,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,OAAO,IAAA;AAAA,EACT;AAEA,EAAA,IAAI,kBAAA,GAAqB,QAAQ,kBAAA,IAAsB,EAAA;AACvD,EAAA,IAAI,CAAC,qBAAA,CAAsB,MAAA,EAAQ,kBAAkB,CAAA,EAAG;AACtD,IAAA,OAAO,IAAA;AAAA,EACT;AAKA,EAAA,IAAI,MAAA,GAAS,aAAA,IAAiB,iBAAA,GAAoB,YAAA,GAAe,UAAA;AACjE,EAAA,IAAI,OAAA,GAAU,IAAA,CAAK,YAAA,EAAc,iBAAiB,CAAA;AAClD,EAAA,IAAI,GAAA,GAAM,CAAA,EAAG,MAAM,CAAA,oBAAA,EAAuB,MAAM,CAAA,CAAA;AAChD,EAAA,OAAO,UAAU,CAAA,EAAG,GAAG,MAAM,kBAAA,CAAmB,OAAO,CAAC,CAAA,CAAA,GAAK,GAAA;AAC/D;;;AC1GO,SAAS,oCAAA,CACd,OAAA,GAAuD,EAAC,EACxB;AAChC,EAAA,IAAI,SAAA,uBAAgB,GAAA,EAAgB;AACpC,EAAA,IAAI,KAAA,GAAwC;AAAA,IAC1C,WAAW,OAAA,CAAQ,SAAA;AAAA,IACnB,QAAQ,OAAA,CAAQ,MAAA;AAAA,IAChB,UAAU,EAAE,GAAI,OAAA,CAAQ,QAAA,IAAY,EAAC,EAAG;AAAA,IACxC,iBAAA,EAAmB,MAAM,KAAA,CAAM,QAAA;AAAA,IAC/B,WAAA,EAAa,MAAM,KAAA,CAAM,QAAA;AAAA,IACzB,SAAA,EAAW,CAAC,QAAA,KAAyB;AACnC,MAAA,SAAA,CAAU,IAAI,QAAQ,CAAA;AACtB,MAAA,OAAO,MAAM;AACX,QAAA,SAAA,CAAU,OAAO,QAAQ,CAAA;AAAA,MAC3B,CAAA;AAAA,IACF,CAAA;AAAA,IACA,mBAAA,EAAqB,CAAC,IAAA,KAAkC;AACtD,MAAA,KAAA,CAAM,WAAW,EAAE,GAAG,KAAA,CAAM,QAAA,EAAU,GAAG,IAAA,EAAK;AAC9C,MAAA,KAAA,IAAS,YAAY,SAAA,EAAW;AAC9B,QAAA,QAAA,EAAS;AAAA,MACX;AAAA,IACF;AAAA,GACF;AAEA,EAAA,OAAO,KAAA;AACT;;;AC/BO,SAAS,YAAA,CACd,GAAA,EACA,IAAA,EACA,QAAA,EACoB;AACpB,EAAA,IAAI,IAAA,GAAO,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AACzB,EAAA,IAAI,OAAA,GAAmB,GAAA;AAEvB,EAAA,KAAA,IAAS,OAAO,IAAA,EAAM;AACpB,IAAA,IAAI,OAAA,IAAW,IAAA,IAAQ,OAAO,OAAA,KAAY,QAAA,EAAU;AAClD,MAAA,OAAO,QAAA;AAAA,IACT;AACA,IAAA,OAAA,GAAW,QAAoC,GAAG,CAAA;AAAA,EACpD;AAEA,EAAA,IAAI,OAAO,YAAY,QAAA,EAAU;AAC/B,IAAA,OAAO,OAAA;AAAA,EACT;AAEA,EAAA,OAAO,QAAA;AACT;AASO,SAAS,WAAA,CACd,UACA,SAAA,EACQ;AACR,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,OAAO,QAAA;AAAA,EACT;AAEA,EAAA,OAAO,QAAA,CAAS,OAAA,CAAQ,gBAAA,EAAkB,CAAC,OAAO,GAAA,KAAgB;AAChE,IAAA,IAAI,KAAA,GAAQ,UAAU,GAAG,CAAA;AACzB,IAAA,OAAO,KAAA,KAAU,MAAA,GAAY,KAAA,GAAQ,MAAA,CAAO,KAAK,CAAA;AAAA,EACnD,CAAC,CAAA;AACH;AAsCO,SAAS,gBACd,OAAA,EACmB;AACnB,EAAA,IAAI,EAAE,aAAA,EAAe,iBAAA,EAAmB,eAAA,EAAiB,WAAU,GAAI,OAAA;AACvE,EAAA,OAAO,CAAC,KAAK,SAAA,KAAc;AAEzB,IAAA,IAAI,SAAA,EAAW;AACb,MAAA,IAAI,QAAA,GAAW,SAAA,CAAU,GAAA,EAAK,SAAS,CAAA;AAEvC,MAAA,IAAI,QAAA,IAAY,aAAa,GAAA,EAAK;AAChC,QAAA,OAAO,QAAA;AAAA,MACT;AAAA,IACF;AAIA,IAAA,IAAI,MAAA,GACF,mBAAmB,MAAA,CAAO,MAAA,CAAO,iBAAiB,GAAG,CAAA,GACjD,eAAA,CAAgB,GAAG,CAAA,GACnB,MAAA;AAEN,IAAA,IAAI,QAAA,GAAW,iBAAA,GACX,YAAA,CAAa,iBAAA,EAAmB,GAAG,CAAA,GACnC,MAAA;AACJ,IAAA,IAAI,WAAA,GAAc,YAAA,CAAa,aAAA,EAAe,GAAG,CAAA;AAGjD,IAAA,IAAI,GAAA,GAAM,MAAA,IAAU,QAAA,IAAY,WAAA,IAAe,GAAA;AAC/C,IAAA,OAAO,WAAA,CAAY,KAAK,SAAS,CAAA;AAAA,EACnC,CAAA;AACF;;;AC9GO,IAAM,mBAAN,MAAuB;AAAA;AAAA,EAE5B,YAAoC,EAAC;AAAA,EACpB,SAAA,uBAAiC,GAAA,EAAI;AAAA;AAAA,EAGtD,YAAA,GAAe,CAAC,SAAA,KAAsC;AACpD,IAAA,IAAA,CAAK,SAAA,GAAY,EAAE,GAAG,SAAA,EAAU;AAChC,IAAA,IAAA,CAAK,IAAA,EAAK;AAAA,EACZ,CAAA;AAAA;AAAA,EAGA,eAAA,GAAkB,CAAC,YAAA,KAAyC;AAC1D,IAAA,IAAA,CAAK,YAAY,EAAE,GAAG,IAAA,CAAK,SAAA,EAAW,GAAG,YAAA,EAAa;AACtD,IAAA,IAAA,CAAK,IAAA,EAAK;AAAA,EACZ,CAAA;AAAA;AAAA,EAGA,WAAA,GAAc,MAAM,IAAA,CAAK,SAAA;AAAA;AAAA,EAGzB,iBAAA,GAAoB,MAAM,IAAA,CAAK,SAAA;AAAA;AAAA,EAG/B,SAAA,GAAY,CAAC,QAAA,KAAyB;AACpC,IAAA,IAAA,CAAK,SAAA,CAAU,IAAI,QAAQ,CAAA;AAC3B,IAAA,OAAO,MAAM;AACX,MAAA,IAAA,CAAK,SAAA,CAAU,OAAO,QAAQ,CAAA;AAAA,IAChC,CAAA;AAAA,EACF,CAAA;AAAA,EAEiB,OAAO,MAAM;AAC5B,IAAA,KAAA,MAAW,QAAA,IAAY,KAAA,CAAM,IAAA,CAAK,IAAA,CAAK,SAAS,CAAA,EAAG;AACjD,MAAA,IAAI;AACF,QAAA,QAAA,EAAS;AAAA,MACX,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAA,CAAM,oCAAoC,KAAK,CAAA;AAAA,MACzD;AAAA,IACF;AAAA,EACF,CAAA;AACF;AAQO,IAAM,cAAA,GAAiB","file":"index.js","sourcesContent":["import type { SchemaType } from '@weaverse/schema'\nimport type { WeaverseNextThemeSchema } from './types'\n\n/**\n * Generate default component data from a schema's `settings` inputs.\n *\n * Mirrors Hydrogen's `generateDataFromSchema` (settings → `{ [name]:\n * defaultValue }`) but is kept local so `@weaverse/next` doesn't depend on\n * `@weaverse/hydrogen`. Falls back to the deprecated `inspector` array when a\n * schema predates `settings`.\n */\nexport function generateDataFromSchema(\n schema: SchemaType | WeaverseNextThemeSchema | undefined\n): Record<string, unknown> {\n let data: Record<string, unknown> = {}\n if (!schema) {\n return data\n }\n\n let groups =\n (schema.settings as {\n inputs?: { name?: string; defaultValue?: unknown }[]\n }[]) ??\n (schema as { inspector?: typeof groups }).inspector ??\n []\n\n for (let group of groups) {\n for (let input of group?.inputs ?? []) {\n let { name, defaultValue } = input\n if (name && defaultValue !== null && defaultValue !== undefined) {\n data[name] = defaultValue\n }\n }\n }\n\n return data\n}\n\n/**\n * Whether the code runs in a browser window.\n *\n * Defined here rather than re-exported from `@weaverse/react`, which sits\n * behind the `'use client'` boundary: there a Server Component would receive a\n * client reference, a truthy object, instead of `false`.\n */\nexport let isBrowser = typeof window !== 'undefined'\n\n/** Whether the code runs in a browser window embedded in an iframe. */\nexport let isIframe = isBrowser && window.top !== window.self\n","import type {\n WeaverseNextClient,\n WeaverseNextCommerceContext,\n WeaverseNextComponent,\n WeaverseNextComponentData,\n WeaverseNextLoaderData,\n WeaverseNextRequestContext,\n} from './types'\nimport { generateDataFromSchema } from './utils'\n\n/** Inputs for running registered component loaders over a page tree. */\nexport interface RunComponentLoadersArgs {\n /** Weaverse client containing the component registry. */\n client: WeaverseNextClient\n /** Request-scoped commerce override; defaults to `client.commerce`. */\n commerce?: WeaverseNextCommerceContext\n /** Request-context override; defaults to `client.requestContext`. */\n context?: WeaverseNextRequestContext\n /** Page payload to walk; defaults to `client.data`. */\n data?: WeaverseNextLoaderData | null\n}\n\nfunction isItemNode(node: unknown): node is WeaverseNextComponentData {\n return (\n typeof node === 'object' &&\n node !== null &&\n typeof (node as WeaverseNextComponentData).type === 'string'\n )\n}\n\nfunction cloneItem(item: WeaverseNextComponentData): WeaverseNextComponentData {\n return {\n ...item,\n children: Array.isArray(item.children)\n ? item.children.map((child) =>\n isItemNode(child) ? cloneItem(child) : { ...child }\n )\n : item.children,\n }\n}\n\n/**\n * Walk a serialized page tree and run each registered component's `loader`,\n * attaching the result to the item as `loaderData`.\n *\n * Loaders receive explicit `commerce.storefront` (and `weaverse.storefront` as\n * a compatibility alias via the client). Children are walked recursively when\n * they are inline item objects; flat `items` arrays are covered by the\n * top-level walk.\n *\n * @returns a cloned `data` object with `loaderData` attached to cloned items.\n */\nexport async function runWeaverseComponentLoaders(\n args: RunComponentLoadersArgs\n): Promise<WeaverseNextLoaderData | null> {\n let { client, context, commerce } = args\n let sourceData = args.data ?? client.data\n if (!sourceData) {\n return null\n }\n if (!sourceData.page.items.length) {\n return sourceData\n }\n\n let data: WeaverseNextLoaderData = {\n ...sourceData,\n page: {\n ...sourceData.page,\n items: sourceData.page.items.map(cloneItem),\n },\n }\n let items = data.page.items\n\n let componentMap = new Map<string, WeaverseNextComponent>()\n for (let component of client.components) {\n if (component?.schema?.type) {\n componentMap.set(component.schema.type, component)\n }\n }\n\n let visited = new Set<string>()\n let resolvedContext = context ?? client.requestContext\n let resolvedCommerce = commerce ?? client.commerce\n\n // Per-call `weaverse` alias. When a request-scoped `commerce` is passed, the\n // `weaverse.storefront` compatibility alias must resolve to *that* storefront,\n // not the client's construction-time commerce. Pilot-style loaders call\n // `weaverse.storefront.query(...)`, so a stale alias would query the wrong\n // (or an undefined) storefront. When no override is given we reuse the client\n // as-is to preserve its prototype getters.\n let resolvedWeaverse: WeaverseNextClient =\n resolvedCommerce === client.commerce\n ? client\n : {\n ...client,\n commerce: resolvedCommerce,\n storefront: resolvedCommerce?.storefront,\n }\n\n async function walk(nodes: WeaverseNextComponentData[]) {\n for (let item of nodes) {\n if (!item || visited.has(item.id)) {\n continue\n }\n visited.add(item.id)\n\n let component = componentMap.get(item.type)\n if (component?.loader) {\n try {\n item.loaderData = await component.loader({\n data: { ...generateDataFromSchema(component.schema), ...item.data },\n weaverse: resolvedWeaverse,\n context: resolvedContext,\n commerce: resolvedCommerce,\n })\n } catch (error) {\n console.warn('❌ Item loader run failed.', item.type, item.id, error)\n }\n }\n\n let children = item.children\n if (Array.isArray(children)) {\n let inlineChildren = children.filter(\n isItemNode\n ) as WeaverseNextComponentData[]\n if (inlineChildren.length) {\n await walk(inlineChildren)\n }\n }\n }\n }\n\n await walk(items)\n return data\n}\n","import type {\n WeaverseNextRequestContext,\n WeaverseNextRequestInfo,\n} from './types'\n\nfunction toUrl(value: string | URL): URL {\n return typeof value === 'string' ? new URL(value, 'http://localhost') : value\n}\n\nfunction getSearchParamsFromContext(\n context?: WeaverseNextRequestContext\n): URLSearchParams {\n if (context?.searchParams) {\n return new URLSearchParams(context.searchParams)\n }\n\n if (context?.url) {\n let url = toUrl(context.url)\n return new URLSearchParams(url.searchParams)\n }\n\n return new URLSearchParams()\n}\n\n/**\n * Put the request's market prefix (`i18n.pathPrefix`, e.g. `/de-de`) on a\n * pathname that does not carry it yet.\n *\n * A Next app builds its request context from the route path, and with\n * locale-segmented routes that path is usually unprefixed. Studio's address\n * bar follows `requestInfo.pathname`, so without the prefix it snaps back to\n * the default market after every navigation. A path that already carries the\n * prefix, and the default market's empty prefix, pass through unchanged.\n */\nexport function withPathPrefix(\n pathname: string,\n i18n?: WeaverseNextRequestContext['i18n']\n): string {\n let raw = typeof i18n?.pathPrefix === 'string' ? i18n.pathPrefix : ''\n // Split rather than regex-trim: `pathPrefix` is caller input, and an anchored\n // `/\\/+$/` backtracks polynomially on long runs of slashes.\n let segments = raw.split('/').filter(Boolean)\n let prefix = segments.length > 0 ? `/${segments.join('/')}` : ''\n if (\n prefix === '' ||\n pathname === prefix ||\n pathname.startsWith(`${prefix}/`)\n ) {\n return pathname\n }\n return pathname === '/' ? prefix : `${prefix}${pathname}`\n}\n\nfunction getPathnameFromContext(context?: WeaverseNextRequestContext): string {\n if (context?.pathname) {\n return withPathPrefix(context.pathname, context.i18n)\n }\n\n if (context?.url) {\n let url = toUrl(context.url)\n return withPathPrefix(url.pathname || '/', context.i18n)\n }\n\n return '/'\n}\n\nfunction coerceQueryValue(value: string): string | boolean {\n if (value === 'true') {\n return true\n }\n if (value === 'false') {\n return false\n }\n return value\n}\n\nfunction toQueryRecord(\n searchParams: URLSearchParams\n): Record<string, string | boolean> {\n let queries: Record<string, string | boolean> = {}\n for (let [key, value] of searchParams.entries()) {\n queries[key] = coerceQueryValue(value)\n }\n return queries\n}\n\nconst TRANSIENT_STUDIO_PARAMS = new Set([\n 'weaverseDraftItem',\n // Legacy name from the original design-mode draft-item spike. Keep it out of\n // runtime requestInfo too, in case an older Builder bundle is in front of a\n // newer Next storefront.\n '__weaverseDraftItem',\n])\n\nfunction getRequestInfoSearchParams(\n context?: WeaverseNextRequestContext\n): URLSearchParams {\n let searchParams = new URLSearchParams(getSearchParamsFromContext(context))\n for (let key of TRANSIENT_STUDIO_PARAMS) {\n searchParams.delete(key)\n }\n return searchParams\n}\n\n/**\n * Build the Hydrogen-like request info shape consumed by the Studio bridge.\n * Duplicate query keys keep the last value, matching `URLSearchParams` iteration\n * assignment and Hydrogen's practical query-object behavior.\n */\nexport function buildWeaverseNextRequestInfo(\n context?: WeaverseNextRequestContext\n): WeaverseNextRequestInfo {\n let searchParams = getRequestInfoSearchParams(context)\n let search = searchParams.toString()\n\n return {\n pathname: getPathnameFromContext(context),\n search: search ? `?${search}` : '',\n queries: toQueryRecord(searchParams),\n ...(context?.i18n ? { i18n: context.i18n } : {}),\n ...(context?.pageType ? { pageType: context.pageType } : {}),\n ...(context?.handle ? { handle: context.handle } : {}),\n }\n}\n","import type { PageType } from '@weaverse/schema'\nimport { PageTypeSchema } from '@weaverse/schema'\nimport type {\n WeaverseNextComponentData,\n WeaverseNextI18n,\n WeaverseNextRequestInfo,\n} from './types'\n\n/** Default App Router endpoint used for Studio item-loader revalidation. */\nexport const DEFAULT_REVALIDATE_ENDPOINT = '/api/weaverse/revalidate'\n\nconst MAX_ROUTE_CONTEXT_HANDLE_LENGTH = 512\n\n/**\n * Server-owned and transient controls stripped from the revalidation route\n * context on both sides of the trust boundary. Compared case-insensitively, so\n * every entry is stored lowercased. Client sanitization keeps normal traffic\n * clean; the route handler repeats this deny-list as the security boundary.\n *\n * - Server-owned: a crafted `?weaverseProjectId=`/`?weaverseHost=` must never\n * influence server config resolution (see `getWeaverseNextConfigs`), and\n * credential-shaped params never ride along in route context.\n * - Transient: draft-item and RSC transport params never describe route identity.\n */\nexport const DENIED_ROUTE_CONTEXT_PARAMS = [\n 'weaverseprojectid',\n 'weaversehost',\n 'weaverseapikey',\n 'weaverseapibase',\n 'weaversepublicapibase',\n 'weaverseversion',\n 'projectid',\n 'weaversedraftitem',\n '__weaversedraftitem',\n '_rsc',\n]\n\n/** i18n fields allowed to cross the browser boundary. */\nexport const ROUTE_CONTEXT_I18N_KEYS = [\n 'country',\n 'label',\n 'language',\n 'locale',\n 'pathPrefix',\n] as const\n\n/**\n * JSON-safe route subset that may cross the browser boundary alongside the\n * draft item. Never carries headers, cookies, auth, env, project ID, Studio\n * host, API keys/bases, commerce clients, the request context, runtime, or\n * client. `search` is canonical (preserves duplicate keys); the derived\n * `queries` record is intentionally omitted.\n */\nexport interface WeaverseNextRevalidateRouteContext {\n /** Route handle used for page assignment. */\n handle?: string\n /** Public locale and market identity allowed across the browser boundary. */\n i18n?: Pick<\n WeaverseNextI18n,\n 'country' | 'label' | 'language' | 'locale' | 'pathPrefix'\n >\n /** Weaverse page type resolved by the active route. */\n pageType?: PageType\n /** Canonical same-origin route pathname. */\n pathname: string\n /** Sanitized serialized query string, including the leading `?` when set. */\n search: string\n}\n\n/**\n * Minimal runtime surface the in-place apply needs. Structural (not the\n * concrete `WeaverseNextRuntime` class) so unit tests can drive it with a\n * plain mock. `requestInfo` stays optional: a real `WeaverseNextRuntime`\n * always supplies it, but when absent the client omits `routeContext` and the\n * legacy `{ draftItem }` request is preserved.\n */\nexport interface RevalidateItemRuntimeLike {\n /** Live item stores keyed by Weaverse item ID. */\n itemInstances: Map<\n string,\n {\n /** Merge refreshed loader data into the live item store. */\n setData: (update: Record<string, unknown>) => unknown\n }\n >\n /** Active route identity used to construct the optional revalidation payload. */\n requestInfo?: WeaverseNextRequestInfo\n}\n\n/**\n * Strip denied (server-owned/transient) controls from a `search` string and\n * re-serialize it. Preserves ordinary application queries, duplicate keys,\n * encoded Unicode, and mode controls (`isDesignMode`, `isPreviewMode`,\n * `__revisionId`, `sectionType`). Returns `''` or a `?`-prefixed string.\n */\nexport function sanitizeRouteContextSearch(search: string): string {\n let params = new URLSearchParams(search)\n let denied = new Set(DENIED_ROUTE_CONTEXT_PARAMS)\n for (let key of [...new Set(params.keys())]) {\n if (denied.has(key.toLowerCase())) {\n params.delete(key)\n }\n }\n let serialized = params.toString()\n return serialized ? `?${serialized}` : ''\n}\n\n/**\n * Build the sanitized {@link WeaverseNextRevalidateRouteContext} from the\n * active runtime's request info. Returns `undefined` without a usable pathname\n * so the caller omits `routeContext` and keeps the legacy request. This is not\n * the security boundary — the route handler re-validates and re-sanitizes.\n */\nexport function buildWeaverseNextRevalidateRouteContext(\n requestInfo?: WeaverseNextRequestInfo\n): WeaverseNextRevalidateRouteContext | undefined {\n if (\n !requestInfo ||\n typeof requestInfo.pathname !== 'string' ||\n !requestInfo.pathname\n ) {\n return\n }\n\n let routeContext: WeaverseNextRevalidateRouteContext = {\n pathname: requestInfo.pathname,\n search: sanitizeRouteContextSearch(requestInfo.search ?? ''),\n }\n\n let { i18n } = requestInfo\n if (i18n && typeof i18n === 'object') {\n let picked: Record<string, string> = {}\n for (let key of ROUTE_CONTEXT_I18N_KEYS) {\n let value = i18n[key]\n if (typeof value === 'string') {\n picked[key] = value\n }\n }\n if (Object.keys(picked).length) {\n routeContext.i18n = picked\n }\n }\n\n if (\n requestInfo.pageType &&\n PageTypeSchema.safeParse(requestInfo.pageType).success\n ) {\n routeContext.pageType = requestInfo.pageType\n }\n\n if (\n typeof requestInfo.handle === 'string' &&\n requestInfo.handle &&\n requestInfo.handle.length <= MAX_ROUTE_CONTEXT_HANDLE_LENGTH\n ) {\n routeContext.handle = requestInfo.handle\n }\n\n return routeContext\n}\n\n/**\n * Studio per-item loader revalidation: POST the unsaved draft item (and, when\n * the runtime exposes route context, a sanitized `routeContext`) to the app's\n * revalidate route (see `createWeaverseNextRevalidateHandler`) and apply the\n * returned `loaderData` to the live item instance in place.\n *\n * No `router.refresh()` is involved, so the RSC tree is never re-applied — no\n * page remount, no scroll reset, and the draft payload never touches the URL.\n *\n * Throws on any failure (missing route, non-OK response, unknown item) so the\n * Builder Studio bridge can detect the miss and fall back to its legacy\n * refresh-based revalidation for this window.\n */\nexport async function revalidateWeaverseNextItem(\n runtime: RevalidateItemRuntimeLike,\n draftItem: WeaverseNextComponentData,\n endpoint: string = DEFAULT_REVALIDATE_ENDPOINT\n): Promise<void> {\n let instance = runtime.itemInstances.get(draftItem.id)\n if (!instance) {\n throw new Error(\n `[weaverse-next] No live item instance for \"${draftItem.id}\".`\n )\n }\n\n // Snapshot route identity at revalidation start so a later navigation cannot\n // retarget this in-flight request. Omit `routeContext` for legacy runtimes.\n let routeContext = buildWeaverseNextRevalidateRouteContext(\n runtime.requestInfo\n )\n let body = routeContext ? { draftItem, routeContext } : { draftItem }\n\n let response = await fetch(endpoint, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(body),\n })\n if (!response.ok) {\n throw new Error(\n `[weaverse-next] Revalidate endpoint responded ${response.status}.`\n )\n }\n\n let { loaderData } = (await response.json()) as { loaderData?: unknown }\n // The item's settings were already mutated by the Studio edit; only the\n // loader payload needs applying. `setData` merges and notifies subscribers,\n // and the new `loaderData` identity is what Builder's revalidation poll\n // observes for completion.\n instance.setData({ loaderData: loaderData ?? null })\n}\n","import type { PageSEOData } from '@weaverse/schema'\nimport type { Metadata } from 'next'\nimport type { WeaverseNextLoaderData, WeaverseNextPageData } from './types'\n\n/** Object containing an optional Weaverse page for SEO extraction. */\nexport interface WeaverseNextSeoPageContainer {\n /** Page whose published SEO fields should be formatted. */\n page?: WeaverseNextPageData | null\n}\n\n/** Input accepted by {@link getWeaverseNextSeoMetadata}. */\nexport type WeaverseNextSeoInput =\n | WeaverseNextLoaderData\n | WeaverseNextPageData\n | WeaverseNextSeoPageContainer\n | null\n | undefined\n\n/** Open Graph metadata accepted by Next.js's `Metadata` API. */\nexport type NextOpenGraph = NonNullable<Metadata['openGraph']>\n\n/** Twitter card metadata accepted by Next.js's `Metadata` API. */\nexport type NextTwitter = NonNullable<Metadata['twitter']>\n\n/**\n * Weaverse page SEO expressed as a subset of Next's `Metadata`. Assignable to\n * `Metadata` as-is: `const metadata: Metadata = getWeaverseNextSeoMetadata(data)`.\n */\nexport interface WeaverseNextSeoMetadata {\n /** Canonical URL settings for Next's metadata API. */\n alternates?: {\n /** Preferred URL for search indexing. */\n canonical?: string\n }\n /** Page meta description. */\n description?: string\n /** Page meta keywords. */\n keywords?: string\n /** Open Graph metadata normalized to Next's supported union. */\n openGraph?: NextOpenGraph\n /** Search crawler indexing and link-following directives. */\n robots: {\n /** Whether crawlers may follow links on the page. */\n follow: boolean\n /** Whether crawlers may index the page. */\n index: boolean\n }\n /** Page title. */\n title?: string\n /** Twitter card metadata normalized for Next's metadata API. */\n twitter?: NextTwitter\n}\n\nfunction hasOpenGraphContent(seo: PageSEOData['openGraph']): boolean {\n return Boolean(seo?.title || seo?.description || seo?.image || seo?.type)\n}\n\nfunction hasTwitterContent(seo: PageSEOData['twitter']): boolean {\n return Boolean(seo?.title || seo?.description || seo?.image || seo?.cardType)\n}\n\nfunction normalizeTwitterCard(\n cardType: NonNullable<PageSEOData['twitter']>['cardType']\n): 'summary' | 'summary_large_image' {\n return cardType === 'summary_large_image' ? 'summary_large_image' : 'summary'\n}\n\n/**\n * Map a Builder Open Graph type onto Next's `OpenGraphType` union. Every\n * Builder value except `product` exists in Next's union and is preserved\n * verbatim; `product` is not modeled by Next and makes `generateMetadata()`\n * throw, so it degrades to `website` — the closest renderable equivalent.\n */\nfunction normalizeOpenGraphType(\n type: NonNullable<PageSEOData['openGraph']>['type']\n): 'article' | 'profile' | 'video.other' | 'website' {\n if (type === 'article' || type === 'profile' || type === 'video.other') {\n return type\n }\n return 'website'\n}\n\n/**\n * Convert Builder SEO fields into metadata accepted by Next.js.\n *\n * Unsupported Open Graph product types and incomplete Twitter app/player\n * cards are safely downgraded to renderable Next.js variants.\n */\nexport function formatWeaverseNextSeoMetadata(\n seo: PageSEOData | null | undefined\n): WeaverseNextSeoMetadata {\n let index = seo?.robots?.index !== false\n let follow = seo?.robots?.follow !== false\n let metadata: WeaverseNextSeoMetadata = {\n robots: { index, follow },\n }\n\n if (!seo) {\n return metadata\n }\n\n if (seo.title) {\n metadata.title = seo.title\n }\n if (seo.description) {\n metadata.description = seo.description\n }\n if (seo.keywords) {\n metadata.keywords = seo.keywords\n }\n if (seo.canonicalUrl) {\n metadata.alternates = { canonical: seo.canonicalUrl }\n }\n\n let openGraph = seo.openGraph\n if (hasOpenGraphContent(openGraph)) {\n metadata.openGraph = {\n title: openGraph?.title,\n description: openGraph?.description,\n images: openGraph?.image ? [openGraph.image] : undefined,\n type: normalizeOpenGraphType(openGraph?.type),\n }\n }\n\n let twitter = seo.twitter\n if (hasTwitterContent(twitter)) {\n // Builder does not collect the descriptors Next requires for `app` cards\n // (Next throws when they are missing) or `player` cards (which render an\n // empty, useless card without a player URL and dimensions). Downgrade both\n // to `summary` rather than emitting metadata Next cannot render.\n metadata.twitter = {\n card: normalizeTwitterCard(twitter?.cardType),\n title: twitter?.title,\n description: twitter?.description,\n images: twitter?.image ? [twitter.image] : undefined,\n }\n }\n\n return metadata\n}\n\n/**\n * Read page SEO from loader data or a page payload and format it for Next.js\n * `generateMetadata`. Missing data returns indexable/followable robot defaults.\n */\nexport function getWeaverseNextSeoMetadata(\n data: WeaverseNextSeoInput\n): WeaverseNextSeoMetadata {\n if (!data) {\n return formatWeaverseNextSeoMetadata(null)\n }\n let page =\n 'items' in data && 'id' in data\n ? (data as WeaverseNextPageData)\n : ((data as WeaverseNextSeoPageContainer).page ?? null)\n return formatWeaverseNextSeoMetadata(page?.seo ?? null)\n}\n","import type { WeaverseNextRuntimeInternal } from './types'\n\n/**\n * Minimal structural shape of the Next App Router returned by `useRouter()`\n * (`next/navigation`) that the Studio bridge needs. Declared locally — rather\n * than importing `AppRouterInstance` from `next` — so the adapter stays a pure\n * function that unit tests can drive with a plain mock and never pulls\n * `next/navigation` into the test graph.\n */\nexport interface WeaverseNextRouterLike {\n /** Add a route to browser history. */\n push: (\n href: string,\n options?: {\n /** Whether to scroll to the top after navigation. */\n scroll?: boolean\n }\n ) => void\n /** Refresh the current App Router route and server data. */\n refresh: () => void\n /** Replace the current browser-history entry. */\n replace: (\n href: string,\n options?: {\n /** Whether to scroll to the top after navigation. */\n scroll?: boolean\n }\n ) => void\n}\n\n/** Resolved Studio navigation/revalidation callbacks for a Next runtime. */\nexport interface WeaverseNextStudioInternals {\n /** Navigate Studio's preview with React Router-compatible options. */\n navigate: NonNullable<WeaverseNextRuntimeInternal['navigate']>\n /** Refresh the current App Router route. */\n revalidate: NonNullable<WeaverseNextRuntimeInternal['revalidate']>\n}\n\n/** Controls how Studio navigation maps to the Next App Router. */\nexport interface CreateWeaverseNextStudioInternalsOptions {\n /** Use `router.replace` instead of `router.push` for navigation. */\n replace?: boolean\n}\n\nfunction shouldResetScroll(\n options?: { preventScrollReset?: boolean } | Record<string, unknown>\n): boolean {\n if (!options || typeof options !== 'object') {\n return true\n }\n return !(options as { preventScrollReset?: boolean }).preventScrollReset\n}\n\n/**\n * Build Studio `navigate` / `revalidate` callbacks from a Next App Router.\n *\n * Maps Hydrogen's React Router semantics onto Next App Router:\n * - `navigate(to, { preventScrollReset })` → `router.push(to, { scroll })`,\n * where `scroll` is the inverse of `preventScrollReset`. Studio passes\n * `preventScrollReset` for in-place edits so the preview viewport is kept,\n * matching React Router's `navigate({ preventScrollReset })`.\n * - `revalidate()` → `router.refresh()`, the App Router's loader-backed refresh\n * and the closest equivalent to React Router's `useRevalidator`.\n *\n * Pure (no React, no `next/navigation`) so it is unit-testable with a mock\n * router; the {@link WeaverseNextRouterLike} contract is the only coupling.\n */\nexport function createWeaverseNextStudioInternals(\n router: WeaverseNextRouterLike,\n options: CreateWeaverseNextStudioInternalsOptions = {}\n): WeaverseNextStudioInternals {\n return {\n navigate: (to, navigateOptions) => {\n let scroll = shouldResetScroll(navigateOptions)\n if (options.replace) {\n router.replace(to, { scroll })\n } else {\n router.push(to, { scroll })\n }\n },\n revalidate: () => {\n router.refresh()\n },\n }\n}\n","import type { WeaverseNextRequestContext } from './types'\n\n/**\n * Weaverse-controlled apex domains the Studio bridge may be served from\n * (matched on the host itself and any subdomain), mirroring Hydrogen's\n * `TRUSTED_STUDIO_DOMAINS`.\n */\nconst TRUSTED_STUDIO_DOMAINS = ['weaverse.io', 'weaverse.dev']\n\nfunction isLoopbackHostname(hostname: string): boolean {\n return (\n hostname === 'localhost' ||\n hostname === '127.0.0.1' ||\n hostname.endsWith('.localhost')\n )\n}\n\nfunction normalizeOrigin(value: string | null): string | null {\n if (!value) {\n return null\n }\n\n try {\n return new URL(value).origin\n } catch {\n return null\n }\n}\n\n/**\n * Whether `origin` is one we trust to serve the Studio bridge script. Matches\n * Hydrogen's `isTrustedStudioHost`: trusts `weaverse.io` / `weaverse.dev` and\n * their subdomains over https, plus loopback (`localhost` / `*.localhost` /\n * `127.0.0.1`) — but only when the storefront itself is loopback (genuine\n * local-builder dev). Loopback is the only place http is allowed; every other\n * trusted host must be https. Arbitrary origins are rejected.\n */\nfunction isTrustedStudioOrigin(\n origin: string,\n storefrontHostname: string\n): boolean {\n let parsed: URL\n try {\n parsed = new URL(origin)\n } catch {\n return false\n }\n\n let { hostname, protocol } = parsed\n if (isLoopbackHostname(storefrontHostname) && isLoopbackHostname(hostname)) {\n return protocol === 'http:' || protocol === 'https:'\n }\n\n if (protocol !== 'https:') {\n return false\n }\n\n return TRUSTED_STUDIO_DOMAINS.some(\n (domain) => hostname === domain || hostname.endsWith(`.${domain}`)\n )\n}\n\nfunction toSearchParams(context?: WeaverseNextRequestContext): URLSearchParams {\n if (context?.searchParams) {\n return new URLSearchParams(context.searchParams)\n }\n\n if (context?.url) {\n let url =\n typeof context.url === 'string'\n ? new URL(context.url, 'http://localhost')\n : context.url\n return new URLSearchParams(url.searchParams)\n }\n\n return new URLSearchParams()\n}\n\nfunction last(searchParams: URLSearchParams, key: string): string | null {\n let values = searchParams.getAll(key)\n return values.length ? (values.at(-1) ?? null) : null\n}\n\n/** Trust context used when resolving a Studio bridge script URL. */\nexport interface ResolveWeaverseNextStudioScriptSrcOptions {\n /** Storefront hostname; required to permit loopback Studio origins. */\n storefrontHostname?: string\n}\n\n/**\n * Resolve the Studio script URL from request/search context. `@weaverse/next`\n * uses the dedicated Next bridge path served by Builder.\n */\nexport function resolveWeaverseNextStudioScriptSrc(\n context?: WeaverseNextRequestContext,\n options: ResolveWeaverseNextStudioScriptSrcOptions = {}\n): string | null {\n let searchParams = toSearchParams(context)\n\n let isDesignMode =\n context?.isDesignMode ?? last(searchParams, 'isDesignMode') === 'true'\n let isPreviewMode =\n context?.isPreviewMode ?? last(searchParams, 'isPreviewMode') === 'true'\n let isRevisionPreview =\n context?.isRevisionPreview ?? Boolean(last(searchParams, '__revisionId'))\n\n if (!(isDesignMode || isPreviewMode || isRevisionPreview)) {\n return null\n }\n\n let origin = normalizeOrigin(last(searchParams, 'weaverseHost'))\n if (!origin) {\n return null\n }\n\n let storefrontHostname = options.storefrontHostname ?? ''\n if (!isTrustedStudioOrigin(origin, storefrontHostname)) {\n return null\n }\n\n // Builder section-preview URLs carry both isDesignMode and isPreviewMode;\n // the preview iframe waits for `preview-size`, which only preview.js emits,\n // so preview/revision mode takes precedence (matching Hydrogen).\n let bundle = isPreviewMode || isRevisionPreview ? 'preview.js' : 'index.js'\n let version = last(searchParams, 'weaverseVersion')\n let url = `${origin}/static/studio/next/${bundle}`\n return version ? `${url}?v=${encodeURIComponent(version)}` : url\n}\n","import type { SchemaType } from '@weaverse/schema'\nimport type {\n WeaverseNextThemeSchema,\n WeaverseNextThemeSettingsStore,\n} from './types'\n\n/** Initial values for a root-scoped theme-settings store. */\nexport interface CreateWeaverseNextThemeSettingsStoreOptions {\n /** Public environment values exposed alongside the store. */\n publicEnv?: Record<string, string | undefined>\n /** Theme schema associated with the settings. */\n schema?: SchemaType | WeaverseNextThemeSchema\n /** Initial setting values. */\n settings?: Record<string, unknown>\n}\n\n/**\n * Small external store shape compatible with the Studio bridge and React's\n * `useSyncExternalStore` contract. The bridge calls `updateThemeSettings` during\n * live theme edits, so keep that method name stable.\n */\nexport function createWeaverseNextThemeSettingsStore(\n options: CreateWeaverseNextThemeSettingsStoreOptions = {}\n): WeaverseNextThemeSettingsStore {\n let listeners = new Set<() => void>()\n let store: WeaverseNextThemeSettingsStore = {\n publicEnv: options.publicEnv,\n schema: options.schema,\n settings: { ...(options.settings ?? {}) },\n getServerSnapshot: () => store.settings,\n getSnapshot: () => store.settings,\n subscribe: (listener: () => void) => {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n updateThemeSettings: (next: Record<string, unknown>) => {\n store.settings = { ...store.settings, ...next }\n for (let listener of listeners) {\n listener()\n }\n },\n }\n\n return store\n}\n","/**\n * Pure translation helpers, free of React so server code can call them.\n *\n * `translation-context.tsx` builds the client provider and hook on top of\n * these; keeping them apart lets the root entry export them as real functions\n * outside the `'use client'` boundary.\n */\n\n/**\n * Traverse a nested object by dot-path.\n *\n * @example\n * getNestedKey({ cart: { title: 'Cart' } }, 'cart.title') // => 'Cart'\n * getNestedKey({}, 'cart.title', 'fallback') // => 'fallback'\n */\nexport function getNestedKey(\n obj: Record<string, unknown>,\n path: string,\n fallback?: string\n): string | undefined {\n let keys = path.split('.')\n let current: unknown = obj\n\n for (let key of keys) {\n if (current == null || typeof current !== 'object') {\n return fallback\n }\n current = (current as Record<string, unknown>)[key]\n }\n\n if (typeof current === 'string') {\n return current\n }\n\n return fallback\n}\n\n/**\n * Replace `{{variable}}` patterns in a string with provided values.\n *\n * @example\n * interpolate('Hello {{name}}!', { name: 'World' }) // => 'Hello World!'\n * interpolate('-{{percentage}}% Off', { percentage: 15 }) // => '-15% Off'\n */\nexport function interpolate(\n template: string,\n variables?: Record<string, string | number>\n): string {\n if (!variables) {\n return template\n }\n\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (match, key: string) => {\n let value = variables[key]\n return value === undefined ? match : String(value)\n })\n}\n\n/**\n * Signature for a translation function.\n */\nexport type TranslateFunction = (\n key: string,\n variables?: Record<string, string | number>\n) => string\n\n/** Translation sources accepted by {@link createTranslate}. */\nexport interface CreateTranslateSources {\n /** Unsaved live overrides received from Builder design mode. */\n designOverrides?: Record<string, string>\n /** Host application's highest-priority translation function. */\n externalT?: TranslateFunction\n /** Active-locale static-text overrides loaded from Weaverse. */\n merchantOverrides?: Record<string, unknown>\n /** Default-locale static content from the theme schema. */\n staticContent: Record<string, unknown>\n}\n\n/**\n * Build the `t()` translation function over a fixed set of sources.\n *\n * Resolution order, highest priority first:\n * 1. `externalT` – host i18n (e.g. Shopify), unless it echoes the key\n * 2. `designOverrides` – live design-mode edits, flat dot-path keys\n * 3. `merchantOverrides` – locale overrides from the API, nested\n * 4. `staticContent` – the theme's default locale JSON\n * 5. the key itself\n *\n * Design overrides are looked up per-key (own properties only) rather than\n * merged into `merchantOverrides`: a flat key like `cart.title` must override\n * exactly that leaf without wiping sibling keys (`cart.subtitle`), and a\n * per-key own-property lookup never builds nested objects from\n * merchant-controlled keys, so it cannot pollute `Object.prototype`.\n */\nexport function createTranslate(\n sources: CreateTranslateSources\n): TranslateFunction {\n let { staticContent, merchantOverrides, designOverrides, externalT } = sources\n return (key, variables) => {\n // Priority 1: external t (e.g. Shopify i18n, third-party library).\n if (externalT) {\n let external = externalT(key, variables)\n // Accept the external value unless it echoed the key unchanged.\n if (external && external !== key) {\n return external\n }\n }\n\n // Priority 2: live design-mode override (flat, keyed by exact dot-path,\n // own properties only so inherited keys never resolve to functions).\n let design =\n designOverrides && Object.hasOwn(designOverrides, key)\n ? designOverrides[key]\n : undefined\n // Priority 3: merchant overrides (nested). Priority 4: static content.\n let override = merchantOverrides\n ? getNestedKey(merchantOverrides, key)\n : undefined\n let staticValue = getNestedKey(staticContent, key)\n\n // Priority 5: the key itself as the final fallback.\n let raw = design ?? override ?? staticValue ?? key\n return interpolate(raw, variables)\n }\n}\n","/**\n * Minimal mutable store for design-mode static text overrides.\n *\n * `useSyncExternalStore`-compatible. Passed into {@link TranslationProvider}\n * (from `./translation-context`) which subscribes internally and layers\n * overrides on top of `merchantOverrides`/`staticContent`. The Studio bridge\n * calls `updateOverrides()` via `runtime.internal.translationStore` (also\n * exposed as the deprecated `runtime.internal.themeTextStore` alias) so live\n * static-text edits reach the runtime — identical surface to Hydrogen's store,\n * so Builder's existing static-text RPC works with `@weaverse/next` unchanged.\n *\n * Shape: flat `Record<string, string>` — dot-notation keys map to values\n * (e.g. \"cart.title\" → \"Shopping Cart\").\n */\nexport class TranslationStore {\n /** Current flat translation overrides keyed by dot path. */\n overrides: Record<string, string> = {}\n private readonly listeners: Set<() => void> = new Set()\n\n /** Replace every override and notify subscribers. */\n setOverrides = (overrides: Record<string, string>) => {\n this.overrides = { ...overrides }\n this.emit()\n }\n\n /** Merge changed overrides into the current values and notify subscribers. */\n updateOverrides = (newOverrides: Record<string, string>) => {\n this.overrides = { ...this.overrides, ...newOverrides }\n this.emit()\n }\n\n /** Return the current client-side override snapshot. */\n getSnapshot = () => this.overrides\n\n /** Return the override snapshot used during server rendering. */\n getServerSnapshot = () => this.overrides\n\n /** Subscribe to override changes and return an unsubscribe function. */\n subscribe = (callback: () => void) => {\n this.listeners.add(callback)\n return () => {\n this.listeners.delete(callback)\n }\n }\n\n private readonly emit = () => {\n for (const listener of Array.from(this.listeners)) {\n try {\n listener()\n } catch (error) {\n console.error('TranslationStore: Listener error', error)\n }\n }\n }\n}\n\n/**\n * Legacy constructor name for {@link TranslationStore}.\n *\n * @deprecated Replace `ThemeTextStore` with {@link TranslationStore}; the\n * store contract and runtime behavior are unchanged.\n */\nexport const ThemeTextStore = TranslationStore\n/**\n * Legacy type name for {@link TranslationStore}.\n *\n * @deprecated Import {@link TranslationStore} instead.\n */\nexport type ThemeTextStore = TranslationStore\n"]}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/studio-router.ts","../src/studio-script-src.ts","../src/theme-settings-store.ts","../src/translate.ts","../src/translation-store.ts"],"sourcesContent":["import type { WeaverseNextRuntimeInternal } from './types'\n\n/**\n * Minimal structural shape of the Next App Router returned by `useRouter()`\n * (`next/navigation`) that the Studio bridge needs. Declared locally — rather\n * than importing `AppRouterInstance` from `next` — so the adapter stays a pure\n * function that unit tests can drive with a plain mock and never pulls\n * `next/navigation` into the test graph.\n */\nexport interface WeaverseNextRouterLike {\n /** Add a route to browser history. */\n push: (\n href: string,\n options?: {\n /** Whether to scroll to the top after navigation. */\n scroll?: boolean\n }\n ) => void\n /** Refresh the current App Router route and server data. */\n refresh: () => void\n /** Replace the current browser-history entry. */\n replace: (\n href: string,\n options?: {\n /** Whether to scroll to the top after navigation. */\n scroll?: boolean\n }\n ) => void\n}\n\n/** Resolved Studio navigation/revalidation callbacks for a Next runtime. */\nexport interface WeaverseNextStudioInternals {\n /** Navigate Studio's preview with React Router-compatible options. */\n navigate: NonNullable<WeaverseNextRuntimeInternal['navigate']>\n /** Refresh the current App Router route. */\n revalidate: NonNullable<WeaverseNextRuntimeInternal['revalidate']>\n}\n\n/** Controls how Studio navigation maps to the Next App Router. */\nexport interface CreateWeaverseNextStudioInternalsOptions {\n /** Use `router.replace` instead of `router.push` for navigation. */\n replace?: boolean\n}\n\nfunction shouldResetScroll(\n options?: { preventScrollReset?: boolean } | Record<string, unknown>\n): boolean {\n if (!options || typeof options !== 'object') {\n return true\n }\n return !(options as { preventScrollReset?: boolean }).preventScrollReset\n}\n\n/**\n * Build Studio `navigate` / `revalidate` callbacks from a Next App Router.\n *\n * Maps Hydrogen's React Router semantics onto Next App Router:\n * - `navigate(to, { preventScrollReset })` → `router.push(to, { scroll })`,\n * where `scroll` is the inverse of `preventScrollReset`. Studio passes\n * `preventScrollReset` for in-place edits so the preview viewport is kept,\n * matching React Router's `navigate({ preventScrollReset })`.\n * - `revalidate()` → `router.refresh()`, the App Router's loader-backed refresh\n * and the closest equivalent to React Router's `useRevalidator`.\n *\n * Pure (no React, no `next/navigation`) so it is unit-testable with a mock\n * router; the {@link WeaverseNextRouterLike} contract is the only coupling.\n */\nexport function createWeaverseNextStudioInternals(\n router: WeaverseNextRouterLike,\n options: CreateWeaverseNextStudioInternalsOptions = {}\n): WeaverseNextStudioInternals {\n return {\n navigate: (to, navigateOptions) => {\n let scroll = shouldResetScroll(navigateOptions)\n if (options.replace) {\n router.replace(to, { scroll })\n } else {\n router.push(to, { scroll })\n }\n },\n revalidate: () => {\n router.refresh()\n },\n }\n}\n","import type { WeaverseNextRequestContext } from './types'\n\n/**\n * Weaverse-controlled apex domains the Studio bridge may be served from\n * (matched on the host itself and any subdomain), mirroring Hydrogen's\n * `TRUSTED_STUDIO_DOMAINS`.\n */\nconst TRUSTED_STUDIO_DOMAINS = ['weaverse.io', 'weaverse.dev']\n\nfunction isLoopbackHostname(hostname: string): boolean {\n return (\n hostname === 'localhost' ||\n hostname === '127.0.0.1' ||\n hostname.endsWith('.localhost')\n )\n}\n\nfunction normalizeOrigin(value: string | null): string | null {\n if (!value) {\n return null\n }\n\n try {\n return new URL(value).origin\n } catch {\n return null\n }\n}\n\n/**\n * Whether `origin` is one we trust to serve the Studio bridge script. Matches\n * Hydrogen's `isTrustedStudioHost`: trusts `weaverse.io` / `weaverse.dev` and\n * their subdomains over https, plus loopback (`localhost` / `*.localhost` /\n * `127.0.0.1`) — but only when the storefront itself is loopback (genuine\n * local-builder dev). Loopback is the only place http is allowed; every other\n * trusted host must be https. Arbitrary origins are rejected.\n */\nfunction isTrustedStudioOrigin(\n origin: string,\n storefrontHostname: string\n): boolean {\n let parsed: URL\n try {\n parsed = new URL(origin)\n } catch {\n return false\n }\n\n let { hostname, protocol } = parsed\n if (isLoopbackHostname(storefrontHostname) && isLoopbackHostname(hostname)) {\n return protocol === 'http:' || protocol === 'https:'\n }\n\n if (protocol !== 'https:') {\n return false\n }\n\n return TRUSTED_STUDIO_DOMAINS.some(\n (domain) => hostname === domain || hostname.endsWith(`.${domain}`)\n )\n}\n\nfunction toSearchParams(context?: WeaverseNextRequestContext): URLSearchParams {\n if (context?.searchParams) {\n return new URLSearchParams(context.searchParams)\n }\n\n if (context?.url) {\n let url =\n typeof context.url === 'string'\n ? new URL(context.url, 'http://localhost')\n : context.url\n return new URLSearchParams(url.searchParams)\n }\n\n return new URLSearchParams()\n}\n\nfunction last(searchParams: URLSearchParams, key: string): string | null {\n let values = searchParams.getAll(key)\n return values.length ? (values.at(-1) ?? null) : null\n}\n\n/** Trust context used when resolving a Studio bridge script URL. */\nexport interface ResolveWeaverseNextStudioScriptSrcOptions {\n /** Storefront hostname; required to permit loopback Studio origins. */\n storefrontHostname?: string\n}\n\n/**\n * Resolve the Studio script URL from request/search context. `@weaverse/next`\n * uses the dedicated Next bridge path served by Builder.\n */\nexport function resolveWeaverseNextStudioScriptSrc(\n context?: WeaverseNextRequestContext,\n options: ResolveWeaverseNextStudioScriptSrcOptions = {}\n): string | null {\n let searchParams = toSearchParams(context)\n\n let isDesignMode =\n context?.isDesignMode ?? last(searchParams, 'isDesignMode') === 'true'\n let isPreviewMode =\n context?.isPreviewMode ?? last(searchParams, 'isPreviewMode') === 'true'\n let isRevisionPreview =\n context?.isRevisionPreview ?? Boolean(last(searchParams, '__revisionId'))\n\n if (!(isDesignMode || isPreviewMode || isRevisionPreview)) {\n return null\n }\n\n let origin = normalizeOrigin(last(searchParams, 'weaverseHost'))\n if (!origin) {\n return null\n }\n\n let storefrontHostname = options.storefrontHostname ?? ''\n if (!isTrustedStudioOrigin(origin, storefrontHostname)) {\n return null\n }\n\n // Builder section-preview URLs carry both isDesignMode and isPreviewMode;\n // the preview iframe waits for `preview-size`, which only preview.js emits,\n // so preview/revision mode takes precedence (matching Hydrogen).\n let bundle = isPreviewMode || isRevisionPreview ? 'preview.js' : 'index.js'\n let version = last(searchParams, 'weaverseVersion')\n let url = `${origin}/static/studio/next/${bundle}`\n return version ? `${url}?v=${encodeURIComponent(version)}` : url\n}\n","import type { SchemaType } from '@weaverse/schema'\nimport type {\n WeaverseNextThemeSchema,\n WeaverseNextThemeSettingsStore,\n} from './types'\n\n/** Initial values for a root-scoped theme-settings store. */\nexport interface CreateWeaverseNextThemeSettingsStoreOptions {\n /** Public environment values exposed alongside the store. */\n publicEnv?: Record<string, string | undefined>\n /** Theme schema associated with the settings. */\n schema?: SchemaType | WeaverseNextThemeSchema\n /** Initial setting values. */\n settings?: Record<string, unknown>\n}\n\n/**\n * Small external store shape compatible with the Studio bridge and React's\n * `useSyncExternalStore` contract. The bridge calls `updateThemeSettings` during\n * live theme edits, so keep that method name stable.\n */\nexport function createWeaverseNextThemeSettingsStore(\n options: CreateWeaverseNextThemeSettingsStoreOptions = {}\n): WeaverseNextThemeSettingsStore {\n let listeners = new Set<() => void>()\n let store: WeaverseNextThemeSettingsStore = {\n publicEnv: options.publicEnv,\n schema: options.schema,\n settings: { ...(options.settings ?? {}) },\n getServerSnapshot: () => store.settings,\n getSnapshot: () => store.settings,\n subscribe: (listener: () => void) => {\n listeners.add(listener)\n return () => {\n listeners.delete(listener)\n }\n },\n updateThemeSettings: (next: Record<string, unknown>) => {\n store.settings = { ...store.settings, ...next }\n for (let listener of listeners) {\n listener()\n }\n },\n }\n\n return store\n}\n","/**\n * Pure translation helpers, free of React so server code can call them.\n *\n * `translation-context.tsx` builds the client provider and hook on top of\n * these; keeping them apart lets the root entry export them as real functions\n * outside the `'use client'` boundary.\n */\n\n/**\n * Traverse a nested object by dot-path.\n *\n * @example\n * getNestedKey({ cart: { title: 'Cart' } }, 'cart.title') // => 'Cart'\n * getNestedKey({}, 'cart.title', 'fallback') // => 'fallback'\n */\nexport function getNestedKey(\n obj: Record<string, unknown>,\n path: string,\n fallback?: string\n): string | undefined {\n let keys = path.split('.')\n let current: unknown = obj\n\n for (let key of keys) {\n if (current == null || typeof current !== 'object') {\n return fallback\n }\n current = (current as Record<string, unknown>)[key]\n }\n\n if (typeof current === 'string') {\n return current\n }\n\n return fallback\n}\n\n/**\n * Replace `{{variable}}` patterns in a string with provided values.\n *\n * @example\n * interpolate('Hello {{name}}!', { name: 'World' }) // => 'Hello World!'\n * interpolate('-{{percentage}}% Off', { percentage: 15 }) // => '-15% Off'\n */\nexport function interpolate(\n template: string,\n variables?: Record<string, string | number>\n): string {\n if (!variables) {\n return template\n }\n\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (match, key: string) => {\n let value = variables[key]\n return value === undefined ? match : String(value)\n })\n}\n\n/**\n * Signature for a translation function.\n */\nexport type TranslateFunction = (\n key: string,\n variables?: Record<string, string | number>\n) => string\n\n/** Translation sources accepted by {@link createTranslate}. */\nexport interface CreateTranslateSources {\n /** Unsaved live overrides received from Builder design mode. */\n designOverrides?: Record<string, string>\n /** Host application's highest-priority translation function. */\n externalT?: TranslateFunction\n /** Active-locale static-text overrides loaded from Weaverse. */\n merchantOverrides?: Record<string, unknown>\n /** Default-locale static content from the theme schema. */\n staticContent: Record<string, unknown>\n}\n\n/**\n * Build the `t()` translation function over a fixed set of sources.\n *\n * Resolution order, highest priority first:\n * 1. `externalT` – host i18n (e.g. Shopify), unless it echoes the key\n * 2. `designOverrides` – live design-mode edits, flat dot-path keys\n * 3. `merchantOverrides` – locale overrides from the API, nested\n * 4. `staticContent` – the theme's default locale JSON\n * 5. the key itself\n *\n * Design overrides are looked up per-key (own properties only) rather than\n * merged into `merchantOverrides`: a flat key like `cart.title` must override\n * exactly that leaf without wiping sibling keys (`cart.subtitle`), and a\n * per-key own-property lookup never builds nested objects from\n * merchant-controlled keys, so it cannot pollute `Object.prototype`.\n */\nexport function createTranslate(\n sources: CreateTranslateSources\n): TranslateFunction {\n let { staticContent, merchantOverrides, designOverrides, externalT } = sources\n return (key, variables) => {\n // Priority 1: external t (e.g. Shopify i18n, third-party library).\n if (externalT) {\n let external = externalT(key, variables)\n // Accept the external value unless it echoed the key unchanged.\n if (external && external !== key) {\n return external\n }\n }\n\n // Priority 2: live design-mode override (flat, keyed by exact dot-path,\n // own properties only so inherited keys never resolve to functions).\n let design =\n designOverrides && Object.hasOwn(designOverrides, key)\n ? designOverrides[key]\n : undefined\n // Priority 3: merchant overrides (nested). Priority 4: static content.\n let override = merchantOverrides\n ? getNestedKey(merchantOverrides, key)\n : undefined\n let staticValue = getNestedKey(staticContent, key)\n\n // Priority 5: the key itself as the final fallback.\n let raw = design ?? override ?? staticValue ?? key\n return interpolate(raw, variables)\n }\n}\n","/**\n * Minimal mutable store for design-mode static text overrides.\n *\n * `useSyncExternalStore`-compatible. Passed into {@link TranslationProvider}\n * (from `./translation-context`) which subscribes internally and layers\n * overrides on top of `merchantOverrides`/`staticContent`. The Studio bridge\n * calls `updateOverrides()` via `runtime.internal.translationStore` (also\n * exposed as the deprecated `runtime.internal.themeTextStore` alias) so live\n * static-text edits reach the runtime — identical surface to Hydrogen's store,\n * so Builder's existing static-text RPC works with `@weaverse/next` unchanged.\n *\n * Shape: flat `Record<string, string>` — dot-notation keys map to values\n * (e.g. \"cart.title\" → \"Shopping Cart\").\n */\nexport class TranslationStore {\n /** Current flat translation overrides keyed by dot path. */\n overrides: Record<string, string> = {}\n private readonly listeners: Set<() => void> = new Set()\n\n /** Replace every override and notify subscribers. */\n setOverrides = (overrides: Record<string, string>) => {\n this.overrides = { ...overrides }\n this.emit()\n }\n\n /** Merge changed overrides into the current values and notify subscribers. */\n updateOverrides = (newOverrides: Record<string, string>) => {\n this.overrides = { ...this.overrides, ...newOverrides }\n this.emit()\n }\n\n /** Return the current client-side override snapshot. */\n getSnapshot = () => this.overrides\n\n /** Return the override snapshot used during server rendering. */\n getServerSnapshot = () => this.overrides\n\n /** Subscribe to override changes and return an unsubscribe function. */\n subscribe = (callback: () => void) => {\n this.listeners.add(callback)\n return () => {\n this.listeners.delete(callback)\n }\n }\n\n private readonly emit = () => {\n for (const listener of Array.from(this.listeners)) {\n try {\n listener()\n } catch (error) {\n console.error('TranslationStore: Listener error', error)\n }\n }\n }\n}\n\n/**\n * Legacy constructor name for {@link TranslationStore}.\n *\n * @deprecated Replace `ThemeTextStore` with {@link TranslationStore}; the\n * store contract and runtime behavior are unchanged.\n */\nexport const ThemeTextStore = TranslationStore\n/**\n * Legacy type name for {@link TranslationStore}.\n *\n * @deprecated Import {@link TranslationStore} instead.\n */\nexport type ThemeTextStore = TranslationStore\n"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -1,203 +1,167 @@
1
- export { DEFAULT_REVALIDATE_ENDPOINT, buildWeaverseNextRequestInfo, buildWeaverseNextRevalidateRouteContext, formatWeaverseNextSeoMetadata, generateDataFromSchema, getWeaverseNextSeoMetadata, isBrowser, isIframe, revalidateWeaverseNextItem, runWeaverseComponentLoaders } from './chunk-OSC5HR5V.mjs';
2
- export * from '@weaverse/schema';
3
- export { ThemeTextProvider, TranslationProvider, WeaverseNextProvider, WeaverseNextRenderer, WeaverseNextRootProvider, WeaverseNextRuntime, WeaverseNextStudio, WeaverseNextStudioBridge, WeaverseNextStudioConnect, bindWeaverseNextStudioRuntime, createWeaverseNextClient, createWeaverseNextRuntime, loadWeaverseNextStudioScript, useChildInstances, useItemInstance, useParentInstance, useThemeSettings, useThemeText, useTranslation, useWeaverse, useWeaverseCommerce, useWeaverseNextStudioInternals, useWeaversePageData, useWeaverseRootData } from './client-boundary.mjs';
4
-
5
- // src/studio-router.ts
1
+ import { a as buildWeaverseNextRevalidateRouteContext, c as buildWeaverseNextRequestInfo, d as generateDataFromSchema, f as isBrowser, n as getWeaverseNextSeoMetadata, o as revalidateWeaverseNextItem, p as isIframe, r as DEFAULT_REVALIDATE_ENDPOINT, t as formatWeaverseNextSeoMetadata, u as runWeaverseComponentLoaders } from "./seo-C-S2viuI.mjs";
2
+ import { ThemeTextProvider, TranslationProvider, WeaverseNextProvider, WeaverseNextRenderer, WeaverseNextRootProvider, WeaverseNextRuntime, WeaverseNextStudio, WeaverseNextStudioBridge, WeaverseNextStudioConnect, bindWeaverseNextStudioRuntime, createWeaverseNextClient, createWeaverseNextRuntime, loadWeaverseNextStudioScript, useChildInstances, useItemInstance, useParentInstance, useThemeSettings, useThemeText, useTranslation, useWeaverse, useWeaverseCommerce, useWeaverseNextStudioInternals, useWeaversePageData, useWeaverseRootData } from "./client-boundary.mjs";
3
+ export * from "@weaverse/schema";
4
+ //#region src/studio-router.ts
6
5
  function shouldResetScroll(options) {
7
- if (!options || typeof options !== "object") {
8
- return true;
9
- }
10
- return !options.preventScrollReset;
6
+ if (!options || typeof options !== "object") return true;
7
+ return !options.preventScrollReset;
11
8
  }
12
9
  function createWeaverseNextStudioInternals(router, options = {}) {
13
- return {
14
- navigate: (to, navigateOptions) => {
15
- let scroll = shouldResetScroll(navigateOptions);
16
- if (options.replace) {
17
- router.replace(to, { scroll });
18
- } else {
19
- router.push(to, { scroll });
20
- }
21
- },
22
- revalidate: () => {
23
- router.refresh();
24
- }
25
- };
10
+ return {
11
+ navigate: (to, navigateOptions) => {
12
+ let scroll = shouldResetScroll(navigateOptions);
13
+ if (options.replace) router.replace(to, { scroll });
14
+ else router.push(to, { scroll });
15
+ },
16
+ revalidate: () => {
17
+ router.refresh();
18
+ }
19
+ };
26
20
  }
27
-
28
- // src/studio-script-src.ts
29
- var TRUSTED_STUDIO_DOMAINS = ["weaverse.io", "weaverse.dev"];
21
+ //#endregion
22
+ //#region src/studio-script-src.ts
23
+ const TRUSTED_STUDIO_DOMAINS = ["weaverse.io", "weaverse.dev"];
30
24
  function isLoopbackHostname(hostname) {
31
- return hostname === "localhost" || hostname === "127.0.0.1" || hostname.endsWith(".localhost");
25
+ return hostname === "localhost" || hostname === "127.0.0.1" || hostname.endsWith(".localhost");
32
26
  }
33
27
  function normalizeOrigin(value) {
34
- if (!value) {
35
- return null;
36
- }
37
- try {
38
- return new URL(value).origin;
39
- } catch {
40
- return null;
41
- }
28
+ if (!value) return null;
29
+ try {
30
+ return new URL(value).origin;
31
+ } catch {
32
+ return null;
33
+ }
42
34
  }
43
35
  function isTrustedStudioOrigin(origin, storefrontHostname) {
44
- let parsed;
45
- try {
46
- parsed = new URL(origin);
47
- } catch {
48
- return false;
49
- }
50
- let { hostname, protocol } = parsed;
51
- if (isLoopbackHostname(storefrontHostname) && isLoopbackHostname(hostname)) {
52
- return protocol === "http:" || protocol === "https:";
53
- }
54
- if (protocol !== "https:") {
55
- return false;
56
- }
57
- return TRUSTED_STUDIO_DOMAINS.some(
58
- (domain) => hostname === domain || hostname.endsWith(`.${domain}`)
59
- );
36
+ let parsed;
37
+ try {
38
+ parsed = new URL(origin);
39
+ } catch {
40
+ return false;
41
+ }
42
+ let { hostname, protocol } = parsed;
43
+ if (isLoopbackHostname(storefrontHostname) && isLoopbackHostname(hostname)) return protocol === "http:" || protocol === "https:";
44
+ if (protocol !== "https:") return false;
45
+ return TRUSTED_STUDIO_DOMAINS.some((domain) => hostname === domain || hostname.endsWith(`.${domain}`));
60
46
  }
61
47
  function toSearchParams(context) {
62
- if (context?.searchParams) {
63
- return new URLSearchParams(context.searchParams);
64
- }
65
- if (context?.url) {
66
- let url = typeof context.url === "string" ? new URL(context.url, "http://localhost") : context.url;
67
- return new URLSearchParams(url.searchParams);
68
- }
69
- return new URLSearchParams();
48
+ if (context?.searchParams) return new URLSearchParams(context.searchParams);
49
+ if (context?.url) {
50
+ let url = typeof context.url === "string" ? new URL(context.url, "http://localhost") : context.url;
51
+ return new URLSearchParams(url.searchParams);
52
+ }
53
+ return new URLSearchParams();
70
54
  }
71
55
  function last(searchParams, key) {
72
- let values = searchParams.getAll(key);
73
- return values.length ? values.at(-1) ?? null : null;
56
+ let values = searchParams.getAll(key);
57
+ return values.length ? values.at(-1) ?? null : null;
74
58
  }
75
59
  function resolveWeaverseNextStudioScriptSrc(context, options = {}) {
76
- let searchParams = toSearchParams(context);
77
- let isDesignMode = context?.isDesignMode ?? last(searchParams, "isDesignMode") === "true";
78
- let isPreviewMode = context?.isPreviewMode ?? last(searchParams, "isPreviewMode") === "true";
79
- let isRevisionPreview = context?.isRevisionPreview ?? Boolean(last(searchParams, "__revisionId"));
80
- if (!(isDesignMode || isPreviewMode || isRevisionPreview)) {
81
- return null;
82
- }
83
- let origin = normalizeOrigin(last(searchParams, "weaverseHost"));
84
- if (!origin) {
85
- return null;
86
- }
87
- let storefrontHostname = options.storefrontHostname ?? "";
88
- if (!isTrustedStudioOrigin(origin, storefrontHostname)) {
89
- return null;
90
- }
91
- let bundle = isPreviewMode || isRevisionPreview ? "preview.js" : "index.js";
92
- let version = last(searchParams, "weaverseVersion");
93
- let url = `${origin}/static/studio/next/${bundle}`;
94
- return version ? `${url}?v=${encodeURIComponent(version)}` : url;
60
+ let searchParams = toSearchParams(context);
61
+ let isDesignMode = context?.isDesignMode ?? last(searchParams, "isDesignMode") === "true";
62
+ let isPreviewMode = context?.isPreviewMode ?? last(searchParams, "isPreviewMode") === "true";
63
+ let isRevisionPreview = context?.isRevisionPreview ?? Boolean(last(searchParams, "__revisionId"));
64
+ if (!(isDesignMode || isPreviewMode || isRevisionPreview)) return null;
65
+ let origin = normalizeOrigin(last(searchParams, "weaverseHost"));
66
+ if (!origin) return null;
67
+ if (!isTrustedStudioOrigin(origin, options.storefrontHostname ?? "")) return null;
68
+ let bundle = isPreviewMode || isRevisionPreview ? "preview.js" : "index.js";
69
+ let version = last(searchParams, "weaverseVersion");
70
+ let url = `${origin}/static/studio/next/${bundle}`;
71
+ return version ? `${url}?v=${encodeURIComponent(version)}` : url;
95
72
  }
96
-
97
- // src/theme-settings-store.ts
73
+ //#endregion
74
+ //#region src/theme-settings-store.ts
98
75
  function createWeaverseNextThemeSettingsStore(options = {}) {
99
- let listeners = /* @__PURE__ */ new Set();
100
- let store = {
101
- publicEnv: options.publicEnv,
102
- schema: options.schema,
103
- settings: { ...options.settings ?? {} },
104
- getServerSnapshot: () => store.settings,
105
- getSnapshot: () => store.settings,
106
- subscribe: (listener) => {
107
- listeners.add(listener);
108
- return () => {
109
- listeners.delete(listener);
110
- };
111
- },
112
- updateThemeSettings: (next) => {
113
- store.settings = { ...store.settings, ...next };
114
- for (let listener of listeners) {
115
- listener();
116
- }
117
- }
118
- };
119
- return store;
76
+ let listeners = /* @__PURE__ */ new Set();
77
+ let store = {
78
+ publicEnv: options.publicEnv,
79
+ schema: options.schema,
80
+ settings: { ...options.settings ?? {} },
81
+ getServerSnapshot: () => store.settings,
82
+ getSnapshot: () => store.settings,
83
+ subscribe: (listener) => {
84
+ listeners.add(listener);
85
+ return () => {
86
+ listeners.delete(listener);
87
+ };
88
+ },
89
+ updateThemeSettings: (next) => {
90
+ store.settings = {
91
+ ...store.settings,
92
+ ...next
93
+ };
94
+ for (let listener of listeners) listener();
95
+ }
96
+ };
97
+ return store;
120
98
  }
121
-
122
- // src/translate.ts
99
+ //#endregion
100
+ //#region src/translate.ts
123
101
  function getNestedKey(obj, path, fallback) {
124
- let keys = path.split(".");
125
- let current = obj;
126
- for (let key of keys) {
127
- if (current == null || typeof current !== "object") {
128
- return fallback;
129
- }
130
- current = current[key];
131
- }
132
- if (typeof current === "string") {
133
- return current;
134
- }
135
- return fallback;
102
+ let keys = path.split(".");
103
+ let current = obj;
104
+ for (let key of keys) {
105
+ if (current == null || typeof current !== "object") return fallback;
106
+ current = current[key];
107
+ }
108
+ if (typeof current === "string") return current;
109
+ return fallback;
136
110
  }
137
111
  function interpolate(template, variables) {
138
- if (!variables) {
139
- return template;
140
- }
141
- return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
142
- let value = variables[key];
143
- return value === void 0 ? match : String(value);
144
- });
112
+ if (!variables) return template;
113
+ return template.replace(/\{\{(\w+)\}\}/g, (match, key) => {
114
+ let value = variables[key];
115
+ return value === void 0 ? match : String(value);
116
+ });
145
117
  }
146
118
  function createTranslate(sources) {
147
- let { staticContent, merchantOverrides, designOverrides, externalT } = sources;
148
- return (key, variables) => {
149
- if (externalT) {
150
- let external = externalT(key, variables);
151
- if (external && external !== key) {
152
- return external;
153
- }
154
- }
155
- let design = designOverrides && Object.hasOwn(designOverrides, key) ? designOverrides[key] : void 0;
156
- let override = merchantOverrides ? getNestedKey(merchantOverrides, key) : void 0;
157
- let staticValue = getNestedKey(staticContent, key);
158
- let raw = design ?? override ?? staticValue ?? key;
159
- return interpolate(raw, variables);
160
- };
119
+ let { staticContent, merchantOverrides, designOverrides, externalT } = sources;
120
+ return (key, variables) => {
121
+ if (externalT) {
122
+ let external = externalT(key, variables);
123
+ if (external && external !== key) return external;
124
+ }
125
+ let design = designOverrides && Object.hasOwn(designOverrides, key) ? designOverrides[key] : void 0;
126
+ let override = merchantOverrides ? getNestedKey(merchantOverrides, key) : void 0;
127
+ let staticValue = getNestedKey(staticContent, key);
128
+ return interpolate(design ?? override ?? staticValue ?? key, variables);
129
+ };
161
130
  }
162
-
163
- // src/translation-store.ts
131
+ //#endregion
132
+ //#region src/translation-store.ts
164
133
  var TranslationStore = class {
165
- /** Current flat translation overrides keyed by dot path. */
166
- overrides = {};
167
- listeners = /* @__PURE__ */ new Set();
168
- /** Replace every override and notify subscribers. */
169
- setOverrides = (overrides) => {
170
- this.overrides = { ...overrides };
171
- this.emit();
172
- };
173
- /** Merge changed overrides into the current values and notify subscribers. */
174
- updateOverrides = (newOverrides) => {
175
- this.overrides = { ...this.overrides, ...newOverrides };
176
- this.emit();
177
- };
178
- /** Return the current client-side override snapshot. */
179
- getSnapshot = () => this.overrides;
180
- /** Return the override snapshot used during server rendering. */
181
- getServerSnapshot = () => this.overrides;
182
- /** Subscribe to override changes and return an unsubscribe function. */
183
- subscribe = (callback) => {
184
- this.listeners.add(callback);
185
- return () => {
186
- this.listeners.delete(callback);
187
- };
188
- };
189
- emit = () => {
190
- for (const listener of Array.from(this.listeners)) {
191
- try {
192
- listener();
193
- } catch (error) {
194
- console.error("TranslationStore: Listener error", error);
195
- }
196
- }
197
- };
134
+ overrides = {};
135
+ listeners = /* @__PURE__ */ new Set();
136
+ setOverrides = (overrides) => {
137
+ this.overrides = { ...overrides };
138
+ this.emit();
139
+ };
140
+ updateOverrides = (newOverrides) => {
141
+ this.overrides = {
142
+ ...this.overrides,
143
+ ...newOverrides
144
+ };
145
+ this.emit();
146
+ };
147
+ getSnapshot = () => this.overrides;
148
+ getServerSnapshot = () => this.overrides;
149
+ subscribe = (callback) => {
150
+ this.listeners.add(callback);
151
+ return () => {
152
+ this.listeners.delete(callback);
153
+ };
154
+ };
155
+ emit = () => {
156
+ for (const listener of Array.from(this.listeners)) try {
157
+ listener();
158
+ } catch (error) {
159
+ console.error("TranslationStore: Listener error", error);
160
+ }
161
+ };
198
162
  };
199
- var ThemeTextStore = TranslationStore;
163
+ const ThemeTextStore = TranslationStore;
164
+ //#endregion
165
+ export { DEFAULT_REVALIDATE_ENDPOINT, ThemeTextProvider, ThemeTextStore, TranslationProvider, TranslationStore, WeaverseNextProvider, WeaverseNextRenderer, WeaverseNextRootProvider, WeaverseNextRuntime, WeaverseNextStudio, WeaverseNextStudioBridge, WeaverseNextStudioConnect, bindWeaverseNextStudioRuntime, buildWeaverseNextRequestInfo, buildWeaverseNextRevalidateRouteContext, createTranslate, createWeaverseNextClient, createWeaverseNextRuntime, createWeaverseNextStudioInternals, createWeaverseNextThemeSettingsStore, formatWeaverseNextSeoMetadata, generateDataFromSchema, getNestedKey, getWeaverseNextSeoMetadata, interpolate, isBrowser, isIframe, loadWeaverseNextStudioScript, resolveWeaverseNextStudioScriptSrc, revalidateWeaverseNextItem, runWeaverseComponentLoaders, useChildInstances, useItemInstance, useParentInstance, useThemeSettings, useThemeText, useTranslation, useWeaverse, useWeaverseCommerce, useWeaverseNextStudioInternals, useWeaversePageData, useWeaverseRootData };
200
166
 
201
- export { ThemeTextStore, TranslationStore, createTranslate, createWeaverseNextStudioInternals, createWeaverseNextThemeSettingsStore, getNestedKey, interpolate, resolveWeaverseNextStudioScriptSrc };
202
- //# sourceMappingURL=index.mjs.map
203
167
  //# sourceMappingURL=index.mjs.map