@ops-ai/electron-feature-flags-toggly 1.0.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/CHANGELOG.md +14 -0
- package/LICENSE +21 -0
- package/README.md +156 -0
- package/dist/index.cjs +80 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +3 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +72 -0
- package/dist/index.js.map +1 -0
- package/dist/main/index.cjs +853 -0
- package/dist/main/index.cjs.map +1 -0
- package/dist/main/index.d.cts +131 -0
- package/dist/main/index.d.ts +131 -0
- package/dist/main/index.js +830 -0
- package/dist/main/index.js.map +1 -0
- package/dist/preload/index.cjs +72 -0
- package/dist/preload/index.cjs.map +1 -0
- package/dist/preload/index.d.cts +7 -0
- package/dist/preload/index.d.ts +7 -0
- package/dist/preload/index.js +70 -0
- package/dist/preload/index.js.map +1 -0
- package/dist/react/index.cjs +146 -0
- package/dist/react/index.cjs.map +1 -0
- package/dist/react/index.d.cts +39 -0
- package/dist/react/index.d.ts +39 -0
- package/dist/react/index.js +141 -0
- package/dist/react/index.js.map +1 -0
- package/dist/renderer/index.cjs +80 -0
- package/dist/renderer/index.cjs.map +1 -0
- package/dist/renderer/index.d.cts +13 -0
- package/dist/renderer/index.d.ts +13 -0
- package/dist/renderer/index.js +72 -0
- package/dist/renderer/index.js.map +1 -0
- package/dist/types-BbMSwQVV.d.cts +47 -0
- package/dist/types-BbMSwQVV.d.ts +47 -0
- package/package.json +132 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/main/cache.ts","../../src/sdk-identity.ts","../../src/ws-sync.ts","../../src/main/client.ts","../../src/ipc-channels.ts","../../src/main/ipc.ts"],"names":["join","readFile","path","mkdir","writeFile","unlink","InMemoryJwksCache","randomUUID","toBooleanDefinitions","appendEvaluationContext","resolveEvaluatedDefinition","applyLocalGate","normalizeEntityContext","evaluateEvaluatedGate","buildFlagGateIndex","readResponseBody","parseEvaluatedResponseBody","unwrapDefsPayload","WebSocket"],"mappings":";;;;;;;;;;;;;;;AAUA,SAAS,gBAAgB,KAAA,EAAuB;AAC9C,EAAA,OAAO,KAAA,CAAM,OAAA,CAAQ,kBAAA,EAAoB,GAAG,CAAA;AAC9C;AAEO,SAAS,kBAAA,CACd,YAAA,EACA,MAAA,EACA,WAAA,EACA,UAAA,EACQ;AACR,EAAA,MAAM,GAAA,GAAMA,SAAA,CAAK,YAAA,EAAc,QAAQ,CAAA;AACvC,EAAA,MAAM,IAAA,GAAO,CAAA,MAAA,EAAS,eAAA,CAAgB,MAAM,CAAC,CAAA,CAAA,EAAI,eAAA,CAAgB,WAAW,CAAC,CAAA,CAAA,EAAI,eAAA,CAAgB,UAAU,CAAC,CAAA,KAAA,CAAA;AAC5G,EAAA,OAAOA,SAAA,CAAK,KAAK,IAAI,CAAA;AACvB;AAEO,IAAM,mBAAN,MAAuB;AAAA,EAC5B,YAA6B,YAAA,EAAsB;AAAtB,IAAA,IAAA,CAAA,YAAA,GAAA,YAAA;AAAA,EAAuB;AAAA,EAAvB,YAAA;AAAA,EAErB,QAAA,CAAS,MAAA,EAAgB,WAAA,EAAqB,UAAA,EAA4B;AAChF,IAAA,OAAO,kBAAA,CAAmB,IAAA,CAAK,YAAA,EAAc,MAAA,EAAQ,aAAa,UAAU,CAAA;AAAA,EAC9E;AAAA,EAEA,MAAM,IAAA,CACJ,MAAA,EACA,WAAA,EACA,UAAA,EACgC;AAChC,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,QAAA,CAAS,MAAA,EAAQ,aAAa,UAAU,CAAA;AAC1D,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,MAAMC,iBAAA,CAAS,IAAA,EAAM,OAAO,CAAA;AACxC,MAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,MAAA,IAAI,CAAC,MAAA,IAAU,OAAO,MAAA,KAAW,QAAA,IAAY,CAAC,MAAA,CAAO,KAAA,IAAS,OAAO,MAAA,CAAO,KAAA,KAAU,QAAA,EAAU;AAC9F,QAAA,OAAO,IAAA;AAAA,MACT;AACA,MAAA,OAAO;AAAA,QACL,OAAO,MAAA,CAAO,KAAA;AAAA,QACd,QAAA,EAAU,OAAO,QAAA,IAAY,IAAA;AAAA,QAC7B,SAAA,EAAW,OAAO,MAAA,CAAO,SAAA,KAAc,WAAW,MAAA,CAAO,SAAA,GAAY,KAAK,GAAA;AAAI,OAChF;AAAA,IACF,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,IAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEA,MAAM,KAAA,CACJ,MAAA,EACA,WAAA,EACA,YACA,KAAA,EACe;AACf,IAAA,MAAMC,MAAA,GAAO,IAAA,CAAK,QAAA,CAAS,MAAA,EAAQ,aAAa,UAAU,CAAA;AAC1D,IAAA,MAAMC,cAAA,CAAMH,UAAK,IAAA,CAAK,YAAA,EAAc,QAAQ,CAAA,EAAG,EAAE,SAAA,EAAW,IAAA,EAAM,CAAA;AAClE,IAAA,MAAMI,mBAAUF,MAAA,EAAM,IAAA,CAAK,SAAA,CAAU,KAAK,GAAG,OAAO,CAAA;AAAA,EACtD;AAAA,EAEA,MAAM,KAAA,CAAM,MAAA,EAAgB,WAAA,EAAqB,UAAA,EAAmC;AAClF,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,QAAA,CAAS,MAAA,EAAQ,aAAa,UAAU,CAAA;AAC1D,IAAA,IAAI;AACF,MAAA,MAAMG,gBAAO,IAAI,CAAA;AAAA,IACnB,CAAA,CAAA,MAAQ;AAAA,IAER;AAAA,EACF;AACF;;;ACzEO,IAAM,MAAA,GAAS;AACf,IAAM,WAAA,GAAc;AAEpB,IAAM,aAAA,GAAgB,cAAA;AACtB,IAAM,kBAAA,GAAqB,sBAAA;AAE3B,SAAS,YAAA,GAAuB;AACrC,EAAA,OAAO,CAAA,OAAA,EAAU,MAAM,CAAA,CAAA,EAAI,WAAW,CAAA,CAAA;AACxC;AAEO,SAAS,gBAAA,GAA2C;AACzD,EAAA,OAAO;AAAA,IACL,CAAC,aAAa,GAAG,MAAA;AAAA,IACjB,CAAC,kBAAkB,GAAG;AAAA,GACxB;AACF;AAEO,SAAS,qBAAqB,MAAA,EAA+B;AAClE,EAAA,MAAA,CAAO,GAAA,CAAI,OAAO,MAAM,CAAA;AACxB,EAAA,MAAA,CAAO,GAAA,CAAI,cAAc,WAAW,CAAA;AACtC;AAEO,SAAS,2BAAA,CACd,QAAA,GAAmC,EAAC,EACZ;AACxB,EAAA,OAAO;AAAA,IACL,GAAG,QAAA;AAAA,IACH,cAAc,YAAA,EAAa;AAAA,IAC3B,GAAG,gBAAA;AAAiB,GACtB;AACF;;;AC5BO,IAAM,2BAAA,GAA8B,wBAAA;AAEpC,IAAM,oBAAA,GAAuB,GAAA;AAC7B,IAAM,mBAAA,GAAsB,GAAA;AAC5B,IAAM,mBAAA,GAAsB,GAAA;AAU5B,SAAS,iBAAA,CACd,OAAA,EACA,MAAA,EACA,UAAA,EACQ;AACR,EAAA,MAAM,MAAA,GAAS,OAAA,CACZ,OAAA,CAAQ,aAAA,EAAe,QAAQ,CAAA,CAC/B,OAAA,CAAQ,YAAA,EAAc,OAAO,CAAA,CAC7B,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAA;AACpB,EAAA,MAAM,MAAA,GAAS,IAAI,eAAA,EAAgB;AACnC,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,MAAA,CAAO,GAAA,CAAI,OAAO,UAAU,CAAA;AAAA,EAC9B;AACA,EAAA,oBAAA,CAAqB,MAAM,CAAA;AAC3B,EAAA,MAAM,KAAA,GAAQ,OAAO,QAAA,EAAS;AAC9B,EAAA,OAAO,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,MAAM,MAAM,KAAA,GAAQ,CAAA,CAAA,EAAI,KAAK,CAAA,CAAA,GAAK,EAAE,CAAA,CAAA;AAC1D;AAEO,SAAS,wBAAwB,OAAA,EAAyB;AAC/D,EAAA,OAAO,IAAA,CAAK,IAAI,oBAAA,GAAuB,IAAA,CAAK,IAAI,CAAA,EAAG,OAAO,GAAG,mBAAmB,CAAA;AAClF;AAEO,SAAS,iBAAA,CACd,SACA,UAAA,EACS;AACT,EAAA,IAAI,OAAA,CAAQ,SAAS,MAAA,EAAQ;AAC3B,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,IAAI,OAAA,CAAQ,cAAc,IAAA,EAAM;AAC9B,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,IAAI,CAAC,UAAA,EAAY;AACf,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,IAAI,OAAA,CAAQ,IAAA,IAAQ,OAAA,CAAQ,IAAA,KAAS,UAAA,EAAY;AAC/C,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,KAAA;AACT;AAEO,SAAS,yBAAA,CACd,SACA,UAAA,EACS;AACT,EAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,eAAA,IAAmB,OAAA,CAAQ,SAAS,QAAA,EAAU;AACjE,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,IAAI,CAAC,OAAA,CAAQ,IAAA,IAAQ,CAAC,UAAA,EAAY;AAChC,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,QAAQ,IAAA,KAAS,UAAA;AAC1B;AAEO,SAAS,+BAA+B,OAAA,EAAiC;AAC9E,EAAA,OAAO,QAAQ,IAAA,KAAS,qBAAA;AAC1B;AAOO,SAAS,uBAAA,CACd,SACA,gBAAA,EACyB;AACzB,EAAA,IAAI,8BAAA,CAA+B,OAAO,CAAA,EAAG;AAC3C,IAAA,OAAO,EAAE,QAAQ,cAAA,EAAe;AAAA,EAClC;AACA,EAAA,IAAI,yBAAA,CAA0B,OAAA,EAAS,gBAAgB,CAAA,EAAG;AACxD,IAAA,OAAO,EAAE,MAAA,EAAQ,gBAAA,EAAkB,GAAA,EAAK,OAAA,CAAQ,QAAQ,IAAA,EAAK;AAAA,EAC/D;AACA,EAAA,OAAO,EAAE,QAAQ,MAAA,EAAO;AAC1B;AAEO,SAAS,qBAAA,CACd,IAAA,EACA,OAAA,EACA,KAAA,EAKM;AACN,EAAA,IAAI,IAAA,CAAK,WAAW,cAAA,EAAgB;AAClC,IAAA,KAAA,CAAM,WAAA,EAAY;AAClB,IAAA;AAAA,EACF;AACA,EAAA,IAAI,IAAA,CAAK,WAAW,gBAAA,EAAkB;AACpC,IAAA,KAAA,CAAM,aAAA,CAAc,KAAK,GAAG,CAAA;AAC5B,IAAA;AAAA,EACF;AACA,EAAA,IAAI,QAAQ,IAAA,EAAM;AAChB,IAAA,KAAA,CAAM,kBAAA,CAAmB,QAAQ,IAAI,CAAA;AAAA,EACvC;AACF;AAEO,SAAS,2BAA2B,QAAA,EAAmC;AAC5E,EAAA,IAAI,CAAC,QAAA,CAAS,OAAA,EAAS,GAAA,EAAK;AAC1B,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,QAAA,CAAS,QAAQ,GAAA,CAAI,2BAA2B,KAAK,QAAA,CAAS,OAAA,CAAQ,IAAI,MAAM,CAAA;AACzF;AAMO,SAAS,8BAAA,CACd,KACA,GAAA,EACQ;AACR,EAAA,IAAI,CAAC,GAAA,EAAK;AACR,IAAA,OAAO,GAAA;AAAA,EACT;AACA,EAAA,IAAI;AACF,IAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,GAAG,CAAA;AAC1B,IAAA,MAAA,CAAO,YAAA,CAAa,GAAA,CAAI,KAAA,EAAO,GAAG,CAAA;AAClC,IAAA,OAAO,OAAO,QAAA,EAAS;AAAA,EACzB,CAAA,CAAA,MAAQ;AACN,IAAA,MAAM,SAAA,GAAY,GAAA,CAAI,QAAA,CAAS,GAAG,IAAI,GAAA,GAAM,GAAA;AAC5C,IAAA,OAAO,GAAG,GAAG,CAAA,EAAG,SAAS,CAAA,IAAA,EAAO,kBAAA,CAAmB,GAAG,CAAC,CAAA,CAAA;AAAA,EACzD;AACF;;;AC9FA,IAAM,gBAAA,GAAmB,+BAAA;AACzB,IAAM,mBAAA,GAAsB,YAAA;AAC5B,IAAM,uBAAA,GAA0B,GAAA;AAChC,IAAM,wBAAA,GAA2B,IAAI,EAAA,GAAK,GAAA;AAC1C,IAAM,yBAAA,GAA4B,KAAK,EAAA,GAAK,GAAA;AAE5C,IAAM,eAAN,MAAmB;AAAA,EACT,QAAgB,EAAC;AAAA,EAEzB,QAAQ,IAAA,EAAkB;AACxB,IAAA,IAAA,CAAK,KAAA,CAAM,KAAK,IAAI,CAAA;AAAA,EACtB;AAAA,EAEA,MAAM,uBAAA,CACJ,OAAA,EACA,YAAA,EACsC;AACtC,IAAA,IAAI,IAAA,GAAoC,MAAA;AACxC,IAAA,KAAA,MAAW,IAAA,IAAQ,KAAK,KAAA,EAAO;AAC7B,MAAA,IAAI,KAAK,gBAAA,EAAkB;AACzB,QAAA,IAAA,GAAQ,MAAM,IAAA,CAAK,gBAAA,CAAiB,OAAA,EAAS,YAAY,CAAA,IAAM,IAAA;AAAA,MACjE;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,sBAAA,CACJ,OAAA,EACA,IAAA,EACA,MAAA,EACe;AACf,IAAA,KAAA,MAAW,IAAA,IAAQ,KAAK,KAAA,EAAO;AAC7B,MAAA,IAAI,KAAK,eAAA,EAAiB;AACxB,QAAA,MAAM,IAAA,CAAK,eAAA,CAAgB,OAAA,EAAS,IAAA,EAAM,MAAM,CAAA;AAAA,MAClD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,sBAAsB,QAAA,EAAoC;AAC9D,IAAA,IAAI,IAAA,GAAgB,MAAA;AACpB,IAAA,KAAA,MAAW,IAAA,IAAQ,KAAK,KAAA,EAAO;AAC7B,MAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,QAAA,IAAA,GAAQ,MAAM,IAAA,CAAK,cAAA,CAAe,QAAQ,CAAA,IAAM,IAAA;AAAA,MAClD;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,MAAM,oBAAA,CAAqB,QAAA,EAAkB,IAAA,EAA8B;AACzE,IAAA,KAAA,MAAW,IAAA,IAAQ,KAAK,KAAA,EAAO;AAC7B,MAAA,IAAI,KAAK,aAAA,EAAe;AACtB,QAAA,MAAM,IAAA,CAAK,aAAA,CAAc,QAAA,EAAU,IAAa,CAAA;AAAA,MAClD;AAAA,IACF;AAAA,EACF;AAAA,EAEA,MAAM,oBAAoB,KAAA,EAA4C;AACpE,IAAA,KAAA,MAAW,IAAA,IAAQ,KAAK,KAAA,EAAO;AAC7B,MAAA,IAAI,KAAK,YAAA,EAAc;AACrB,QAAA,MAAM,IAAA,CAAK,aAAa,KAAK,CAAA;AAAA,MAC/B;AAAA,IACF;AAAA,EACF;AACF,CAAA;AAIO,IAAM,uBAAN,MAA2B;AAAA,EACxB,MAAA;AAAA,EAcS,KAAA;AAAA,EACA,YAAA,GAAe,IAAI,YAAA,EAAa;AAAA,EAChC,SAAA,GAAY,IAAIC,kCAAA,EAAkB;AAAA,EAClC,SAAA;AAAA,EACA,SAAA,uBAAgB,GAAA,EAA0B;AAAA,EAEnD,WAAiC,EAAC;AAAA,EAClC,cAAA,GAAiB,KAAA;AAAA,EACjB,QAAA;AAAA,EACA,SAAmB,EAAC;AAAA,EACpB,SAAiC,EAAC;AAAA,EAClC,yBAAA,GAA2C,IAAA;AAAA,EAC3C,qBAAA,GAAuC,IAAA;AAAA,EACvC,QAAA,GAAW,KAAA;AAAA,EACX,YAAA,GAAsD,IAAA;AAAA,EACtD,oBAAA,GAA6D,IAAA;AAAA,EAC7D,EAAA,GAAuB,IAAA;AAAA,EACvB,WAAA,GAAc,KAAA;AAAA,EACd,gBAAA,GAAyD,IAAA;AAAA,EACzD,kBAAA,GAAqB,CAAA;AAAA,EACrB,mBAAA,GAAsB,CAAA;AAAA,EACtB,aAA0B,EAAC;AAAA,EAC3B,cAAA,uBAAoC,GAAA,EAAI;AAAA,EACxC,WAAA,GAAoD,IAAA;AAAA,EAE5D,YAAY,MAAA,EAA8B;AACxC,IAAA,IAAI,CAAC,OAAO,YAAA,EAAc;AACxB,MAAA,MAAM,IAAI,MAAM,yDAAyD,CAAA;AAAA,IAC3E;AAEA,IAAA,IAAA,CAAK,MAAA,GAAS;AAAA,MACZ,OAAA,EAAS,OAAO,OAAA,IAAW,gBAAA;AAAA,MAC3B,WAAA,EAAa,OAAO,WAAA,IAAe,mBAAA;AAAA,MACnC,cAAA,EAAgB,OAAO,cAAA,IAAkB,uBAAA;AAAA,MACzC,2BAAA,EACE,OAAO,2BAAA,IAA+B,wBAAA;AAAA,MACxC,gBAAA,EAAkB,OAAO,gBAAA,IAAoB,KAAA;AAAA,MAC7C,OAAA,EAAS,OAAO,OAAA,IAAW,KAAA;AAAA,MAC3B,iBAAA,EACE,MAAA,CAAO,iBAAA,IAAqB,OAAA,CAAQ,OAAO,MAAM,CAAA;AAAA,MACnD,GAAG,MAAA;AAAA,MACH,cAAc,MAAA,CAAO;AAAA,KACvB;AAEA,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAI,gBAAA,CAAiB,IAAA,CAAK,OAAO,YAAY,CAAA;AAC1D,IAAA,IAAA,CAAK,SAAA,GACH,MAAA,CAAO,KAAA,KACN,OAAO,UAAA,CAAW,KAAA,KAAU,UAAA,GACzB,UAAA,CAAW,KAAA,CAAM,IAAA,CAAK,UAAU,CAAA,GAAA,CAC/B,MAAM;AACL,MAAA,MAAM,IAAI,MAAM,8CAA8C,CAAA;AAAA,IAChE,CAAA,GAAG,CAAA;AAET,IAAA,IAAA,CAAK,QAAA,GAAW,MAAA,CAAO,QAAA,IAAYC,iBAAA,EAAW;AAC9C,IAAA,IAAA,CAAK,MAAA,GAAS,OAAO,MAAA,GAAS,CAAC,GAAG,MAAA,CAAO,MAAM,IAAI,EAAC;AACpD,IAAA,IAAA,CAAK,MAAA,GAAS,OAAO,MAAA,GAAS,EAAE,GAAG,MAAA,CAAO,MAAA,KAAW,EAAC;AAEtD,IAAA,IAAI,OAAO,KAAA,EAAO;AAChB,MAAA,KAAA,MAAW,IAAA,IAAQ,OAAO,KAAA,EAAO;AAC/B,QAAA,IAAA,CAAK,YAAA,CAAa,QAAQ,IAAI,CAAA;AAAA,MAChC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,QAAQ,IAAA,EAAkB;AACxB,IAAA,IAAA,CAAK,YAAA,CAAa,QAAQ,IAAI,CAAA;AAAA,EAChC;AAAA,EAEA,eAAe,QAAA,EAA4C;AACzD,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;AAAA,EAEQ,kBAAA,GAA2B;AACjC,IAAA,MAAM,QAAA,GAAW,KAAK,eAAA,EAAgB;AACtC,IAAA,KAAA,MAAW,QAAA,IAAY,KAAK,SAAA,EAAW;AACrC,MAAA,IAAI;AACF,QAAA,QAAA,CAAS,QAAQ,CAAA;AAAA,MACnB,SAAS,KAAA,EAAO;AACd,QAAA,IAAA,CAAK,WAAA,CAAY,gCAAgC,KAAK,CAAA;AAAA,MACxD;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,WAAA,CAAY,SAAiB,KAAA,EAAuB;AAC1D,IAAA,IAAA,CAAK,MAAA,CAAO,OAAA,GAAU,OAAA,EAAS,KAAK,CAAA;AACpC,IAAA,IAAI,IAAA,CAAK,OAAO,OAAA,EAAS;AACvB,MAAA,OAAA,CAAQ,IAAA,CAAK,CAAA,SAAA,EAAY,OAAO,CAAA,CAAA,EAAI,KAAK,CAAA;AAAA,IAC3C;AAAA,EACF;AAAA,EAEA,IAAY,eAAA,GAA0B;AACpC,IAAA,MAAM,SAAS,IAAA,CAAK,MAAA;AACpB,IAAA,OAAO,CAAA,GAAA,EAAM,kBAAA;AAAA,MACX,KAAK,SAAA,CAAU;AAAA,QACb,KAAK,QAAA,IAAY,EAAA;AAAA,QACjB,CAAC,GAAG,IAAA,CAAK,MAAM,CAAA,CAAE,IAAA,CAAK,CAAC,CAAA,EAAG,CAAA,KAAM,CAAA,CAAE,aAAA,CAAc,CAAC,CAAC,CAAA;AAAA,QAClD,MAAA,CAAO,OAAA,CAAQ,MAAM,CAAA,CAAE,KAAK,CAAC,CAAC,CAAC,CAAA,EAAG,CAAC,CAAC,CAAA,KAAM,CAAA,CAAE,aAAA,CAAc,CAAC,CAAC;AAAA,OAC7D;AAAA,KACF,CAAA,CAAA;AAAA,EACH;AAAA,EAEQ,eAAA,GAAwC;AAC9C,IAAA,OAAOC,qCAAA,CAAqB,KAAK,QAAQ,CAAA;AAAA,EAC3C;AAAA,EAEQ,gBAAA,GAAyC;AAC/C,IAAA,IAAI,KAAK,cAAA,EAAgB;AACvB,MAAA,OAAO,IAAA,CAAK,QAAA;AAAA,IACd;AACA,IAAA,MAAM,QAAA,GAAW,IAAA,CAAK,MAAA,CAAO,YAAA,IAAgB,EAAC;AAC9C,IAAA,OAAO,EAAE,GAAG,QAAA,EAAS;AAAA,EACvB;AAAA,EAEQ,iBAAA,GAA4B;AAClC,IAAA,MAAM,OAAO,IAAA,CAAK,MAAA,CAAO,OAAA,CAAQ,OAAA,CAAQ,OAAO,EAAE,CAAA;AAClD,IAAA,MAAM,MAAM,IAAI,GAAA;AAAA,MACd,CAAA,EAAG,IAAI,CAAA,kBAAA,EAAqB,IAAA,CAAK,OAAO,MAAM,CAAA,CAAA,EAAI,IAAA,CAAK,MAAA,CAAO,WAAW,CAAA;AAAA,KAC3E;AACA,IAAAC,wCAAA;AAAA,MACE,GAAA;AAAA,MACA;AAAA,QACE,UAAU,IAAA,CAAK,QAAA;AAAA,QACf,QAAQ,IAAA,CAAK,MAAA;AAAA,QACb,QAAQ,IAAA,CAAK;AAAA,OACf;AAAA,MACA;AAAA,KACF;AACA,IAAA,OAAO,IAAI,QAAA,EAAS;AAAA,EACtB;AAAA,EAEQ,iBAAA,CAAkB,kBAAkB,KAAA,EAA+B;AACzE,IAAA,MAAM,QAAA,GAAW,eAAA,GAAkB,IAAA,GAAO,IAAA,CAAK,yBAAA;AAC/C,IAAA,OAAO,2BAAA;AAAA,MACL,QAAA,GAAW,EAAE,eAAA,EAAiB,QAAA,EAAU,QAAQ,kBAAA,EAAmB,GAAI,EAAE,MAAA,EAAQ,kBAAA;AAAmB,KACtG;AAAA,EACF;AAAA,EAEQ,cAAc,QAAA,EAA0B;AAC9C,IAAA,MAAM,QAAA,GAAW,2BAA2B,QAAQ,CAAA;AACpD,IAAA,IAAI,QAAA,EAAU;AACZ,MAAA,IAAA,CAAK,yBAAA,GAA4B,QAAA,CAAS,OAAA,CAAQ,UAAA,EAAY,EAAE,CAAA;AAAA,IAClE;AAAA,EACF;AAAA,EAEA,MAAc,YAAA,GAA8B;AAC1C,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,CAAO,MAAA,EAAQ;AACvB,MAAA;AAAA,IACF;AACA,IAAA,IAAI;AACF,MAAA,MAAM,KAAK,KAAA,CAAM,KAAA;AAAA,QACf,KAAK,MAAA,CAAO,MAAA;AAAA,QACZ,KAAK,MAAA,CAAO,WAAA;AAAA,QACZ,IAAA,CAAK,eAAA;AAAA,QACL;AAAA,UACE,OAAO,IAAA,CAAK,QAAA;AAAA,UACZ,UAAU,IAAA,CAAK,yBAAA;AAAA,UACf,SAAA,EAAW,KAAK,GAAA;AAAI;AACtB,OACF;AAAA,IACF,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,WAAA,CAAY,8BAA8B,KAAK,CAAA;AAAA,IACtD;AAAA,EACF;AAAA,EAEA,MAAc,aAAA,GAAkC;AAC9C,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,CAAO,MAAA,EAAQ;AACvB,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,IAAI;AACF,MAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,KAAA,CAAM,IAAA;AAAA,QAC7B,KAAK,MAAA,CAAO,MAAA;AAAA,QACZ,KAAK,MAAA,CAAO,WAAA;AAAA,QACZ,IAAA,CAAK;AAAA,OACP;AACA,MAAA,IAAI,CAAC,KAAA,EAAO;AACV,QAAA,OAAO,KAAA;AAAA,MACT;AACA,MAAA,IAAA,CAAK,WAAW,KAAA,CAAM,KAAA;AACtB,MAAA,IAAA,CAAK,4BAA4B,KAAA,CAAM,QAAA;AACvC,MAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AACtB,MAAA,OAAO,IAAA;AAAA,IACT,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,WAAA,CAAY,6BAA6B,KAAK,CAAA;AACnD,MAAA,OAAO,KAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,oBAAA,CACN,KACA,aAAA,EACS;AACT,IAAA,MAAM,QAAA,GAAWC,2CAAA;AAAA,MACf,IAAA,CAAK,SAAS,GAAG,CAAA;AAAA,MACjB,aAAA;AAAA,MACA,IAAA,CAAK,MAAA,CAAO,YAAA,GAAe,GAAG,CAAA,IAAK;AAAA,KACrC;AACA,IAAA,OAAOC,gCAAe,QAAA,EAAU,GAAA,EAAK,IAAA,CAAK,UAAA,EAAY,KAAK,cAAc,CAAA;AAAA,EAC3E;AAAA,EAEA,WAAA,CACE,GAAA,EACA,aAAA,EACA,IAAA,EACS;AACT,IAAA,MAAM,GAAA,GAAMC,uCAAA,CAAuB,aAAA,EAAe,IAAI,CAAA;AACtD,IAAA,KAAK,IAAA,CAAK,mBAAmB,GAAA,EAAK,MAAM,KAAK,oBAAA,CAAqB,GAAA,EAAK,GAAG,CAAC,CAAA;AAC3E,IAAA,OAAO,IAAA,CAAK,oBAAA,CAAqB,GAAA,EAAK,GAAG,CAAA;AAAA,EAC3C;AAAA,EAEA,YAAA,CACE,GAAA,EACA,aAAA,EACA,IAAA,EACS;AACT,IAAA,OAAO,CAAC,IAAA,CAAK,WAAA,CAAY,GAAA,EAAK,eAAe,IAAI,CAAA;AAAA,EACnD;AAAA,EAEA,oBACE,IAAA,EACA,WAAA,GAA2C,OAC3C,MAAA,GAAS,KAAA,EACT,eACA,IAAA,EACS;AACT,IAAA,MAAM,GAAA,GAAMA,uCAAA,CAAuB,aAAA,EAAe,IAAI,CAAA;AACtD,IAAA,MAAM,GAAA,GAAM,WAAA,KAAgB,KAAA,GAAQ,KAAA,GAAQ,KAAA;AAC5C,IAAA,IAAI,IAAA,CAAK,WAAW,CAAA,EAAG;AACrB,MAAA,OAAO,CAAC,MAAA;AAAA,IACV;AAEA,IAAA,IAAI,OAAO,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA,CAAE,WAAW,CAAA,EAAG;AAC3C,MAAA,MAAM,MAAA,GAAS,MAAA;AACf,MAAA,KAAK,KAAK,kBAAA,CAAmB,IAAA,CAAK,CAAC,CAAA,EAAG,MAAM,MAAM,CAAA;AAClD,MAAA,OAAO,MAAA;AAAA,IACT;AACA,IAAA,MAAM,YAAY,CAAC,GAAA,KAAgB,IAAA,CAAK,oBAAA,CAAqB,KAAK,GAAG,CAAA;AACrE,IAAA,IAAI,KAAA;AACJ,IAAA,IAAI,QAAQ,KAAA,EAAO;AACjB,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,IAAA,CAAK,SAAS,CAAA;AACjC,MAAA,KAAA,GAAQ,MAAA,GAAS,CAAC,KAAA,GAAQ,KAAA;AAAA,IAC5B,CAAA,MAAO;AACL,MAAA,MAAM,KAAA,GAAQ,IAAA,CAAK,KAAA,CAAM,SAAS,CAAA;AAClC,MAAA,KAAA,GAAQ,MAAA,GAAS,CAAC,KAAA,GAAQ,KAAA;AAAA,IAC5B;AAEA,IAAA,IAAI,IAAA,CAAK,UAAA,CAAW,MAAA,KAAW,CAAA,EAAG;AAChC,MAAA,KAAA,GAAQC,uCAAsB,IAAA,CAAK,QAAA,EAAU,IAAA,EAAM,GAAA,EAAK,QAAQ,GAAG,CAAA;AAAA,IACrE;AACA,IAAA,KAAK,KAAK,kBAAA,CAAmB,IAAA,CAAK,CAAC,CAAA,EAAG,MAAM,KAAK,CAAA;AACjD,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEA,MAAc,kBAAA,CACZ,OAAA,EACA,QAAA,EACe;AACf,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,GAAO,MAAM,IAAA,CAAK,YAAA,CAAa,wBAAwB,OAAO,CAAA;AACpE,MAAA,MAAM,SAAS,QAAA,EAAS;AACxB,MAAA,MAAM,IAAA,CAAK,YAAA,CAAa,sBAAA,CAAuB,OAAA,EAAS,MAAM,MAAM,CAAA;AAAA,IACtE,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,WAAA,CAAY,wBAAwB,KAAK,CAAA;AAAA,IAChD;AAAA,EACF;AAAA,EAEA,QAAA,GAAiC;AAC/B,IAAA,OAAO,KAAK,eAAA,EAAgB;AAAA,EAC9B;AAAA,EAEA,cAAc,KAAA,EAA0B;AACtC,IAAA,IAAA,CAAK,UAAA,GAAa,CAAC,GAAG,KAAK,CAAA;AAC3B,IAAA,IAAA,CAAK,cAAA,GAAiBC,mCAAA,CAAmB,IAAA,CAAK,UAAU,CAAA;AAAA,EAC1D;AAAA,EAEA,MAAM,OAAA,GAAyC;AAC7C,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,OAAO,KAAK,eAAA,EAAgB;AAAA,IAC9B;AAEA,IAAA,IAAI,CAAC,IAAA,CAAK,MAAA,CAAO,MAAA,EAAQ;AACvB,MAAA,IAAA,CAAK,WAAW,EAAE,GAAI,KAAK,MAAA,CAAO,YAAA,IAAgB,EAAC,EAAG;AACtD,MAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AACtB,MAAA,IAAA,CAAK,kBAAA,EAAmB;AACxB,MAAA,OAAO,KAAK,eAAA,EAAgB;AAAA,IAC9B;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,IAAA,CAAK,qBAAA;AACjB,MAAA,IAAA,CAAK,qBAAA,GAAwB,IAAA;AAC7B,MAAA,MAAM,GAAA,GAAM,8BAAA,CAA+B,IAAA,CAAK,iBAAA,IAAqB,GAAG,CAAA;AACxE,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,iBAAA,CAAkB,OAAA,CAAQ,GAAG,CAAC,CAAA;AAEnD,MAAA,MAAM,UAAA,GAAa,IAAI,eAAA,EAAgB;AACvC,MAAA,MAAM,SAAA,GAAY,UAAA;AAAA,QAChB,MAAM,WAAW,KAAA,EAAM;AAAA,QACvB,KAAK,MAAA,CAAO;AAAA,OACd;AAEA,MAAA,MAAM,QAAA,GAAW,MAAM,IAAA,CAAK,SAAA,CAAU,GAAA,EAAK;AAAA,QACzC,MAAA,EAAQ,KAAA;AAAA,QACR,OAAA;AAAA,QACA,QAAQ,UAAA,CAAW;AAAA,OACpB,CAAA;AACD,MAAA,YAAA,CAAa,SAAS,CAAA;AAEtB,MAAA,IAAI,QAAA,CAAS,WAAW,GAAA,EAAK;AAC3B,QAAA,IAAA,CAAK,cAAc,QAAQ,CAAA;AAC3B,QAAA,MAAM,KAAK,YAAA,EAAa;AACxB,QAAA,OAAO,KAAK,eAAA,EAAgB;AAAA,MAC9B;AAEA,MAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,QAAA,MAAM,IAAI,MAAM,CAAA,KAAA,EAAQ,QAAA,CAAS,MAAM,CAAA,CAAA,EAAI,QAAA,CAAS,UAAU,CAAA,CAAE,CAAA;AAAA,MAClE;AAEA,MAAA,MAAM,QAAA,GAAW,MAAMC,iCAAA,CAAiB,QAAQ,CAAA;AAChD,MAAA,MAAM,MAAA,GAAS,MAAMC,2CAAA,CAA2B,QAAA,EAAU;AAAA,QACxD,gBAAA,EAAkB,KAAK,MAAA,CAAO,gBAAA;AAAA,QAC9B,OAAA,EAAS,KAAK,MAAA,CAAO,OAAA;AAAA,QACrB,aAAA,EAAe,KAAK,MAAA,CAAO,aAAA;AAAA,QAC3B,sBAAA,EAAwB,IAAA,CAAK,MAAA,CAAO,sBAAA,IAA0B,KAAA,CAAA;AAAA,QAC9D,OAAA;AAAA,QACA,WAAW,IAAA,CAAK,SAAA;AAAA,QAChB,SAAS,IAAA,CAAK,MAAA,CAAO,mBACjB,MACE,IAAA,CAAK,UAAU,GAAA,CAAI;AAAA,UACjB,gBAAA,EAAkB,IAAA;AAAA,UAClB,OAAA,EAAS,KAAK,MAAA,CAAO,OAAA;AAAA,UACrB,aAAA,EAAe,KAAK,MAAA,CAAO,aAAA;AAAA,UAC3B,sBAAA,EACE,IAAA,CAAK,MAAA,CAAO,sBAAA,IAA0B,KAAA,CAAA;AAAA,UACxC,OAAA;AAAA,UACA,WAAW,IAAA,CAAK;AAAA,SACjB,CAAA,GACH,KAAA;AAAA,OACL,CAAA;AAED,MAAA,MAAM,IAAA,GAAA,CACJ,KAAK,MAAA,CAAO,gBAAA,GACP,SACAC,kCAAA,CAAkB,MAAM,MAC1B,EAAC;AAEN,MAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAChB,MAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AACtB,MAAA,IAAA,CAAK,cAAc,QAAQ,CAAA;AAC3B,MAAA,MAAM,KAAK,YAAA,EAAa;AACxB,MAAA,MAAM,IAAA,CAAK,YAAA,CAAa,mBAAA,CAAoB,IAAA,CAAK,iBAAiB,CAAA;AAClE,MAAA,IAAA,CAAK,kBAAA,EAAmB;AACxB,MAAA,OAAO,KAAK,eAAA,EAAgB;AAAA,IAC9B,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,WAAA,CAAY,mCAAmC,KAAK,CAAA;AACzD,MAAA,IAAI,CAAC,KAAK,cAAA,EAAgB;AACxB,QAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,aAAA,EAAc;AACxC,QAAA,IAAI,CAAC,MAAA,EAAQ;AACX,UAAA,IAAA,CAAK,QAAA,GAAW,KAAK,gBAAA,EAAiB;AACtC,UAAA,IAAA,CAAK,cAAA,GAAiB,IAAA;AAAA,QACxB;AAAA,MACF;AACA,MAAA,IAAA,CAAK,kBAAA,EAAmB;AACxB,MAAA,OAAO,KAAK,eAAA,EAAgB;AAAA,IAC9B;AAAA,EACF;AAAA,EAEA,MAAM,IAAA,GAAsC;AAC1C,IAAA,IAAI,KAAK,WAAA,EAAa;AACpB,MAAA,OAAO,IAAA,CAAK,WAAA;AAAA,IACd;AACA,IAAA,IAAA,CAAK,WAAA,GAAc,KAAK,MAAA,EAAO;AAC/B,IAAA,OAAO,IAAA,CAAK,WAAA;AAAA,EACd;AAAA,EAEA,MAAc,MAAA,GAAwC;AACpD,IAAA,MAAM,KAAK,aAAA,EAAc;AACzB,IAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,CAAK,OAAA,EAAQ;AACjC,IAAA,IAAA,CAAK,oBAAA,EAAqB;AAC1B,IAAA,IAAI,IAAA,CAAK,MAAA,CAAO,iBAAA,IAAqB,IAAA,CAAK,OAAO,MAAA,EAAQ;AACvD,MAAA,IAAA,CAAK,cAAA,EAAe;AAAA,IACtB;AACA,IAAA,OAAO,KAAA;AAAA,EACT;AAAA,EAEA,MAAM,WAAW,KAAA,EAAuD;AACtE,IAAA,IAAI,KAAA,CAAM,aAAa,MAAA,EAAW;AAChC,MAAA,MAAM,OAAO,MAAM,IAAA,CAAK,YAAA,CAAa,qBAAA,CAAsB,MAAM,QAAQ,CAAA;AACzE,MAAA,IAAA,CAAK,WAAW,KAAA,CAAM,QAAA;AACtB,MAAA,MAAM,IAAA,CAAK,YAAA,CAAa,oBAAA,CAAqB,KAAA,CAAM,UAAU,IAAI,CAAA;AAAA,IACnE;AACA,IAAA,IAAI,KAAA,CAAM,WAAW,MAAA,EAAW;AAC9B,MAAA,IAAA,CAAK,MAAA,GAAS,CAAC,GAAG,KAAA,CAAM,MAAM,CAAA;AAAA,IAChC;AACA,IAAA,IAAI,KAAA,CAAM,WAAW,MAAA,EAAW;AAC9B,MAAA,IAAA,CAAK,MAAA,GAAS,EAAE,GAAG,KAAA,CAAM,MAAA,EAAO;AAAA,IAClC;AACA,IAAA,IAAA,CAAK,cAAA,GAAiB,KAAA;AACtB,IAAA,IAAA,CAAK,yBAAA,GAA4B,IAAA;AACjC,IAAA,OAAO,KAAK,OAAA,EAAQ;AAAA,EACtB;AAAA,EAEA,MAAM,YAAA,GAA8C;AAClD,IAAA,IAAA,CAAK,WAAWV,iBAAA,EAAW;AAC3B,IAAA,IAAA,CAAK,SAAS,EAAC;AACf,IAAA,IAAA,CAAK,SAAS,EAAC;AACf,IAAA,IAAA,CAAK,cAAA,GAAiB,KAAA;AACtB,IAAA,IAAA,CAAK,yBAAA,GAA4B,IAAA;AACjC,IAAA,OAAO,KAAK,OAAA,EAAQ;AAAA,EACtB;AAAA,EAEQ,oBAAA,GAA6B;AACnC,IAAA,IAAA,CAAK,mBAAA,EAAoB;AACzB,IAAA,MAAM,WAAW,MACf,IAAA,CAAK,WAAA,GACD,yBAAA,GACA,KAAK,MAAA,CAAO,2BAAA;AAElB,IAAA,IAAA,CAAK,YAAA,GAAe,YAAY,MAAM;AACpC,MAAA,IAAI,KAAK,WAAA,EAAa;AACpB,QAAA,MAAM,OAAA,GAAU,IAAA,CAAK,GAAA,EAAI,GAAI,IAAA,CAAK,mBAAA;AAClC,QAAA,IAAI,UAAU,yBAAA,EAA2B;AACvC,UAAA;AAAA,QACF;AAAA,MACF;AACA,MAAA,IAAA,CAAK,mBAAA,GAAsB,KAAK,GAAA,EAAI;AACpC,MAAA,KAAK,KAAK,OAAA,EAAQ;AAAA,IACpB,CAAA,EAAG,KAAK,GAAA,CAAI,QAAA,IAAY,IAAA,CAAK,MAAA,CAAO,2BAA2B,CAAC,CAAA;AAAA,EAClE;AAAA,EAEQ,mBAAA,GAA4B;AAClC,IAAA,IAAI,KAAK,YAAA,EAAc;AACrB,MAAA,aAAA,CAAc,KAAK,YAAY,CAAA;AAC/B,MAAA,IAAA,CAAK,YAAA,GAAe,IAAA;AAAA,IACtB;AAAA,EACF;AAAA,EAEQ,wBAAA,CAAyB,mBAAmB,KAAA,EAAa;AAC/D,IAAA,IAAI,KAAK,oBAAA,EAAsB;AAC7B,MAAA,YAAA,CAAa,KAAK,oBAAoB,CAAA;AAAA,IACxC;AACA,IAAA,IAAA,CAAK,oBAAA,GAAuB,WAAW,MAAM;AAC3C,MAAA,IAAA,CAAK,oBAAA,GAAuB,IAAA;AAC5B,MAAA,IAAI,gBAAA,IAAoB,IAAA,CAAK,MAAA,CAAO,gBAAA,EAAkB;AACpD,QAAA,IAAA,CAAK,yBAAA,GAA4B,IAAA;AACjC,QAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AAAA,MACvB;AACA,MAAA,KAAK,KAAK,OAAA,EAAQ;AAAA,IACpB,GAAG,mBAAmB,CAAA;AAAA,EACxB;AAAA,EAEQ,gBAAgB,GAAA,EAA8B;AACpD,IAAA,IAAI;AACF,MAAA,MAAM,OAAA,GAAU,IAAA,CAAK,KAAA,CAAM,MAAA,CAAO,GAAG,CAAC,CAAA;AACtC,MAAA,IAAI,OAAA,CAAQ,SAAS,MAAA,EAAQ;AAC3B,QAAA;AAAA,MACF;AACA,MAAA,IAAI,iBAAA,CAAkB,OAAA,EAAS,IAAA,CAAK,yBAAyB,CAAA,EAAG;AAC9D,QAAA,IAAA,CAAK,wBAAA,EAAyB;AAC9B,QAAA;AAAA,MACF;AACA,MAAA,IAAI,OAAA,CAAQ,IAAA,KAAS,MAAA,IAAU,OAAA,CAAQ,IAAA,EAAM;AAC3C,QAAA,IAAA,CAAK,4BAA4B,OAAA,CAAQ,IAAA;AACzC,QAAA;AAAA,MACF;AACA,MAAA,MAAM,IAAA,GAAO,uBAAA,CAAwB,OAAA,EAAS,IAAA,CAAK,yBAAyB,CAAA;AAC5E,MAAA,qBAAA,CAAsB,MAAM,OAAA,EAAS;AAAA,QACnC,WAAA,EAAa,MAAM,IAAA,CAAK,wBAAA,CAAyB,IAAI,CAAA;AAAA,QACrD,aAAA,EAAe,CAAC,GAAA,KAAQ;AACtB,UAAA,IAAA,CAAK,qBAAA,GAAwB,GAAA;AAC7B,UAAA,IAAA,CAAK,yBAAA,GAA4B,IAAA;AACjC,UAAA,IAAA,CAAK,wBAAA,EAAyB;AAAA,QAChC,CAAA;AAAA,QACA,kBAAA,EAAoB,CAAC,IAAA,KAAS;AAC5B,UAAA,IAAA,CAAK,yBAAA,GAA4B,IAAA;AAAA,QACnC;AAAA,OACD,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,WAAA,CAAY,qCAAqC,KAAK,CAAA;AAAA,IAC7D;AAAA,EACF;AAAA,EAEA,cAAA,GAAuB;AACrB,IAAA,IAAI,IAAA,CAAK,YAAY,CAAC,IAAA,CAAK,OAAO,MAAA,IAAU,CAAC,IAAA,CAAK,MAAA,CAAO,iBAAA,EAAmB;AAC1E,MAAA;AAAA,IACF;AACA,IAAA,IAAA,CAAK,cAAc,KAAK,CAAA;AAExB,IAAA,MAAM,GAAA,GAAM,iBAAA;AAAA,MACV,KAAK,MAAA,CAAO,OAAA;AAAA,MACZ,KAAK,MAAA,CAAO,MAAA;AAAA,MACZ,IAAA,CAAK;AAAA,KACP;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,EAAA,GAAK,IAAIW,0BAAA,CAAU,GAAG,CAAA;AAC5B,MAAA,IAAA,CAAK,EAAA,GAAK,EAAA;AAEV,MAAA,EAAA,CAAG,EAAA,CAAG,QAAQ,MAAM;AAClB,QAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AACnB,QAAA,IAAA,CAAK,kBAAA,GAAqB,CAAA;AAC1B,QAAA,IAAA,CAAK,mBAAA,GAAsB,KAAK,GAAA,EAAI;AACpC,QAAA,IAAI,IAAA,CAAK,OAAO,OAAA,EAAS;AACvB,UAAA,OAAA,CAAQ,IAAI,8BAA8B,CAAA;AAAA,QAC5C;AAAA,MACF,CAAC,CAAA;AAED,MAAA,EAAA,CAAG,GAAG,SAAA,EAAW,CAAC,SAAS,IAAA,CAAK,eAAA,CAAgB,IAAI,CAAC,CAAA;AAErD,MAAA,EAAA,CAAG,EAAA,CAAG,SAAS,MAAM;AACnB,QAAA,IAAA,CAAK,WAAA,GAAc,KAAA;AACnB,QAAA,IAAA,CAAK,EAAA,GAAK,IAAA;AACV,QAAA,IAAA,CAAK,iBAAA,EAAkB;AAAA,MACzB,CAAC,CAAA;AAED,MAAA,EAAA,CAAG,EAAA,CAAG,OAAA,EAAS,CAAC,KAAA,KAAU;AACxB,QAAA,IAAA,CAAK,WAAA,CAAY,mBAAmB,KAAK,CAAA;AAAA,MAC3C,CAAC,CAAA;AAAA,IACH,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,WAAA,CAAY,6BAA6B,KAAK,CAAA;AACnD,MAAA,IAAA,CAAK,iBAAA,EAAkB;AAAA,IACzB;AAAA,EACF;AAAA,EAEQ,iBAAA,GAA0B;AAChC,IAAA,IAAI,IAAA,CAAK,QAAA,IAAY,CAAC,IAAA,CAAK,OAAO,iBAAA,EAAmB;AACnD,MAAA;AAAA,IACF;AACA,IAAA,IAAI,KAAK,gBAAA,EAAkB;AACzB,MAAA;AAAA,IACF;AACA,IAAA,MAAM,KAAA,GAAQ,uBAAA,CAAwB,IAAA,CAAK,kBAAkB,CAAA;AAC7D,IAAA,IAAA,CAAK,kBAAA,IAAsB,CAAA;AAC3B,IAAA,IAAA,CAAK,gBAAA,GAAmB,WAAW,MAAM;AACvC,MAAA,IAAA,CAAK,gBAAA,GAAmB,IAAA;AACxB,MAAA,IAAA,CAAK,cAAA,EAAe;AAAA,IACtB,GAAG,KAAK,CAAA;AAAA,EACV;AAAA,EAEA,aAAA,CAAc,iBAAiB,IAAA,EAAY;AACzC,IAAA,IAAI,IAAA,CAAK,oBAAoB,cAAA,EAAgB;AAC3C,MAAA,YAAA,CAAa,KAAK,gBAAgB,CAAA;AAClC,MAAA,IAAA,CAAK,gBAAA,GAAmB,IAAA;AAAA,IAC1B;AACA,IAAA,IAAI,KAAK,EAAA,EAAI;AACX,MAAA,IAAI;AACF,QAAA,IAAA,CAAK,GAAG,kBAAA,EAAmB;AAC3B,QAAA,IAAA,CAAK,GAAG,KAAA,EAAM;AAAA,MAChB,CAAA,CAAA,MAAQ;AAAA,MAER;AACA,MAAA,IAAA,CAAK,EAAA,GAAK,IAAA;AAAA,IACZ;AACA,IAAA,IAAA,CAAK,WAAA,GAAc,KAAA;AAAA,EACrB;AAAA,EAEA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAChB,IAAA,IAAA,CAAK,mBAAA,EAAoB;AACzB,IAAA,IAAI,KAAK,oBAAA,EAAsB;AAC7B,MAAA,YAAA,CAAa,KAAK,oBAAoB,CAAA;AACtC,MAAA,IAAA,CAAK,oBAAA,GAAuB,IAAA;AAAA,IAC9B;AACA,IAAA,IAAA,CAAK,cAAc,IAAI,CAAA;AACvB,IAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AACrB,IAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAAA,EACrB;AACF;AAEA,IAAI,SAAA,GAAyC,IAAA;AAE7C,eAAsB,WACpB,MAAA,EAC+B;AAC/B,EAAA,IAAI,SAAA,EAAW;AACb,IAAA,SAAA,CAAU,KAAA,EAAM;AAAA,EAClB;AACA,EAAA,SAAA,GAAY,IAAI,qBAAqB,MAAM,CAAA;AAC3C,EAAA,OAAO,UAAU,IAAA,EAAK;AACxB;AAEO,SAAS,SAAA,GAAyC;AACvD,EAAA,OAAO,SAAA;AACT;AAEO,SAAS,WAAA,CACd,GAAA,EACA,aAAA,EACA,IAAA,EACS;AACT,EAAA,OAAO,SAAA,EAAW,WAAA,CAAY,GAAA,EAAK,aAAA,EAAe,IAAI,CAAA,IAAK,KAAA;AAC7D;AAEO,SAAS,YAAA,CACd,GAAA,EACA,aAAA,EACA,IAAA,EACS;AACT,EAAA,OAAO,SAAA,EAAW,YAAA,CAAa,GAAA,EAAK,aAAA,EAAe,IAAI,CAAA,IAAK,IAAA;AAC9D;AAEO,SAAS,mBAAA,CACd,IAAA,EACA,WAAA,EACA,MAAA,EACA,eACA,IAAA,EACS;AACT,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,OAAO,MAAA,IAAU,KAAA;AAAA,EACnB;AACA,EAAA,OAAO,SAAA,CAAU,mBAAA;AAAA,IACf,IAAA;AAAA,IACA,WAAA;AAAA,IACA,MAAA;AAAA,IACA,aAAA;AAAA,IACA;AAAA,GACF;AACF;AAEA,eAAsB,WACpB,KAAA,EAC+B;AAC/B,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,MAAM,IAAI,MAAM,mDAAmD,CAAA;AAAA,EACrE;AACA,EAAA,OAAO,SAAA,CAAU,WAAW,KAAK,CAAA;AACnC;AAEA,eAAsB,YAAA,GAA8C;AAClE,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,MAAM,IAAI,MAAM,mDAAmD,CAAA;AAAA,EACrE;AACA,EAAA,OAAO,UAAU,YAAA,EAAa;AAChC;AAEO,SAAS,QAAQ,IAAA,EAAkB;AACxC,EAAA,SAAA,EAAW,QAAQ,IAAI,CAAA;AACzB;AAEO,SAAS,WAAA,GAAoB;AAClC,EAAA,SAAA,EAAW,KAAA,EAAM;AACjB,EAAA,SAAA,GAAY,IAAA;AACd;AAGO,SAAS,qBAAA,GAA8B;AAC5C,EAAA,SAAA,EAAW,KAAA,EAAM;AACjB,EAAA,SAAA,GAAY,IAAA;AACd;;;ACxwBO,IAAM,UAAA,GAAa;AAEnB,IAAM,YAAA,GAAe;AAAA,EAC1B,WAAA,EAAa,GAAG,UAAU,CAAA,WAAA,CAAA;AAAA,EAC1B,YAAA,EAAc,GAAG,UAAU,CAAA,YAAA,CAAA;AAAA,EAC3B,mBAAA,EAAqB,GAAG,UAAU,CAAA,mBAAA,CAAA;AAAA,EAClC,QAAA,EAAU,GAAG,UAAU,CAAA,QAAA,CAAA;AAAA,EACvB,UAAA,EAAY,GAAG,UAAU,CAAA,UAAA,CAAA;AAAA,EACzB,YAAA,EAAc,GAAG,UAAU,CAAA,YAAA,CAAA;AAAA,EAC3B,YAAA,EAAc,GAAG,UAAU,CAAA,aAAA;AAC7B;;;AC6BO,SAAS,iBAAA,CACd,OAAA,EACA,UAAA,GAA6D,MAAM,EAAC,EACxD;AACZ,EAAA,MAAM,SAAS,SAAA,EAAU;AACzB,EAAA,IAAI,CAAC,MAAA,EAAQ;AACX,IAAA,MAAM,IAAI,MAAM,sEAAsE,CAAA;AAAA,EACxF;AAEA,EAAA,OAAA,CAAQ,GAAG,YAAA,CAAa,WAAA,EAAa,CAAC,KAAA,EAAO,GAAA,EAAK,eAAe,IAAA,KAAS;AACxE,IAAA,KAAA,CAAM,WAAA,GAAc,WAAA;AAAA,MAClB,OAAO,GAAG,CAAA;AAAA,MACV,aAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAA,CAAQ,GAAG,YAAA,CAAa,YAAA,EAAc,CAAC,KAAA,EAAO,GAAA,EAAK,eAAe,IAAA,KAAS;AACzE,IAAA,KAAA,CAAM,WAAA,GAAc,YAAA;AAAA,MAClB,OAAO,GAAG,CAAA;AAAA,MACV,aAAA;AAAA,MACA;AAAA,KACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAA,CAAQ,EAAA;AAAA,IACN,YAAA,CAAa,mBAAA;AAAA,IACb,CAAC,KAAA,EAAO,IAAA,EAAM,WAAA,EAAa,MAAA,EAAQ,eAAe,IAAA,KAAS;AACzD,MAAA,KAAA,CAAM,WAAA,GAAc,mBAAA;AAAA,QACjB,QAAqB,EAAC;AAAA,QACvB,WAAA;AAAA,QACA,QAAQ,MAAM,CAAA;AAAA,QACd,aAAA;AAAA,QACA;AAAA,OACF;AAAA,IACF;AAAA,GACF;AAEA,EAAA,OAAA,CAAQ,MAAA,CAAO,YAAA,CAAa,QAAA,EAAU,MAAM;AAC1C,IAAA,OAAO,SAAA,EAAU,EAAG,QAAA,EAAS,IAAK,EAAC;AAAA,EACrC,CAAC,CAAA;AAED,EAAA,OAAA,CAAQ,MAAA,CAAO,YAAA,CAAa,UAAA,EAAY,CAAC,QAAQ,OAAA,KAAY;AAC3D,IAAA,OAAO,UAAA,CAAY,OAAA,IAA+B,EAAE,CAAA;AAAA,EACtD,CAAC,CAAA;AAED,EAAA,OAAA,CAAQ,MAAA,CAAO,YAAA,CAAa,YAAA,EAAc,MAAM;AAC9C,IAAA,OAAO,YAAA,EAAa;AAAA,EACtB,CAAC,CAAA;AAED,EAAA,MAAM,WAAA,GAAc,MAAA,CAAO,cAAA,CAAe,CAAC,KAAA,KAAU;AACnD,IAAA,KAAA,MAAW,GAAA,IAAO,YAAW,EAAG;AAC9B,MAAA,IAAI;AACF,QAAA,IAAI,GAAA,CAAI,eAAc,EAAG;AACvB,UAAA;AAAA,QACF;AACA,QAAA,IAAI,GAAA,CAAI,WAAA,CAAY,WAAA,IAAc,EAAG;AACnC,UAAA;AAAA,QACF;AACA,QAAA,GAAA,CAAI,WAAA,CAAY,IAAA,CAAK,YAAA,CAAa,YAAA,EAAc,KAAK,CAAA;AAAA,MACvD,CAAA,CAAA,MAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAO,MAAM;AACX,IAAA,WAAA,EAAY;AACZ,IAAA,OAAA,CAAQ,kBAAA,GAAqB,aAAa,WAAW,CAAA;AACrD,IAAA,OAAA,CAAQ,kBAAA,GAAqB,aAAa,YAAY,CAAA;AACtD,IAAA,OAAA,CAAQ,kBAAA,GAAqB,aAAa,mBAAmB,CAAA;AAC7D,IAAA,OAAA,CAAQ,aAAA,GAAgB,aAAa,QAAQ,CAAA;AAC7C,IAAA,OAAA,CAAQ,aAAA,GAAgB,aAAa,UAAU,CAAA;AAC/C,IAAA,OAAA,CAAQ,aAAA,GAAgB,aAAa,YAAY,CAAA;AAAA,EACnD,CAAA;AACF","file":"index.cjs","sourcesContent":["import { mkdir, readFile, writeFile, unlink } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport type { EvaluatedDefinitions } from '@ops-ai/toggly-hooks-types'\n\nexport interface DiskCacheEntry {\n flags: EvaluatedDefinitions\n revision: string | null\n updatedAt: number\n}\n\nfunction sanitizeSegment(value: string): string {\n return value.replace(/[^a-zA-Z0-9._-]/g, '_')\n}\n\nexport function buildCacheFilePath(\n userDataPath: string,\n appKey: string,\n environment: string,\n contextKey: string,\n): string {\n const dir = join(userDataPath, 'toggly')\n const name = `flags-${sanitizeSegment(appKey)}-${sanitizeSegment(environment)}-${sanitizeSegment(contextKey)}.json`\n return join(dir, name)\n}\n\nexport class DiskFeatureCache {\n constructor(private readonly userDataPath: string) {}\n\n private filePath(appKey: string, environment: string, contextKey: string): string {\n return buildCacheFilePath(this.userDataPath, appKey, environment, contextKey)\n }\n\n async read(\n appKey: string,\n environment: string,\n contextKey: string,\n ): Promise<DiskCacheEntry | null> {\n const path = this.filePath(appKey, environment, contextKey)\n try {\n const raw = await readFile(path, 'utf-8')\n const parsed = JSON.parse(raw) as DiskCacheEntry\n if (!parsed || typeof parsed !== 'object' || !parsed.flags || typeof parsed.flags !== 'object') {\n return null\n }\n return {\n flags: parsed.flags,\n revision: parsed.revision ?? null,\n updatedAt: typeof parsed.updatedAt === 'number' ? parsed.updatedAt : Date.now(),\n }\n } catch {\n return null\n }\n }\n\n async write(\n appKey: string,\n environment: string,\n contextKey: string,\n entry: DiskCacheEntry,\n ): Promise<void> {\n const path = this.filePath(appKey, environment, contextKey)\n await mkdir(join(this.userDataPath, 'toggly'), { recursive: true })\n await writeFile(path, JSON.stringify(entry), 'utf-8')\n }\n\n async clear(appKey: string, environment: string, contextKey: string): Promise<void> {\n const path = this.filePath(appKey, environment, contextKey)\n try {\n await unlink(path)\n } catch {\n // ignore missing file\n }\n }\n}\n","export const SDK_ID = 'electron'\nexport const SDK_VERSION = '1.0.0'\n\nexport const SDK_HEADER_ID = 'X-Toggly-Sdk'\nexport const SDK_HEADER_VERSION = 'X-Toggly-Sdk-Version'\n\nexport function sdkUserAgent(): string {\n return `toggly-${SDK_ID}/${SDK_VERSION}`\n}\n\nexport function sdkCustomHeaders(): Record<string, string> {\n return {\n [SDK_HEADER_ID]: SDK_ID,\n [SDK_HEADER_VERSION]: SDK_VERSION,\n }\n}\n\nexport function appendSdkQueryParams(params: URLSearchParams): void {\n params.set('sdk', SDK_ID)\n params.set('sdkVersion', SDK_VERSION)\n}\n\nexport function buildDefinitionFetchHeaders(\n existing: Record<string, string> = {},\n): Record<string, string> {\n return {\n ...existing,\n 'User-Agent': sdkUserAgent(),\n ...sdkCustomHeaders(),\n }\n}\n","import { appendSdkQueryParams } from './sdk-identity.js'\n\nexport const DEFINITIONS_REVISION_HEADER = 'X-Definitions-Revision'\n\nexport const WS_RECONNECT_BASE_MS = 5000\nexport const WS_RECONNECT_MAX_MS = 60000\nexport const REFRESH_DEBOUNCE_MS = 300\n\nexport interface WsSyncMessage {\n type: string\n etag?: string\n lastUpdated?: number\n unchanged?: boolean\n kid?: string\n}\n\nexport function buildWebSocketUrl(\n baseUri: string,\n appKey: string,\n cachedEtag: string | null,\n): string {\n const wsBase = baseUri\n .replace(/^https:\\/\\//, 'wss://')\n .replace(/^http:\\/\\//, 'ws://')\n .replace(/\\/$/, '')\n const params = new URLSearchParams()\n if (cachedEtag) {\n params.set('rev', cachedEtag)\n }\n appendSdkQueryParams(params)\n const query = params.toString()\n return `${wsBase}/${appKey}/ws${query ? `?${query}` : ''}`\n}\n\nexport function getNextReconnectDelayMs(attempt: number): number {\n return Math.min(WS_RECONNECT_BASE_MS * Math.pow(2, attempt), WS_RECONNECT_MAX_MS)\n}\n\nexport function shouldFetchOnSync(\n message: WsSyncMessage,\n cachedEtag: string | null,\n): boolean {\n if (message.type !== 'sync') {\n return false\n }\n if (message.unchanged === true) {\n return false\n }\n if (!cachedEtag) {\n return true\n }\n if (message.etag && message.etag !== cachedEtag) {\n return true\n }\n return false\n}\n\nexport function shouldFetchOnFlagsUpdated(\n message: WsSyncMessage,\n cachedEtag: string | null,\n): boolean {\n if (message.type !== 'flags-updated' && message.type !== 'update') {\n return false\n }\n if (!message.etag || !cachedEtag) {\n return true\n }\n return message.etag !== cachedEtag\n}\n\nexport function shouldFetchOnSigningKeyUpdated(message: WsSyncMessage): boolean {\n return message.type === 'signing-key-updated'\n}\n\nexport type FlagsUpdatedRefreshPlan =\n | { action: 'none' }\n | { action: 'refresh-jwks' }\n | { action: 'refresh-pinned'; pin: string | null }\n\nexport function planFlagsUpdatedRefresh(\n message: WsSyncMessage,\n previousRevision: string | null,\n): FlagsUpdatedRefreshPlan {\n if (shouldFetchOnSigningKeyUpdated(message)) {\n return { action: 'refresh-jwks' }\n }\n if (shouldFetchOnFlagsUpdated(message, previousRevision)) {\n return { action: 'refresh-pinned', pin: message.etag ?? null }\n }\n return { action: 'none' }\n}\n\nexport function applyFlagsUpdatedPlan(\n plan: FlagsUpdatedRefreshPlan,\n message: WsSyncMessage,\n hooks: {\n refreshJwks: () => void\n refreshPinned: (pin: string | null) => void\n cacheEtagIfPresent: (etag: string) => void\n },\n): void {\n if (plan.action === 'refresh-jwks') {\n hooks.refreshJwks()\n return\n }\n if (plan.action === 'refresh-pinned') {\n hooks.refreshPinned(plan.pin)\n return\n }\n if (message.etag) {\n hooks.cacheEtagIfPresent(message.etag)\n }\n}\n\nexport function extractDefinitionsRevision(response: Response): string | null {\n if (!response.headers?.get) {\n return null\n }\n return response.headers.get(DEFINITIONS_REVISION_HEADER) ?? response.headers.get('ETag')\n}\n\n/**\n * Append `?rev=` for a cache-proof definitions GET after `flags-updated`.\n * Never cache a WebSocket etag before HTTP confirms the revision.\n */\nexport function appendDefinitionsRevisionParam(\n url: string,\n rev: string | null | undefined,\n): string {\n if (!rev) {\n return url\n }\n try {\n const parsed = new URL(url)\n parsed.searchParams.set('rev', rev)\n return parsed.toString()\n } catch {\n const separator = url.includes('?') ? '&' : '?'\n return `${url}${separator}rev=${encodeURIComponent(rev)}`\n }\n}\n","import {\n appendEvaluationContext,\n evaluateEvaluatedGate,\n normalizeEntityContext,\n resolveEvaluatedDefinition,\n toBooleanDefinitions,\n type EvaluatedDefinitions,\n type Hook,\n type TogglyEntityContext,\n type EvaluationSeriesData,\n} from '@ops-ai/toggly-hooks-types'\nimport {\n InMemoryJwksCache,\n parseEvaluatedResponseBody,\n readResponseBody,\n unwrapDefsPayload,\n} from '@ops-ai/toggly-signed-defs'\nimport {\n applyLocalGate,\n buildFlagGateIndex,\n type FlagGateIndex,\n type LocalGate,\n} from '@ops-ai/toggly-local-gates'\nimport WebSocket from 'ws'\nimport { randomUUID } from 'node:crypto'\nimport { DiskFeatureCache } from './cache.js'\nimport { buildDefinitionFetchHeaders } from '../sdk-identity.js'\nimport {\n appendDefinitionsRevisionParam,\n applyFlagsUpdatedPlan,\n buildWebSocketUrl,\n extractDefinitionsRevision,\n getNextReconnectDelayMs,\n planFlagsUpdatedRefresh,\n REFRESH_DEBOUNCE_MS,\n shouldFetchOnSync,\n type WsSyncMessage,\n} from '../ws-sync.js'\nimport type {\n EntityContextInput,\n FeatureFlagsSnapshot,\n FeatureRequirement,\n SetContextInput,\n TogglyElectronConfig,\n} from '../types.js'\n\nconst DEFAULT_BASE_URI = 'https://definitions.toggly.io'\nconst DEFAULT_ENVIRONMENT = 'Production'\nconst DEFAULT_CONNECT_TIMEOUT = 5000\nconst DEFAULT_REFRESH_INTERVAL = 3 * 60 * 1000\nconst FALLBACK_REFRESH_INTERVAL = 20 * 60 * 1000\n\nclass HookExecutor {\n private hooks: Hook[] = []\n\n addHook(hook: Hook): void {\n this.hooks.push(hook)\n }\n\n async executeBeforeEvaluation(\n flagKey: string,\n defaultValue?: boolean,\n ): Promise<EvaluationSeriesData | void> {\n let data: EvaluationSeriesData | void = undefined\n for (const hook of this.hooks) {\n if (hook.beforeEvaluation) {\n data = (await hook.beforeEvaluation(flagKey, defaultValue)) ?? data\n }\n }\n return data\n }\n\n async executeAfterEvaluation(\n flagKey: string,\n data: EvaluationSeriesData | void,\n result: boolean,\n ): Promise<void> {\n for (const hook of this.hooks) {\n if (hook.afterEvaluation) {\n await hook.afterEvaluation(flagKey, data, result)\n }\n }\n }\n\n async executeBeforeIdentify(identity: string): Promise<unknown> {\n let data: unknown = undefined\n for (const hook of this.hooks) {\n if (hook.beforeIdentify) {\n data = (await hook.beforeIdentify(identity)) ?? data\n }\n }\n return data\n }\n\n async executeAfterIdentify(identity: string, data: unknown): Promise<void> {\n for (const hook of this.hooks) {\n if (hook.afterIdentify) {\n await hook.afterIdentify(identity, data as never)\n }\n }\n }\n\n async executeAfterRefresh(flags: FeatureFlagsSnapshot): Promise<void> {\n for (const hook of this.hooks) {\n if (hook.afterRefresh) {\n await hook.afterRefresh(flags)\n }\n }\n }\n}\n\nexport type FlagsUpdatedListener = (flags: FeatureFlagsSnapshot) => void\n\nexport class ElectronTogglyClient {\n private config: Required<\n Pick<\n TogglyElectronConfig,\n | 'baseURI'\n | 'environment'\n | 'connectTimeout'\n | 'featureFlagsRefreshInterval'\n | 'verifySignatures'\n | 'isDebug'\n | 'userDataPath'\n >\n > &\n TogglyElectronConfig\n\n private readonly cache: DiskFeatureCache\n private readonly hookExecutor = new HookExecutor()\n private readonly jwksCache = new InMemoryJwksCache()\n private readonly fetchImpl: typeof fetch\n private readonly listeners = new Set<FlagsUpdatedListener>()\n\n private features: EvaluatedDefinitions = {}\n private hasLoadedFlags = false\n private identity: string\n private groups: string[] = []\n private claims: Record<string, string> = {}\n private cachedDefinitionsRevision: string | null = null\n private pendingDefinitionsPin: string | null = null\n private disposed = false\n private refreshTimer: ReturnType<typeof setInterval> | null = null\n private refreshDebounceTimer: ReturnType<typeof setTimeout> | null = null\n private ws: WebSocket | null = null\n private wsConnected = false\n private wsReconnectTimer: ReturnType<typeof setTimeout> | null = null\n private wsReconnectAttempt = 0\n private lastFallbackRefresh = 0\n private localGates: LocalGate[] = []\n private localGateIndex: FlagGateIndex = new Map()\n private initPromise: Promise<FeatureFlagsSnapshot> | null = null\n\n constructor(config: TogglyElectronConfig) {\n if (!config.userDataPath) {\n throw new Error('userDataPath is required (pass app.getPath(\"userData\"))')\n }\n\n this.config = {\n baseURI: config.baseURI ?? DEFAULT_BASE_URI,\n environment: config.environment ?? DEFAULT_ENVIRONMENT,\n connectTimeout: config.connectTimeout ?? DEFAULT_CONNECT_TIMEOUT,\n featureFlagsRefreshInterval:\n config.featureFlagsRefreshInterval ?? DEFAULT_REFRESH_INTERVAL,\n verifySignatures: config.verifySignatures ?? false,\n isDebug: config.isDebug ?? false,\n enableLiveUpdates:\n config.enableLiveUpdates ?? Boolean(config.appKey),\n ...config,\n userDataPath: config.userDataPath,\n }\n\n this.cache = new DiskFeatureCache(this.config.userDataPath)\n this.fetchImpl =\n config.fetch ??\n (typeof globalThis.fetch === 'function'\n ? globalThis.fetch.bind(globalThis)\n : (() => {\n throw new Error('fetch is not available; provide config.fetch')\n })())\n\n this.identity = config.identity ?? randomUUID()\n this.groups = config.groups ? [...config.groups] : []\n this.claims = config.claims ? { ...config.claims } : {}\n\n if (config.hooks) {\n for (const hook of config.hooks) {\n this.hookExecutor.addHook(hook)\n }\n }\n }\n\n addHook(hook: Hook): void {\n this.hookExecutor.addHook(hook)\n }\n\n onFlagsUpdated(listener: FlagsUpdatedListener): () => void {\n this.listeners.add(listener)\n return () => {\n this.listeners.delete(listener)\n }\n }\n\n private notifyFlagsUpdated(): void {\n const snapshot = this.getBooleanFlags()\n for (const listener of this.listeners) {\n try {\n listener(snapshot)\n } catch (error) {\n this.reportError('Flags updated listener error', error)\n }\n }\n }\n\n private reportError(message: string, error?: unknown): void {\n this.config.onError?.(message, error)\n if (this.config.isDebug) {\n console.warn(`[Toggly] ${message}`, error)\n }\n }\n\n private get contextCacheKey(): string {\n const claims = this.claims\n return `v2:${encodeURIComponent(\n JSON.stringify([\n this.identity ?? '',\n [...this.groups].sort((a, b) => a.localeCompare(b)),\n Object.entries(claims).sort(([a], [b]) => a.localeCompare(b)),\n ]),\n )}`\n }\n\n private getBooleanFlags(): FeatureFlagsSnapshot {\n return toBooleanDefinitions(this.features)\n }\n\n private getFallbackFlags(): EvaluatedDefinitions {\n if (this.hasLoadedFlags) {\n return this.features\n }\n const defaults = this.config.flagDefaults ?? {}\n return { ...defaults }\n }\n\n private buildEvaluatedUrl(): string {\n const base = this.config.baseURI.replace(/\\/$/, '')\n const url = new URL(\n `${base}/evaluated-signed/${this.config.appKey}/${this.config.environment}`,\n )\n appendEvaluationContext(\n url,\n {\n identity: this.identity,\n groups: this.groups,\n claims: this.claims,\n },\n 'evaluated',\n )\n return url.toString()\n }\n\n private buildFetchHeaders(skipIfNoneMatch = false): Record<string, string> {\n const revision = skipIfNoneMatch ? null : this.cachedDefinitionsRevision\n return buildDefinitionFetchHeaders(\n revision ? { 'If-None-Match': revision, Accept: 'application/json' } : { Accept: 'application/json' },\n )\n }\n\n private applyRevision(response: Response): void {\n const revision = extractDefinitionsRevision(response)\n if (revision) {\n this.cachedDefinitionsRevision = revision.replace(/^\"+|\"+$/g, '')\n }\n }\n\n private async persistCache(): Promise<void> {\n if (!this.config.appKey) {\n return\n }\n try {\n await this.cache.write(\n this.config.appKey,\n this.config.environment,\n this.contextCacheKey,\n {\n flags: this.features,\n revision: this.cachedDefinitionsRevision,\n updatedAt: Date.now(),\n },\n )\n } catch (error) {\n this.reportError('Failed to write disk cache', error)\n }\n }\n\n private async loadDiskCache(): Promise<boolean> {\n if (!this.config.appKey) {\n return false\n }\n try {\n const entry = await this.cache.read(\n this.config.appKey,\n this.config.environment,\n this.contextCacheKey,\n )\n if (!entry) {\n return false\n }\n this.features = entry.flags\n this.cachedDefinitionsRevision = entry.revision\n this.hasLoadedFlags = true\n return true\n } catch (error) {\n this.reportError('Failed to read disk cache', error)\n return false\n }\n }\n\n private resolveEffectiveFlag(\n key: string,\n entityContext?: TogglyEntityContext | null,\n ): boolean {\n const resolved = resolveEvaluatedDefinition(\n this.features[key],\n entityContext,\n this.config.flagDefaults?.[key] ?? false,\n )\n return applyLocalGate(resolved, key, this.localGates, this.localGateIndex)\n }\n\n isFeatureOn(\n key: string,\n entityContext?: EntityContextInput,\n kind?: string,\n ): boolean {\n const ctx = normalizeEntityContext(entityContext, kind)\n void this.runEvaluationHooks(key, () => this.resolveEffectiveFlag(key, ctx))\n return this.resolveEffectiveFlag(key, ctx)\n }\n\n isFeatureOff(\n key: string,\n entityContext?: EntityContextInput,\n kind?: string,\n ): boolean {\n return !this.isFeatureOn(key, entityContext, kind)\n }\n\n evaluateFeatureGate(\n keys: string[],\n requirement: FeatureRequirement | string = 'all',\n negate = false,\n entityContext?: EntityContextInput,\n kind?: string,\n ): boolean {\n const ctx = normalizeEntityContext(entityContext, kind)\n const req = requirement === 'any' ? 'any' : 'all'\n if (keys.length === 0) {\n return !negate\n }\n // Empty feature map with keys → fail closed (match evaluateStoredFeatureKeys)\n if (Object.keys(this.features).length === 0) {\n const closed = negate\n void this.runEvaluationHooks(keys[0], () => closed)\n return closed\n }\n const isEnabled = (key: string) => this.resolveEffectiveFlag(key, ctx)\n let gated: boolean\n if (req === 'any') {\n const anyOn = keys.some(isEnabled)\n gated = negate ? !anyOn : anyOn\n } else {\n const allOn = keys.every(isEnabled)\n gated = negate ? !allOn : allOn\n }\n // Keep evaluateEvaluatedGate in the hot path for parity when no local gates\n if (this.localGates.length === 0) {\n gated = evaluateEvaluatedGate(this.features, keys, req, negate, ctx)\n }\n void this.runEvaluationHooks(keys[0], () => gated)\n return gated\n }\n\n private async runEvaluationHooks(\n flagKey: string,\n evaluate: () => boolean,\n ): Promise<void> {\n try {\n const data = await this.hookExecutor.executeBeforeEvaluation(flagKey)\n const result = evaluate()\n await this.hookExecutor.executeAfterEvaluation(flagKey, data, result)\n } catch (error) {\n this.reportError('Hook execution error', error)\n }\n }\n\n getFlags(): FeatureFlagsSnapshot {\n return this.getBooleanFlags()\n }\n\n setLocalGates(gates: LocalGate[]): void {\n this.localGates = [...gates]\n this.localGateIndex = buildFlagGateIndex(this.localGates)\n }\n\n async refresh(): Promise<FeatureFlagsSnapshot> {\n if (this.disposed) {\n return this.getBooleanFlags()\n }\n\n if (!this.config.appKey) {\n this.features = { ...(this.config.flagDefaults ?? {}) }\n this.hasLoadedFlags = true\n this.notifyFlagsUpdated()\n return this.getBooleanFlags()\n }\n\n try {\n const pin = this.pendingDefinitionsPin\n this.pendingDefinitionsPin = null\n const url = appendDefinitionsRevisionParam(this.buildEvaluatedUrl(), pin)\n const headers = this.buildFetchHeaders(Boolean(pin))\n\n const controller = new AbortController()\n const timeoutId = setTimeout(\n () => controller.abort(),\n this.config.connectTimeout,\n )\n\n const response = await this.fetchImpl(url, {\n method: 'GET',\n headers,\n signal: controller.signal,\n })\n clearTimeout(timeoutId)\n\n if (response.status === 304) {\n this.applyRevision(response)\n await this.persistCache()\n return this.getBooleanFlags()\n }\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status} ${response.statusText}`)\n }\n\n const bodyText = await readResponseBody(response)\n const parsed = await parseEvaluatedResponseBody(bodyText, {\n verifySignatures: this.config.verifySignatures,\n baseURI: this.config.baseURI,\n allowedKeyIds: this.config.allowedKeyIds,\n maxSignatureAgeSeconds: this.config.maxSignatureAgeSeconds ?? undefined,\n headers,\n fetchImpl: this.fetchImpl,\n getJwks: this.config.verifySignatures\n ? () =>\n this.jwksCache.get({\n verifySignatures: true,\n baseURI: this.config.baseURI,\n allowedKeyIds: this.config.allowedKeyIds,\n maxSignatureAgeSeconds:\n this.config.maxSignatureAgeSeconds ?? undefined,\n headers,\n fetchImpl: this.fetchImpl,\n })\n : undefined,\n })\n\n const defs = (\n this.config.verifySignatures\n ? (parsed as EvaluatedDefinitions)\n : (unwrapDefsPayload(parsed) as EvaluatedDefinitions)\n ) ?? {}\n\n this.features = defs\n this.hasLoadedFlags = true\n this.applyRevision(response)\n await this.persistCache()\n await this.hookExecutor.executeAfterRefresh(this.getBooleanFlags())\n this.notifyFlagsUpdated()\n return this.getBooleanFlags()\n } catch (error) {\n this.reportError('Failed to refresh feature flags', error)\n if (!this.hasLoadedFlags) {\n const loaded = await this.loadDiskCache()\n if (!loaded) {\n this.features = this.getFallbackFlags()\n this.hasLoadedFlags = true\n }\n }\n this.notifyFlagsUpdated()\n return this.getBooleanFlags()\n }\n }\n\n async init(): Promise<FeatureFlagsSnapshot> {\n if (this.initPromise) {\n return this.initPromise\n }\n this.initPromise = this.doInit()\n return this.initPromise\n }\n\n private async doInit(): Promise<FeatureFlagsSnapshot> {\n await this.loadDiskCache()\n const flags = await this.refresh()\n this.startRefreshInterval()\n if (this.config.enableLiveUpdates && this.config.appKey) {\n this.startWebSocket()\n }\n return flags\n }\n\n async setContext(input: SetContextInput): Promise<FeatureFlagsSnapshot> {\n if (input.identity !== undefined) {\n const data = await this.hookExecutor.executeBeforeIdentify(input.identity)\n this.identity = input.identity\n await this.hookExecutor.executeAfterIdentify(input.identity, data)\n }\n if (input.groups !== undefined) {\n this.groups = [...input.groups]\n }\n if (input.claims !== undefined) {\n this.claims = { ...input.claims }\n }\n this.hasLoadedFlags = false\n this.cachedDefinitionsRevision = null\n return this.refresh()\n }\n\n async clearContext(): Promise<FeatureFlagsSnapshot> {\n this.identity = randomUUID()\n this.groups = []\n this.claims = {}\n this.hasLoadedFlags = false\n this.cachedDefinitionsRevision = null\n return this.refresh()\n }\n\n private startRefreshInterval(): void {\n this.stopRefreshInterval()\n const interval = () =>\n this.wsConnected\n ? FALLBACK_REFRESH_INTERVAL\n : this.config.featureFlagsRefreshInterval\n\n this.refreshTimer = setInterval(() => {\n if (this.wsConnected) {\n const elapsed = Date.now() - this.lastFallbackRefresh\n if (elapsed < FALLBACK_REFRESH_INTERVAL) {\n return\n }\n }\n this.lastFallbackRefresh = Date.now()\n void this.refresh()\n }, Math.min(interval(), this.config.featureFlagsRefreshInterval))\n }\n\n private stopRefreshInterval(): void {\n if (this.refreshTimer) {\n clearInterval(this.refreshTimer)\n this.refreshTimer = null\n }\n }\n\n private scheduleDebouncedRefresh(forceJwksRefresh = false): void {\n if (this.refreshDebounceTimer) {\n clearTimeout(this.refreshDebounceTimer)\n }\n this.refreshDebounceTimer = setTimeout(() => {\n this.refreshDebounceTimer = null\n if (forceJwksRefresh && this.config.verifySignatures) {\n this.cachedDefinitionsRevision = null\n this.jwksCache.clear()\n }\n void this.refresh()\n }, REFRESH_DEBOUNCE_MS)\n }\n\n private handleWsMessage(raw: WebSocket.RawData): void {\n try {\n const message = JSON.parse(String(raw)) as WsSyncMessage\n if (message.type === 'ping') {\n return\n }\n if (shouldFetchOnSync(message, this.cachedDefinitionsRevision)) {\n this.scheduleDebouncedRefresh()\n return\n }\n if (message.type === 'sync' && message.etag) {\n this.cachedDefinitionsRevision = message.etag\n return\n }\n const plan = planFlagsUpdatedRefresh(message, this.cachedDefinitionsRevision)\n applyFlagsUpdatedPlan(plan, message, {\n refreshJwks: () => this.scheduleDebouncedRefresh(true),\n refreshPinned: (pin) => {\n this.pendingDefinitionsPin = pin\n this.cachedDefinitionsRevision = null\n this.scheduleDebouncedRefresh()\n },\n cacheEtagIfPresent: (etag) => {\n this.cachedDefinitionsRevision = etag\n },\n })\n } catch (error) {\n this.reportError('Failed to parse WebSocket message', error)\n }\n }\n\n startWebSocket(): void {\n if (this.disposed || !this.config.appKey || !this.config.enableLiveUpdates) {\n return\n }\n this.stopWebSocket(false)\n\n const url = buildWebSocketUrl(\n this.config.baseURI,\n this.config.appKey,\n this.cachedDefinitionsRevision,\n )\n\n try {\n const ws = new WebSocket(url)\n this.ws = ws\n\n ws.on('open', () => {\n this.wsConnected = true\n this.wsReconnectAttempt = 0\n this.lastFallbackRefresh = Date.now()\n if (this.config.isDebug) {\n console.log('[Toggly] WebSocket connected')\n }\n })\n\n ws.on('message', (data) => this.handleWsMessage(data))\n\n ws.on('close', () => {\n this.wsConnected = false\n this.ws = null\n this.scheduleReconnect()\n })\n\n ws.on('error', (error) => {\n this.reportError('WebSocket error', error)\n })\n } catch (error) {\n this.reportError('Failed to start WebSocket', error)\n this.scheduleReconnect()\n }\n }\n\n private scheduleReconnect(): void {\n if (this.disposed || !this.config.enableLiveUpdates) {\n return\n }\n if (this.wsReconnectTimer) {\n return\n }\n const delay = getNextReconnectDelayMs(this.wsReconnectAttempt)\n this.wsReconnectAttempt += 1\n this.wsReconnectTimer = setTimeout(() => {\n this.wsReconnectTimer = null\n this.startWebSocket()\n }, delay)\n }\n\n stopWebSocket(clearReconnect = true): void {\n if (this.wsReconnectTimer && clearReconnect) {\n clearTimeout(this.wsReconnectTimer)\n this.wsReconnectTimer = null\n }\n if (this.ws) {\n try {\n this.ws.removeAllListeners()\n this.ws.close()\n } catch {\n // ignore\n }\n this.ws = null\n }\n this.wsConnected = false\n }\n\n close(): void {\n this.disposed = true\n this.stopRefreshInterval()\n if (this.refreshDebounceTimer) {\n clearTimeout(this.refreshDebounceTimer)\n this.refreshDebounceTimer = null\n }\n this.stopWebSocket(true)\n this.listeners.clear()\n this.initPromise = null\n }\n}\n\nlet singleton: ElectronTogglyClient | null = null\n\nexport async function initToggly(\n config: TogglyElectronConfig,\n): Promise<FeatureFlagsSnapshot> {\n if (singleton) {\n singleton.close()\n }\n singleton = new ElectronTogglyClient(config)\n return singleton.init()\n}\n\nexport function getToggly(): ElectronTogglyClient | null {\n return singleton\n}\n\nexport function isFeatureOn(\n key: string,\n entityContext?: EntityContextInput,\n kind?: string,\n): boolean {\n return singleton?.isFeatureOn(key, entityContext, kind) ?? false\n}\n\nexport function isFeatureOff(\n key: string,\n entityContext?: EntityContextInput,\n kind?: string,\n): boolean {\n return singleton?.isFeatureOff(key, entityContext, kind) ?? true\n}\n\nexport function evaluateFeatureGate(\n keys: string[],\n requirement?: FeatureRequirement | string,\n negate?: boolean,\n entityContext?: EntityContextInput,\n kind?: string,\n): boolean {\n if (!singleton) {\n return negate ?? false\n }\n return singleton.evaluateFeatureGate(\n keys,\n requirement,\n negate,\n entityContext,\n kind,\n )\n}\n\nexport async function setContext(\n input: SetContextInput,\n): Promise<FeatureFlagsSnapshot> {\n if (!singleton) {\n throw new Error('Toggly is not initialized. Call initToggly first.')\n }\n return singleton.setContext(input)\n}\n\nexport async function clearContext(): Promise<FeatureFlagsSnapshot> {\n if (!singleton) {\n throw new Error('Toggly is not initialized. Call initToggly first.')\n }\n return singleton.clearContext()\n}\n\nexport function addHook(hook: Hook): void {\n singleton?.addHook(hook)\n}\n\nexport function closeToggly(): void {\n singleton?.close()\n singleton = null\n}\n\n/** Test helper — reset singleton without requiring prior init. */\nexport function __resetTogglyForTests(): void {\n singleton?.close()\n singleton = null\n}\n","/** Internal channel names — not part of the public renderer API. */\nexport const IPC_PREFIX = 'toggly:' as const\n\nexport const IPC_CHANNELS = {\n isFeatureOn: `${IPC_PREFIX}isFeatureOn`,\n isFeatureOff: `${IPC_PREFIX}isFeatureOff`,\n evaluateFeatureGate: `${IPC_PREFIX}evaluateFeatureGate`,\n getFlags: `${IPC_PREFIX}getFlags`,\n setContext: `${IPC_PREFIX}setContext`,\n clearContext: `${IPC_PREFIX}clearContext`,\n flagsUpdated: `${IPC_PREFIX}flags-updated`,\n} as const\n\nexport type IpcChannelName = (typeof IPC_CHANNELS)[keyof typeof IPC_CHANNELS]\n","import type { BrowserWindow } from 'electron'\nimport { IPC_CHANNELS } from '../ipc-channels.js'\nimport {\n clearContext,\n evaluateFeatureGate,\n getToggly,\n isFeatureOff,\n isFeatureOn,\n setContext,\n type ElectronTogglyClient,\n} from './client.js'\nimport type { EntityContextInput, FeatureRequirement, SetContextInput } from '../types.js'\n\nexport type IpcMainLike = {\n on: (\n channel: string,\n listener: (event: { returnValue: unknown }, ...args: unknown[]) => void,\n ) => void\n handle: (\n channel: string,\n listener: (event: unknown, ...args: unknown[]) => unknown | Promise<unknown>,\n ) => void\n removeHandler?: (channel: string) => void\n removeAllListeners?: (channel: string) => void\n}\n\nexport type WebContentsLike = {\n send: (channel: string, ...args: unknown[]) => void\n isDestroyed?: () => boolean\n}\n\nexport type BrowserWindowLike = {\n webContents: WebContentsLike\n isDestroyed?: () => boolean\n}\n\n/**\n * Register main-process handlers and fan out flag updates to renderer windows.\n * Call after `initToggly`.\n */\nexport function registerTogglyIpc(\n ipcMain: IpcMainLike,\n getWindows: () => Array<BrowserWindow | BrowserWindowLike> = () => [],\n): () => void {\n const client = getToggly()\n if (!client) {\n throw new Error('Toggly is not initialized. Call initToggly before registerTogglyIpc.')\n }\n\n ipcMain.on(IPC_CHANNELS.isFeatureOn, (event, key, entityContext, kind) => {\n event.returnValue = isFeatureOn(\n String(key),\n entityContext as EntityContextInput,\n kind as string | undefined,\n )\n })\n\n ipcMain.on(IPC_CHANNELS.isFeatureOff, (event, key, entityContext, kind) => {\n event.returnValue = isFeatureOff(\n String(key),\n entityContext as EntityContextInput,\n kind as string | undefined,\n )\n })\n\n ipcMain.on(\n IPC_CHANNELS.evaluateFeatureGate,\n (event, keys, requirement, negate, entityContext, kind) => {\n event.returnValue = evaluateFeatureGate(\n (keys as string[]) ?? [],\n requirement as FeatureRequirement | string | undefined,\n Boolean(negate),\n entityContext as EntityContextInput,\n kind as string | undefined,\n )\n },\n )\n\n ipcMain.handle(IPC_CHANNELS.getFlags, () => {\n return getToggly()?.getFlags() ?? {}\n })\n\n ipcMain.handle(IPC_CHANNELS.setContext, (_event, context) => {\n return setContext((context as SetContextInput) ?? {})\n })\n\n ipcMain.handle(IPC_CHANNELS.clearContext, () => {\n return clearContext()\n })\n\n const unsubscribe = client.onFlagsUpdated((flags) => {\n for (const win of getWindows()) {\n try {\n if (win.isDestroyed?.()) {\n continue\n }\n if (win.webContents.isDestroyed?.()) {\n continue\n }\n win.webContents.send(IPC_CHANNELS.flagsUpdated, flags)\n } catch {\n // window may have closed\n }\n }\n })\n\n return () => {\n unsubscribe()\n ipcMain.removeAllListeners?.(IPC_CHANNELS.isFeatureOn)\n ipcMain.removeAllListeners?.(IPC_CHANNELS.isFeatureOff)\n ipcMain.removeAllListeners?.(IPC_CHANNELS.evaluateFeatureGate)\n ipcMain.removeHandler?.(IPC_CHANNELS.getFlags)\n ipcMain.removeHandler?.(IPC_CHANNELS.setContext)\n ipcMain.removeHandler?.(IPC_CHANNELS.clearContext)\n }\n}\n\nexport type { ElectronTogglyClient }\n"]}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { Hook, EvaluatedDefinitions } from '@ops-ai/toggly-hooks-types';
|
|
2
|
+
export { Hook } from '@ops-ai/toggly-hooks-types';
|
|
3
|
+
import { LocalGate } from '@ops-ai/toggly-local-gates';
|
|
4
|
+
import { T as TogglyElectronConfig, a as FeatureFlagsSnapshot, E as EntityContextInput, F as FeatureRequirement, S as SetContextInput } from '../types-BbMSwQVV.cjs';
|
|
5
|
+
import { BrowserWindow } from 'electron';
|
|
6
|
+
|
|
7
|
+
type FlagsUpdatedListener = (flags: FeatureFlagsSnapshot) => void;
|
|
8
|
+
declare class ElectronTogglyClient {
|
|
9
|
+
private config;
|
|
10
|
+
private readonly cache;
|
|
11
|
+
private readonly hookExecutor;
|
|
12
|
+
private readonly jwksCache;
|
|
13
|
+
private readonly fetchImpl;
|
|
14
|
+
private readonly listeners;
|
|
15
|
+
private features;
|
|
16
|
+
private hasLoadedFlags;
|
|
17
|
+
private identity;
|
|
18
|
+
private groups;
|
|
19
|
+
private claims;
|
|
20
|
+
private cachedDefinitionsRevision;
|
|
21
|
+
private pendingDefinitionsPin;
|
|
22
|
+
private disposed;
|
|
23
|
+
private refreshTimer;
|
|
24
|
+
private refreshDebounceTimer;
|
|
25
|
+
private ws;
|
|
26
|
+
private wsConnected;
|
|
27
|
+
private wsReconnectTimer;
|
|
28
|
+
private wsReconnectAttempt;
|
|
29
|
+
private lastFallbackRefresh;
|
|
30
|
+
private localGates;
|
|
31
|
+
private localGateIndex;
|
|
32
|
+
private initPromise;
|
|
33
|
+
constructor(config: TogglyElectronConfig);
|
|
34
|
+
addHook(hook: Hook): void;
|
|
35
|
+
onFlagsUpdated(listener: FlagsUpdatedListener): () => void;
|
|
36
|
+
private notifyFlagsUpdated;
|
|
37
|
+
private reportError;
|
|
38
|
+
private get contextCacheKey();
|
|
39
|
+
private getBooleanFlags;
|
|
40
|
+
private getFallbackFlags;
|
|
41
|
+
private buildEvaluatedUrl;
|
|
42
|
+
private buildFetchHeaders;
|
|
43
|
+
private applyRevision;
|
|
44
|
+
private persistCache;
|
|
45
|
+
private loadDiskCache;
|
|
46
|
+
private resolveEffectiveFlag;
|
|
47
|
+
isFeatureOn(key: string, entityContext?: EntityContextInput, kind?: string): boolean;
|
|
48
|
+
isFeatureOff(key: string, entityContext?: EntityContextInput, kind?: string): boolean;
|
|
49
|
+
evaluateFeatureGate(keys: string[], requirement?: FeatureRequirement | string, negate?: boolean, entityContext?: EntityContextInput, kind?: string): boolean;
|
|
50
|
+
private runEvaluationHooks;
|
|
51
|
+
getFlags(): FeatureFlagsSnapshot;
|
|
52
|
+
setLocalGates(gates: LocalGate[]): void;
|
|
53
|
+
refresh(): Promise<FeatureFlagsSnapshot>;
|
|
54
|
+
init(): Promise<FeatureFlagsSnapshot>;
|
|
55
|
+
private doInit;
|
|
56
|
+
setContext(input: SetContextInput): Promise<FeatureFlagsSnapshot>;
|
|
57
|
+
clearContext(): Promise<FeatureFlagsSnapshot>;
|
|
58
|
+
private startRefreshInterval;
|
|
59
|
+
private stopRefreshInterval;
|
|
60
|
+
private scheduleDebouncedRefresh;
|
|
61
|
+
private handleWsMessage;
|
|
62
|
+
startWebSocket(): void;
|
|
63
|
+
private scheduleReconnect;
|
|
64
|
+
stopWebSocket(clearReconnect?: boolean): void;
|
|
65
|
+
close(): void;
|
|
66
|
+
}
|
|
67
|
+
declare function initToggly(config: TogglyElectronConfig): Promise<FeatureFlagsSnapshot>;
|
|
68
|
+
declare function getToggly(): ElectronTogglyClient | null;
|
|
69
|
+
declare function isFeatureOn(key: string, entityContext?: EntityContextInput, kind?: string): boolean;
|
|
70
|
+
declare function isFeatureOff(key: string, entityContext?: EntityContextInput, kind?: string): boolean;
|
|
71
|
+
declare function evaluateFeatureGate(keys: string[], requirement?: FeatureRequirement | string, negate?: boolean, entityContext?: EntityContextInput, kind?: string): boolean;
|
|
72
|
+
declare function setContext(input: SetContextInput): Promise<FeatureFlagsSnapshot>;
|
|
73
|
+
declare function clearContext(): Promise<FeatureFlagsSnapshot>;
|
|
74
|
+
declare function addHook(hook: Hook): void;
|
|
75
|
+
declare function closeToggly(): void;
|
|
76
|
+
/** Test helper — reset singleton without requiring prior init. */
|
|
77
|
+
declare function __resetTogglyForTests(): void;
|
|
78
|
+
|
|
79
|
+
type IpcMainLike = {
|
|
80
|
+
on: (channel: string, listener: (event: {
|
|
81
|
+
returnValue: unknown;
|
|
82
|
+
}, ...args: unknown[]) => void) => void;
|
|
83
|
+
handle: (channel: string, listener: (event: unknown, ...args: unknown[]) => unknown | Promise<unknown>) => void;
|
|
84
|
+
removeHandler?: (channel: string) => void;
|
|
85
|
+
removeAllListeners?: (channel: string) => void;
|
|
86
|
+
};
|
|
87
|
+
type WebContentsLike = {
|
|
88
|
+
send: (channel: string, ...args: unknown[]) => void;
|
|
89
|
+
isDestroyed?: () => boolean;
|
|
90
|
+
};
|
|
91
|
+
type BrowserWindowLike = {
|
|
92
|
+
webContents: WebContentsLike;
|
|
93
|
+
isDestroyed?: () => boolean;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Register main-process handlers and fan out flag updates to renderer windows.
|
|
97
|
+
* Call after `initToggly`.
|
|
98
|
+
*/
|
|
99
|
+
declare function registerTogglyIpc(ipcMain: IpcMainLike, getWindows?: () => Array<BrowserWindow | BrowserWindowLike>): () => void;
|
|
100
|
+
|
|
101
|
+
interface DiskCacheEntry {
|
|
102
|
+
flags: EvaluatedDefinitions;
|
|
103
|
+
revision: string | null;
|
|
104
|
+
updatedAt: number;
|
|
105
|
+
}
|
|
106
|
+
declare function buildCacheFilePath(userDataPath: string, appKey: string, environment: string, contextKey: string): string;
|
|
107
|
+
declare class DiskFeatureCache {
|
|
108
|
+
private readonly userDataPath;
|
|
109
|
+
constructor(userDataPath: string);
|
|
110
|
+
private filePath;
|
|
111
|
+
read(appKey: string, environment: string, contextKey: string): Promise<DiskCacheEntry | null>;
|
|
112
|
+
write(appKey: string, environment: string, contextKey: string, entry: DiskCacheEntry): Promise<void>;
|
|
113
|
+
clear(appKey: string, environment: string, contextKey: string): Promise<void>;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Internal channel names — not part of the public renderer API. */
|
|
117
|
+
declare const IPC_PREFIX: "toggly:";
|
|
118
|
+
declare const IPC_CHANNELS: {
|
|
119
|
+
readonly isFeatureOn: "toggly:isFeatureOn";
|
|
120
|
+
readonly isFeatureOff: "toggly:isFeatureOff";
|
|
121
|
+
readonly evaluateFeatureGate: "toggly:evaluateFeatureGate";
|
|
122
|
+
readonly getFlags: "toggly:getFlags";
|
|
123
|
+
readonly setContext: "toggly:setContext";
|
|
124
|
+
readonly clearContext: "toggly:clearContext";
|
|
125
|
+
readonly flagsUpdated: "toggly:flags-updated";
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
declare const SDK_ID = "electron";
|
|
129
|
+
declare const SDK_VERSION = "1.0.0";
|
|
130
|
+
|
|
131
|
+
export { type DiskCacheEntry, DiskFeatureCache, ElectronTogglyClient, EntityContextInput, FeatureFlagsSnapshot, FeatureRequirement, IPC_CHANNELS, IPC_PREFIX, SDK_ID, SDK_VERSION, SetContextInput, TogglyElectronConfig, __resetTogglyForTests, addHook, buildCacheFilePath, clearContext, closeToggly, evaluateFeatureGate, getToggly, initToggly, isFeatureOff, isFeatureOn, registerTogglyIpc, setContext };
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { Hook, EvaluatedDefinitions } from '@ops-ai/toggly-hooks-types';
|
|
2
|
+
export { Hook } from '@ops-ai/toggly-hooks-types';
|
|
3
|
+
import { LocalGate } from '@ops-ai/toggly-local-gates';
|
|
4
|
+
import { T as TogglyElectronConfig, a as FeatureFlagsSnapshot, E as EntityContextInput, F as FeatureRequirement, S as SetContextInput } from '../types-BbMSwQVV.js';
|
|
5
|
+
import { BrowserWindow } from 'electron';
|
|
6
|
+
|
|
7
|
+
type FlagsUpdatedListener = (flags: FeatureFlagsSnapshot) => void;
|
|
8
|
+
declare class ElectronTogglyClient {
|
|
9
|
+
private config;
|
|
10
|
+
private readonly cache;
|
|
11
|
+
private readonly hookExecutor;
|
|
12
|
+
private readonly jwksCache;
|
|
13
|
+
private readonly fetchImpl;
|
|
14
|
+
private readonly listeners;
|
|
15
|
+
private features;
|
|
16
|
+
private hasLoadedFlags;
|
|
17
|
+
private identity;
|
|
18
|
+
private groups;
|
|
19
|
+
private claims;
|
|
20
|
+
private cachedDefinitionsRevision;
|
|
21
|
+
private pendingDefinitionsPin;
|
|
22
|
+
private disposed;
|
|
23
|
+
private refreshTimer;
|
|
24
|
+
private refreshDebounceTimer;
|
|
25
|
+
private ws;
|
|
26
|
+
private wsConnected;
|
|
27
|
+
private wsReconnectTimer;
|
|
28
|
+
private wsReconnectAttempt;
|
|
29
|
+
private lastFallbackRefresh;
|
|
30
|
+
private localGates;
|
|
31
|
+
private localGateIndex;
|
|
32
|
+
private initPromise;
|
|
33
|
+
constructor(config: TogglyElectronConfig);
|
|
34
|
+
addHook(hook: Hook): void;
|
|
35
|
+
onFlagsUpdated(listener: FlagsUpdatedListener): () => void;
|
|
36
|
+
private notifyFlagsUpdated;
|
|
37
|
+
private reportError;
|
|
38
|
+
private get contextCacheKey();
|
|
39
|
+
private getBooleanFlags;
|
|
40
|
+
private getFallbackFlags;
|
|
41
|
+
private buildEvaluatedUrl;
|
|
42
|
+
private buildFetchHeaders;
|
|
43
|
+
private applyRevision;
|
|
44
|
+
private persistCache;
|
|
45
|
+
private loadDiskCache;
|
|
46
|
+
private resolveEffectiveFlag;
|
|
47
|
+
isFeatureOn(key: string, entityContext?: EntityContextInput, kind?: string): boolean;
|
|
48
|
+
isFeatureOff(key: string, entityContext?: EntityContextInput, kind?: string): boolean;
|
|
49
|
+
evaluateFeatureGate(keys: string[], requirement?: FeatureRequirement | string, negate?: boolean, entityContext?: EntityContextInput, kind?: string): boolean;
|
|
50
|
+
private runEvaluationHooks;
|
|
51
|
+
getFlags(): FeatureFlagsSnapshot;
|
|
52
|
+
setLocalGates(gates: LocalGate[]): void;
|
|
53
|
+
refresh(): Promise<FeatureFlagsSnapshot>;
|
|
54
|
+
init(): Promise<FeatureFlagsSnapshot>;
|
|
55
|
+
private doInit;
|
|
56
|
+
setContext(input: SetContextInput): Promise<FeatureFlagsSnapshot>;
|
|
57
|
+
clearContext(): Promise<FeatureFlagsSnapshot>;
|
|
58
|
+
private startRefreshInterval;
|
|
59
|
+
private stopRefreshInterval;
|
|
60
|
+
private scheduleDebouncedRefresh;
|
|
61
|
+
private handleWsMessage;
|
|
62
|
+
startWebSocket(): void;
|
|
63
|
+
private scheduleReconnect;
|
|
64
|
+
stopWebSocket(clearReconnect?: boolean): void;
|
|
65
|
+
close(): void;
|
|
66
|
+
}
|
|
67
|
+
declare function initToggly(config: TogglyElectronConfig): Promise<FeatureFlagsSnapshot>;
|
|
68
|
+
declare function getToggly(): ElectronTogglyClient | null;
|
|
69
|
+
declare function isFeatureOn(key: string, entityContext?: EntityContextInput, kind?: string): boolean;
|
|
70
|
+
declare function isFeatureOff(key: string, entityContext?: EntityContextInput, kind?: string): boolean;
|
|
71
|
+
declare function evaluateFeatureGate(keys: string[], requirement?: FeatureRequirement | string, negate?: boolean, entityContext?: EntityContextInput, kind?: string): boolean;
|
|
72
|
+
declare function setContext(input: SetContextInput): Promise<FeatureFlagsSnapshot>;
|
|
73
|
+
declare function clearContext(): Promise<FeatureFlagsSnapshot>;
|
|
74
|
+
declare function addHook(hook: Hook): void;
|
|
75
|
+
declare function closeToggly(): void;
|
|
76
|
+
/** Test helper — reset singleton without requiring prior init. */
|
|
77
|
+
declare function __resetTogglyForTests(): void;
|
|
78
|
+
|
|
79
|
+
type IpcMainLike = {
|
|
80
|
+
on: (channel: string, listener: (event: {
|
|
81
|
+
returnValue: unknown;
|
|
82
|
+
}, ...args: unknown[]) => void) => void;
|
|
83
|
+
handle: (channel: string, listener: (event: unknown, ...args: unknown[]) => unknown | Promise<unknown>) => void;
|
|
84
|
+
removeHandler?: (channel: string) => void;
|
|
85
|
+
removeAllListeners?: (channel: string) => void;
|
|
86
|
+
};
|
|
87
|
+
type WebContentsLike = {
|
|
88
|
+
send: (channel: string, ...args: unknown[]) => void;
|
|
89
|
+
isDestroyed?: () => boolean;
|
|
90
|
+
};
|
|
91
|
+
type BrowserWindowLike = {
|
|
92
|
+
webContents: WebContentsLike;
|
|
93
|
+
isDestroyed?: () => boolean;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* Register main-process handlers and fan out flag updates to renderer windows.
|
|
97
|
+
* Call after `initToggly`.
|
|
98
|
+
*/
|
|
99
|
+
declare function registerTogglyIpc(ipcMain: IpcMainLike, getWindows?: () => Array<BrowserWindow | BrowserWindowLike>): () => void;
|
|
100
|
+
|
|
101
|
+
interface DiskCacheEntry {
|
|
102
|
+
flags: EvaluatedDefinitions;
|
|
103
|
+
revision: string | null;
|
|
104
|
+
updatedAt: number;
|
|
105
|
+
}
|
|
106
|
+
declare function buildCacheFilePath(userDataPath: string, appKey: string, environment: string, contextKey: string): string;
|
|
107
|
+
declare class DiskFeatureCache {
|
|
108
|
+
private readonly userDataPath;
|
|
109
|
+
constructor(userDataPath: string);
|
|
110
|
+
private filePath;
|
|
111
|
+
read(appKey: string, environment: string, contextKey: string): Promise<DiskCacheEntry | null>;
|
|
112
|
+
write(appKey: string, environment: string, contextKey: string, entry: DiskCacheEntry): Promise<void>;
|
|
113
|
+
clear(appKey: string, environment: string, contextKey: string): Promise<void>;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/** Internal channel names — not part of the public renderer API. */
|
|
117
|
+
declare const IPC_PREFIX: "toggly:";
|
|
118
|
+
declare const IPC_CHANNELS: {
|
|
119
|
+
readonly isFeatureOn: "toggly:isFeatureOn";
|
|
120
|
+
readonly isFeatureOff: "toggly:isFeatureOff";
|
|
121
|
+
readonly evaluateFeatureGate: "toggly:evaluateFeatureGate";
|
|
122
|
+
readonly getFlags: "toggly:getFlags";
|
|
123
|
+
readonly setContext: "toggly:setContext";
|
|
124
|
+
readonly clearContext: "toggly:clearContext";
|
|
125
|
+
readonly flagsUpdated: "toggly:flags-updated";
|
|
126
|
+
};
|
|
127
|
+
|
|
128
|
+
declare const SDK_ID = "electron";
|
|
129
|
+
declare const SDK_VERSION = "1.0.0";
|
|
130
|
+
|
|
131
|
+
export { type DiskCacheEntry, DiskFeatureCache, ElectronTogglyClient, EntityContextInput, FeatureFlagsSnapshot, FeatureRequirement, IPC_CHANNELS, IPC_PREFIX, SDK_ID, SDK_VERSION, SetContextInput, TogglyElectronConfig, __resetTogglyForTests, addHook, buildCacheFilePath, clearContext, closeToggly, evaluateFeatureGate, getToggly, initToggly, isFeatureOff, isFeatureOn, registerTogglyIpc, setContext };
|