kaafil-react-uikit 0.2.0 → 0.3.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.
Files changed (35) hide show
  1. package/dist/admin/index.cjs +73 -73
  2. package/dist/admin/index.js +3 -3
  3. package/dist/{chunk-RG4YDSCN.cjs → chunk-BBC5EX5O.cjs} +4 -4
  4. package/dist/{chunk-RG4YDSCN.cjs.map → chunk-BBC5EX5O.cjs.map} +1 -1
  5. package/dist/{chunk-7UFX3Y2U.cjs → chunk-ECCQW5LN.cjs} +5 -2
  6. package/dist/chunk-ECCQW5LN.cjs.map +1 -0
  7. package/dist/{chunk-HTIY33UH.cjs → chunk-FVK7HMQ5.cjs} +21 -21
  8. package/dist/{chunk-HTIY33UH.cjs.map → chunk-FVK7HMQ5.cjs.map} +1 -1
  9. package/dist/{chunk-OZJ74DVQ.cjs → chunk-HACH2NUM.cjs} +3 -3
  10. package/dist/chunk-HACH2NUM.cjs.map +1 -0
  11. package/dist/{chunk-6WV5VYT2.cjs → chunk-MNUCVVIE.cjs} +59 -4
  12. package/dist/chunk-MNUCVVIE.cjs.map +1 -0
  13. package/dist/{chunk-7ISKFGLW.js → chunk-RWLO6IFX.js} +3 -3
  14. package/dist/chunk-RWLO6IFX.js.map +1 -0
  15. package/dist/{chunk-L3QEMEFM.js → chunk-VLP323AD.js} +5 -2
  16. package/dist/chunk-VLP323AD.js.map +1 -0
  17. package/dist/{chunk-RSC2ZJUP.js → chunk-WTTGPWMR.js} +59 -4
  18. package/dist/chunk-WTTGPWMR.js.map +1 -0
  19. package/dist/{chunk-SIAPCJ7G.js → chunk-YTSYRLGS.js} +4 -4
  20. package/dist/{chunk-SIAPCJ7G.js.map → chunk-YTSYRLGS.js.map} +1 -1
  21. package/dist/{chunk-LJJMNZ7B.js → chunk-YU2242AR.js} +3 -3
  22. package/dist/{chunk-LJJMNZ7B.js.map → chunk-YU2242AR.js.map} +1 -1
  23. package/dist/core/index.cjs +56 -56
  24. package/dist/core/index.js +7 -7
  25. package/dist/manager/index.cjs +48 -48
  26. package/dist/manager/index.js +2 -2
  27. package/dist/traveller/index.cjs +4 -4
  28. package/dist/traveller/index.js +2 -2
  29. package/package.json +2 -2
  30. package/dist/chunk-6WV5VYT2.cjs.map +0 -1
  31. package/dist/chunk-7ISKFGLW.js.map +0 -1
  32. package/dist/chunk-7UFX3Y2U.cjs.map +0 -1
  33. package/dist/chunk-L3QEMEFM.js.map +0 -1
  34. package/dist/chunk-OZJ74DVQ.cjs.map +0 -1
  35. package/dist/chunk-RSC2ZJUP.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/core/hooks/useShareForms.ts","../src/core/hooks/useShareSnapshot.ts"],"names":["client","useKaafilClient","usePersona","useOfflineEngine","useServerTime","useState","useCallback","useEffect","isDevelopment","useOfflineEvent","useOfflineMutation","SyncOpMethod","useContext","OfflineEngineContext"],"mappings":";;;;;;;;AA6LA,SAAS,gBAAA,CACP,OACA,UAAA,EACsB;AACtB,EAAA,IAAI,UAAU,MAAA,EAAW;AACvB,IAAA,OAAO,aAAa,WAAA,GAAc,SAAA;AAAA,EACpC;AACA,EAAA,OAAO,KAAA,CAAM,MAAA,KAAW,CAAA,GAAI,YAAA,GAAe,gBAAA;AAC7C;AAEA,SAAS,iBAAA,CACP,OAAA,EACA,MAAA,EACA,QAAA,EACA,QAAA,EAC+E;AAC/E,EAAA,IAAI,OAAA,EAAS;AACX,IAAA,OAAO,EAAE,MAAA,EAAQ,mBAAA,EAAqB,EAAA,EAAI,YAAY,MAAA,EAAO;AAAA,EAC/D;AAIA,EAAA,MAAM,MAAA,GAAS,aAAa,MAAA,GAAY,EAAE,IAAI,QAAA,EAAU,IAAA,EAAM,UAAkB,GAAI,MAAA;AACpF,EAAA,MAAM,QAAA,GACJ,WAAW,MAAA,KAAW,MAAA,GAAY,EAAE,EAAA,EAAI,MAAA,EAAQ,IAAA,EAAM,MAAA,EAAgB,GAAI,MAAA,CAAA;AAC5E,EAAA,IAAI,aAAa,MAAA,EAAW;AAC1B,IAAA,OAAO,EAAE,MAAA,EAAQ,MAAA,EAAQ,EAAA,EAAI,MAAA,EAAU;AAAA,EACzC;AACA,EAAA,MAAM,EAAE,EAAA,EAAI,IAAA,EAAK,GAAI,QAAA;AACrB,EAAA,IAAI,EAAA,CAAG,WAAW,QAAA,EAAU;AAC1B,IAAA,IAAI,EAAA,CAAG,UAAA,EAAY,IAAA,KAAS,kBAAA,EAAoB;AAC9C,MAAA,OAAO,EAAE,MAAA,EAAQ,YAAA,EAAc,EAAA,EAAG;AAAA,IACpC;AACA,IAAA,IAAI,EAAA,CAAG,UAAA,EAAY,IAAA,KAAS,kBAAA,EAAoB;AAC9C,MAAA,OAAO,EAAE,MAAA,EAAQ,kBAAA,EAAoB,EAAA,EAAG;AAAA,IAC1C;AAQA,IAAA,OAAO,EAAE,MAAA,EAAQ,gBAAA,EAAkB,EAAA,EAAG;AAAA,EACxC;AACA,EAAA,IAAI,EAAA,CAAG,WAAW,MAAA,EAAQ;AACxB,IAAA,OAAO,EAAE,MAAA,EAAQ,IAAA,KAAS,QAAA,GAAW,WAAA,GAAc,QAAQ,EAAA,EAAG;AAAA,EAChE;AAEA,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,OAAO,EAAE,MAAA,EAAQ,gBAAA,EAAkB,EAAA,EAAG;AAAA,EACxC;AACA,EAAA,OAAO,EAAE,MAAA,EAAQ,IAAA,KAAS,QAAA,GAAW,YAAA,GAAe,UAAU,EAAA,EAAG;AACnE;AAEO,SAAS,cAAc,KAAA,EAAiC;AAC7D,EAAA,MAAMA,WAASC,iCAAA,EAAgB;AAC/B,EAAA,MAAM,UAAUC,4BAAA,EAAW;AAC3B,EAAA,MAAM,SAASC,kCAAA,EAAiB;AAChC,EAAA,MAAM,EAAE,GAAA,EAAK,aAAA,EAAc,GAAIC,+BAAA,EAAc;AAK7C,EAAA,MAAM,kBAAkB,aAAA,KAAkB,MAAA;AAE1C,EAAA,MAAM,CAAC,KAAA,EAAO,QAAQ,CAAA,GAAIC,eAAmD,MAAS,CAAA;AACtF,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIA,eAA6B,MAAS,CAAA;AAC1E,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIA,eAAS,KAAK,CAAA;AAClD,EAAA,MAAM,CAAC,OAAA,EAAS,UAAU,CAAA,GAAIA,eAAS,KAAK,CAAA;AAC5C,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIA,cAAA;AAAA,IAC9B,MAAM,OAAO,SAAA,KAAc,WAAA,IAAe,SAAA,CAAU;AAAA,GACtD;AAEA,EAAA,MAAM,SAAA,GAAYC,kBAAY,YAA2B;AACvD,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,MAAMN,QAAA,CAAO,KAAA,CAAM,MAAM,IAAA,CAAK,EAAE,OAAO,CAAA;AACxD,MAAA,QAAA,CAAS,SAAS,KAAK,CAAA;AACvB,MAAA,aAAA,CAAc,QAAA,CAAS,KAAK,UAAU,CAAA;AACtC,MAAA,aAAA,CAAc,KAAK,CAAA;AAAA,IACrB,CAAA,CAAA,MAAQ;AAKN,MAAA,aAAA,CAAc,IAAI,CAAA;AAAA,IACpB;AAAA,EACF,CAAA,EAAG,CAACA,QAAA,EAAQ,KAAK,CAAC,CAAA;AAElB,EAAAO,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,YAAY,OAAA,EAAS;AACvB,MAAA,IAAIC,iCAAc,EAAG;AACnB,QAAA,MAAM,IAAI,KAAA;AAAA,UACR;AAAA,SAEF;AAAA,MACF;AACA,MAAA;AAAA,IACF;AACA,IAAA,KAAK,SAAA,EAAU;AAAA,EACjB,CAAA,EAAG,CAAC,OAAA,EAAS,SAAS,CAAC,CAAA;AAKvB,EAAAD,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,OAAO,WAAW,WAAA,EAAa;AACjC,MAAA;AAAA,IACF;AACA,IAAA,MAAM,YAAA,GAAe,MAAY,WAAA,CAAY,IAAI,CAAA;AACjD,IAAA,MAAM,aAAA,GAAgB,MAAY,WAAA,CAAY,KAAK,CAAA;AACnD,IAAA,MAAA,CAAO,gBAAA,CAAiB,UAAU,YAAY,CAAA;AAC9C,IAAA,MAAA,CAAO,gBAAA,CAAiB,WAAW,aAAa,CAAA;AAChD,IAAA,OAAO,MAAM;AACX,MAAA,MAAA,CAAO,mBAAA,CAAoB,UAAU,YAAY,CAAA;AACjD,MAAA,MAAA,CAAO,mBAAA,CAAoB,WAAW,aAAa,CAAA;AAAA,IACrD,CAAA;AAAA,EACF,CAAA,EAAG,EAAE,CAAA;AAEL,EAAAE,iCAAA,CAAgB,iBAAiB,MAAM;AACrC,IAAA,UAAA,CAAW,IAAI,CAAA;AAIf,IAAA,KAAA,MAAW,EAAA,IAAM,MAAA,CAAO,MAAA,CAAO,GAAA,EAAI,EAAG;AACpC,MAAA,IAAI,EAAA,CAAG,YAAY,KAAA,KAAU,EAAA,CAAG,WAAW,SAAA,IAAa,EAAA,CAAG,WAAW,QAAA,CAAA,EAAW;AAC/E,QAAA,KAAK,MAAA,CAAO,MAAA,CAAO,IAAA,CAAK,EAAA,CAAG,EAAE,CAAA;AAAA,MAC/B;AAAA,IACF;AAAA,EACF,CAAC,CAAA;AAED,EAAA,MAAM,eAAeC,oCAAA,CAAwC;AAAA,IAC3D,OAAA,EAAS,KAAA;AAAA,IACT,OAAA,EAAS,CAAC,cAAA,EAAgB,KAAA,KAAU;AAClC,MAAA,MAAM,KAAA,GACJ,MAAM,YAAA,KAAiB,MAAA,GACnB,iBAAiB,kBAAA,CAAmB,KAAA,CAAM,YAAY,CAAC,CAAA,CAAA,GACvD,EAAA;AACN,MAAA,OAAO,eAAe,OAAA,CAAQ;AAAA,QAC5B,OAAA,EAAS,KAAA;AAAA,QACT,QAAQC,mBAAA,CAAa,IAAA;AAAA,QACrB,MAAM,CAAA,cAAA,EAAiB,KAAK,UAAU,KAAA,CAAM,MAAM,QAAQ,KAAK,CAAA,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAM/D,WAAA,EAAa,eAAA;AAAA,QACb,IAAA,EAAM;AAAA,UACJ,SAAS,KAAA,CAAM,OAAA;AAAA,UACf,aAAa,KAAA,CAAM,WAAA;AAAA,UACnB,GAAI,MAAM,QAAA,KAAa,MAAA,GAAY,EAAE,QAAA,EAAU,KAAA,CAAM,QAAA,EAAS,GAAI,EAAC;AAAA,UACnE,GAAI,MAAM,WAAA,KAAgB,MAAA,GAAY,EAAE,WAAA,EAAa,KAAA,CAAM,WAAA,EAAY,GAAI;AAAC,SAC9E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,QAYA,GAAI,eAAA,GAAkB,EAAE,YAAY,GAAA,EAAI,KAAM;AAAC,OAChD,CAAA;AAAA,IACH;AAAA,GACD,CAAA;AAED,EAAA,MAAM,iBAAiBD,oCAAA,CAAwC;AAAA,IAC7D,OAAA,EAAS,KAAA;AAAA,IACT,OAAA,EAAS,CAAC,cAAA,EAAgB,KAAA,KAAU;AAClC,MAAA,MAAM,KAAA,GACJ,MAAM,YAAA,KAAiB,MAAA,GACnB,iBAAiB,kBAAA,CAAmB,KAAA,CAAM,YAAY,CAAC,CAAA,CAAA,GACvD,EAAA;AACN,MAAA,OAAO,eAAe,OAAA,CAAQ;AAAA,QAC5B,OAAA,EAAS,KAAA;AAAA,QACT,QAAQC,mBAAA,CAAa,IAAA;AAAA,QACrB,MAAM,CAAA,cAAA,EAAiB,KAAK,UAAU,KAAA,CAAM,MAAM,UAAU,KAAK,CAAA,CAAA;AAAA,QACjE,WAAA,EAAa,iBAAA;AAAA,QACb,IAAA,EAAM;AAAA,UACJ,SAAS,KAAA,CAAM,OAAA;AAAA,UACf,aAAa,KAAA,CAAM,WAAA;AAAA,UACnB,GAAI,MAAM,QAAA,KAAa,MAAA,GAAY,EAAE,QAAA,EAAU,KAAA,CAAM,QAAA,EAAS,GAAI,EAAC;AAAA,UACnE,GAAI,MAAM,WAAA,KAAgB,MAAA,GAAY,EAAE,WAAA,EAAa,KAAA,CAAM,WAAA,EAAY,GAAI;AAAC,SAC9E;AAAA;AAAA,QAEA,GAAI,eAAA,GAAkB,EAAE,YAAY,GAAA,EAAI,KAAM;AAAC,OAChD,CAAA;AAAA,IACH;AAAA,GACD,CAAA;AAED,EAAA,MAAM,UAAA,GAAaL,iBAAA;AAAA,IACjB,OACE,QACA,OAAA,KACqC;AACrC,MAAA,MAAM,QAAA,GAAW,MAAMN,QAAA,CAAO,KAAA,CAAM,MAAM,MAAA,CAAO;AAAA,QAC/C,KAAA;AAAA,QACA,MAAA;AAAA,QACA,GAAI,SAAS,YAAA,KAAiB,MAAA,GAAY,EAAE,YAAA,EAAc,OAAA,CAAQ,YAAA,EAAa,GAAI;AAAC,OACrF,CAAA;AACD,MAAA,OAAO,QAAA;AAAA,IACT,CAAA;AAAA,IACA,CAACA,UAAQ,KAAK;AAAA,GAChB;AAEA,EAAA,MAAM,EAAE,MAAA,EAAQ,WAAA,EAAa,EAAA,EAAI,SAAQ,GAAI,iBAAA;AAAA,IAC3C,OAAA;AAAA,IACA,YAAA,CAAa,EAAA;AAAA,IACb,cAAA,CAAe,EAAA;AAAA,IACf;AAAA,GACF;AAEA,EAAA,OAAO;AAAA,IACL,MAAA,EAAQ,gBAAA,CAAiB,KAAA,EAAO,UAAU,CAAA;AAAA,IAC1C,KAAA,EAAO,SAAS,EAAC;AAAA,IACjB,UAAA;AAAA,IACA,OAAA,EAAS,SAAA;AAAA,IACT,UAAA;AAAA,IACA,MAAM,YAAA,CAAa,MAAA;AAAA,IACnB,QAAQ,cAAA,CAAe,MAAA;AAAA,IACvB,WAAA;AAAA,IACA;AAAA,GACF;AACF;ACvVA,IAAM,mCAAmB,IAAI,GAAA,CAAI,CAAC,MAAA,EAAQ,MAAM,CAAC,CAAA;AAE1C,SAAS,gBAAA,CACd,OACA,OAAA,EACqB;AAMrB,EAAA,MAAM,SAASC,iCAAA,EAAgB;AAC/B,EAAA,MAAM,UAAUC,4BAAA,EAAW;AAC3B,EAAA,MAAM,MAAA,GAASU,iBAAWC,sCAAoB,CAAA;AAC9C,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIR,eAAmD,MAAS,CAAA;AAC5F,EAAA,MAAM,CAAC,IAAA,EAAM,OAAO,CAAA,GAAIA,eAAwC,MAAS,CAAA;AACzE,EAAA,MAAM,CAAC,UAAA,EAAY,aAAa,CAAA,GAAIA,eAA6B,MAAS,CAAA;AAC1E,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAIA,cAAAA;AAAA,IAC9B;AAAA,GACF;AAEA,EAAAE,gBAAU,MAAM;AACd,IAAA,IAAI,YAAY,OAAA,EAAS;AACvB,MAAA,IAAIC,iCAAc,EAAG;AACnB,QAAA,MAAM,IAAI,KAAA;AAAA,UACR;AAAA,SAEF;AAAA,MACF;AACA,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,SAAA,GAAY,KAAA;AAChB,IAAA,eAAe,IAAA,GAAsB;AACnC,MAAA,IAAI;AACF,QAAA,MAAM,WAAW,MAAM,MAAA,CAAO,MAAM,QAAA,CAAS,EAAE,OAAO,CAAA;AACtD,QAAA,IAAI,SAAA,EAAW;AACb,UAAA;AAAA,QACF;AACA,QAAA,MAAM,GAAA,uBAAU,GAAA,EAAqB;AACrC,QAAA,KAAA,MAAW,CAAC,GAAA,EAAK,KAAK,KAAK,MAAA,CAAO,OAAA,CAAQ,QAAQ,CAAA,EAAG;AACnD,UAAA,IAAI,CAAC,gBAAA,CAAiB,GAAA,CAAI,GAAG,CAAA,EAAG;AAC9B,YAAA,GAAA,CAAI,GAAA,CAAI,KAAK,KAAK,CAAA;AAAA,UACpB;AAAA,QACF;AACA,QAAA,WAAA,CAAY,GAAG,CAAA;AACf,QAAA,OAAA,CAAQ,SAAS,IAAI,CAAA;AACrB,QAAA,aAAA,CAAc,QAAA,CAAS,KAAK,UAAU,CAAA;AAAA,MACxC,CAAA,CAAA,MAAQ;AAKN,QAAA,IAAI,CAAC,SAAA,EAAW;AACd,UAAA,WAAA,CAAY,WAAW,CAAA;AAAA,QACzB;AAAA,MACF;AAAA,IACF;AACA,IAAA,KAAK,IAAA,EAAK;AAEV,IAAA,IAAI,WAAW,IAAA,EAAM;AACnB,MAAA,OAAO,MAAM;AACX,QAAA,SAAA,GAAY,IAAA;AAAA,MACd,CAAA;AAAA,IACF;AACA,IAAA,MAAM,kBAAA,GAAqB,OAAO,MAAA,CAAO,EAAA,CAAG,iBAAiB,MAAM,WAAA,CAAY,SAAS,CAAC,CAAA;AACzF,IAAA,MAAM,kBAAA,GAAqB,OAAO,MAAA,CAAO,EAAA,CAAG,iBAAiB,MAAM,WAAA,CAAY,SAAS,CAAC,CAAA;AACzF,IAAA,OAAO,MAAM;AACX,MAAA,SAAA,GAAY,IAAA;AACZ,MAAA,kBAAA,EAAmB;AACnB,MAAA,kBAAA,EAAmB;AAAA,IACrB,CAAA;AAAA,EACF,GAAG,CAAC,MAAA,EAAQ,OAAA,EAAS,KAAA,EAAO,MAAM,CAAC,CAAA;AAEnC,EAAA,IAAI,aAAa,MAAA,EAAW;AAC1B,IAAA,OAAO,EAAE,QAAQ,QAAA,EAAU,QAAA,EAAU,4BAAY,IAAI,GAAA,EAAI,EAAG,IAAA,EAAM,UAAA,EAAW;AAAA,EAC/E;AACA,EAAA,IAAI,aAAa,MAAA,EAAW;AAC1B,IAAA,OAAO,EAAE,MAAA,EAAQ,SAAA,EAAW,QAAA,kBAAU,IAAI,KAAI,EAAG,IAAA,EAAM,MAAA,EAAW,UAAA,EAAY,MAAA,EAAU;AAAA,EAC1F;AACA,EAAA,OAAO,EAAE,MAAA,EAAQ,OAAA,EAAS,QAAA,EAAU,MAAM,UAAA,EAAW;AACvD","file":"chunk-RG4YDSCN.cjs","sourcesContent":["'use client';\n\n// `08-core-hooks.md §3` (new row — `ShareFormsSection`'s `Backed by`,\n// `ui-kit/families/traveller/02-forms.md`, cited): the write-back half of\n// the traveller share surface. `forms` is the ONLY write-back section on\n// the whole share surface; every other section is read-only through\n// `useShareSnapshot()` alone. This hook wraps the four dedicated\n// `shareAuth`-only routes `share.forms.{list,render,save,submit}`\n// (`kaafil-js/src/resources/share.ts`, verified this session).\n//\n// ── WHY THIS HOOK DOES NOT ALSO CALL `useShareSnapshot()` ──────────────────\n//\n// `02-forms.md`'s `Backed by` field says the section's own `/core` hook\n// \"composes both\" — the snapshot (for `forms` section presence) and the\n// dedicated routes (for the actual list/render/save/submit). This file\n// deliberately does NOT reproduce the snapshot fetch: `ShareFormsSection`\n// (future work, not this file) is only ever mounted once its own call to\n// `useShareSnapshot(token)` has already confirmed `sections.has('forms')`\n// (`01-share-sections.md`'s registry-driven mount rule) — duplicating that\n// fetch here would be a second, redundant read of the same snapshot for no\n// new information, and this hook has nothing to add to a presence check it\n// does not own. What this file DOES independently reproduce is\n// `useShareSnapshot()`'s own persona gate and its `share.expired`/\n// `share.revoked` subscriptions (`08-core-hooks.md §0`: \"every domain hook\n// is capability-gated internally\" — the share-surface's equivalent gate is\n// the persona check, applied the same way every other hook in this catalog\n// applies its own).\n//\n// ── SPEC TENSION FLAGGED: \"cache-first\" vs. \"the dedicated routes\" ─────────\n//\n// `02-forms.md`'s `Offline` field says the list \"rides the scoped share\n// snapshot cache-first, same as every other section\", but its own `Backed\n// by` field says in the same breath that \"the actual form list/render/\n// save/submit calls ride the dedicated forms-share routes\" — and\n// `ShareSnapshotResponse`'s per-section shape (verified,\n// `useShareSnapshot.ts`) carries no registered `forms` array with\n// `fillState`/`opensAt`/`closesAt` fields; only `ShareFormsListResponse`\n// (`GET /api/v1/share/{token}/forms`) does. This file follows the more\n// specific, SDK-verified statement — a LIVE `share.forms.list()` call,\n// refreshable on demand — the same \"own live-fetch sub-state, not a\n// `snapshot.updated` subscription\" pattern `useRooming.ts`'s\n// `unassignedPool` already uses for an analogous non-delta read. Flagged\n// for the doc owner to resolve; not silently picked one way with no trace.\n//\n// ── `clientToken` IS NOT A HOOK-MINTED IDEMPOTENCY KEY ──────────────────────\n//\n// `ShareSaveFormRequest`/`ShareSubmitFormRequest` (verified,\n// `kaafil-js/openapi/openapi.json`) require a body-level `clientToken`\n// (16-255 chars) — the SDK's own comment on `share.ts` calls it \"this\n// route's own de-dupe key, distinct from the automatic `Idempotency-Key`\n// header\", and `modules/forms/FRD.md §4.1/§8` calls it \"a fixed\n// `clientToken` generated once at enqueue and reused on every retry\" —\n// i.e. exactly the write-once, replay-unchanged lifecycle hard rule #4\n// reserves for `OfflineEngine.enqueue()`'s own internal idempotency-key\n// minting. This hook does NOT invent a value for it (that would be exactly\n// the \"hook mints its own idempotency key\" anti-pattern hard rule #4\n// forbids, even though `clientToken` is a different field from the\n// transport `Idempotency-Key` header `enqueue()` mints separately and\n// automatically for every op, share writes included). Instead\n// `ShareFormWriteInput.clientToken` is a REQUIRED field the CALLER\n// supplies — a future `ShareFormsSection`/`ShareFormFillScreen` generates\n// one value per form-fill session (e.g. once, the first time a field is\n// touched) and passes the SAME value to every `save()`/`submit()` call for\n// that session, which is what makes retries of the SAME logical write\n// dedupe wire-side. This hook only ever forwards it into the body verbatim.\n//\n// ── REVOCATION DROPS QUEUED WRITES — A REAL SDK GAP, WORKED AROUND HERE ────\n//\n// `02-forms.md`'s `Offline` field: \"Revocation is different and has no\n// grace: a `REVOKED` token drops queued writes unsent and purges the local\n// copy immediately.\" Verified against `kaafil-js/src/offline/share.ts`\n// this session: `ShareGuard.invalidate()` treats `'expired'` and\n// `'revoked'` IDENTICALLY — it purges the read snapshot in both cases and\n// only PRESERVES (never drops) the outbox either way; nothing in\n// `kaafil-js` currently distinguishes \"grace-covered\" from \"unsent, drop\n// it\" at the outbox level. This is a genuine SDK/spec disagreement — see\n// this file's final report note. Rather than leave the spec's hard\n// requirement unmet, this hook enforces it locally on `share.revoked`,\n// riding the outbox's own existing `drop()` primitive (the identical call\n// `useConflicts()`'s `'keep-current'` resolution already makes) — this is\n// composing an existing primitive in reaction to an event, not a second\n// sync engine (hard rule #3): no retry ladder, no cache, no idempotency\n// logic is reimplemented here, only \"remove this op from the outbox\".\n\nimport type { KaafilClient, OutboxOp } from 'kaafil-js/client';\nimport { SyncOpMethod } from 'kaafil-js/client';\nimport { useCallback, useEffect, useState } from 'react';\nimport { isDevelopment } from '../internal/isDevelopment';\nimport { useKaafilClient } from './useKaafilClient';\nimport { useOfflineEngine } from './useOfflineEngine';\nimport { useOfflineEvent } from './useOfflineEvent';\nimport { useOfflineMutation } from './useOfflineMutation';\nimport { usePersona } from './usePersona';\nimport { useServerTime } from './useServerTime';\n\ntype ShareFormsClient = Pick<KaafilClient, 'share'>;\n\n/** One row of `GET /api/v1/share/{token}/forms` — `ShareFormsListResponse`\n * (verified, `kaafil-js/openapi/openapi.json`). Metadata only: no prefill,\n * no field list, no answers (`FRD:traveller-share §4.8`) — that detail\n * arrives only from `renderForm()` below. */\nexport interface ShareFormListItem {\n readonly formId: string;\n readonly key: string;\n readonly title: string;\n readonly phase: string;\n readonly required: boolean;\n readonly fillState: string;\n readonly opensAt: string | null;\n readonly closesAt: string | null;\n readonly responseStatus: string | null;\n readonly submittedAt: string | null;\n}\n\n/** One answer in a `save`/`submit` body — `ShareSaveFormRequest.answers[]`\n * / `ShareSubmitFormRequest.answers[]` (verified). */\nexport interface ShareFormAnswer {\n readonly fieldKey: string;\n readonly value: unknown;\n}\n\nexport interface ShareFormWriteInput {\n readonly formId: string;\n readonly answers: readonly ShareFormAnswer[];\n /** This route's own de-dupe key — REQUIRED by the wire schema. See this\n * file's header (\"`clientToken` IS NOT A HOOK-MINTED IDEMPOTENCY KEY\") —\n * the caller mints this once per form-fill session and reuses it across\n * every save/submit/retry of that session; this hook never generates it. */\n readonly clientToken: string;\n /** Group fill within the same `TripTraveller.partyId` — omit when the\n * token itself already scopes to a single traveller. */\n readonly travellerRef?: string;\n readonly startNew?: boolean;\n readonly isAnonymous?: boolean;\n}\n\nexport type ShareFormsListStatus = 'loading' | 'list-empty' | 'list-populated' | 'not-found';\n\n/**\n * The write-side status a `save()`/`submit()` call's tracked `OutboxOp`\n * resolves to. Deliberately excludes `'filling'` (`02-forms.md`'s own\n * `States` list also names it): `'filling'` is \"the traveller is editing\n * fields, no request in flight yet\" — a pure local UI mode with no\n * server/outbox signal behind it, so it belongs to the composite that owns\n * the form's field state, never to this hook, which only ever reflects\n * something async.\n */\nexport type ShareFormsWriteStatus =\n | 'idle'\n | 'saving'\n | 'submitting'\n | 'submitted'\n | 'conflicted'\n | 'subject-required'\n | 'queued-offline'\n | 'dropped-on-revoke';\n\nexport interface ShareFormsResult {\n readonly status: ShareFormsListStatus;\n /** `[]` in both the `'loading'` and the `'list-empty'` states — a\n * consumer distinguishes them via `status`, never via array emptiness\n * alone (`02-forms.md`'s `Gating`: an empty list is a NORMAL steady\n * state, never an error, never a placeholder). */\n readonly forms: readonly ShareFormListItem[];\n readonly serverTime: string | undefined;\n /** Re-runs `share.forms.list()`. A composite calls this after a\n * `submit()` lands, since submitting can change another form's\n * `fillState` (e.g. an any-phase trigger opening a follow-up form). */\n readonly refresh: () => Promise<void>;\n /** `GET /api/v1/share/{token}/forms/{formId}` — the fully-resolved,\n * ready-to-paint form (definition merged with any in-progress answers).\n * An open shape (`ShareRenderResponse` has no closed schema yet,\n * verified) — a live call, not cached, matching `save`/`submit`'s own\n * un-cached write path. */\n readonly renderForm: (\n formId: string,\n options?: { readonly travellerRef?: string },\n ) => Promise<Record<string, unknown>>;\n /** An in-progress save — no required-field validation server-side. */\n readonly save: (input: ShareFormWriteInput) => Promise<OutboxOp>;\n /** Finalizes the response — full validation, one transaction. */\n readonly submit: (input: ShareFormWriteInput) => Promise<OutboxOp>;\n /** The combined save/submit write status — see `ShareFormsWriteStatus`. */\n readonly writeStatus: ShareFormsWriteStatus;\n /** The most recently tracked save/submit `OutboxOp`, or `undefined`\n * before either has ever been called. */\n readonly writeOp: OutboxOp | undefined;\n}\n\nfunction deriveListStatus(\n forms: readonly ShareFormListItem[] | undefined,\n listFailed: boolean,\n): ShareFormsListStatus {\n if (forms === undefined) {\n return listFailed ? 'not-found' : 'loading';\n }\n return forms.length === 0 ? 'list-empty' : 'list-populated';\n}\n\nfunction deriveWriteStatus(\n revoked: boolean,\n saveOp: OutboxOp | undefined,\n submitOp: OutboxOp | undefined,\n isOnline: boolean,\n): { readonly status: ShareFormsWriteStatus; readonly op: OutboxOp | undefined } {\n if (revoked) {\n return { status: 'dropped-on-revoke', op: submitOp ?? saveOp };\n }\n // `submit` always takes precedence when both are in play — finishing a\n // submission is the more advanced, more important-to-surface state of\n // the two for the same form.\n const active = submitOp !== undefined ? { op: submitOp, kind: 'submit' as const } : undefined;\n const fallback =\n active ?? (saveOp !== undefined ? { op: saveOp, kind: 'save' as const } : undefined);\n if (fallback === undefined) {\n return { status: 'idle', op: undefined };\n }\n const { op, kind } = fallback;\n if (op.status === 'parked') {\n if (op.parkReason?.code === 'CONFLICT_VERSION') {\n return { status: 'conflicted', op };\n }\n if (op.parkReason?.code === 'SUBJECT_REQUIRED') {\n return { status: 'subject-required', op };\n }\n // Any other park reason (e.g. `ShareWriteGraceExpired` —\n // `kaafil-js/src/offline/share.ts`, a grace window that closed before\n // this op ever synced) reports the same as a still-queued offline\n // write: the honest \"still catching up\" framing until it is provably\n // gone (`02-forms.md`'s `Offline` field). A distinct terminal wording\n // for that specific park reason is `ShareFormsSection`'s own\n // presentation concern, not this hook's.\n return { status: 'queued-offline', op };\n }\n if (op.status === 'done') {\n return { status: kind === 'submit' ? 'submitted' : 'idle', op };\n }\n // pending or inflight.\n if (!isOnline) {\n return { status: 'queued-offline', op };\n }\n return { status: kind === 'submit' ? 'submitting' : 'saving', op };\n}\n\nexport function useShareForms(token: string): ShareFormsResult {\n const client = useKaafilClient() as ShareFormsClient;\n const persona = usePersona();\n const engine = useOfflineEngine();\n const { now, sinceLastSync } = useServerTime();\n // `now()` throws before this session's first `snapshot.updated` event —\n // see `useServerTime.ts`'s own \"CALLERS: guard the call site\" note. This\n // hook's writes stay legal without a stamp (see the `enqueuedAt` call\n // sites below), so the guard is \"can I use it\", never \"must I have it\".\n const serverTimeKnown = sinceLastSync !== undefined;\n\n const [forms, setForms] = useState<readonly ShareFormListItem[] | undefined>(undefined);\n const [serverTime, setServerTime] = useState<string | undefined>(undefined);\n const [listFailed, setListFailed] = useState(false);\n const [revoked, setRevoked] = useState(false);\n const [isOnline, setIsOnline] = useState(\n () => typeof navigator === 'undefined' || navigator.onLine,\n );\n\n const fetchList = useCallback(async (): Promise<void> => {\n try {\n const response = await client.share.forms.list({ token });\n setForms(response.items);\n setServerTime(response.meta.serverTime);\n setListFailed(false);\n } catch {\n // `GET .../forms` only ever fails `RESOURCE_NOT_FOUND` (`FRD:\n // traveller-share §4.1`'s route table, verified) — the share 404\n // carve-out means dark/cross-scope/genuinely-gone collapse to one\n // shape, same reasoning `useShareSnapshot()` applies to its own read.\n setListFailed(true);\n }\n }, [client, token]);\n\n useEffect(() => {\n if (persona !== 'share') {\n if (isDevelopment()) {\n throw new Error(\n 'useShareForms() was called from a manager/agencyAdmin session — ' +\n 'this hook is `share`-only (families/traveller/02-forms.md, `ShareFormsSection`).',\n );\n }\n return;\n }\n void fetchList();\n }, [persona, fetchList]);\n\n // A browser-level connectivity signal, same source `useOutboxStatus()`\n // reads (`kaafil-js`'s `OfflineEngine` exposes no queryable connectivity\n // flag of its own — see that hook's own header, verified again here).\n useEffect(() => {\n if (typeof window === 'undefined') {\n return;\n }\n const handleOnline = (): void => setIsOnline(true);\n const handleOffline = (): void => setIsOnline(false);\n window.addEventListener('online', handleOnline);\n window.addEventListener('offline', handleOffline);\n return () => {\n window.removeEventListener('online', handleOnline);\n window.removeEventListener('offline', handleOffline);\n };\n }, []);\n\n useOfflineEvent('share.revoked', () => {\n setRevoked(true);\n // See this file's header (\"REVOCATION DROPS QUEUED WRITES\"). Only this\n // token's own lane, and only ops still in play (a `'done'` op already\n // landed and has nothing left to drop).\n for (const op of engine.outbox.all()) {\n if (op.tripRef === token && (op.status === 'pending' || op.status === 'parked')) {\n void engine.outbox.drop(op.id);\n }\n }\n });\n\n const saveMutation = useOfflineMutation<ShareFormWriteInput>({\n tripRef: token,\n enqueue: (mutationEngine, input) => {\n const query =\n input.travellerRef !== undefined\n ? `?travellerRef=${encodeURIComponent(input.travellerRef)}`\n : '';\n return mutationEngine.enqueue({\n tripRef: token,\n method: SyncOpMethod.Post,\n path: `/api/v1/share/${token}/forms/${input.formId}/save${query}`,\n // Hardcoded literal, not imported: `OperationId` is not exported\n // from `kaafil-js/client`'s public surface (same reasoning\n // `useRooming.ts` documents). Value verified against\n // `kaafil-js/src/generated/security.ts` this session:\n // `OperationId.ShareSaveForm === 'shareSaveForm'`.\n operationId: 'shareSaveForm' as never,\n body: {\n answers: input.answers,\n clientToken: input.clientToken,\n ...(input.startNew !== undefined ? { startNew: input.startNew } : {}),\n ...(input.isAnonymous !== undefined ? { isAnonymous: input.isAnonymous } : {}),\n },\n // The server-anchored \"now\" this write was created at — never\n // `Date.now()`/`new Date()` (hard rule #6) — `EnqueueWriteOptions\n // .enqueuedAt`'s own doc comment: \"client-attested and only ever\n // used by the server to REFUSE\" (the 7-day post-expiry grace\n // check). Optional on the wire, and genuinely omitted here on a\n // cold session: `useServerTime().now()` throws before this\n // session's very first `snapshot.updated` event has landed (its\n // own documented behaviour, guarded at the call site exactly as\n // its header instructs) — a share write attempted in that narrow\n // window still enqueues durably, just without a client-attested\n // stamp for the server's grace check to read.\n ...(serverTimeKnown ? { enqueuedAt: now() } : {}),\n });\n },\n });\n\n const submitMutation = useOfflineMutation<ShareFormWriteInput>({\n tripRef: token,\n enqueue: (mutationEngine, input) => {\n const query =\n input.travellerRef !== undefined\n ? `?travellerRef=${encodeURIComponent(input.travellerRef)}`\n : '';\n return mutationEngine.enqueue({\n tripRef: token,\n method: SyncOpMethod.Post,\n path: `/api/v1/share/${token}/forms/${input.formId}/submit${query}`,\n operationId: 'shareSubmitForm' as never,\n body: {\n answers: input.answers,\n clientToken: input.clientToken,\n ...(input.startNew !== undefined ? { startNew: input.startNew } : {}),\n ...(input.isAnonymous !== undefined ? { isAnonymous: input.isAnonymous } : {}),\n },\n // See the identical `save` enqueue above for why this is guarded.\n ...(serverTimeKnown ? { enqueuedAt: now() } : {}),\n });\n },\n });\n\n const renderForm = useCallback(\n async (\n formId: string,\n options?: { readonly travellerRef?: string },\n ): Promise<Record<string, unknown>> => {\n const response = await client.share.forms.render({\n token,\n formId,\n ...(options?.travellerRef !== undefined ? { travellerRef: options.travellerRef } : {}),\n });\n return response;\n },\n [client, token],\n );\n\n const { status: writeStatus, op: writeOp } = deriveWriteStatus(\n revoked,\n saveMutation.op,\n submitMutation.op,\n isOnline,\n );\n\n return {\n status: deriveListStatus(forms, listFailed),\n forms: forms ?? [],\n serverTime,\n refresh: fetchList,\n renderForm,\n save: saveMutation.mutate,\n submit: submitMutation.mutate,\n writeStatus,\n writeOp,\n };\n}\n","'use client';\n\n// `08-core-hooks.md §3.1`. The single assembled read behind the whole\n// traveller share surface. Wraps `share.snapshot()` (verified `shareAuth`\n// -only in `security.ts` — no `apiKeyAuth` alternative exists for any\n// `share.*` operation), read cache-first from the snapshot once\n// `OfflineEngine`'s `share` option is configured.\n//\n// VERIFIED SHAPE (`openapi/openapi.json`'s `ShareSnapshotResponse`, this\n// session): a flat object with one property PER section key, each present\n// only when the link exposes it and data exists — never `null`, never an\n// empty placeholder — plus a `trip` echo (`name`/`startDate`/`endDate`/\n// `timezone`/`phase`) that is NOT one of the thirteen section flags\n// (`09-registries.md §5`). This hook builds `sections` by taking every own\n// key off the response except `trip` and `meta` — additive-safe against a\n// future 14th section key without needing this file to enumerate all\n// thirteen by name.\n//\n// `trip` and the server clock are surfaced as their OWN top-level fields on\n// `ShareSnapshotResult`, never folded into `sections`: every consumer of\n// `sections` (starting with `KaafilShareView`, which walks the map and\n// renders one composite per key) treats \"is this key present\" as \"should I\n// render a section for it\" — letting `trip`/`meta` leak into that map would\n// make the view try to mount a `<ShareTripSection>`/`<ShareMetaSection>`\n// that has never existed. But every traveller composite still needs BOTH:\n// `trip.timezone` is the one zone `DateDisplay`/`TimeDisplay` may legally\n// anchor to on this surface (never the device zone, never a fabricated\n// `'UTC'`), `trip.phase` lets a composite react to PRE_DEPARTURE/ON_TRIP/\n// POST_TRIP, and `meta.serverTime` is the only trusted \"now\" a share\n// composite may read without going through `useServerTime()` (hard rule\n// #6 — no `Date.now()`/`new Date()` in `src/core`). Hence: two extra return\n// fields, kept structurally apart from the section map they must never\n// pollute.\n\nimport type { KaafilClient } from 'kaafil-js/client';\nimport { useContext, useEffect, useState } from 'react';\nimport { OfflineEngineContext } from '../internal/contexts';\nimport { isDevelopment } from '../internal/isDevelopment';\nimport { useKaafilClient } from './useKaafilClient';\nimport { usePersona } from './usePersona';\n\nexport interface ShareSnapshotOptions {\n readonly travellerRef?: string;\n}\n\n// Derived from the SDK's own return type rather than hand-copied — this\n// stays correct for free if `kaafil-js` grows another `trip` field, instead\n// of silently drifting the way the old `'UTC'` constants did.\ntype ShareSnapshotResponse = Awaited<ReturnType<KaafilClient['share']['snapshot']>>;\n\n/** The trip echo every snapshot response carries — `name`/`startDate`/\n * `endDate` plus the two fields this hook used to throw away:\n * `timezone` (the IANA zone every traveller-facing render must anchor to)\n * and `phase` (server-computed `PRE_DEPARTURE`/`ON_TRIP`/`POST_TRIP`). */\nexport type ShareSnapshotTrip = ShareSnapshotResponse['trip'];\n\nexport interface ShareSnapshotResult {\n readonly status: 'loading' | 'ready' | 'expired' | 'revoked' | 'not-found';\n readonly sections: ReadonlyMap<string, unknown>;\n /** The snapshot's `trip` echo, or `undefined` before any response has\n * landed (mirrors `sections`' own \"empty until ready\" behaviour). NEVER a\n * section key — see this file's header. */\n readonly trip: ShareSnapshotTrip | undefined;\n /** `meta.serverTime` off the most recently landed snapshot response — the\n * only trusted clock a share composite may read (hard rule #6). Kept\n * separate from `useServerTime()`'s own stream (which advances off\n * `OfflineEngine`'s `snapshot.updated` event, not this hook's own fetch)\n * so a composite that only ever calls `useShareSnapshot()` still has a\n * real server stamp to compare against without also wiring the offline\n * engine's event stream. `undefined` before any response has landed. */\n readonly serverTime: string | undefined;\n}\n\nconst NON_SECTION_KEYS = new Set(['trip', 'meta']);\n\nexport function useShareSnapshot(\n token: string,\n options?: ShareSnapshotOptions,\n): ShareSnapshotResult {\n void options; // `travellerRef` narrows which subject-token rows the server\n // itself returns for a `travellerRef`-scoped share link — this hook has no\n // client-side use for it beyond passing the token through; the server does\n // the scoping (`09-registries.md §5`, `families/traveller/01-share-sections.md`, cited).\n\n const client = useKaafilClient();\n const persona = usePersona();\n const engine = useContext(OfflineEngineContext);\n const [sections, setSections] = useState<ReadonlyMap<string, unknown> | undefined>(undefined);\n const [trip, setTrip] = useState<ShareSnapshotTrip | undefined>(undefined);\n const [serverTime, setServerTime] = useState<string | undefined>(undefined);\n const [terminal, setTerminal] = useState<'expired' | 'revoked' | 'not-found' | undefined>(\n undefined,\n );\n\n useEffect(() => {\n if (persona !== 'share') {\n if (isDevelopment()) {\n throw new Error(\n 'useShareSnapshot() was called from a manager/agencyAdmin session — ' +\n 'this hook is `share`-only (08-core-hooks.md §3.1).',\n );\n }\n return;\n }\n\n let cancelled = false;\n async function load(): Promise<void> {\n try {\n const response = await client.share.snapshot({ token });\n if (cancelled) {\n return;\n }\n const map = new Map<string, unknown>();\n for (const [key, value] of Object.entries(response)) {\n if (!NON_SECTION_KEYS.has(key)) {\n map.set(key, value);\n }\n }\n setSections(map);\n setTrip(response.trip);\n setServerTime(response.meta.serverTime);\n } catch {\n // `06-capability-and-personas.md §9`: dark, cross-scope, and\n // genuinely-gone all collapse to the identical shape here — this\n // hook cannot and must not try to distinguish them, so any failure\n // to read the snapshot at all reports the same `'not-found'`.\n if (!cancelled) {\n setTerminal('not-found');\n }\n }\n }\n void load();\n\n if (engine === null) {\n return () => {\n cancelled = true;\n };\n }\n const unsubscribeExpired = engine.events.on('share.expired', () => setTerminal('expired'));\n const unsubscribeRevoked = engine.events.on('share.revoked', () => setTerminal('revoked'));\n return () => {\n cancelled = true;\n unsubscribeExpired();\n unsubscribeRevoked();\n };\n }, [client, persona, token, engine]);\n\n if (terminal !== undefined) {\n return { status: terminal, sections: sections ?? new Map(), trip, serverTime };\n }\n if (sections === undefined) {\n return { status: 'loading', sections: new Map(), trip: undefined, serverTime: undefined };\n }\n return { status: 'ready', sections, trip, serverTime };\n}\n"]}
1
+ {"version":3,"sources":["../src/core/hooks/useShareForms.ts","../src/core/hooks/useShareSnapshot.ts"],"names":["client","useKaafilClient","usePersona","useOfflineEngine","useServerTime","useState","useCallback","useEffect","isDevelopment","useOfflineEvent","useOfflineMutation","SyncOpMethod","useContext","OfflineEngineContext"],"mappings":"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","file":"chunk-BBC5EX5O.cjs","sourcesContent":["'use client';\n\n// `08-core-hooks.md §3` (new row — `ShareFormsSection`'s `Backed by`,\n// `ui-kit/families/traveller/02-forms.md`, cited): the write-back half of\n// the traveller share surface. `forms` is the ONLY write-back section on\n// the whole share surface; every other section is read-only through\n// `useShareSnapshot()` alone. This hook wraps the four dedicated\n// `shareAuth`-only routes `share.forms.{list,render,save,submit}`\n// (`kaafil-js/src/resources/share.ts`, verified this session).\n//\n// ── WHY THIS HOOK DOES NOT ALSO CALL `useShareSnapshot()` ──────────────────\n//\n// `02-forms.md`'s `Backed by` field says the section's own `/core` hook\n// \"composes both\" — the snapshot (for `forms` section presence) and the\n// dedicated routes (for the actual list/render/save/submit). This file\n// deliberately does NOT reproduce the snapshot fetch: `ShareFormsSection`\n// (future work, not this file) is only ever mounted once its own call to\n// `useShareSnapshot(token)` has already confirmed `sections.has('forms')`\n// (`01-share-sections.md`'s registry-driven mount rule) — duplicating that\n// fetch here would be a second, redundant read of the same snapshot for no\n// new information, and this hook has nothing to add to a presence check it\n// does not own. What this file DOES independently reproduce is\n// `useShareSnapshot()`'s own persona gate and its `share.expired`/\n// `share.revoked` subscriptions (`08-core-hooks.md §0`: \"every domain hook\n// is capability-gated internally\" — the share-surface's equivalent gate is\n// the persona check, applied the same way every other hook in this catalog\n// applies its own).\n//\n// ── SPEC TENSION FLAGGED: \"cache-first\" vs. \"the dedicated routes\" ─────────\n//\n// `02-forms.md`'s `Offline` field says the list \"rides the scoped share\n// snapshot cache-first, same as every other section\", but its own `Backed\n// by` field says in the same breath that \"the actual form list/render/\n// save/submit calls ride the dedicated forms-share routes\" — and\n// `ShareSnapshotResponse`'s per-section shape (verified,\n// `useShareSnapshot.ts`) carries no registered `forms` array with\n// `fillState`/`opensAt`/`closesAt` fields; only `ShareFormsListResponse`\n// (`GET /api/v1/share/{token}/forms`) does. This file follows the more\n// specific, SDK-verified statement — a LIVE `share.forms.list()` call,\n// refreshable on demand — the same \"own live-fetch sub-state, not a\n// `snapshot.updated` subscription\" pattern `useRooming.ts`'s\n// `unassignedPool` already uses for an analogous non-delta read. Flagged\n// for the doc owner to resolve; not silently picked one way with no trace.\n//\n// ── `clientToken` IS NOT A HOOK-MINTED IDEMPOTENCY KEY ──────────────────────\n//\n// `ShareSaveFormRequest`/`ShareSubmitFormRequest` (verified,\n// `kaafil-js/openapi/openapi.json`) require a body-level `clientToken`\n// (16-255 chars) — the SDK's own comment on `share.ts` calls it \"this\n// route's own de-dupe key, distinct from the automatic `Idempotency-Key`\n// header\", and `modules/forms/FRD.md §4.1/§8` calls it \"a fixed\n// `clientToken` generated once at enqueue and reused on every retry\" —\n// i.e. exactly the write-once, replay-unchanged lifecycle hard rule #4\n// reserves for `OfflineEngine.enqueue()`'s own internal idempotency-key\n// minting. This hook does NOT invent a value for it (that would be exactly\n// the \"hook mints its own idempotency key\" anti-pattern hard rule #4\n// forbids, even though `clientToken` is a different field from the\n// transport `Idempotency-Key` header `enqueue()` mints separately and\n// automatically for every op, share writes included). Instead\n// `ShareFormWriteInput.clientToken` is a REQUIRED field the CALLER\n// supplies — a future `ShareFormsSection`/`ShareFormFillScreen` generates\n// one value per form-fill session (e.g. once, the first time a field is\n// touched) and passes the SAME value to every `save()`/`submit()` call for\n// that session, which is what makes retries of the SAME logical write\n// dedupe wire-side. This hook only ever forwards it into the body verbatim.\n//\n// ── REVOCATION DROPS QUEUED WRITES — A REAL SDK GAP, WORKED AROUND HERE ────\n//\n// `02-forms.md`'s `Offline` field: \"Revocation is different and has no\n// grace: a `REVOKED` token drops queued writes unsent and purges the local\n// copy immediately.\" Verified against `kaafil-js/src/offline/share.ts`\n// this session: `ShareGuard.invalidate()` treats `'expired'` and\n// `'revoked'` IDENTICALLY — it purges the read snapshot in both cases and\n// only PRESERVES (never drops) the outbox either way; nothing in\n// `kaafil-js` currently distinguishes \"grace-covered\" from \"unsent, drop\n// it\" at the outbox level. This is a genuine SDK/spec disagreement — see\n// this file's final report note. Rather than leave the spec's hard\n// requirement unmet, this hook enforces it locally on `share.revoked`,\n// riding the outbox's own existing `drop()` primitive (the identical call\n// `useConflicts()`'s `'keep-current'` resolution already makes) — this is\n// composing an existing primitive in reaction to an event, not a second\n// sync engine (hard rule #3): no retry ladder, no cache, no idempotency\n// logic is reimplemented here, only \"remove this op from the outbox\".\n\nimport type { KaafilClient, OutboxOp } from 'kaafil-js/client';\nimport { SyncOpMethod } from 'kaafil-js/client';\nimport { useCallback, useEffect, useState } from 'react';\nimport { isDevelopment } from '../internal/isDevelopment';\nimport { useKaafilClient } from './useKaafilClient';\nimport { useOfflineEngine } from './useOfflineEngine';\nimport { useOfflineEvent } from './useOfflineEvent';\nimport { useOfflineMutation } from './useOfflineMutation';\nimport { usePersona } from './usePersona';\nimport { useServerTime } from './useServerTime';\n\ntype ShareFormsClient = Pick<KaafilClient, 'share'>;\n\n/** One row of `GET /api/v1/share/{token}/forms` — `ShareFormsListResponse`\n * (verified, `kaafil-js/openapi/openapi.json`). Metadata only: no prefill,\n * no field list, no answers (`FRD:traveller-share §4.8`) — that detail\n * arrives only from `renderForm()` below. */\nexport interface ShareFormListItem {\n readonly formId: string;\n readonly key: string;\n readonly title: string;\n readonly phase: string;\n readonly required: boolean;\n readonly fillState: string;\n readonly opensAt: string | null;\n readonly closesAt: string | null;\n readonly responseStatus: string | null;\n readonly submittedAt: string | null;\n}\n\n/** One answer in a `save`/`submit` body — `ShareSaveFormRequest.answers[]`\n * / `ShareSubmitFormRequest.answers[]` (verified). */\nexport interface ShareFormAnswer {\n readonly fieldKey: string;\n readonly value: unknown;\n}\n\nexport interface ShareFormWriteInput {\n readonly formId: string;\n readonly answers: readonly ShareFormAnswer[];\n /** This route's own de-dupe key — REQUIRED by the wire schema. See this\n * file's header (\"`clientToken` IS NOT A HOOK-MINTED IDEMPOTENCY KEY\") —\n * the caller mints this once per form-fill session and reuses it across\n * every save/submit/retry of that session; this hook never generates it. */\n readonly clientToken: string;\n /** Group fill within the same `TripTraveller.partyId` — omit when the\n * token itself already scopes to a single traveller. */\n readonly travellerRef?: string;\n readonly startNew?: boolean;\n readonly isAnonymous?: boolean;\n}\n\nexport type ShareFormsListStatus = 'loading' | 'list-empty' | 'list-populated' | 'not-found';\n\n/**\n * The write-side status a `save()`/`submit()` call's tracked `OutboxOp`\n * resolves to. Deliberately excludes `'filling'` (`02-forms.md`'s own\n * `States` list also names it): `'filling'` is \"the traveller is editing\n * fields, no request in flight yet\" — a pure local UI mode with no\n * server/outbox signal behind it, so it belongs to the composite that owns\n * the form's field state, never to this hook, which only ever reflects\n * something async.\n */\nexport type ShareFormsWriteStatus =\n | 'idle'\n | 'saving'\n | 'submitting'\n | 'submitted'\n | 'conflicted'\n | 'subject-required'\n | 'queued-offline'\n | 'dropped-on-revoke';\n\nexport interface ShareFormsResult {\n readonly status: ShareFormsListStatus;\n /** `[]` in both the `'loading'` and the `'list-empty'` states — a\n * consumer distinguishes them via `status`, never via array emptiness\n * alone (`02-forms.md`'s `Gating`: an empty list is a NORMAL steady\n * state, never an error, never a placeholder). */\n readonly forms: readonly ShareFormListItem[];\n readonly serverTime: string | undefined;\n /** Re-runs `share.forms.list()`. A composite calls this after a\n * `submit()` lands, since submitting can change another form's\n * `fillState` (e.g. an any-phase trigger opening a follow-up form). */\n readonly refresh: () => Promise<void>;\n /** `GET /api/v1/share/{token}/forms/{formId}` — the fully-resolved,\n * ready-to-paint form (definition merged with any in-progress answers).\n * An open shape (`ShareRenderResponse` has no closed schema yet,\n * verified) — a live call, not cached, matching `save`/`submit`'s own\n * un-cached write path. */\n readonly renderForm: (\n formId: string,\n options?: { readonly travellerRef?: string },\n ) => Promise<Record<string, unknown>>;\n /** An in-progress save — no required-field validation server-side. */\n readonly save: (input: ShareFormWriteInput) => Promise<OutboxOp>;\n /** Finalizes the response — full validation, one transaction. */\n readonly submit: (input: ShareFormWriteInput) => Promise<OutboxOp>;\n /** The combined save/submit write status — see `ShareFormsWriteStatus`. */\n readonly writeStatus: ShareFormsWriteStatus;\n /** The most recently tracked save/submit `OutboxOp`, or `undefined`\n * before either has ever been called. */\n readonly writeOp: OutboxOp | undefined;\n}\n\nfunction deriveListStatus(\n forms: readonly ShareFormListItem[] | undefined,\n listFailed: boolean,\n): ShareFormsListStatus {\n if (forms === undefined) {\n return listFailed ? 'not-found' : 'loading';\n }\n return forms.length === 0 ? 'list-empty' : 'list-populated';\n}\n\nfunction deriveWriteStatus(\n revoked: boolean,\n saveOp: OutboxOp | undefined,\n submitOp: OutboxOp | undefined,\n isOnline: boolean,\n): { readonly status: ShareFormsWriteStatus; readonly op: OutboxOp | undefined } {\n if (revoked) {\n return { status: 'dropped-on-revoke', op: submitOp ?? saveOp };\n }\n // `submit` always takes precedence when both are in play — finishing a\n // submission is the more advanced, more important-to-surface state of\n // the two for the same form.\n const active = submitOp !== undefined ? { op: submitOp, kind: 'submit' as const } : undefined;\n const fallback =\n active ?? (saveOp !== undefined ? { op: saveOp, kind: 'save' as const } : undefined);\n if (fallback === undefined) {\n return { status: 'idle', op: undefined };\n }\n const { op, kind } = fallback;\n if (op.status === 'parked') {\n if (op.parkReason?.code === 'CONFLICT_VERSION') {\n return { status: 'conflicted', op };\n }\n if (op.parkReason?.code === 'SUBJECT_REQUIRED') {\n return { status: 'subject-required', op };\n }\n // Any other park reason (e.g. `ShareWriteGraceExpired` —\n // `kaafil-js/src/offline/share.ts`, a grace window that closed before\n // this op ever synced) reports the same as a still-queued offline\n // write: the honest \"still catching up\" framing until it is provably\n // gone (`02-forms.md`'s `Offline` field). A distinct terminal wording\n // for that specific park reason is `ShareFormsSection`'s own\n // presentation concern, not this hook's.\n return { status: 'queued-offline', op };\n }\n if (op.status === 'done') {\n return { status: kind === 'submit' ? 'submitted' : 'idle', op };\n }\n // pending or inflight.\n if (!isOnline) {\n return { status: 'queued-offline', op };\n }\n return { status: kind === 'submit' ? 'submitting' : 'saving', op };\n}\n\nexport function useShareForms(token: string): ShareFormsResult {\n const client = useKaafilClient() as ShareFormsClient;\n const persona = usePersona();\n const engine = useOfflineEngine();\n const { now, sinceLastSync } = useServerTime();\n // `now()` throws before this session's first `snapshot.updated` event —\n // see `useServerTime.ts`'s own \"CALLERS: guard the call site\" note. This\n // hook's writes stay legal without a stamp (see the `enqueuedAt` call\n // sites below), so the guard is \"can I use it\", never \"must I have it\".\n const serverTimeKnown = sinceLastSync !== undefined;\n\n const [forms, setForms] = useState<readonly ShareFormListItem[] | undefined>(undefined);\n const [serverTime, setServerTime] = useState<string | undefined>(undefined);\n const [listFailed, setListFailed] = useState(false);\n const [revoked, setRevoked] = useState(false);\n const [isOnline, setIsOnline] = useState(\n () => typeof navigator === 'undefined' || navigator.onLine,\n );\n\n const fetchList = useCallback(async (): Promise<void> => {\n try {\n const response = await client.share.forms.list({ token });\n setForms(response.items);\n setServerTime(response.meta.serverTime);\n setListFailed(false);\n } catch {\n // `GET .../forms` only ever fails `RESOURCE_NOT_FOUND` (`FRD:\n // traveller-share §4.1`'s route table, verified) — the share 404\n // carve-out means dark/cross-scope/genuinely-gone collapse to one\n // shape, same reasoning `useShareSnapshot()` applies to its own read.\n setListFailed(true);\n }\n }, [client, token]);\n\n useEffect(() => {\n if (persona !== 'share') {\n if (isDevelopment()) {\n throw new Error(\n 'useShareForms() was called from a manager/agencyAdmin session — ' +\n 'this hook is `share`-only (families/traveller/02-forms.md, `ShareFormsSection`).',\n );\n }\n return;\n }\n void fetchList();\n }, [persona, fetchList]);\n\n // A browser-level connectivity signal, same source `useOutboxStatus()`\n // reads (`kaafil-js`'s `OfflineEngine` exposes no queryable connectivity\n // flag of its own — see that hook's own header, verified again here).\n useEffect(() => {\n if (typeof window === 'undefined') {\n return;\n }\n const handleOnline = (): void => setIsOnline(true);\n const handleOffline = (): void => setIsOnline(false);\n window.addEventListener('online', handleOnline);\n window.addEventListener('offline', handleOffline);\n return () => {\n window.removeEventListener('online', handleOnline);\n window.removeEventListener('offline', handleOffline);\n };\n }, []);\n\n useOfflineEvent('share.revoked', () => {\n setRevoked(true);\n // See this file's header (\"REVOCATION DROPS QUEUED WRITES\"). Only this\n // token's own lane, and only ops still in play (a `'done'` op already\n // landed and has nothing left to drop).\n for (const op of engine.outbox.all()) {\n if (op.tripRef === token && (op.status === 'pending' || op.status === 'parked')) {\n void engine.outbox.drop(op.id);\n }\n }\n });\n\n const saveMutation = useOfflineMutation<ShareFormWriteInput>({\n tripRef: token,\n enqueue: (mutationEngine, input) => {\n const query =\n input.travellerRef !== undefined\n ? `?travellerRef=${encodeURIComponent(input.travellerRef)}`\n : '';\n return mutationEngine.enqueue({\n tripRef: token,\n method: SyncOpMethod.Post,\n path: `/api/v1/share/${token}/forms/${input.formId}/save${query}`,\n // Hardcoded literal, not imported: `OperationId` is not exported\n // from `kaafil-js/client`'s public surface (same reasoning\n // `useRooming.ts` documents). Value verified against\n // `kaafil-js/src/generated/security.ts` this session:\n // `OperationId.ShareSaveForm === 'shareSaveForm'`.\n operationId: 'shareSaveForm' as never,\n body: {\n answers: input.answers,\n clientToken: input.clientToken,\n ...(input.startNew !== undefined ? { startNew: input.startNew } : {}),\n ...(input.isAnonymous !== undefined ? { isAnonymous: input.isAnonymous } : {}),\n },\n // The server-anchored \"now\" this write was created at — never\n // `Date.now()`/`new Date()` (hard rule #6) — `EnqueueWriteOptions\n // .enqueuedAt`'s own doc comment: \"client-attested and only ever\n // used by the server to REFUSE\" (the 7-day post-expiry grace\n // check). Optional on the wire, and genuinely omitted here on a\n // cold session: `useServerTime().now()` throws before this\n // session's very first `snapshot.updated` event has landed (its\n // own documented behaviour, guarded at the call site exactly as\n // its header instructs) — a share write attempted in that narrow\n // window still enqueues durably, just without a client-attested\n // stamp for the server's grace check to read.\n ...(serverTimeKnown ? { enqueuedAt: now() } : {}),\n });\n },\n });\n\n const submitMutation = useOfflineMutation<ShareFormWriteInput>({\n tripRef: token,\n enqueue: (mutationEngine, input) => {\n const query =\n input.travellerRef !== undefined\n ? `?travellerRef=${encodeURIComponent(input.travellerRef)}`\n : '';\n return mutationEngine.enqueue({\n tripRef: token,\n method: SyncOpMethod.Post,\n path: `/api/v1/share/${token}/forms/${input.formId}/submit${query}`,\n operationId: 'shareSubmitForm' as never,\n body: {\n answers: input.answers,\n clientToken: input.clientToken,\n ...(input.startNew !== undefined ? { startNew: input.startNew } : {}),\n ...(input.isAnonymous !== undefined ? { isAnonymous: input.isAnonymous } : {}),\n },\n // See the identical `save` enqueue above for why this is guarded.\n ...(serverTimeKnown ? { enqueuedAt: now() } : {}),\n });\n },\n });\n\n const renderForm = useCallback(\n async (\n formId: string,\n options?: { readonly travellerRef?: string },\n ): Promise<Record<string, unknown>> => {\n const response = await client.share.forms.render({\n token,\n formId,\n ...(options?.travellerRef !== undefined ? { travellerRef: options.travellerRef } : {}),\n });\n return response;\n },\n [client, token],\n );\n\n const { status: writeStatus, op: writeOp } = deriveWriteStatus(\n revoked,\n saveMutation.op,\n submitMutation.op,\n isOnline,\n );\n\n return {\n status: deriveListStatus(forms, listFailed),\n forms: forms ?? [],\n serverTime,\n refresh: fetchList,\n renderForm,\n save: saveMutation.mutate,\n submit: submitMutation.mutate,\n writeStatus,\n writeOp,\n };\n}\n","'use client';\n\n// `08-core-hooks.md §3.1`. The single assembled read behind the whole\n// traveller share surface. Wraps `share.snapshot()` (verified `shareAuth`\n// -only in `security.ts` — no `apiKeyAuth` alternative exists for any\n// `share.*` operation), read cache-first from the snapshot once\n// `OfflineEngine`'s `share` option is configured.\n//\n// VERIFIED SHAPE (`openapi/openapi.json`'s `ShareSnapshotResponse`, this\n// session): a flat object with one property PER section key, each present\n// only when the link exposes it and data exists — never `null`, never an\n// empty placeholder — plus a `trip` echo (`name`/`startDate`/`endDate`/\n// `timezone`/`phase`) that is NOT one of the thirteen section flags\n// (`09-registries.md §5`). This hook builds `sections` by taking every own\n// key off the response except `trip` and `meta` — additive-safe against a\n// future 14th section key without needing this file to enumerate all\n// thirteen by name.\n//\n// `trip` and the server clock are surfaced as their OWN top-level fields on\n// `ShareSnapshotResult`, never folded into `sections`: every consumer of\n// `sections` (starting with `KaafilShareView`, which walks the map and\n// renders one composite per key) treats \"is this key present\" as \"should I\n// render a section for it\" — letting `trip`/`meta` leak into that map would\n// make the view try to mount a `<ShareTripSection>`/`<ShareMetaSection>`\n// that has never existed. But every traveller composite still needs BOTH:\n// `trip.timezone` is the one zone `DateDisplay`/`TimeDisplay` may legally\n// anchor to on this surface (never the device zone, never a fabricated\n// `'UTC'`), `trip.phase` lets a composite react to PRE_DEPARTURE/ON_TRIP/\n// POST_TRIP, and `meta.serverTime` is the only trusted \"now\" a share\n// composite may read without going through `useServerTime()` (hard rule\n// #6 — no `Date.now()`/`new Date()` in `src/core`). Hence: two extra return\n// fields, kept structurally apart from the section map they must never\n// pollute.\n\nimport type { KaafilClient } from 'kaafil-js/client';\nimport { useContext, useEffect, useState } from 'react';\nimport { OfflineEngineContext } from '../internal/contexts';\nimport { isDevelopment } from '../internal/isDevelopment';\nimport { useKaafilClient } from './useKaafilClient';\nimport { usePersona } from './usePersona';\n\nexport interface ShareSnapshotOptions {\n readonly travellerRef?: string;\n}\n\n// Derived from the SDK's own return type rather than hand-copied — this\n// stays correct for free if `kaafil-js` grows another `trip` field, instead\n// of silently drifting the way the old `'UTC'` constants did.\ntype ShareSnapshotResponse = Awaited<ReturnType<KaafilClient['share']['snapshot']>>;\n\n/** The trip echo every snapshot response carries — `name`/`startDate`/\n * `endDate` plus the two fields this hook used to throw away:\n * `timezone` (the IANA zone every traveller-facing render must anchor to)\n * and `phase` (server-computed `PRE_DEPARTURE`/`ON_TRIP`/`POST_TRIP`). */\nexport type ShareSnapshotTrip = ShareSnapshotResponse['trip'];\n\nexport interface ShareSnapshotResult {\n readonly status: 'loading' | 'ready' | 'expired' | 'revoked' | 'not-found';\n readonly sections: ReadonlyMap<string, unknown>;\n /** The snapshot's `trip` echo, or `undefined` before any response has\n * landed (mirrors `sections`' own \"empty until ready\" behaviour). NEVER a\n * section key — see this file's header. */\n readonly trip: ShareSnapshotTrip | undefined;\n /** `meta.serverTime` off the most recently landed snapshot response — the\n * only trusted clock a share composite may read (hard rule #6). Kept\n * separate from `useServerTime()`'s own stream (which advances off\n * `OfflineEngine`'s `snapshot.updated` event, not this hook's own fetch)\n * so a composite that only ever calls `useShareSnapshot()` still has a\n * real server stamp to compare against without also wiring the offline\n * engine's event stream. `undefined` before any response has landed. */\n readonly serverTime: string | undefined;\n}\n\nconst NON_SECTION_KEYS = new Set(['trip', 'meta']);\n\nexport function useShareSnapshot(\n token: string,\n options?: ShareSnapshotOptions,\n): ShareSnapshotResult {\n void options; // `travellerRef` narrows which subject-token rows the server\n // itself returns for a `travellerRef`-scoped share link — this hook has no\n // client-side use for it beyond passing the token through; the server does\n // the scoping (`09-registries.md §5`, `families/traveller/01-share-sections.md`, cited).\n\n const client = useKaafilClient();\n const persona = usePersona();\n const engine = useContext(OfflineEngineContext);\n const [sections, setSections] = useState<ReadonlyMap<string, unknown> | undefined>(undefined);\n const [trip, setTrip] = useState<ShareSnapshotTrip | undefined>(undefined);\n const [serverTime, setServerTime] = useState<string | undefined>(undefined);\n const [terminal, setTerminal] = useState<'expired' | 'revoked' | 'not-found' | undefined>(\n undefined,\n );\n\n useEffect(() => {\n if (persona !== 'share') {\n if (isDevelopment()) {\n throw new Error(\n 'useShareSnapshot() was called from a manager/agencyAdmin session — ' +\n 'this hook is `share`-only (08-core-hooks.md §3.1).',\n );\n }\n return;\n }\n\n let cancelled = false;\n async function load(): Promise<void> {\n try {\n const response = await client.share.snapshot({ token });\n if (cancelled) {\n return;\n }\n const map = new Map<string, unknown>();\n for (const [key, value] of Object.entries(response)) {\n if (!NON_SECTION_KEYS.has(key)) {\n map.set(key, value);\n }\n }\n setSections(map);\n setTrip(response.trip);\n setServerTime(response.meta.serverTime);\n } catch {\n // `06-capability-and-personas.md §9`: dark, cross-scope, and\n // genuinely-gone all collapse to the identical shape here — this\n // hook cannot and must not try to distinguish them, so any failure\n // to read the snapshot at all reports the same `'not-found'`.\n if (!cancelled) {\n setTerminal('not-found');\n }\n }\n }\n void load();\n\n if (engine === null) {\n return () => {\n cancelled = true;\n };\n }\n const unsubscribeExpired = engine.events.on('share.expired', () => setTerminal('expired'));\n const unsubscribeRevoked = engine.events.on('share.revoked', () => setTerminal('revoked'));\n return () => {\n cancelled = true;\n unsubscribeExpired();\n unsubscribeRevoked();\n };\n }, [client, persona, token, engine]);\n\n if (terminal !== undefined) {\n return { status: terminal, sections: sections ?? new Map(), trip, serverTime };\n }\n if (sections === undefined) {\n return { status: 'loading', sections: new Map(), trip: undefined, serverTime: undefined };\n }\n return { status: 'ready', sections, trip, serverTime };\n}\n"]}
@@ -14,6 +14,9 @@ function useServerTime() {
14
14
  return;
15
15
  }
16
16
  const unsubscribe = engine.events.on("snapshot.updated", (event) => {
17
+ if (event.serverTime === void 0) {
18
+ return;
19
+ }
17
20
  observedAtPerfRef.current = performance.now();
18
21
  setLastServerTime(event.serverTime);
19
22
  });
@@ -36,5 +39,5 @@ function useServerTime() {
36
39
  }
37
40
 
38
41
  exports.useServerTime = useServerTime;
39
- //# sourceMappingURL=chunk-7UFX3Y2U.cjs.map
40
- //# sourceMappingURL=chunk-7UFX3Y2U.cjs.map
42
+ //# sourceMappingURL=chunk-ECCQW5LN.cjs.map
43
+ //# sourceMappingURL=chunk-ECCQW5LN.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/core/hooks/useServerTime.ts"],"names":["useContext","OfflineEngineContext","useState","useRef","useEffect"],"mappings":";;;;;AA8BA,IAAM,gBAAA,GAAmB,GAAA;AAElB,SAAS,aAAA,GAA+B;AAC7C,EAAA,MAAM,MAAA,GAASA,iBAAWC,sCAAoB,CAAA;AAC9C,EAAA,MAAM,CAAC,cAAA,EAAgB,iBAAiB,CAAA,GAAIC,eAA6B,MAAS,CAAA;AAClF,EAAA,MAAM,iBAAA,GAAoBC,aAA2B,MAAS,CAAA;AAC9D,EAAA,MAAM,GAAG,SAAS,CAAA,GAAID,eAAS,CAAC,CAAA;AAEhC,EAAAE,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,WAAW,IAAA,EAAM;AACnB,MAAA;AAAA,IACF;AAKA,IAAA,MAAM,cAAc,MAAA,CAAO,MAAA,CAAO,EAAA,CAAG,kBAAA,EAAoB,CAAC,KAAA,KAAU;AASlE,MAAA,IAAI,KAAA,CAAM,eAAe,MAAA,EAAW;AAClC,QAAA;AAAA,MACF;AACA,MAAA,iBAAA,CAAkB,OAAA,GAAU,YAAY,GAAA,EAAI;AAC5C,MAAA,iBAAA,CAAkB,MAAM,UAAU,CAAA;AAAA,IACpC,CAAC,CAAA;AACD,IAAA,OAAO,WAAA;AAAA,EACT,CAAA,EAAG,CAAC,MAAM,CAAC,CAAA;AAEX,EAAAA,eAAA,CAAU,MAAM;AACd,IAAA,MAAM,EAAA,GAAK,YAAY,MAAM,SAAA,CAAU,CAAC,IAAA,KAAS,IAAA,GAAO,CAAC,CAAA,EAAG,gBAAgB,CAAA;AAC5E,IAAA,OAAO,MAAM,cAAc,EAAE,CAAA;AAAA,EAC/B,CAAA,EAAG,EAAE,CAAA;AAEL,EAAA,SAAS,GAAA,GAAc;AACrB,IAAA,IAAI,cAAA,KAAmB,MAAA,IAAa,iBAAA,CAAkB,OAAA,KAAY,MAAA,EAAW;AAY3E,MAAA,MAAM,IAAI,KAAA;AAAA,QACR;AAAA,OAEF;AAAA,IACF;AACA,IAAA,MAAM,SAAA,GAAY,WAAA,CAAY,GAAA,EAAI,GAAI,iBAAA,CAAkB,OAAA;AACxD,IAAA,OAAO,IAAI,KAAK,IAAA,CAAK,KAAA,CAAM,cAAc,CAAA,GAAI,SAAS,EAAE,WAAA,EAAY;AAAA,EACtE;AAEA,EAAA,OAAO,EAAE,GAAA,EAAK,aAAA,EAAe,cAAA,EAAe;AAC9C","file":"chunk-ECCQW5LN.cjs","sourcesContent":["'use client';\n\n// `08-core-hooks.md §1.6`. The single place that turns the stream of\n// `meta.serverTime` stamps into a usable clock, so no composite reads\n// `meta.serverTime` off an individual response by hand.\n//\n// Hard rule #6 (\"Zero `Date.now()`/`new Date()` local getters in\n// `src/core`\") bans exactly the two calls that fabricate \"now\" from the\n// local wall clock: `Date.now()` and no-argument `new Date()`. This file\n// never calls either. Advancing a SERVER-supplied timestamp by an elapsed\n// delta necessarily needs SOME measure of \"how much local time passed\" —\n// this file measures that with `performance.now()`, a monotonic clock with\n// no relationship to wall-clock \"now\" (it cannot be read as a date, only as\n// a duration), and applies the delta with `new Date(<epoch-ms>)` /\n// `Date.parse(<iso-string>)` — both single-argument forms that operate on a\n// value already anchored to `meta.serverTime`, never on the local clock.\n\nimport { useContext, useEffect, useRef, useState } from 'react';\nimport { OfflineEngineContext } from '../internal/contexts';\n\nexport interface ServerTimeApi {\n now: () => string;\n sinceLastSync: string | undefined;\n}\n\n/** Re-renders any hook consumer often enough for a mounted countdown to look\n * live, without pretending the underlying value moved forward on its own\n * merits (`08-core-hooks.md §1.6`'s sandbox time-travel caveat: this timer\n * forces a re-render, it never advances the stamp past what the last real\n * response justified). */\nconst TICK_INTERVAL_MS = 1000;\n\nexport function useServerTime(): ServerTimeApi {\n const engine = useContext(OfflineEngineContext);\n const [lastServerTime, setLastServerTime] = useState<string | undefined>(undefined);\n const observedAtPerfRef = useRef<number | undefined>(undefined);\n const [, forceTick] = useState(0);\n\n useEffect(() => {\n if (engine === null) {\n return;\n }\n // `snapshot.updated` is the one event in `OfflineEventMap` that carries\n // `serverTime` (`kaafil-js/src/offline/events.ts`, verified this\n // session) — the engine's other five events do not, so this is the only\n // subscription this hook can build without inventing a stamp.\n const unsubscribe = engine.events.on('snapshot.updated', (event) => {\n // `serverTime` is ABSENT on a change that never involved the server —\n // an optimistic create painted while offline, or an op the host\n // discarded (`kaafil-js/src/offline/events.ts`). Those are real snapshot\n // changes and a list must repaint for them, but they carry no reading,\n // and taking `undefined` here would erase the last real one this\n // session had: `now()` would start throwing again mid-session, on a\n // device that HAS heard from the server, because the manager ticked\n // something off out of signal.\n if (event.serverTime === undefined) {\n return;\n }\n observedAtPerfRef.current = performance.now();\n setLastServerTime(event.serverTime);\n });\n return unsubscribe;\n }, [engine]);\n\n useEffect(() => {\n const id = setInterval(() => forceTick((tick) => tick + 1), TICK_INTERVAL_MS);\n return () => clearInterval(id);\n }, []);\n\n function now(): string {\n if (lastServerTime === undefined || observedAtPerfRef.current === undefined) {\n // No response has ever landed in this session yet. Fabricating a\n // value from the local wall clock is exactly what hard rule #6\n // forbids — this is the one case this hook cannot silently satisfy\n // its own non-optional return type, so it says so loudly instead.\n // CALLERS: this is a real, expected window — React runs an effect\n // (which is how this hook's own subscription above starts) strictly\n // AFTER the render that needs `now()`'s result has already committed,\n // so a component's very FIRST render can hit this throw even when\n // wired up correctly. Guard the call site, matching\n // `useStaleness.ts`'s own precedent, rather than reaching for a\n // device-clock fallback here (hard rule #6 forbids exactly that).\n throw new Error(\n 'useServerTime().now() was called before any response carrying meta.serverTime ' +\n 'had been observed — there is no server timestamp yet to advance from.',\n );\n }\n const elapsedMs = performance.now() - observedAtPerfRef.current;\n return new Date(Date.parse(lastServerTime) + elapsedMs).toISOString();\n }\n\n return { now, sinceLastSync: lastServerTime };\n}\n"]}
@@ -1,7 +1,7 @@
1
1
  'use strict';
2
2
 
3
- var chunk6WV5VYT2_cjs = require('./chunk-6WV5VYT2.cjs');
4
- var chunk7UFX3Y2U_cjs = require('./chunk-7UFX3Y2U.cjs');
3
+ var chunkMNUCVVIE_cjs = require('./chunk-MNUCVVIE.cjs');
4
+ var chunkECCQW5LN_cjs = require('./chunk-ECCQW5LN.cjs');
5
5
  var chunkUALMCHNW_cjs = require('./chunk-UALMCHNW.cjs');
6
6
  var react = require('react');
7
7
  var client = require('kaafil-js/client');
@@ -400,12 +400,12 @@ function useAgencyTrips() {
400
400
  );
401
401
  return { makeTripsFetch, segmentCounts };
402
402
  }
403
- var useBookingsInternal = chunk6WV5VYT2_cjs.createDomainHook("bookings", (tripRef) => {
403
+ var useBookingsInternal = chunkMNUCVVIE_cjs.createDomainHook("bookings", (tripRef) => {
404
404
  const {
405
405
  rows: bookings,
406
406
  syncedAt,
407
407
  refreshLive
408
- } = chunk6WV5VYT2_cjs.useSnapshotList(tripRef, "bookings", {
408
+ } = chunkMNUCVVIE_cjs.useSnapshotList(tripRef, "bookings", {
409
409
  live: async (liveClient, ref) => {
410
410
  const response = await liveClient.bookings.list({ tripRef: ref });
411
411
  return { rows: [...response], syncedAt: response.meta.serverTime };
@@ -470,7 +470,7 @@ var DirectoriesWriteError = class _DirectoriesWriteError extends Error {
470
470
  };
471
471
  function useDirectories(agencyRef) {
472
472
  const client = chunkUALMCHNW_cjs.useKaafilClient();
473
- const serverTime = chunk7UFX3Y2U_cjs.useServerTime();
473
+ const serverTime = chunkECCQW5LN_cjs.useServerTime();
474
474
  const makeManagersFetch = react.useCallback(
475
475
  (filters) => async (cursor) => {
476
476
  const page = await client.agencies.managers.listPage({
@@ -517,7 +517,7 @@ function useDirectories(agencyRef) {
517
517
  isLead: input.isLead
518
518
  });
519
519
  } catch (error) {
520
- throw new DirectoriesWriteError(chunk6WV5VYT2_cjs.classifyError(error));
520
+ throw new DirectoriesWriteError(chunkMNUCVVIE_cjs.classifyError(error));
521
521
  }
522
522
  },
523
523
  [client]
@@ -532,7 +532,7 @@ function useDirectories(agencyRef) {
532
532
  ...input.isLead === void 0 ? {} : { isLead: input.isLead }
533
533
  });
534
534
  } catch (error) {
535
- throw new DirectoriesWriteError(chunk6WV5VYT2_cjs.classifyError(error));
535
+ throw new DirectoriesWriteError(chunkMNUCVVIE_cjs.classifyError(error));
536
536
  }
537
537
  },
538
538
  [client]
@@ -545,7 +545,7 @@ function useDirectories(agencyRef) {
545
545
  managerRef: input.managerRef
546
546
  });
547
547
  } catch (error) {
548
- throw new DirectoriesWriteError(chunk6WV5VYT2_cjs.classifyError(error));
548
+ throw new DirectoriesWriteError(chunkMNUCVVIE_cjs.classifyError(error));
549
549
  }
550
550
  },
551
551
  [client]
@@ -581,7 +581,7 @@ function useDirectories(agencyRef) {
581
581
  if (error instanceof DirectoriesWriteError) {
582
582
  throw error;
583
583
  }
584
- throw new DirectoriesWriteError(chunk6WV5VYT2_cjs.classifyError(error));
584
+ throw new DirectoriesWriteError(chunkMNUCVVIE_cjs.classifyError(error));
585
585
  }
586
586
  },
587
587
  [client, serverTime]
@@ -597,7 +597,7 @@ function useDirectories(agencyRef) {
597
597
  externalTravellerId: input.externalTravellerId
598
598
  });
599
599
  } catch (error) {
600
- throw new DirectoriesWriteError(chunk6WV5VYT2_cjs.classifyError(error));
600
+ throw new DirectoriesWriteError(chunkMNUCVVIE_cjs.classifyError(error));
601
601
  }
602
602
  },
603
603
  [client]
@@ -610,7 +610,7 @@ function useDirectories(agencyRef) {
610
610
  travellerRef: input.travellerRef
611
611
  });
612
612
  } catch (error) {
613
- throw new DirectoriesWriteError(chunk6WV5VYT2_cjs.classifyError(error));
613
+ throw new DirectoriesWriteError(chunkMNUCVVIE_cjs.classifyError(error));
614
614
  }
615
615
  },
616
616
  [client]
@@ -625,7 +625,7 @@ function useDirectories(agencyRef) {
625
625
  travellerRefs: [...input.travellerRefs]
626
626
  });
627
627
  } catch (error) {
628
- throw new DirectoriesWriteError(chunk6WV5VYT2_cjs.classifyError(error));
628
+ throw new DirectoriesWriteError(chunkMNUCVVIE_cjs.classifyError(error));
629
629
  }
630
630
  },
631
631
  [client]
@@ -642,7 +642,7 @@ function useDirectories(agencyRef) {
642
642
  ...input.travellerRefs !== void 0 ? { travellerRefs: [...input.travellerRefs] } : {}
643
643
  });
644
644
  } catch (error) {
645
- throw new DirectoriesWriteError(chunk6WV5VYT2_cjs.classifyError(error));
645
+ throw new DirectoriesWriteError(chunkMNUCVVIE_cjs.classifyError(error));
646
646
  }
647
647
  },
648
648
  [client]
@@ -652,7 +652,7 @@ function useDirectories(agencyRef) {
652
652
  try {
653
653
  await client.trips.parties.remove({ tripRef: input.tripRef, partyId: input.partyId });
654
654
  } catch (error) {
655
- throw new DirectoriesWriteError(chunk6WV5VYT2_cjs.classifyError(error));
655
+ throw new DirectoriesWriteError(chunkMNUCVVIE_cjs.classifyError(error));
656
656
  }
657
657
  },
658
658
  [client]
@@ -666,7 +666,7 @@ function useDirectories(agencyRef) {
666
666
  body: input.body
667
667
  });
668
668
  } catch (error) {
669
- throw new DirectoriesWriteError(chunk6WV5VYT2_cjs.classifyError(error));
669
+ throw new DirectoriesWriteError(chunkMNUCVVIE_cjs.classifyError(error));
670
670
  }
671
671
  },
672
672
  [client]
@@ -781,7 +781,7 @@ function useShareLinks(tripRef, travellerRef) {
781
781
  await refresh();
782
782
  return minted;
783
783
  } catch (error) {
784
- throw new ShareLinkWriteError(chunk6WV5VYT2_cjs.classifyError(error));
784
+ throw new ShareLinkWriteError(chunkMNUCVVIE_cjs.classifyError(error));
785
785
  }
786
786
  },
787
787
  [client, tripRef, refresh]
@@ -792,7 +792,7 @@ function useShareLinks(tripRef, travellerRef) {
792
792
  await client.shareTokens.revoke({ id });
793
793
  await refresh();
794
794
  } catch (error) {
795
- throw new ShareLinkWriteError(chunk6WV5VYT2_cjs.classifyError(error));
795
+ throw new ShareLinkWriteError(chunkMNUCVVIE_cjs.classifyError(error));
796
796
  }
797
797
  },
798
798
  [client, refresh]
@@ -808,7 +808,7 @@ function useShareLinks(tripRef, travellerRef) {
808
808
  });
809
809
  await refresh();
810
810
  } catch (error) {
811
- throw new ShareLinkWriteError(chunk6WV5VYT2_cjs.classifyError(error));
811
+ throw new ShareLinkWriteError(chunkMNUCVVIE_cjs.classifyError(error));
812
812
  }
813
813
  },
814
814
  [client, refresh]
@@ -820,7 +820,7 @@ function useShareLinks(tripRef, travellerRef) {
820
820
  await refresh();
821
821
  return minted;
822
822
  } catch (error) {
823
- throw new ShareLinkWriteError(chunk6WV5VYT2_cjs.classifyError(error));
823
+ throw new ShareLinkWriteError(chunkMNUCVVIE_cjs.classifyError(error));
824
824
  }
825
825
  },
826
826
  [client, refresh]
@@ -954,5 +954,5 @@ exports.useDirectories = useDirectories;
954
954
  exports.usePaginatedList = usePaginatedList;
955
955
  exports.useShareLinks = useShareLinks;
956
956
  exports.useTravellerFormResponses = useTravellerFormResponses;
957
- //# sourceMappingURL=chunk-HTIY33UH.cjs.map
958
- //# sourceMappingURL=chunk-HTIY33UH.cjs.map
957
+ //# sourceMappingURL=chunk-FVK7HMQ5.cjs.map
958
+ //# sourceMappingURL=chunk-FVK7HMQ5.cjs.map