expo-invoke 1.3.0 → 2.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.
Files changed (117) hide show
  1. package/android/src/main/java/expo/modules/invoke/InteractiveWidgetReceiver.kt +47 -0
  2. package/android/src/main/java/expo/modules/invoke/InvokeSliceProvider.kt +83 -0
  3. package/android/src/main/java/expo/modules/invoke/ShortcutsHelper.kt +38 -32
  4. package/build/plugin/android/withAndroidInvoke.d.ts +3 -1
  5. package/build/plugin/android/withAndroidInvoke.js +71 -15
  6. package/build/plugin/android/withAndroidInvoke.js.map +1 -1
  7. package/build/plugin/codegen/generateSwiftAppClip.d.ts +2 -0
  8. package/build/plugin/codegen/generateSwiftAppClip.js +20 -0
  9. package/build/plugin/codegen/generateSwiftAppClip.js.map +1 -0
  10. package/build/plugin/codegen/generateSwiftEntities.d.ts +2 -0
  11. package/build/plugin/codegen/generateSwiftEntities.js +91 -0
  12. package/build/plugin/codegen/generateSwiftEntities.js.map +1 -0
  13. package/build/plugin/codegen/generateSwiftFocusFilters.d.ts +2 -0
  14. package/build/plugin/codegen/generateSwiftFocusFilters.js +42 -0
  15. package/build/plugin/codegen/generateSwiftFocusFilters.js.map +1 -0
  16. package/build/plugin/codegen/generateSwiftIntents.d.ts +2 -0
  17. package/build/plugin/codegen/generateSwiftIntents.js +43 -13
  18. package/build/plugin/codegen/generateSwiftIntents.js.map +1 -1
  19. package/build/plugin/ios/withIOSInvoke.d.ts +8 -1
  20. package/build/plugin/ios/withIOSInvoke.js +61 -10
  21. package/build/plugin/ios/withIOSInvoke.js.map +1 -1
  22. package/build/plugin/src/withInvoke.d.ts +20 -3
  23. package/build/plugin/src/withInvoke.js +23 -4
  24. package/build/plugin/src/withInvoke.js.map +1 -1
  25. package/build/src/components/AddToSiriButton.d.ts +1 -1
  26. package/build/src/components/AddToSiriButton.d.ts.map +1 -1
  27. package/build/src/components/InvokeDebugger.d.ts +1 -1
  28. package/build/src/components/InvokeDebugger.d.ts.map +1 -1
  29. package/build/src/components/ShortcutChip.d.ts +1 -1
  30. package/build/src/components/ShortcutChip.d.ts.map +1 -1
  31. package/build/src/hooks/useBackgroundIntent.d.ts +15 -0
  32. package/build/src/hooks/useBackgroundIntent.d.ts.map +1 -0
  33. package/build/src/hooks/useBackgroundIntent.js +41 -0
  34. package/build/src/hooks/useBackgroundIntent.js.map +1 -0
  35. package/build/src/hooks/useEntityQuery.d.ts +26 -0
  36. package/build/src/hooks/useEntityQuery.d.ts.map +1 -0
  37. package/build/src/hooks/useEntityQuery.js +47 -0
  38. package/build/src/hooks/useEntityQuery.js.map +1 -0
  39. package/build/src/hooks/useFocusFilter.d.ts +1 -1
  40. package/build/src/hooks/useFocusFilter.d.ts.map +1 -1
  41. package/build/src/hooks/useFocusFilter.js.map +1 -1
  42. package/build/src/hooks/useFocusFilterState.d.ts +28 -0
  43. package/build/src/hooks/useFocusFilterState.d.ts.map +1 -0
  44. package/build/src/hooks/useFocusFilterState.js +47 -0
  45. package/build/src/hooks/useFocusFilterState.js.map +1 -0
  46. package/build/src/hooks/useInvoke.d.ts.map +1 -1
  47. package/build/src/hooks/useInvoke.js +3 -0
  48. package/build/src/hooks/useInvoke.js.map +1 -1
  49. package/build/src/hooks/useInvokeAnalytics.d.ts +10 -14
  50. package/build/src/hooks/useInvokeAnalytics.d.ts.map +1 -1
  51. package/build/src/hooks/useInvokeAnalytics.js +21 -14
  52. package/build/src/hooks/useInvokeAnalytics.js.map +1 -1
  53. package/build/src/hooks/useInvokeQueue.d.ts +32 -0
  54. package/build/src/hooks/useInvokeQueue.d.ts.map +1 -0
  55. package/build/src/hooks/useInvokeQueue.js +77 -0
  56. package/build/src/hooks/useInvokeQueue.js.map +1 -0
  57. package/build/src/hooks/useLiveActivity.d.ts +37 -0
  58. package/build/src/hooks/useLiveActivity.d.ts.map +1 -0
  59. package/build/src/hooks/useLiveActivity.js +74 -0
  60. package/build/src/hooks/useLiveActivity.js.map +1 -0
  61. package/build/src/hooks/useOTAConfig.d.ts +24 -0
  62. package/build/src/hooks/useOTAConfig.d.ts.map +1 -0
  63. package/build/src/hooks/useOTAConfig.js +40 -0
  64. package/build/src/hooks/useOTAConfig.js.map +1 -0
  65. package/build/src/hooks/usePushToTalk.d.ts +35 -0
  66. package/build/src/hooks/usePushToTalk.d.ts.map +1 -0
  67. package/build/src/hooks/usePushToTalk.js +101 -0
  68. package/build/src/hooks/usePushToTalk.js.map +1 -0
  69. package/build/src/hooks/useSlice.d.ts +19 -0
  70. package/build/src/hooks/useSlice.d.ts.map +1 -0
  71. package/build/src/hooks/useSlice.js +22 -0
  72. package/build/src/hooks/useSlice.js.map +1 -0
  73. package/build/src/index.d.ts +19 -3
  74. package/build/src/index.d.ts.map +1 -1
  75. package/build/src/index.js +16 -1
  76. package/build/src/index.js.map +1 -1
  77. package/build/src/module.d.ts +18 -3
  78. package/build/src/module.d.ts.map +1 -1
  79. package/build/src/module.js +77 -0
  80. package/build/src/module.js.map +1 -1
  81. package/build/src/types/index.d.ts +117 -4
  82. package/build/src/types/index.d.ts.map +1 -1
  83. package/build/src/utils/analytics.d.ts +1 -7
  84. package/build/src/utils/analytics.d.ts.map +1 -1
  85. package/build/src/utils/analytics.js +9 -0
  86. package/build/src/utils/analytics.js.map +1 -1
  87. package/build/src/utils/invokeError.d.ts +28 -0
  88. package/build/src/utils/invokeError.d.ts.map +1 -0
  89. package/build/src/utils/invokeError.js +57 -0
  90. package/build/src/utils/invokeError.js.map +1 -0
  91. package/build/src/utils/otaConfig.d.ts +9 -0
  92. package/build/src/utils/otaConfig.d.ts.map +1 -0
  93. package/build/src/utils/otaConfig.js +45 -0
  94. package/build/src/utils/otaConfig.js.map +1 -0
  95. package/build/src/utils/persistentAnalytics.d.ts +5 -0
  96. package/build/src/utils/persistentAnalytics.d.ts.map +1 -0
  97. package/build/src/utils/persistentAnalytics.js +52 -0
  98. package/build/src/utils/persistentAnalytics.js.map +1 -0
  99. package/build/src/utils/validation.d.ts +12 -0
  100. package/build/src/utils/validation.d.ts.map +1 -1
  101. package/build/src/utils/validation.js +81 -1
  102. package/build/src/utils/validation.js.map +1 -1
  103. package/build/src/web/index.d.ts +39 -0
  104. package/build/src/web/index.d.ts.map +1 -0
  105. package/build/src/web/index.js +37 -0
  106. package/build/src/web/index.js.map +1 -0
  107. package/build/src/web/module.d.ts +40 -0
  108. package/build/src/web/module.d.ts.map +1 -0
  109. package/build/src/web/module.js +46 -0
  110. package/build/src/web/module.js.map +1 -0
  111. package/ios/AppClip/AppClipHandler.swift +41 -0
  112. package/ios/Background/BackgroundIntentBridge.swift +56 -0
  113. package/ios/Entities/EntityQueryBridge.swift +40 -0
  114. package/ios/FocusFilter/FocusFilterRegistrar.swift +40 -0
  115. package/ios/LiveActivity/LiveActivityManager.swift +83 -0
  116. package/ios/PTT/PTTManager.swift +51 -0
  117. package/package.json +2 -1
@@ -0,0 +1,47 @@
1
+ import { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { addIntentListener, reportFocusFilterResult } from '../module';
3
+ /**
4
+ * Reads the current state of a registered Focus filter.
5
+ * Fires when the user enables/disables a Focus mode that includes this app's filter.
6
+ * iOS 16+ only. Returns a no-op result on Android and older iOS.
7
+ *
8
+ * @param filterId - Must match the FocusFilterDefinition id in app.json
9
+ *
10
+ * @example
11
+ * const { isActive, parameters, confirm } = useFocusFilterState('work-mode');
12
+ * useEffect(() => {
13
+ * if (!isActive) return;
14
+ * hidePersonalErrands(parameters.hidePersonal as boolean);
15
+ * confirm();
16
+ * }, [isActive]);
17
+ */
18
+ export function useFocusFilterState(filterId) {
19
+ const [isActive, setIsActive] = useState(false);
20
+ const [parameters, setParameters] = useState({});
21
+ const filterIdRef = useRef(filterId);
22
+ filterIdRef.current = filterId;
23
+ useEffect(() => {
24
+ const sub = addIntentListener((intent) => {
25
+ var _a;
26
+ if (intent.intentId === `__focusFilter_${filterIdRef.current}`) {
27
+ setIsActive(true);
28
+ setParameters((_a = intent.parameters) !== null && _a !== void 0 ? _a : {});
29
+ }
30
+ else if (intent.intentId === `__focusFilterDismiss_${filterIdRef.current}`) {
31
+ setIsActive(false);
32
+ setParameters({});
33
+ }
34
+ });
35
+ return () => sub.remove();
36
+ }, []);
37
+ const confirm = useCallback(() => {
38
+ reportFocusFilterResult(filterIdRef.current, true);
39
+ }, []);
40
+ const reject = useCallback(() => {
41
+ reportFocusFilterResult(filterIdRef.current, false);
42
+ setIsActive(false);
43
+ setParameters({});
44
+ }, []);
45
+ return { isActive, parameters, confirm, reject };
46
+ }
47
+ //# sourceMappingURL=useFocusFilterState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFocusFilterState.js","sourceRoot":"","sources":["../../../src/hooks/useFocusFilterState.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjE,OAAO,EAAE,iBAAiB,EAAE,uBAAuB,EAAE,MAAM,WAAW,CAAC;AAcvE;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,mBAAmB,CAAC,QAAgB;IAClD,MAAM,CAAC,QAAQ,EAAE,WAAW,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAChD,MAAM,CAAC,UAAU,EAAE,aAAa,CAAC,GAAG,QAAQ,CAAiC,EAAE,CAAC,CAAC;IACjF,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;IACrC,WAAW,CAAC,OAAO,GAAG,QAAQ,CAAC;IAE/B,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,GAAG,GAAG,iBAAiB,CAAC,CAAC,MAAM,EAAE,EAAE;;YACvC,IAAI,MAAM,CAAC,QAAQ,KAAK,iBAAiB,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;gBAC/D,WAAW,CAAC,IAAI,CAAC,CAAC;gBAClB,aAAa,CAAC,MAAA,MAAM,CAAC,UAAU,mCAAI,EAAE,CAAC,CAAC;YACzC,CAAC;iBAAM,IAAI,MAAM,CAAC,QAAQ,KAAK,wBAAwB,WAAW,CAAC,OAAO,EAAE,EAAE,CAAC;gBAC7E,WAAW,CAAC,KAAK,CAAC,CAAC;gBACnB,aAAa,CAAC,EAAE,CAAC,CAAC;YACpB,CAAC;QACH,CAAC,CAAC,CAAC;QACH,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;IAC5B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE;QAC/B,uBAAuB,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACrD,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE;QAC9B,uBAAuB,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,CAAC,CAAC;QACpD,WAAW,CAAC,KAAK,CAAC,CAAC;QACnB,aAAa,CAAC,EAAE,CAAC,CAAC;IACpB,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;AACnD,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"useInvoke.d.ts","sourceRoot":"","sources":["../../../src/hooks/useInvoke.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAK7E,MAAM,WAAW,gBAAgB;IAC/B,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAC;IACvC,uEAAuE;IACvE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC3C,6CAA6C;IAC7C,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,4DAA4D;IAC5D,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,eAAe,CAkCrE"}
1
+ {"version":3,"file":"useInvoke.d.ts","sourceRoot":"","sources":["../../../src/hooks/useInvoke.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAM7E,MAAM,WAAW,gBAAgB;IAC/B,iEAAiE;IACjE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,0EAA0E;IAC1E,MAAM,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAC;IACvC,uEAAuE;IACvE,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,cAAc,KAAK,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IAC9B,gDAAgD;IAChD,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,CAAC;IAC3C,6CAA6C;IAC7C,MAAM,EAAE,YAAY,GAAG,IAAI,CAAC;IAC5B,4DAA4D;IAC5D,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,SAAS,CAAC,OAAO,CAAC,EAAE,gBAAgB,GAAG,eAAe,CAkCrE"}
@@ -2,6 +2,7 @@ import { useEffect, useRef, useState } from 'react';
2
2
  import { consumePendingIntent } from '../utils/actionStore';
3
3
  import { addIntentListener } from '../module';
4
4
  import { trackFired } from '../utils/analytics';
5
+ import { isIntentDisabled } from '../utils/otaConfig';
5
6
  /**
6
7
  * The main hook for receiving intents from any native surface.
7
8
  *
@@ -58,6 +59,8 @@ export function useInvoke(options) {
58
59
  };
59
60
  }
60
61
  function matches(intent, options) {
62
+ if (isIntentDisabled(intent.intentId))
63
+ return false;
61
64
  if ((options === null || options === void 0 ? void 0 : options.intentId) && intent.intentId !== options.intentId)
62
65
  return false;
63
66
  if (options === null || options === void 0 ? void 0 : options.source) {
@@ -1 +1 @@
1
- {"version":3,"file":"useInvoke.js","sourceRoot":"","sources":["../../../src/hooks/useInvoke.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAsBhD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,SAAS,CAAC,OAA0B;;IAClD,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAwB,IAAI,CAAC,CAAC;IAClE,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IACnC,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;IAE7B,SAAS,CAAC,GAAG,EAAE;;QACb,mEAAmE;QACnE,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;QACvC,IAAI,OAAO,IAAI,OAAO,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACpD,UAAU,CAAC,OAAO,CAAC,CAAC;YACpB,SAAS,CAAC,OAAO,CAAC,CAAC;YACnB,MAAA,MAAA,UAAU,CAAC,OAAO,0CAAE,MAAM,mDAAG,OAAO,CAAC,CAAC;QACxC,CAAC;QAED,0DAA0D;QAC1D,MAAM,GAAG,GAAG,iBAAiB,CAAC,CAAC,QAAQ,EAAE,EAAE;;YACzC,IAAI,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1C,UAAU,CAAC,QAAQ,CAAC,CAAC;gBACrB,SAAS,CAAC,QAAQ,CAAC,CAAC;gBACpB,MAAA,MAAA,UAAU,CAAC,OAAO,0CAAE,MAAM,mDAAG,QAAQ,CAAC,CAAC;YACzC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;IAC5B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAEpC,OAAO;QACL,MAAM;QACN,UAAU,EAAE,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,UAAU,mCAAI,EAAE;QACpC,MAAM,EAAE,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,mCAAI,IAAI;QAC9B,KAAK;KACN,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CAAC,MAAsB,EAAE,OAA0B;IACjE,IAAI,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,QAAQ,KAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5E,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM,EAAE,CAAC;QACpB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAClF,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;YAAE,OAAO,KAAK,CAAC;IACrD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
1
+ {"version":3,"file":"useInvoke.js","sourceRoot":"","sources":["../../../src/hooks/useInvoke.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AAEpD,OAAO,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAC9C,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAsBtD;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,MAAM,UAAU,SAAS,CAAC,OAA0B;;IAClD,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAwB,IAAI,CAAC,CAAC;IAClE,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IACnC,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;IAE7B,SAAS,CAAC,GAAG,EAAE;;QACb,mEAAmE;QACnE,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;QACvC,IAAI,OAAO,IAAI,OAAO,CAAC,OAAO,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YACpD,UAAU,CAAC,OAAO,CAAC,CAAC;YACpB,SAAS,CAAC,OAAO,CAAC,CAAC;YACnB,MAAA,MAAA,UAAU,CAAC,OAAO,0CAAE,MAAM,mDAAG,OAAO,CAAC,CAAC;QACxC,CAAC;QAED,0DAA0D;QAC1D,MAAM,GAAG,GAAG,iBAAiB,CAAC,CAAC,QAAQ,EAAE,EAAE;;YACzC,IAAI,OAAO,CAAC,QAAQ,EAAE,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1C,UAAU,CAAC,QAAQ,CAAC,CAAC;gBACrB,SAAS,CAAC,QAAQ,CAAC,CAAC;gBACpB,MAAA,MAAA,UAAU,CAAC,OAAO,0CAAE,MAAM,mDAAG,QAAQ,CAAC,CAAC;YACzC,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO,GAAG,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;IAC5B,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,KAAK,GAAG,GAAG,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IAEpC,OAAO;QACL,MAAM;QACN,UAAU,EAAE,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,UAAU,mCAAI,EAAE;QACpC,MAAM,EAAE,MAAA,MAAM,aAAN,MAAM,uBAAN,MAAM,CAAE,MAAM,mCAAI,IAAI;QAC9B,KAAK;KACN,CAAC;AACJ,CAAC;AAED,SAAS,OAAO,CAAC,MAAsB,EAAE,OAA0B;IACjE,IAAI,gBAAgB,CAAC,MAAM,CAAC,QAAQ,CAAC;QAAE,OAAO,KAAK,CAAC;IACpD,IAAI,CAAA,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,QAAQ,KAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,CAAC,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5E,IAAI,OAAO,aAAP,OAAO,uBAAP,OAAO,CAAE,MAAM,EAAE,CAAC;QACpB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAClF,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC;YAAE,OAAO,KAAK,CAAC;IACrD,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC"}
@@ -1,23 +1,19 @@
1
- import type { InvokeSource } from '../types';
1
+ import type { InvokeSource, AnalyticsRecord } from '../types';
2
2
  export interface InvokeAnalytics {
3
- /** How many times each intentId has fired */
3
+ /** How many times each intentId has fired this session */
4
4
  fired: Record<string, number>;
5
- /** How many times each intentId has been donated */
5
+ /** How many times each intentId has been donated this session */
6
6
  donated: Record<string, number>;
7
- /** How many times each surface triggered an intent */
7
+ /** How many times each surface triggered an intent this session */
8
8
  bySource: Partial<Record<InvokeSource, number>>;
9
9
  /** Total intents fired this session */
10
10
  total: number;
11
+ /** Cumulative counts from previous sessions (persisted to disk) */
12
+ persisted: AnalyticsRecord;
13
+ /** Clear persisted (cross-session) analytics from disk */
14
+ clearPersisted: () => Promise<void>;
15
+ /** ms timestamp when this session started */
16
+ sessionStarted: number;
11
17
  }
12
- /**
13
- * Per-intent fire counts, donation counts, and surface breakdown.
14
- * Use to understand which intents are most popular and which surfaces drive usage.
15
- *
16
- * @example
17
- * const { fired, bySource, total } = useInvokeAnalytics();
18
- * console.log(fired['create_errand']); // 12
19
- * console.log(bySource['siri']); // 8
20
- * console.log(bySource['widget']); // 4
21
- */
22
18
  export declare function useInvokeAnalytics(): InvokeAnalytics;
23
19
  //# sourceMappingURL=useInvokeAnalytics.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"useInvokeAnalytics.d.ts","sourceRoot":"","sources":["../../../src/hooks/useInvokeAnalytics.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAE7C,MAAM,WAAW,eAAe;IAC9B,6CAA6C;IAC7C,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,oDAAoD;IACpD,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,sDAAsD;IACtD,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;IAChD,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,IAAI,eAAe,CAepD"}
1
+ {"version":3,"file":"useInvokeAnalytics.d.ts","sourceRoot":"","sources":["../../../src/hooks/useInvokeAnalytics.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAE9D,MAAM,WAAW,eAAe;IAC9B,0DAA0D;IAC1D,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B,iEAAiE;IACjE,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,mEAAmE;IACnE,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC;IAChD,uCAAuC;IACvC,KAAK,EAAE,MAAM,CAAC;IACd,mEAAmE;IACnE,SAAS,EAAE,eAAe,CAAC;IAC3B,0DAA0D;IAC1D,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACpC,6CAA6C;IAC7C,cAAc,EAAE,MAAM,CAAC;CACxB;AAID,wBAAgB,kBAAkB,IAAI,eAAe,CAiCpD"}
@@ -1,27 +1,34 @@
1
- import { useEffect, useState } from 'react';
1
+ import { useCallback, useEffect, useState } from 'react';
2
2
  import { getAnalytics, onIntentFired } from '../utils/analytics';
3
- /**
4
- * Per-intent fire counts, donation counts, and surface breakdown.
5
- * Use to understand which intents are most popular and which surfaces drive usage.
6
- *
7
- * @example
8
- * const { fired, bySource, total } = useInvokeAnalytics();
9
- * console.log(fired['create_errand']); // 12
10
- * console.log(bySource['siri']); // 8
11
- * console.log(bySource['widget']); // 4
12
- */
3
+ import { loadPersistedAnalytics, clearPersistedAnalytics } from '../utils/persistentAnalytics';
4
+ const _sessionStarted = Date.now();
13
5
  export function useInvokeAnalytics() {
14
6
  const [analytics, setAnalytics] = useState(() => {
15
7
  const a = getAnalytics();
16
- return { ...a, total: Object.values(a.fired).reduce((s, n) => s + n, 0) };
8
+ return {
9
+ ...a,
10
+ total: Object.values(a.fired).reduce((s, n) => s + n, 0),
11
+ sessionStarted: _sessionStarted,
12
+ };
17
13
  });
14
+ const [persisted, setPersisted] = useState({ fired: {}, donated: {}, bySource: {} });
18
15
  useEffect(() => {
16
+ // Load cross-session data on mount
17
+ loadPersistedAnalytics().then(setPersisted);
19
18
  const unsub = onIntentFired(() => {
20
19
  const a = getAnalytics();
21
- setAnalytics({ ...a, total: Object.values(a.fired).reduce((s, n) => s + n, 0) });
20
+ setAnalytics({
21
+ ...a,
22
+ total: Object.values(a.fired).reduce((s, n) => s + n, 0),
23
+ sessionStarted: _sessionStarted,
24
+ });
22
25
  });
23
26
  return unsub;
24
27
  }, []);
25
- return analytics;
28
+ const clearPersisted = useCallback(async () => {
29
+ await clearPersistedAnalytics();
30
+ setPersisted({ fired: {}, donated: {}, bySource: {} });
31
+ }, []);
32
+ return { ...analytics, persisted, clearPersisted };
26
33
  }
27
34
  //# sourceMappingURL=useInvokeAnalytics.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"useInvokeAnalytics.js","sourceRoot":"","sources":["../../../src/hooks/useInvokeAnalytics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAcjE;;;;;;;;;GASG;AACH,MAAM,UAAU,kBAAkB;IAChC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAkB,GAAG,EAAE;QAC/D,MAAM,CAAC,GAAG,YAAY,EAAE,CAAC;QACzB,OAAO,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;IAC5E,CAAC,CAAC,CAAC;IAEH,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,EAAE;YAC/B,MAAM,CAAC,GAAG,YAAY,EAAE,CAAC;YACzB,YAAY,CAAC,EAAE,GAAG,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC;QACnF,CAAC,CAAC,CAAC;QACH,OAAO,KAAK,CAAC;IACf,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,SAAS,CAAC;AACnB,CAAC"}
1
+ {"version":3,"file":"useInvokeAnalytics.js","sourceRoot":"","sources":["../../../src/hooks/useInvokeAnalytics.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACjE,OAAO,EAAE,sBAAsB,EAAE,uBAAuB,EAAE,MAAM,8BAA8B,CAAC;AAoB/F,MAAM,eAAe,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;AAEnC,MAAM,UAAU,kBAAkB;IAChC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAwD,GAAG,EAAE;QACrG,MAAM,CAAC,GAAG,YAAY,EAAE,CAAC;QACzB,OAAO;YACL,GAAG,CAAC;YACJ,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACxD,cAAc,EAAE,eAAe;SAChC,CAAC;IACJ,CAAC,CAAC,CAAC;IAEH,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,CAAkB,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;IAEtG,SAAS,CAAC,GAAG,EAAE;QACb,mCAAmC;QACnC,sBAAsB,EAAE,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;QAE5C,MAAM,KAAK,GAAG,aAAa,CAAC,GAAG,EAAE;YAC/B,MAAM,CAAC,GAAG,YAAY,EAAE,CAAC;YACzB,YAAY,CAAC;gBACX,GAAG,CAAC;gBACJ,KAAK,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACxD,cAAc,EAAE,eAAe;aAChC,CAAC,CAAC;QACL,CAAC,CAAC,CAAC;QACH,OAAO,KAAK,CAAC;IACf,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,cAAc,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;QAC5C,MAAM,uBAAuB,EAAE,CAAC;QAChC,YAAY,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC,CAAC;IACzD,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,OAAO,EAAE,GAAG,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC;AACrD,CAAC"}
@@ -0,0 +1,32 @@
1
+ import type { ResolvedIntent, InvokeSource } from '../types';
2
+ export interface UseInvokeQueueOptions {
3
+ intentId?: string;
4
+ source?: InvokeSource | InvokeSource[];
5
+ /** Milliseconds to wait after the last intent before delivering the batch (default: 500) */
6
+ debounceMs?: number;
7
+ /** Maximum intents to collect before force-flushing (default: unlimited) */
8
+ maxBatch?: number;
9
+ onFire: (intents: ResolvedIntent[]) => void;
10
+ }
11
+ export interface UseInvokeQueueResult {
12
+ /** Intents waiting in the current batch */
13
+ pending: ResolvedIntent[];
14
+ /** Force-deliver the current batch immediately */
15
+ flush: () => void;
16
+ /** Discard the current batch without delivering */
17
+ clear: () => void;
18
+ }
19
+ /**
20
+ * Debounced/batched intent receiver.
21
+ * Collects rapid intent fires and delivers them as a single array after a quiet period.
22
+ * Useful for preventing double-opens from double-tapped widgets or near-simultaneous deep links.
23
+ *
24
+ * @example
25
+ * useInvokeQueue({
26
+ * intentId: 'create_errand',
27
+ * debounceMs: 300,
28
+ * onFire: (intents) => openWizard(intents[0]),
29
+ * });
30
+ */
31
+ export declare function useInvokeQueue(options: UseInvokeQueueOptions): UseInvokeQueueResult;
32
+ //# sourceMappingURL=useInvokeQueue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInvokeQueue.d.ts","sourceRoot":"","sources":["../../../src/hooks/useInvokeQueue.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAI7D,MAAM,WAAW,qBAAqB;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,YAAY,GAAG,YAAY,EAAE,CAAC;IACvC,4FAA4F;IAC5F,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,CAAC,OAAO,EAAE,cAAc,EAAE,KAAK,IAAI,CAAC;CAC7C;AAED,MAAM,WAAW,oBAAoB;IACnC,2CAA2C;IAC3C,OAAO,EAAE,cAAc,EAAE,CAAC;IAC1B,kDAAkD;IAClD,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,mDAAmD;IACnD,KAAK,EAAE,MAAM,IAAI,CAAC;CACnB;AAWD;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,oBAAoB,CAkDnF"}
@@ -0,0 +1,77 @@
1
+ import { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { addIntentListener } from '../module';
3
+ import { consumePendingIntent } from '../utils/actionStore';
4
+ function matches(intent, options) {
5
+ if (options.intentId && intent.intentId !== options.intentId)
6
+ return false;
7
+ if (options.source) {
8
+ const srcs = Array.isArray(options.source) ? options.source : [options.source];
9
+ if (!srcs.includes(intent.source))
10
+ return false;
11
+ }
12
+ return true;
13
+ }
14
+ /**
15
+ * Debounced/batched intent receiver.
16
+ * Collects rapid intent fires and delivers them as a single array after a quiet period.
17
+ * Useful for preventing double-opens from double-tapped widgets or near-simultaneous deep links.
18
+ *
19
+ * @example
20
+ * useInvokeQueue({
21
+ * intentId: 'create_errand',
22
+ * debounceMs: 300,
23
+ * onFire: (intents) => openWizard(intents[0]),
24
+ * });
25
+ */
26
+ export function useInvokeQueue(options) {
27
+ const [pending, setPending] = useState([]);
28
+ const batchRef = useRef([]);
29
+ const timerRef = useRef(null);
30
+ const optionsRef = useRef(options);
31
+ optionsRef.current = options;
32
+ const deliver = useCallback(() => {
33
+ if (timerRef.current)
34
+ clearTimeout(timerRef.current);
35
+ timerRef.current = null;
36
+ const batch = [...batchRef.current];
37
+ if (batch.length === 0)
38
+ return;
39
+ batchRef.current = [];
40
+ setPending([]);
41
+ optionsRef.current.onFire(batch);
42
+ }, []);
43
+ const enqueue = useCallback((intent) => {
44
+ if (!matches(intent, optionsRef.current))
45
+ return;
46
+ batchRef.current.push(intent);
47
+ setPending([...batchRef.current]);
48
+ const { maxBatch, debounceMs = 500 } = optionsRef.current;
49
+ if (maxBatch && batchRef.current.length >= maxBatch) {
50
+ deliver();
51
+ return;
52
+ }
53
+ if (timerRef.current)
54
+ clearTimeout(timerRef.current);
55
+ timerRef.current = setTimeout(deliver, debounceMs);
56
+ }, [deliver]);
57
+ useEffect(() => {
58
+ // Drain cold-start
59
+ const initial = consumePendingIntent();
60
+ if (initial)
61
+ enqueue(initial);
62
+ const sub = addIntentListener(enqueue);
63
+ return () => {
64
+ sub.remove();
65
+ if (timerRef.current)
66
+ clearTimeout(timerRef.current);
67
+ };
68
+ }, [enqueue]);
69
+ const clear = useCallback(() => {
70
+ if (timerRef.current)
71
+ clearTimeout(timerRef.current);
72
+ batchRef.current = [];
73
+ setPending([]);
74
+ }, []);
75
+ return { pending, flush: deliver, clear };
76
+ }
77
+ //# sourceMappingURL=useInvokeQueue.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useInvokeQueue.js","sourceRoot":"","sources":["../../../src/hooks/useInvokeQueue.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import type { LiveActivityConfig, LiveActivityInfo, ParameterValue } from '../types';
2
+ import { type InvokeError } from '../utils/invokeError';
3
+ export interface UseLiveActivityOptions {
4
+ /** Called when any Live Activity operation fails. Receives a structured InvokeError. */
5
+ onError?: (error: InvokeError) => void;
6
+ }
7
+ export interface UseLiveActivityResult {
8
+ /** Start a new Live Activity. Returns the activityId, or empty string on failure. */
9
+ start: (config: LiveActivityConfig) => Promise<string>;
10
+ /** Update the content state of an active Live Activity. */
11
+ update: (activityId: string, contentState: Record<string, ParameterValue>) => void;
12
+ /** End a Live Activity, optionally with a final state snapshot. */
13
+ end: (activityId: string, finalState?: Record<string, ParameterValue>) => void;
14
+ /** All currently active Live Activities of this type. */
15
+ activities: LiveActivityInfo[];
16
+ /** Reload the activities list from native. Null on failure. */
17
+ refresh: () => Promise<void>;
18
+ /** Last error from any operation, null when no error. */
19
+ error: InvokeError | null;
20
+ }
21
+ /**
22
+ * Manage the full lifecycle of Live Activities (Dynamic Island + Lock Screen banners).
23
+ * iOS 16.1+ only. All methods are no-ops on Android and iOS < 16.1.
24
+ *
25
+ * Errors are surfaced via `error` state and optionally via `onError` callback.
26
+ * Operations never throw — the hook always returns safe default values on failure.
27
+ *
28
+ * @param activityType - Must match the ActivityAttributes Swift class name (e.g. "ErrandActivityAttributes")
29
+ *
30
+ * @example
31
+ * const { start, update, end, error } = useLiveActivity('ErrandActivityAttributes');
32
+ * const id = await start({ activityType: 'ErrandActivityAttributes', contentState: { eta: '12 min' } });
33
+ * update(id, { eta: '8 min' });
34
+ * end(id);
35
+ */
36
+ export declare function useLiveActivity(activityType: string, options?: UseLiveActivityOptions): UseLiveActivityResult;
37
+ //# sourceMappingURL=useLiveActivity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLiveActivity.d.ts","sourceRoot":"","sources":["../../../src/hooks/useLiveActivity.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AACrF,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAE3E,MAAM,WAAW,sBAAsB;IACrC,wFAAwF;IACxF,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,qBAAqB;IACpC,qFAAqF;IACrF,KAAK,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;IACvD,2DAA2D;IAC3D,MAAM,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,KAAK,IAAI,CAAC;IACnF,mEAAmE;IACnE,GAAG,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,cAAc,CAAC,KAAK,IAAI,CAAC;IAC/E,yDAAyD;IACzD,UAAU,EAAE,gBAAgB,EAAE,CAAC;IAC/B,+DAA+D;IAC/D,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7B,yDAAyD;IACzD,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;CAC3B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,eAAe,CAC7B,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,sBAA2B,GACnC,qBAAqB,CAwDvB"}
@@ -0,0 +1,74 @@
1
+ import { useCallback, useEffect, useState } from 'react';
2
+ import { startLiveActivity, updateLiveActivity, endLiveActivity, getLiveActivities, } from '../module';
3
+ import { reportInvokeError } from '../utils/invokeError';
4
+ /**
5
+ * Manage the full lifecycle of Live Activities (Dynamic Island + Lock Screen banners).
6
+ * iOS 16.1+ only. All methods are no-ops on Android and iOS < 16.1.
7
+ *
8
+ * Errors are surfaced via `error` state and optionally via `onError` callback.
9
+ * Operations never throw — the hook always returns safe default values on failure.
10
+ *
11
+ * @param activityType - Must match the ActivityAttributes Swift class name (e.g. "ErrandActivityAttributes")
12
+ *
13
+ * @example
14
+ * const { start, update, end, error } = useLiveActivity('ErrandActivityAttributes');
15
+ * const id = await start({ activityType: 'ErrandActivityAttributes', contentState: { eta: '12 min' } });
16
+ * update(id, { eta: '8 min' });
17
+ * end(id);
18
+ */
19
+ export function useLiveActivity(activityType, options = {}) {
20
+ const [activities, setActivities] = useState([]);
21
+ const [error, setError] = useState(null);
22
+ const handleError = useCallback((code, cause) => {
23
+ var _a;
24
+ const err = reportInvokeError(code, cause);
25
+ setError(err);
26
+ (_a = options.onError) === null || _a === void 0 ? void 0 : _a.call(options, err);
27
+ return err;
28
+ // onError reference intentionally excluded — use stable ref if needed
29
+ // eslint-disable-next-line react-hooks/exhaustive-deps
30
+ }, []);
31
+ const refresh = useCallback(async () => {
32
+ try {
33
+ const all = await getLiveActivities();
34
+ setActivities(all.filter((a) => a.activityType === activityType));
35
+ setError(null);
36
+ }
37
+ catch (e) {
38
+ handleError('LIVE_ACTIVITY_FAILED', e);
39
+ }
40
+ }, [activityType, handleError]);
41
+ useEffect(() => {
42
+ refresh();
43
+ }, [refresh]);
44
+ const start = useCallback(async (config) => {
45
+ try {
46
+ const id = await startLiveActivity(config);
47
+ await refresh();
48
+ return id;
49
+ }
50
+ catch (e) {
51
+ handleError('LIVE_ACTIVITY_FAILED', e);
52
+ return '';
53
+ }
54
+ }, [refresh, handleError]);
55
+ const update = useCallback((activityId, contentState) => {
56
+ try {
57
+ updateLiveActivity(activityId, contentState);
58
+ }
59
+ catch (e) {
60
+ handleError('LIVE_ACTIVITY_FAILED', e);
61
+ }
62
+ }, [handleError]);
63
+ const end = useCallback((activityId, finalState) => {
64
+ try {
65
+ endLiveActivity(activityId, finalState);
66
+ setActivities((prev) => prev.filter((a) => a.activityId !== activityId));
67
+ }
68
+ catch (e) {
69
+ handleError('LIVE_ACTIVITY_FAILED', e);
70
+ }
71
+ }, [handleError]);
72
+ return { start, update, end, activities, refresh, error };
73
+ }
74
+ //# sourceMappingURL=useLiveActivity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useLiveActivity.js","sourceRoot":"","sources":["../../../src/hooks/useLiveActivity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,24 @@
1
+ import type { OTAConfig } from '../types';
2
+ export interface UseOTAConfigOptions {
3
+ /** How long to cache the fetched config before re-fetching (default: 1 hour) */
4
+ cacheTtlMs?: number;
5
+ /** Called after a new config is fetched and applied */
6
+ onUpdate?: (config: OTAConfig) => void;
7
+ /** Called when the fetch fails. If not provided, failure is only reflected in `error` state. */
8
+ onError?: (message: string) => void;
9
+ }
10
+ export interface UseOTAConfigResult {
11
+ config: OTAConfig | null;
12
+ loading: boolean;
13
+ error: string | null;
14
+ refresh: () => Promise<void>;
15
+ }
16
+ /**
17
+ * Fetches and applies an OTA config from the given URL.
18
+ * Disabled intents (enabled: false) are automatically filtered out of useInvoke().
19
+ *
20
+ * @example
21
+ * const { config, loading, error } = useOTAConfig('https://myapp.com/invoke-config.json');
22
+ */
23
+ export declare function useOTAConfig(url: string, options?: UseOTAConfigOptions): UseOTAConfigResult;
24
+ //# sourceMappingURL=useOTAConfig.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useOTAConfig.d.ts","sourceRoot":"","sources":["../../../src/hooks/useOTAConfig.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAE1C,MAAM,WAAW,mBAAmB;IAClC,gFAAgF;IAChF,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,SAAS,KAAK,IAAI,CAAC;IACvC,gGAAgG;IAChG,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,SAAS,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE,OAAO,CAAC;IACjB,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC9B;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB,GAAG,kBAAkB,CA4B/F"}
@@ -0,0 +1,40 @@
1
+ import { useCallback, useEffect, useRef, useState } from 'react';
2
+ import { fetchOTAConfig, getOTAConfig } from '../utils/otaConfig';
3
+ /**
4
+ * Fetches and applies an OTA config from the given URL.
5
+ * Disabled intents (enabled: false) are automatically filtered out of useInvoke().
6
+ *
7
+ * @example
8
+ * const { config, loading, error } = useOTAConfig('https://myapp.com/invoke-config.json');
9
+ */
10
+ export function useOTAConfig(url, options = {}) {
11
+ const [config, setConfig] = useState(getOTAConfig);
12
+ const [loading, setLoading] = useState(false);
13
+ const [error, setError] = useState(null);
14
+ const optionsRef = useRef(options);
15
+ optionsRef.current = options;
16
+ const refresh = useCallback(async () => {
17
+ var _a, _b, _c, _d;
18
+ setLoading(true);
19
+ setError(null);
20
+ try {
21
+ const result = await fetchOTAConfig(url, optionsRef.current.cacheTtlMs);
22
+ setConfig(result);
23
+ if (result)
24
+ (_b = (_a = optionsRef.current).onUpdate) === null || _b === void 0 ? void 0 : _b.call(_a, result);
25
+ }
26
+ catch (e) {
27
+ const msg = e instanceof Error ? e.message : 'Failed to fetch OTA config';
28
+ setError(msg);
29
+ (_d = (_c = optionsRef.current).onError) === null || _d === void 0 ? void 0 : _d.call(_c, msg);
30
+ }
31
+ finally {
32
+ setLoading(false);
33
+ }
34
+ }, [url]);
35
+ useEffect(() => {
36
+ refresh();
37
+ }, [refresh]);
38
+ return { config, loading, error, refresh };
39
+ }
40
+ //# sourceMappingURL=useOTAConfig.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useOTAConfig.js","sourceRoot":"","sources":["../../../src/hooks/useOTAConfig.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAmBlE;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW,EAAE,UAA+B,EAAE;IACzE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAmB,YAAY,CAAC,CAAC;IACrE,MAAM,CAAC,OAAO,EAAE,UAAU,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC;IAC9C,MAAM,CAAC,KAAK,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAgB,IAAI,CAAC,CAAC;IACxD,MAAM,UAAU,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IACnC,UAAU,CAAC,OAAO,GAAG,OAAO,CAAC;IAE7B,MAAM,OAAO,GAAG,WAAW,CAAC,KAAK,IAAI,EAAE;;QACrC,UAAU,CAAC,IAAI,CAAC,CAAC;QACjB,QAAQ,CAAC,IAAI,CAAC,CAAC;QACf,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,cAAc,CAAC,GAAG,EAAE,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;YACxE,SAAS,CAAC,MAAM,CAAC,CAAC;YAClB,IAAI,MAAM;gBAAE,MAAA,MAAA,UAAU,CAAC,OAAO,EAAC,QAAQ,mDAAG,MAAM,CAAC,CAAC;QACpD,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,GAAG,GAAG,CAAC,YAAY,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,4BAA4B,CAAC;YAC1E,QAAQ,CAAC,GAAG,CAAC,CAAC;YACd,MAAA,MAAA,UAAU,CAAC,OAAO,EAAC,OAAO,mDAAG,GAAG,CAAC,CAAC;QACpC,CAAC;gBAAS,CAAC;YACT,UAAU,CAAC,KAAK,CAAC,CAAC;QACpB,CAAC;IACH,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAEV,SAAS,CAAC,GAAG,EAAE;QACb,OAAO,EAAE,CAAC;IACZ,CAAC,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IAEd,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;AAC7C,CAAC"}
@@ -0,0 +1,35 @@
1
+ import type { PTTSessionState } from '../types';
2
+ import { type InvokeError } from '../utils/invokeError';
3
+ export interface UsePushToTalkOptions {
4
+ /** Called when any PTT operation fails. Receives a structured InvokeError. */
5
+ onError?: (error: InvokeError) => void;
6
+ }
7
+ export interface UsePushToTalkResult {
8
+ state: PTTSessionState;
9
+ /** Request PTT channel activation */
10
+ start: (participantName?: string) => Promise<void>;
11
+ /** End the PTT session */
12
+ end: () => Promise<void>;
13
+ /** Toggle microphone open/closed */
14
+ setTransmitting: (active: boolean) => void;
15
+ /** Last error from any PTT operation, null when no error. */
16
+ error: InvokeError | null;
17
+ }
18
+ /**
19
+ * Push-to-Talk (PTT) session management.
20
+ * iOS 16+ only via PushToTalk framework. All methods are no-ops on Android and older iOS.
21
+ *
22
+ * Errors are surfaced via `error` state and optionally via `onError` callback.
23
+ * Operations never throw — the hook always returns safe default values on failure.
24
+ *
25
+ * @param channelId - Unique identifier for this PTT channel
26
+ *
27
+ * @example
28
+ * const ptt = usePushToTalk('errand-channel');
29
+ * <Pressable
30
+ * onPressIn={() => ptt.setTransmitting(true)}
31
+ * onPressOut={() => ptt.setTransmitting(false)}
32
+ * />
33
+ */
34
+ export declare function usePushToTalk(channelId: string, options?: UsePushToTalkOptions): UsePushToTalkResult;
35
+ //# sourceMappingURL=usePushToTalk.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePushToTalk.d.ts","sourceRoot":"","sources":["../../../src/hooks/usePushToTalk.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAqB,KAAK,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAI3E,MAAM,WAAW,oBAAoB;IACnC,8EAA8E;IAC9E,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,KAAK,IAAI,CAAC;CACxC;AAED,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,eAAe,CAAC;IACvB,qCAAqC;IACrC,KAAK,EAAE,CAAC,eAAe,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACnD,0BAA0B;IAC1B,GAAG,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACzB,oCAAoC;IACpC,eAAe,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IAC3C,6DAA6D;IAC7D,KAAK,EAAE,WAAW,GAAG,IAAI,CAAC;CAC3B;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAC3B,SAAS,EAAE,MAAM,EACjB,OAAO,GAAE,oBAAyB,GACjC,mBAAmB,CA0ErB"}