@glassly/engine 0.3.7 → 0.3.8-dev.976
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +4 -0
- package/build/engine.d.ts +8 -2
- package/build/engine.d.ts.map +1 -1
- package/build/engine.js +7 -4
- package/build/engine.js.map +1 -1
- package/build/facades/backup.d.ts +14 -0
- package/build/facades/backup.d.ts.map +1 -0
- package/build/facades/backup.js +22 -0
- package/build/facades/backup.js.map +1 -0
- package/build/facades/glasses.d.ts +4 -4
- package/build/facades/glasses.d.ts.map +1 -1
- package/build/facades/glasses.js +4 -4
- package/build/facades/glasses.js.map +1 -1
- package/build/generated/releaseMetadata.js +4 -4
- package/build/generated/releaseMetadata.js.map +1 -1
- package/build/index.d.ts +1 -0
- package/build/index.d.ts.map +1 -1
- package/build/index.js.map +1 -1
- package/build/services/AppRegistry.d.ts +2 -1
- package/build/services/AppRegistry.d.ts.map +1 -1
- package/build/services/AppRegistry.js +38 -8
- package/build/services/AppRegistry.js.map +1 -1
- package/build/services/AppStateBackup.d.ts +98 -0
- package/build/services/AppStateBackup.d.ts.map +1 -0
- package/build/services/AppStateBackup.js +224 -0
- package/build/services/AppStateBackup.js.map +1 -0
- package/build/services/BlobStore.d.ts.map +1 -1
- package/build/services/BlobStore.js +5 -12
- package/build/services/BlobStore.js.map +1 -1
- package/build/services/CloudClientService.d.ts +1 -0
- package/build/services/CloudClientService.d.ts.map +1 -1
- package/build/services/CloudClientService.js +34 -2
- package/build/services/CloudClientService.js.map +1 -1
- package/build/services/DisplayProcessor.d.ts +2 -0
- package/build/services/DisplayProcessor.d.ts.map +1 -1
- package/build/services/DisplayProcessor.js +15 -1
- package/build/services/DisplayProcessor.js.map +1 -1
- package/build/services/GlassesTouchInput.d.ts.map +1 -1
- package/build/services/GlassesTouchInput.js +4 -2
- package/build/services/GlassesTouchInput.js.map +1 -1
- package/build/services/JSCrashloopReportService.d.ts.map +1 -1
- package/build/services/JSCrashloopReportService.js +5 -0
- package/build/services/JSCrashloopReportService.js.map +1 -1
- package/build/services/JSRouter.d.ts +11 -3
- package/build/services/JSRouter.d.ts.map +1 -1
- package/build/services/JSRouter.js +36 -6
- package/build/services/JSRouter.js.map +1 -1
- package/build/services/LocalMiniappRuntime.d.ts +13 -0
- package/build/services/LocalMiniappRuntime.d.ts.map +1 -1
- package/build/services/LocalMiniappRuntime.js +54 -20
- package/build/services/LocalMiniappRuntime.js.map +1 -1
- package/build/services/MiniappEngine.d.ts +9 -0
- package/build/services/MiniappEngine.d.ts.map +1 -1
- package/build/services/MiniappEngine.js +60 -27
- package/build/services/MiniappEngine.js.map +1 -1
- package/build/services/MiniappLauncher.d.ts +2 -0
- package/build/services/MiniappLauncher.d.ts.map +1 -1
- package/build/services/MiniappLauncher.js +6 -0
- package/build/services/MiniappLauncher.js.map +1 -1
- package/build/services/NavigationService.d.ts +1 -0
- package/build/services/NavigationService.d.ts.map +1 -1
- package/build/services/NavigationService.js +20 -6
- package/build/services/NavigationService.js.map +1 -1
- package/build/services/PhoneCalendarService.d.ts.map +1 -1
- package/build/services/PhoneCalendarService.js +8 -0
- package/build/services/PhoneCalendarService.js.map +1 -1
- package/build/services/PhoneNotificationsSync.d.ts.map +1 -1
- package/build/services/PhoneNotificationsSync.js +7 -3
- package/build/services/PhoneNotificationsSync.js.map +1 -1
- package/build/services/SceneRenderer.js +1 -1
- package/build/services/SceneRenderer.js.map +1 -1
- package/build/services/appStateBackupFile.d.ts +32 -0
- package/build/services/appStateBackupFile.d.ts.map +1 -0
- package/build/services/appStateBackupFile.js +135 -0
- package/build/services/appStateBackupFile.js.map +1 -0
- package/build/services/controllers.d.ts.map +1 -1
- package/build/services/controllers.js +11 -3
- package/build/services/controllers.js.map +1 -1
- package/build/services/effectiveCapabilities.js +3 -0
- package/build/services/effectiveCapabilities.js.map +1 -1
- package/build/services/pages/pageEligibility.d.ts.map +1 -1
- package/build/services/pages/pageEligibility.js +8 -1
- package/build/services/pages/pageEligibility.js.map +1 -1
- package/build/services/settingsBridge.d.ts.map +1 -1
- package/build/services/settingsBridge.js +1 -0
- package/build/services/settingsBridge.js.map +1 -1
- package/build/services/{appleWatch/AppleWatchLink.d.ts → watch/WatchLink.d.ts} +8 -7
- package/build/services/watch/WatchLink.d.ts.map +1 -0
- package/build/services/{appleWatch/AppleWatchLink.js → watch/WatchLink.js} +14 -15
- package/build/services/watch/WatchLink.js.map +1 -0
- package/build/stores/apps.d.ts.map +1 -1
- package/build/stores/apps.js +14 -2
- package/build/stores/apps.js.map +1 -1
- package/build/stores/settings.d.ts.map +1 -1
- package/build/stores/settings.js +45 -3
- package/build/stores/settings.js.map +1 -1
- package/build/types/capabilities/even-realities-g1.d.ts.map +1 -1
- package/build/types/capabilities/even-realities-g1.js +3 -0
- package/build/types/capabilities/even-realities-g1.js.map +1 -1
- package/build/types/capabilities/memomind-one.d.ts +3 -0
- package/build/types/capabilities/memomind-one.d.ts.map +1 -0
- package/build/types/capabilities/memomind-one.js +41 -0
- package/build/types/capabilities/memomind-one.js.map +1 -0
- package/build/types/enums.d.ts +6 -2
- package/build/types/enums.d.ts.map +1 -1
- package/build/types/enums.js +4 -0
- package/build/types/enums.js.map +1 -1
- package/build/types/hardware.d.ts +3 -1
- package/build/types/hardware.d.ts.map +1 -1
- package/build/types/hardware.js +3 -1
- package/build/types/hardware.js.map +1 -1
- package/build/utils/display/index.d.ts +2 -1
- package/build/utils/display/index.d.ts.map +1 -1
- package/build/utils/display/index.js +3 -2
- package/build/utils/display/index.js.map +1 -1
- package/build/utils/display/profiles/index.d.ts +2 -1
- package/build/utils/display/profiles/index.d.ts.map +1 -1
- package/build/utils/display/profiles/index.js +3 -2
- package/build/utils/display/profiles/index.js.map +1 -1
- package/build/utils/display/profiles/rayneo-io.d.ts +1 -1
- package/build/utils/display/profiles/rayneo-io.d.ts.map +1 -1
- package/build/utils/display/profiles/rayneo-io.js +1 -1
- package/build/utils/display/profiles/rayneo-io.js.map +1 -1
- package/build/utils/display/scene/index.d.ts +1 -1
- package/build/utils/display/scene/index.d.ts.map +1 -1
- package/build/utils/display/scene/index.js +1 -1
- package/build/utils/display/scene/index.js.map +1 -1
- package/build/utils/display/scene/process.d.ts +6 -0
- package/build/utils/display/scene/process.d.ts.map +1 -1
- package/build/utils/display/scene/process.js +22 -7
- package/build/utils/display/scene/process.js.map +1 -1
- package/build/utils/miniappGlobals.d.ts +13 -17
- package/build/utils/miniappGlobals.d.ts.map +1 -1
- package/build/utils/miniappGlobals.js +24 -56
- package/build/utils/miniappGlobals.js.map +1 -1
- package/package.json +7 -7
- package/src/engine.ts +7 -4
- package/src/facades/backup.ts +28 -0
- package/src/facades/glasses.ts +5 -5
- package/src/generated/releaseMetadata.ts +4 -4
- package/src/index.ts +1 -0
- package/src/services/AppRegistry.ts +36 -9
- package/src/services/AppStateBackup.ts +283 -0
- package/src/services/BlobStore.ts +5 -11
- package/src/services/CloudClientService.ts +35 -4
- package/src/services/DisplayProcessor.ts +20 -8
- package/src/services/GlassesTouchInput.ts +6 -2
- package/src/services/JSCrashloopReportService.ts +5 -0
- package/src/services/JSRouter.ts +37 -6
- package/src/services/LocalMiniappRuntime.ts +55 -20
- package/src/services/MiniappEngine.ts +62 -27
- package/src/services/MiniappLauncher.ts +7 -0
- package/src/services/NavigationService.ts +28 -8
- package/src/services/PhoneCalendarService.ts +7 -0
- package/src/services/PhoneNotificationsSync.ts +8 -3
- package/src/services/SceneRenderer.ts +1 -1
- package/src/services/appStateBackupFile.ts +171 -0
- package/src/services/controllers.ts +12 -3
- package/src/services/effectiveCapabilities.ts +3 -0
- package/src/services/pages/pageEligibility.ts +9 -1
- package/src/services/settingsBridge.ts +1 -0
- package/src/services/{appleWatch/AppleWatchLink.ts → watch/WatchLink.ts} +20 -20
- package/src/stores/apps.ts +13 -2
- package/src/stores/settings.ts +52 -7
- package/src/types/capabilities/even-realities-g1.ts +4 -0
- package/src/types/capabilities/memomind-one.ts +42 -0
- package/src/types/enums.ts +4 -0
- package/src/types/hardware.ts +14 -1
- package/src/utils/display/index.ts +4 -2
- package/src/utils/display/profiles/index.ts +9 -2
- package/src/utils/display/profiles/rayneo-io.ts +6 -1
- package/src/utils/display/scene/index.ts +1 -1
- package/src/utils/display/scene/process.ts +22 -7
- package/src/utils/miniappGlobals.ts +32 -64
- package/build/services/appleWatch/AppleWatchLink.d.ts.map +0 -1
- package/build/services/appleWatch/AppleWatchLink.js.map +0 -1
|
@@ -101,7 +101,7 @@ function routeTouchEvent(event) {
|
|
|
101
101
|
const doubleTap = gesture === "double_tap";
|
|
102
102
|
// The Neural Band's middle finger (index 1) shares the tap names. Either
|
|
103
103
|
// finger leaves the app on screen; the firmware dashboard is the index finger's.
|
|
104
|
-
const osDoubleTap = doubleTap && event.index
|
|
104
|
+
const osDoubleTap = doubleTap && !(event.source === 3 && event.index === 1);
|
|
105
105
|
const osHeadUp = gesture === "head_up";
|
|
106
106
|
if (doubleTap) {
|
|
107
107
|
// The app being left opts out of OS exit by registering double tap (the
|
|
@@ -140,7 +140,9 @@ function routeTouchEvent(event) {
|
|
|
140
140
|
// pagesEligible: connected Glassly CFW glasses, whose firmware leaves the
|
|
141
141
|
// dashboard to the phone; other firmware opens its own on a lift.
|
|
142
142
|
const opensNativeDashboard = osDoubleTap || (osHeadUp && pagesEligible());
|
|
143
|
-
if (opensNativeDashboard &&
|
|
143
|
+
if (opensNativeDashboard &&
|
|
144
|
+
!nativeNavigationService.isActive &&
|
|
145
|
+
isGlassesConnected(useGlassesStore.getState().connection)) {
|
|
144
146
|
useDisplayStore.getState().setDisplayEvent({ layout: { layoutType: "unavailable", reason: "firmware-dashboard" } });
|
|
145
147
|
void Promise.resolve(BluetoothSdk.showDashboard()).catch((err) => {
|
|
146
148
|
console.error("DeviceEventRouter: showDashboard failed:", err);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GlassesTouchInput.js","sourceRoot":"","sources":["../../src/services/GlassesTouchInput.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAC,YAAY,EAAkB,MAAM,wBAAwB,CAAA;AACpE,OAAO,YAAY,MAAM,iCAAiC,CAAA;AAE1D,OAAO,EAAC,iBAAiB,EAAC,MAAM,gBAAgB,CAAA;AAChD,OAAO,EAAC,eAAe,EAAC,MAAM,mBAAmB,CAAA;AACjD,OAAO,EAAC,OAAO,EAAC,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAC,UAAU,EAAC,MAAM,eAAe,CAAA;AACxC,OAAO,kBAAkB,MAAM,4BAA4B,CAAA;AAC3D,OAAO,kBAAkB,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAC,kBAAkB,EAAC,MAAM,oBAAoB,CAAA;AACrD,OAAO,mBAAmB,MAAM,uBAAuB,CAAA;AACvD,OAAO,mBAAmB,MAAM,uBAAuB,CAAA;AACvD,OAAO,EAAC,kBAAkB,EAAC,MAAM,sBAAsB,CAAA;AACvD,OAAO,uBAAuB,MAAM,2BAA2B,CAAA;AAC/D,OAAO,EAAC,YAAY,EAAC,MAAM,qBAAqB,CAAA;AAChD,OAAO,EAAC,aAAa,EAAC,MAAM,yBAAyB,CAAA;AAErD,MAAM,kBAAkB,GAAG,IAAI,kBAAkB,CAAC;IAChD,QAAQ,EAAE,GAAG,EAAE,CAAC,iBAAiB,CAAC,QAAQ,EAAE;IAC5C,oBAAoB,EAAE,GAAG,EAAE,CAAC,mBAAmB,CAAC,iBAAiB,EAAE;IACnE,eAAe,EAAE,CAAC,WAAW,EAAE,IAAI,EAAE,EAAE,CAAC,mBAAmB,CAAC,gBAAgB,CAAC,WAAW,EAAE,IAAI,CAAC;IAC/F,gBAAgB,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,mBAAmB,CAAC,iBAAiB,CAAC,WAAW,CAAC;IACrF,gBAAgB,EAAE,CAAC,WAAW,EAAE,EAAE,CAAC,mBAAmB,CAAC,iBAAiB,CAAC,WAAW,CAAC;IACrF,UAAU,EAAE,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE,KAAK,CAAC;IACpE,YAAY,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,OAAO,CAAC,YAAY,CAAC,OAAO,CAAC;CACzD,CAAC,CAAA;AAEF,6EAA6E;AAC7E,4EAA4E;AAC5E,+EAA+E;AAC/E,uEAAuE;AACvE,8EAA8E;AAC9E,iEAAiE;AACjE,8EAA8E;AAC9E,8EAA8E;AAC9E,0DAA0D;AAC1D,MAAM,mBAAmB,GAAG,IAAI,CAAA;AAChC,0DAA0D;AAC1D,MAAM,WAAW,GAAG,IAAI,GAAG,EAAkB,CAAA;AAE7C,SAAS,OAAO,CAAC,KAAiB;IAChC,OAAO,KAAK,CAAC,YAAY,IAAI,UAAU,KAAK,CAAC,MAAM,EAAE,CAAA;AACvD,CAAC;AAED,SAAS,eAAe,CAAC,KAAiB;IACxC,OAAO,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,KAAK,UAAU,IAAI,KAAK,CAAC,WAAW,KAAK,YAAY,CAAC,CAAA;AACvG,CAAC;AAED,SAAS,eAAe,CAAC,KAAiB;IACxC,MAAM,IAAI,GAAG,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAA;IAC5C,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC,CAAA;IAChD,MAAM,OAAO,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,GAAG,IAAI,CAAA;IAClE,OAAO,OAAO,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,OAAO,IAAI,mBAAmB,CAAA;AAC1E,CAAC;AAED,SAAS,aAAa,CAAC,KAAiB;IACtC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,WAAW,KAAK,YAAY,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS,CAAC,EAAE,CAAC;QAClG,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,CAAA;IACpC,CAAC;AACH,CAAC;AAED,qFAAqF;AACrF,SAAS,WAAW,CAAC,IAAgB;IACnC,MAAM,KAAK,GAAG,EAAC,GAAG,IAAI,EAAC,CAAA;IACvB,OAAO,KAAK,CAAC,QAAQ,CAAA;IACrB,OAAO,KAAK,CAAC,KAAK,CAAA;IAClB,OAAO,KAAK,CAAA;AACd,CAAC;AAED;;;;;GAKG;AACH,SAAS,UAAU,CAAC,KAAiB;IACnC,MAAM,EAAE,GAAG,KAAK,CAAC,YAAY,CAAA;IAC7B,IAAI,EAAE,KAAK,SAAS;QAAE,OAAO,KAAK,CAAA;IAClC,MAAM,KAAK,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC,EAAE,KAAK,CAAA;IACjE,OAAO,KAAK,KAAK,SAAS,IAAI,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAC,GAAG,KAAK,EAAE,OAAO,EAAE,IAAI,EAAC,CAAC,CAAC,CAAC,KAAK,CAAA;AACrF,CAAC;AAED;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAiB;IAClD,IAAI,eAAe,CAAC,KAAK,CAAC,EAAE,CAAC;QAC3B,IAAI,eAAe,CAAC,KAAK,CAAC;YAAE,eAAe,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,CAAA;QAC/D,eAAe,CAAC,EAAC,GAAG,KAAK,EAAE,WAAW,EAAE,KAAK,CAAC,WAAW,KAAK,UAAU,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,aAAa,EAAC,CAAC,CAAA;QACxG,OAAM;IACR,CAAC;IACD,aAAa,CAAC,KAAK,CAAC,CAAA;IACpB,eAAe,CAAC,KAAK,CAAC,CAAA;AACxB,CAAC;AAED,SAAS,eAAe,CAAC,KAAiB;IACxC,MAAM,OAAO,GAAG,KAAK,CAAC,WAAW,CAAA;IACjC,MAAM,QAAQ,GAAG,mBAAmB,CAAC,eAAe,CAAC,OAAO,CAAC,CAAA;IAC7D,MAAM,SAAS,GAAG,OAAO,KAAK,YAAY,CAAA;IAC1C,yEAAyE;IACzE,iFAAiF;IACjF,MAAM,WAAW,GAAG,SAAS,IAAI,KAAK,CAAC,KAAK,KAAK,CAAC,CAAA;IAClD,MAAM,QAAQ,GAAG,OAAO,KAAK,SAAS,CAAA;IAEtC,IAAI,SAAS,EAAE,CAAC;QACd,wEAAwE;QACxE,6EAA6E;QAC7E,qEAAqE;QACrE,qEAAqE;QACrE,kBAAkB;QAClB,MAAM,OAAO,GAAG,mBAAmB,CAAC,iBAAiB,EAAE,CAAA;QACvD,IACE,OAAO,KAAK,IAAI;YAChB,CAAC,mBAAmB,CAAC,eAAe,CAAC,OAAO,EAAE,OAAO,CAAC;YACtD,kBAAkB,CAAC,cAAc,EAAE,EACnC,CAAC;YACD,kBAAkB,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,YAAY,CAAC,CAAA;YAC9E,OAAM;QACR,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,KAAK,IAAI,EAAE,CAAC;QACtB,6FAA6F;QAC7F,IAAI,CAAC,OAAO,KAAK,YAAY,IAAI,QAAQ,CAAC,IAAI,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;YACrE,kBAAkB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,YAAY,EAAE,KAAK,CAAC,SAAS,CAAC,CAAA;QAClF,CAAC;QACD,uEAAuE;QACvE,kBAAkB,CAAC,WAAW,CAAC,OAAO,EAAE,IAAI,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,YAAY,CAAC,CAAA;QAC9E,mBAAmB,CAAC,YAAY,CAAC,aAAa,EAAE,UAAU,CAAC,KAAK,CAAC,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAA;QACvF,OAAM;IACR,CAAC;IAED,sEAAsE;IACtE,mDAAmD;IACnD,kBAAkB,CAAC,WAAW,CAAC,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,KAAK,CAAC,YAAY,CAAC,CAAA;IAE/E,mBAAmB,CAAC,YAAY,CAAC,aAAa,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAA;IAElE,2EAA2E;IAC3E,6EAA6E;IAC7E,4EAA4E;IAC5E,4EAA4E;IAC5E,0EAA0E;IAC1E,yEAAyE;IACzE,0EAA0E;IAC1E,kEAAkE;IAClE,MAAM,oBAAoB,GAAG,WAAW,IAAI,CAAC,QAAQ,IAAI,aAAa,EAAE,CAAC,CAAA;IACzE,IAAI,oBAAoB,IAAI,CAAC,uBAAuB,CAAC,QAAQ,IAAI,kBAAkB,CAAC,eAAe,CAAC,QAAQ,EAAE,CAAC,UAAU,CAAC,EAAE,CAAC;QAC3H,eAAe,CAAC,QAAQ,EAAE,CAAC,eAAe,CAAC,EAAC,MAAM,EAAE,EAAC,UAAU,EAAE,aAAa,EAAE,MAAM,EAAE,oBAAoB,EAAC,EAAC,CAAC,CAAA;QAC/G,KAAK,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,aAAa,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;YAC/D,OAAO,CAAC,KAAK,CAAC,0CAA0C,EAAE,GAAG,CAAC,CAAA;QAChE,CAAC,CAAC,CAAA;IACJ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,kBAAkB,CAAC,KAAK,EAAE,CAAA;IAC1B,WAAW,CAAC,KAAK,EAAE,CAAA;AACrB,CAAC;AAED,iFAAiF;AACjF,MAAM,UAAU,WAAW,CACzB,WAee;IAEf,MAAM,KAAK,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAC,WAAW,CAAA;IACpD,kBAAkB,CAAC;QACjB,IAAI,EAAE,aAAa;QACnB,WAAW;QACX,WAAW,EAAE,MAAM,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,IAAI,CAAC,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,KAAK,CAAC,IAAI,YAAY,CAAC,SAAS;QAC3G,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;KACtB,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import {useDisplayStore} from \"../stores/display\"\nimport {DeviceModels, type TouchEvent} from \"@glassly/bluetooth-sdk\"\nimport BluetoothSdk from \"@glassly/bluetooth-sdk/internal\"\n\nimport {useAppStatusStore} from \"../stores/apps\"\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {BgTimer} from \"../utils/timers\"\nimport {hasInput2d} from \"./controllers\"\nimport dashboardOpenTrace from \"./debug/DashboardOpenTrace\"\nimport gestureDotsService from \"./GestureDotsService\"\nimport {isGlassesConnected} from \"./GlassesReadiness\"\nimport localDisplayManager from \"./LocalDisplayManager\"\nimport localMiniappRuntime from \"./LocalMiniappRuntime\"\nimport {MiniappExitGesture} from \"./MiniappExitGesture\"\nimport nativeNavigationService from \"./NativeNavigationService\"\nimport {isOverlayApp} from \"./pages/overlayApps\"\nimport {pagesEligible} from \"./pages/pageEligibility\"\n\nconst miniappExitGesture = new MiniappExitGesture({\n getState: () => useAppStatusStore.getState(),\n getTargetPackageName: () => localDisplayManager.getMiniappToLeave(),\n beginExitNotice: (packageName, text) => localDisplayManager.beginMiniappExit(packageName, text),\n finishExitNotice: (packageName) => localDisplayManager.finishMiniappExit(packageName),\n cancelExitNotice: (packageName) => localDisplayManager.cancelMiniappExit(packageName),\n setTimeout: (callback, delay) => BgTimer.setTimeout(callback, delay),\n clearTimeout: (timerId) => BgTimer.clearTimeout(timerId),\n})\n\n// The ring reports a slide once per step of travel, whether the CFW forwards\n// it (deviceModel G2) or the ring sends it to the phone itself (deviceModel\n// R1); both tag source 2. One press is one swipe: the stroke's first step goes\n// out as swipe_up / swipe_down, and every step, the first included, as\n// scroll_up / scroll_down with its distance and speed for smooth scrolling. A\n// stroke ends at the ring's next touch_down or tap_end, or after\n// RING_STROKE_IDLE_MS without a step when a report was lost. Reversing within\n// a stroke fires no swipe (a finger rolling back at lift-off). Native receipt\n// timestamps keep strokes apart when JS drains a backlog.\nconst RING_STROKE_IDLE_MS = 1000\n/** Per ring, when the open stroke's last step arrived. */\nconst ringStrokes = new Map<string, number>()\n\nfunction ringKey(event: TouchEvent): string {\n return event.controllerId ?? `source:${event.source}`\n}\n\nfunction isRingSlideStep(event: TouchEvent): boolean {\n return event.source === 2 && (event.gestureName === \"swipe_up\" || event.gestureName === \"swipe_down\")\n}\n\nfunction opensRingStroke(event: TouchEvent): boolean {\n const last = ringStrokes.get(ringKey(event))\n ringStrokes.set(ringKey(event), event.timestamp)\n const elapsed = last === undefined ? null : event.timestamp - last\n return elapsed === null || elapsed < 0 || elapsed >= RING_STROKE_IDLE_MS\n}\n\nfunction endRingStroke(event: TouchEvent): void {\n if (event.source === 2 && (event.gestureName === \"touch_down\" || event.gestureName === \"tap_end\")) {\n ringStrokes.delete(ringKey(event))\n }\n}\n\n/** The discrete swipe a stroke opens with: the step's travel belongs to scroll_*. */\nfunction strokeSwipe(step: TouchEvent): TouchEvent {\n const swipe = {...step}\n delete swipe.distance\n delete swipe.speed\n return swipe\n}\n\n/**\n * Miniapps' copy of the touch: `input2d: true` when it came from a controller\n * that swipes in two dimensions (the Neural Band), the field absent otherwise,\n * so a 1D swipe from the temples or the ring stays tellable while a band is\n * connected under the same gesture names.\n */\nfunction toMiniapps(event: TouchEvent): TouchEvent & {input2d?: true} {\n const id = event.controllerId\n if (id === undefined) return event\n const model = useGlassesStore.getState().controllers?.[id]?.model\n return model !== undefined && hasInput2d(model) ? {...event, input2d: true} : event\n}\n\n/**\n * Route both real glasses input and phone mirror controls through the same\n * policy. A claimed gesture goes to the app holding the claim, alone; an\n * unclaimed one goes to every subscriber and then the engine's default. The\n * one rule ahead of the claims: an unclaimed double tap leaves the miniapp\n * the wearer is in — the one visibly on the glasses, else the running\n * standard app on an empty screen — whoever else claimed the gesture; the\n * dashboard's claim is for the screen with no app in it. Head position\n * (head_up / head_down) is a gesture like any other: the dashboard claims it\n * while it runs, and an unclaimed head_up on glasses that defer the dashboard\n * to the phone opens the native one, as it would with no app at all. A ring\n * slide step becomes one swipe per stroke plus a scroll step (see above).\n */\nexport function dispatchTouchEvent(event: TouchEvent): void {\n if (isRingSlideStep(event)) {\n if (opensRingStroke(event)) routeTouchEvent(strokeSwipe(event))\n routeTouchEvent({...event, gestureName: event.gestureName === \"swipe_up\" ? \"scroll_up\" : \"scroll_down\"})\n return\n }\n endRingStroke(event)\n routeTouchEvent(event)\n}\n\nfunction routeTouchEvent(event: TouchEvent): void {\n const gesture = event.gestureName\n const claimant = localMiniappRuntime.gestureClaimant(gesture)\n const doubleTap = gesture === \"double_tap\"\n // The Neural Band's middle finger (index 1) shares the tap names. Either\n // finger leaves the app on screen; the firmware dashboard is the index finger's.\n const osDoubleTap = doubleTap && event.index !== 1\n const osHeadUp = gesture === \"head_up\"\n\n if (doubleTap) {\n // The app being left opts out of OS exit by registering double tap (the\n // terminal's back-to-menu). The latest claimant still receives it. Otherwise\n // the tap means \"leave the app\". The controller shows the bounded OS\n // notice first, then uses the normal store stop path (and closes its\n // phone overlay).\n const leaving = localDisplayManager.getMiniappToLeave()\n if (\n leaving !== null &&\n !localMiniappRuntime.hasGestureClaim(leaving, gesture) &&\n miniappExitGesture.tryExitMiniapp()\n ) {\n gestureDotsService.noteGesture(gesture, true, event.index, event.controllerId)\n return\n }\n }\n\n if (claimant !== null) {\n // An overlay app claims the double tap and head-up on an empty screen to open the dashboard.\n if ((gesture === \"double_tap\" || osHeadUp) && isOverlayApp(claimant)) {\n dashboardOpenTrace.trigger(osHeadUp ? \"head-up\" : \"double-tap\", event.timestamp)\n }\n // The press may have started before this app claimed its release edge.\n gestureDotsService.noteGesture(gesture, true, event.index, event.controllerId)\n localMiniappRuntime.forwardEvent(\"touch_event\", toMiniapps(event), undefined, claimant)\n return\n }\n\n // Gesture-dots debug indicator (any device, gated by its setting). It\n // only paints while the screen is otherwise empty.\n gestureDotsService.noteGesture(gesture, false, event.index, event.controllerId)\n\n localMiniappRuntime.forwardEvent(\"touch_event\", toMiniapps(event))\n\n // Nobody claimed a double tap or a head-up: the glasses' native dashboard.\n // On eligible Glassly CFW glasses the dashboard miniapp claims both while it\n // runs (ADR-0006); stock firmware keeps its native dashboard (ADR-0002) and\n // opens it on a head-up by itself, so only the double tap is relayed there.\n // The modal nav UI owns the screen; showDashboard would fight it. Without\n // glasses there is no dashboard to open, and the mirror keeps its frame.\n // pagesEligible: connected Glassly CFW glasses, whose firmware leaves the\n // dashboard to the phone; other firmware opens its own on a lift.\n const opensNativeDashboard = osDoubleTap || (osHeadUp && pagesEligible())\n if (opensNativeDashboard && !nativeNavigationService.isActive && isGlassesConnected(useGlassesStore.getState().connection)) {\n useDisplayStore.getState().setDisplayEvent({layout: {layoutType: \"unavailable\", reason: \"firmware-dashboard\"}})\n void Promise.resolve(BluetoothSdk.showDashboard()).catch((err) => {\n console.error(\"DeviceEventRouter: showDashboard failed:\", err)\n })\n }\n}\n\nexport function resetTouchInput(): void {\n miniappExitGesture.reset()\n ringStrokes.clear()\n}\n\n/** Phone mirror input uses the same dashboard/miniapp policy as real glasses. */\nexport function sendGesture(\n gestureName:\n | \"single_tap\"\n | \"tap_start\"\n | \"double_tap\"\n | \"tap_end\"\n | \"tap_then_hold\"\n | \"touch_down\"\n | \"swipe_up\"\n | \"swipe_down\"\n | \"swipe_left\"\n | \"swipe_right\"\n | \"long_press\"\n | \"dial_up\"\n | \"dial_down\"\n | \"head_up\"\n | \"head_down\",\n): void {\n const model = useGlassesStore.getState().deviceModel\n dispatchTouchEvent({\n type: \"touch_event\",\n gestureName,\n deviceModel: Object.values(DeviceModels).find((candidate) => candidate === model) ?? DeviceModels.Simulated,\n timestamp: Date.now(),\n })\n}\n"]}
|
|
1
|
+
{"version":3,"file":"GlassesTouchInput.js","sourceRoot":"","sources":["../../src/services/GlassesTouchInput.ts"],"names":[],"mappings":"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","sourcesContent":["import {useDisplayStore} from \"../stores/display\"\nimport {DeviceModels, type TouchEvent} from \"@glassly/bluetooth-sdk\"\nimport BluetoothSdk from \"@glassly/bluetooth-sdk/internal\"\n\nimport {useAppStatusStore} from \"../stores/apps\"\nimport {useGlassesStore} from \"../stores/glasses\"\nimport {BgTimer} from \"../utils/timers\"\nimport {hasInput2d} from \"./controllers\"\nimport dashboardOpenTrace from \"./debug/DashboardOpenTrace\"\nimport gestureDotsService from \"./GestureDotsService\"\nimport {isGlassesConnected} from \"./GlassesReadiness\"\nimport localDisplayManager from \"./LocalDisplayManager\"\nimport localMiniappRuntime from \"./LocalMiniappRuntime\"\nimport {MiniappExitGesture} from \"./MiniappExitGesture\"\nimport nativeNavigationService from \"./NativeNavigationService\"\nimport {isOverlayApp} from \"./pages/overlayApps\"\nimport {pagesEligible} from \"./pages/pageEligibility\"\n\nconst miniappExitGesture = new MiniappExitGesture({\n getState: () => useAppStatusStore.getState(),\n getTargetPackageName: () => localDisplayManager.getMiniappToLeave(),\n beginExitNotice: (packageName, text) => localDisplayManager.beginMiniappExit(packageName, text),\n finishExitNotice: (packageName) => localDisplayManager.finishMiniappExit(packageName),\n cancelExitNotice: (packageName) => localDisplayManager.cancelMiniappExit(packageName),\n setTimeout: (callback, delay) => BgTimer.setTimeout(callback, delay),\n clearTimeout: (timerId) => BgTimer.clearTimeout(timerId),\n})\n\n// The ring reports a slide once per step of travel, whether the CFW forwards\n// it (deviceModel G2) or the ring sends it to the phone itself (deviceModel\n// R1); both tag source 2. One press is one swipe: the stroke's first step goes\n// out as swipe_up / swipe_down, and every step, the first included, as\n// scroll_up / scroll_down with its distance and speed for smooth scrolling. A\n// stroke ends at the ring's next touch_down or tap_end, or after\n// RING_STROKE_IDLE_MS without a step when a report was lost. Reversing within\n// a stroke fires no swipe (a finger rolling back at lift-off). Native receipt\n// timestamps keep strokes apart when JS drains a backlog.\nconst RING_STROKE_IDLE_MS = 1000\n/** Per ring, when the open stroke's last step arrived. */\nconst ringStrokes = new Map<string, number>()\n\nfunction ringKey(event: TouchEvent): string {\n return event.controllerId ?? `source:${event.source}`\n}\n\nfunction isRingSlideStep(event: TouchEvent): boolean {\n return event.source === 2 && (event.gestureName === \"swipe_up\" || event.gestureName === \"swipe_down\")\n}\n\nfunction opensRingStroke(event: TouchEvent): boolean {\n const last = ringStrokes.get(ringKey(event))\n ringStrokes.set(ringKey(event), event.timestamp)\n const elapsed = last === undefined ? null : event.timestamp - last\n return elapsed === null || elapsed < 0 || elapsed >= RING_STROKE_IDLE_MS\n}\n\nfunction endRingStroke(event: TouchEvent): void {\n if (event.source === 2 && (event.gestureName === \"touch_down\" || event.gestureName === \"tap_end\")) {\n ringStrokes.delete(ringKey(event))\n }\n}\n\n/** The discrete swipe a stroke opens with: the step's travel belongs to scroll_*. */\nfunction strokeSwipe(step: TouchEvent): TouchEvent {\n const swipe = {...step}\n delete swipe.distance\n delete swipe.speed\n return swipe\n}\n\n/**\n * Miniapps' copy of the touch: `input2d: true` when it came from a controller\n * that swipes in two dimensions (the Neural Band), the field absent otherwise,\n * so a 1D swipe from the temples or the ring stays tellable while a band is\n * connected under the same gesture names.\n */\nfunction toMiniapps(event: TouchEvent): TouchEvent & {input2d?: true} {\n const id = event.controllerId\n if (id === undefined) return event\n const model = useGlassesStore.getState().controllers?.[id]?.model\n return model !== undefined && hasInput2d(model) ? {...event, input2d: true} : event\n}\n\n/**\n * Route both real glasses input and phone mirror controls through the same\n * policy. A claimed gesture goes to the app holding the claim, alone; an\n * unclaimed one goes to every subscriber and then the engine's default. The\n * one rule ahead of the claims: an unclaimed double tap leaves the miniapp\n * the wearer is in — the one visibly on the glasses, else the running\n * standard app on an empty screen — whoever else claimed the gesture; the\n * dashboard's claim is for the screen with no app in it. Head position\n * (head_up / head_down) is a gesture like any other: the dashboard claims it\n * while it runs, and an unclaimed head_up on glasses that defer the dashboard\n * to the phone opens the native one, as it would with no app at all. A ring\n * slide step becomes one swipe per stroke plus a scroll step (see above).\n */\nexport function dispatchTouchEvent(event: TouchEvent): void {\n if (isRingSlideStep(event)) {\n if (opensRingStroke(event)) routeTouchEvent(strokeSwipe(event))\n routeTouchEvent({...event, gestureName: event.gestureName === \"swipe_up\" ? \"scroll_up\" : \"scroll_down\"})\n return\n }\n endRingStroke(event)\n routeTouchEvent(event)\n}\n\nfunction routeTouchEvent(event: TouchEvent): void {\n const gesture = event.gestureName\n const claimant = localMiniappRuntime.gestureClaimant(gesture)\n const doubleTap = gesture === \"double_tap\"\n // The Neural Band's middle finger (index 1) shares the tap names. Either\n // finger leaves the app on screen; the firmware dashboard is the index finger's.\n const osDoubleTap = doubleTap && !(event.source === 3 && event.index === 1)\n const osHeadUp = gesture === \"head_up\"\n\n if (doubleTap) {\n // The app being left opts out of OS exit by registering double tap (the\n // terminal's back-to-menu). The latest claimant still receives it. Otherwise\n // the tap means \"leave the app\". The controller shows the bounded OS\n // notice first, then uses the normal store stop path (and closes its\n // phone overlay).\n const leaving = localDisplayManager.getMiniappToLeave()\n if (\n leaving !== null &&\n !localMiniappRuntime.hasGestureClaim(leaving, gesture) &&\n miniappExitGesture.tryExitMiniapp()\n ) {\n gestureDotsService.noteGesture(gesture, true, event.index, event.controllerId)\n return\n }\n }\n\n if (claimant !== null) {\n // An overlay app claims the double tap and head-up on an empty screen to open the dashboard.\n if ((gesture === \"double_tap\" || osHeadUp) && isOverlayApp(claimant)) {\n dashboardOpenTrace.trigger(osHeadUp ? \"head-up\" : \"double-tap\", event.timestamp)\n }\n // The press may have started before this app claimed its release edge.\n gestureDotsService.noteGesture(gesture, true, event.index, event.controllerId)\n localMiniappRuntime.forwardEvent(\"touch_event\", toMiniapps(event), undefined, claimant)\n return\n }\n\n // Gesture-dots debug indicator (any device, gated by its setting). It\n // only paints while the screen is otherwise empty.\n gestureDotsService.noteGesture(gesture, false, event.index, event.controllerId)\n\n localMiniappRuntime.forwardEvent(\"touch_event\", toMiniapps(event))\n\n // Nobody claimed a double tap or a head-up: the glasses' native dashboard.\n // On eligible Glassly CFW glasses the dashboard miniapp claims both while it\n // runs (ADR-0006); stock firmware keeps its native dashboard (ADR-0002) and\n // opens it on a head-up by itself, so only the double tap is relayed there.\n // The modal nav UI owns the screen; showDashboard would fight it. Without\n // glasses there is no dashboard to open, and the mirror keeps its frame.\n // pagesEligible: connected Glassly CFW glasses, whose firmware leaves the\n // dashboard to the phone; other firmware opens its own on a lift.\n const opensNativeDashboard = osDoubleTap || (osHeadUp && pagesEligible())\n if (\n opensNativeDashboard &&\n !nativeNavigationService.isActive &&\n isGlassesConnected(useGlassesStore.getState().connection)\n ) {\n useDisplayStore.getState().setDisplayEvent({layout: {layoutType: \"unavailable\", reason: \"firmware-dashboard\"}})\n void Promise.resolve(BluetoothSdk.showDashboard()).catch((err) => {\n console.error(\"DeviceEventRouter: showDashboard failed:\", err)\n })\n }\n}\n\nexport function resetTouchInput(): void {\n miniappExitGesture.reset()\n ringStrokes.clear()\n}\n\n/** Phone mirror input uses the same dashboard/miniapp policy as real glasses. */\nexport function sendGesture(\n gestureName:\n | \"single_tap\"\n | \"tap_start\"\n | \"double_tap\"\n | \"tap_end\"\n | \"tap_then_hold\"\n | \"touch_down\"\n | \"swipe_up\"\n | \"swipe_down\"\n | \"swipe_left\"\n | \"swipe_right\"\n | \"long_press\"\n | \"dial_up\"\n | \"dial_down\"\n | \"head_up\"\n | \"head_down\",\n): void {\n const model = useGlassesStore.getState().deviceModel\n dispatchTouchEvent({\n type: \"touch_event\",\n gestureName,\n deviceModel: Object.values(DeviceModels).find((candidate) => candidate === model) ?? DeviceModels.Simulated,\n timestamp: Date.now(),\n })\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JSCrashloopReportService.d.ts","sourceRoot":"","sources":["../../src/services/JSCrashloopReportService.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,+BAA+B,EACrC,MAAM,yBAAyB,CAAA;AAQhC,wBAAsB,uBAAuB,CAAC,MAAM,EAAE;IACpD,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;CACxB,GAAG,OAAO,CAAC,+BAA+B,CAAC,
|
|
1
|
+
{"version":3,"file":"JSCrashloopReportService.d.ts","sourceRoot":"","sources":["../../src/services/JSCrashloopReportService.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,+BAA+B,EACrC,MAAM,yBAAyB,CAAA;AAQhC,wBAAsB,uBAAuB,CAAC,MAAM,EAAE;IACpD,WAAW,EAAE,MAAM,CAAA;IACnB,MAAM,EAAE,MAAM,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,EAAE,CAAA;CACxB,GAAG,OAAO,CAAC,+BAA+B,CAAC,CA6B3C;AAeD,wBAAgB,6BAA6B,IAAI,IAAI,CAGpD;AAED,wBAAgB,4BAA4B,IAAI,IAAI,CAGnD"}
|
|
@@ -8,6 +8,11 @@ let unsubscribe = null;
|
|
|
8
8
|
export async function submitJSCrashloopReport(params) {
|
|
9
9
|
const { packageName, reason, lastLogLines = [] } = params;
|
|
10
10
|
const app = useAppStatusStore.getState().apps.find((a) => a.packageName === packageName);
|
|
11
|
+
// A dev miniapp's crash is its developer's to fix; JSRouter forwards it to their dev server.
|
|
12
|
+
if (app?.isMiniappDev) {
|
|
13
|
+
console.log(`[${LOG_TAG}] Not reporting a dev miniapp crashloop:`, packageName);
|
|
14
|
+
return { status: "skipped", reason: "dev miniapp" };
|
|
15
|
+
}
|
|
11
16
|
const appName = app?.name ?? packageName;
|
|
12
17
|
const result = await submitAutomaticReport({
|
|
13
18
|
kind: "automatic",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JSCrashloopReportService.js","sourceRoot":"","sources":["../../src/services/JSCrashloopReportService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,qBAAqB,EAAC,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAC,iBAAiB,EAAC,MAAM,gBAAgB,CAAA;AAChD,OAAO,EACL,kCAAkC,EAClC,iCAAiC,GAElC,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAC,gBAAgB,EAAC,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAC,mBAAmB,EAA0B,MAAM,wBAAwB,CAAA;AAEnF,MAAM,OAAO,GAAG,mBAAmB,CAAA;AAEnC,IAAI,WAAW,GAAwB,IAAI,CAAA;AAE3C,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,MAI7C;IACC,MAAM,EAAC,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,EAAE,EAAC,GAAG,MAAM,CAAA;IACvD,MAAM,GAAG,GAAG,iBAAiB,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,WAAW,CAAC,CAAA;IACxF,MAAM,OAAO,GAAG,GAAG,EAAE,IAAI,IAAI,WAAW,CAAA;IACxC,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC;QACzC,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE;YACP,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,mBAAmB;YAC3B,MAAM,EAAE,uBAAuB;YAC/B,uBAAuB,EAAE,WAAW;YACpC,gBAAgB,EAAE,OAAO;SAC1B;QACD,MAAM,EAAE;YACN,gBAAgB,EAAE,GAAG,OAAO,+BAA+B;YAC3D,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,EAAC,MAAM,EAAE,YAAY,EAAC,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/D,cAAc,EAAE,UAAU;SAC3B;QACD,WAAW,EAAE,gBAAgB,WAAW,EAAE;KAC3C,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,iCAAiC,CAAC,MAAM,CAAC,CAAA;IACxD,kCAAkC,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,CAAA;IAChE,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,kBAAkB,CAAC,YAAgC;IAC1D,IAAI,YAAY,CAAC,IAAI,KAAK,mBAAmB,IAAI,CAAC,YAAY,CAAC,WAAW;QAAE,OAAM;IAClF,MAAM,WAAW,GAAG,YAAY,CAAC,WAAW,CAAA;IAC5C,MAAM,YAAY,GAAG,gBAAgB,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,CAAA;IACnF,KAAK,uBAAuB,CAAC;QAC3B,WAAW;QACX,MAAM,EAAE,YAAY,CAAC,MAAM;QAC3B,YAAY;KACb,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACjB,OAAO,CAAC,KAAK,CAAC,IAAI,OAAO,qBAAqB,EAAE,KAAK,CAAC,CAAA;IACxD,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,6BAA6B;IAC3C,IAAI,WAAW;QAAE,OAAM;IACvB,WAAW,GAAG,mBAAmB,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAA;AACjE,CAAC;AAED,MAAM,UAAU,4BAA4B;IAC1C,WAAW,EAAE,EAAE,CAAA;IACf,WAAW,GAAG,IAAI,CAAA;AACpB,CAAC","sourcesContent":["import {submitAutomaticReport} from \"../facades/reports\"\nimport {useAppStatusStore} from \"../stores/apps\"\nimport {\n logAutomaticReportSubmissionStatus,\n toAutomaticReportSubmissionStatus,\n type AutomaticReportSubmissionStatus,\n} from \"./AutomaticReportResult\"\nimport {getMiniappEngine} from \"./MiniappEngine\"\nimport {islandNotifications, type IslandNotification} from \"./NotificationsEmitter\"\n\nconst LOG_TAG = \"JSCrashloopReport\"\n\nlet unsubscribe: (() => void) | null = null\n\nexport async function submitJSCrashloopReport(params: {\n packageName: string\n reason: string\n lastLogLines?: string[]\n}): Promise<AutomaticReportSubmissionStatus> {\n const {packageName, reason, lastLogLines = []} = params\n const app = useAppStatusStore.getState().apps.find((a) => a.packageName === packageName)\n const appName = app?.name ?? packageName\n const result = await submitAutomaticReport({\n kind: \"automatic\",\n trigger: {\n type: \"automatic\",\n source: \"miniapp_crashloop\",\n reason: \"js_crashloop_disabled\",\n sourceAppletPackageName: packageName,\n sourceAppletName: appName,\n },\n report: {\n expectedBehavior: `${appName} should run without crashing.`,\n actualBehavior: JSON.stringify({reason, lastLogLines}, null, 2),\n systemPriority: \"critical\",\n },\n throttleKey: `js_crashloop:${packageName}`,\n })\n\n const status = toAutomaticReportSubmissionStatus(result)\n logAutomaticReportSubmissionStatus(LOG_TAG, status, packageName)\n return status\n}\n\nfunction handleNotification(notification: IslandNotification): void {\n if (notification.kind !== \"miniapp_crashloop\" || !notification.packageName) return\n const packageName = notification.packageName\n const lastLogLines = getMiniappEngine()?.router.logRing.snapshot(packageName) ?? []\n void submitJSCrashloopReport({\n packageName,\n reason: notification.reason,\n lastLogLines,\n }).catch((error) => {\n console.error(`[${LOG_TAG}] Unexpected error:`, error)\n })\n}\n\nexport function startJSCrashloopReportService(): void {\n if (unsubscribe) return\n unsubscribe = islandNotifications.subscribe(handleNotification)\n}\n\nexport function stopJSCrashloopReportService(): void {\n unsubscribe?.()\n unsubscribe = null\n}\n"]}
|
|
1
|
+
{"version":3,"file":"JSCrashloopReportService.js","sourceRoot":"","sources":["../../src/services/JSCrashloopReportService.ts"],"names":[],"mappings":"AAAA,OAAO,EAAC,qBAAqB,EAAC,MAAM,oBAAoB,CAAA;AACxD,OAAO,EAAC,iBAAiB,EAAC,MAAM,gBAAgB,CAAA;AAChD,OAAO,EACL,kCAAkC,EAClC,iCAAiC,GAElC,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAC,gBAAgB,EAAC,MAAM,iBAAiB,CAAA;AAChD,OAAO,EAAC,mBAAmB,EAA0B,MAAM,wBAAwB,CAAA;AAEnF,MAAM,OAAO,GAAG,mBAAmB,CAAA;AAEnC,IAAI,WAAW,GAAwB,IAAI,CAAA;AAE3C,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,MAI7C;IACC,MAAM,EAAC,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,EAAE,EAAC,GAAG,MAAM,CAAA;IACvD,MAAM,GAAG,GAAG,iBAAiB,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,WAAW,CAAC,CAAA;IACxF,6FAA6F;IAC7F,IAAI,GAAG,EAAE,YAAY,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,IAAI,OAAO,0CAA0C,EAAE,WAAW,CAAC,CAAA;QAC/E,OAAO,EAAC,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,aAAa,EAAC,CAAA;IACnD,CAAC;IACD,MAAM,OAAO,GAAG,GAAG,EAAE,IAAI,IAAI,WAAW,CAAA;IACxC,MAAM,MAAM,GAAG,MAAM,qBAAqB,CAAC;QACzC,IAAI,EAAE,WAAW;QACjB,OAAO,EAAE;YACP,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,mBAAmB;YAC3B,MAAM,EAAE,uBAAuB;YAC/B,uBAAuB,EAAE,WAAW;YACpC,gBAAgB,EAAE,OAAO;SAC1B;QACD,MAAM,EAAE;YACN,gBAAgB,EAAE,GAAG,OAAO,+BAA+B;YAC3D,cAAc,EAAE,IAAI,CAAC,SAAS,CAAC,EAAC,MAAM,EAAE,YAAY,EAAC,EAAE,IAAI,EAAE,CAAC,CAAC;YAC/D,cAAc,EAAE,UAAU;SAC3B;QACD,WAAW,EAAE,gBAAgB,WAAW,EAAE;KAC3C,CAAC,CAAA;IAEF,MAAM,MAAM,GAAG,iCAAiC,CAAC,MAAM,CAAC,CAAA;IACxD,kCAAkC,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,CAAA;IAChE,OAAO,MAAM,CAAA;AACf,CAAC;AAED,SAAS,kBAAkB,CAAC,YAAgC;IAC1D,IAAI,YAAY,CAAC,IAAI,KAAK,mBAAmB,IAAI,CAAC,YAAY,CAAC,WAAW;QAAE,OAAM;IAClF,MAAM,WAAW,GAAG,YAAY,CAAC,WAAW,CAAA;IAC5C,MAAM,YAAY,GAAG,gBAAgB,EAAE,EAAE,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAC,IAAI,EAAE,CAAA;IACnF,KAAK,uBAAuB,CAAC;QAC3B,WAAW;QACX,MAAM,EAAE,YAAY,CAAC,MAAM;QAC3B,YAAY;KACb,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;QACjB,OAAO,CAAC,KAAK,CAAC,IAAI,OAAO,qBAAqB,EAAE,KAAK,CAAC,CAAA;IACxD,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,6BAA6B;IAC3C,IAAI,WAAW;QAAE,OAAM;IACvB,WAAW,GAAG,mBAAmB,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAA;AACjE,CAAC;AAED,MAAM,UAAU,4BAA4B;IAC1C,WAAW,EAAE,EAAE,CAAA;IACf,WAAW,GAAG,IAAI,CAAA;AACpB,CAAC","sourcesContent":["import {submitAutomaticReport} from \"../facades/reports\"\nimport {useAppStatusStore} from \"../stores/apps\"\nimport {\n logAutomaticReportSubmissionStatus,\n toAutomaticReportSubmissionStatus,\n type AutomaticReportSubmissionStatus,\n} from \"./AutomaticReportResult\"\nimport {getMiniappEngine} from \"./MiniappEngine\"\nimport {islandNotifications, type IslandNotification} from \"./NotificationsEmitter\"\n\nconst LOG_TAG = \"JSCrashloopReport\"\n\nlet unsubscribe: (() => void) | null = null\n\nexport async function submitJSCrashloopReport(params: {\n packageName: string\n reason: string\n lastLogLines?: string[]\n}): Promise<AutomaticReportSubmissionStatus> {\n const {packageName, reason, lastLogLines = []} = params\n const app = useAppStatusStore.getState().apps.find((a) => a.packageName === packageName)\n // A dev miniapp's crash is its developer's to fix; JSRouter forwards it to their dev server.\n if (app?.isMiniappDev) {\n console.log(`[${LOG_TAG}] Not reporting a dev miniapp crashloop:`, packageName)\n return {status: \"skipped\", reason: \"dev miniapp\"}\n }\n const appName = app?.name ?? packageName\n const result = await submitAutomaticReport({\n kind: \"automatic\",\n trigger: {\n type: \"automatic\",\n source: \"miniapp_crashloop\",\n reason: \"js_crashloop_disabled\",\n sourceAppletPackageName: packageName,\n sourceAppletName: appName,\n },\n report: {\n expectedBehavior: `${appName} should run without crashing.`,\n actualBehavior: JSON.stringify({reason, lastLogLines}, null, 2),\n systemPriority: \"critical\",\n },\n throttleKey: `js_crashloop:${packageName}`,\n })\n\n const status = toAutomaticReportSubmissionStatus(result)\n logAutomaticReportSubmissionStatus(LOG_TAG, status, packageName)\n return status\n}\n\nfunction handleNotification(notification: IslandNotification): void {\n if (notification.kind !== \"miniapp_crashloop\" || !notification.packageName) return\n const packageName = notification.packageName\n const lastLogLines = getMiniappEngine()?.router.logRing.snapshot(packageName) ?? []\n void submitJSCrashloopReport({\n packageName,\n reason: notification.reason,\n lastLogLines,\n }).catch((error) => {\n console.error(`[${LOG_TAG}] Unexpected error:`, error)\n })\n}\n\nexport function startJSCrashloopReportService(): void {\n if (unsubscribe) return\n unsubscribe = islandNotifications.subscribe(handleNotification)\n}\n\nexport function stopJSCrashloopReportService(): void {\n unsubscribe?.()\n unsubscribe = null\n}\n"]}
|
|
@@ -114,6 +114,8 @@ export declare class JSRouter {
|
|
|
114
114
|
* frames pass through unchanged.
|
|
115
115
|
*/
|
|
116
116
|
uiRouter: UIRouter | null;
|
|
117
|
+
/** Teardowns in progress, so a stop and a racing start or stop see the same one. */
|
|
118
|
+
private readonly unregistering;
|
|
117
119
|
constructor(runtime: LocalMiniappRuntime, crust: JSCrustBinding, logger?: RouterLogger);
|
|
118
120
|
/**
|
|
119
121
|
* Subscribe to Crust's `js_message` event. Idempotent — calling
|
|
@@ -159,12 +161,18 @@ export declare class JSRouter {
|
|
|
159
161
|
private handleCrash;
|
|
160
162
|
private summarizeReason;
|
|
161
163
|
/**
|
|
162
|
-
* Tear down a JSContext and unregister from the runtime.
|
|
163
|
-
*
|
|
164
|
-
*
|
|
164
|
+
* Tear down a JSContext and unregister from the runtime. The session's
|
|
165
|
+
* `onBeforeDisconnect` handlers get a short grace window first, so a
|
|
166
|
+
* miniapp can clear what it drew and end its own work while its messages
|
|
167
|
+
* still reach the host. Concurrent calls share one teardown.
|
|
165
168
|
*/
|
|
166
169
|
unregister(packageName: string): Promise<void>;
|
|
170
|
+
/** Resolves once an in-flight {@link unregister} of this package has finished. */
|
|
171
|
+
whenUnregistered(packageName: string): Promise<void>;
|
|
172
|
+
private teardown;
|
|
167
173
|
/** List packages the router has registered. */
|
|
174
|
+
/** The user opened a running miniapp again; the source rides the next respawn too. */
|
|
175
|
+
notifyLaunch(packageName: string, launchSource: MiniappLaunchSource): void;
|
|
168
176
|
registeredPackages(): string[];
|
|
169
177
|
/**
|
|
170
178
|
* Validate that a reused background JSContext is still responsive when its
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JSRouter.d.ts","sourceRoot":"","sources":["../../src/services/JSRouter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,mBAAmB,CAAA;AAGxD,OAAO,KAAK,mBAAmB,MAAM,uBAAuB,CAAA;AAC5D,OAAO,KAAK,EAAC,mBAAmB,EAAC,MAAM,kBAAkB,CAAA;AAEzD,OAAO,KAAK,EAAC,wBAAwB,EAAC,MAAM,uBAAuB,CAAA;AACnE,OAAO,KAAK,EAAC,iBAAiB,EAAC,MAAM,qBAAqB,CAAA;AAC1D,OAAO,EAAC,eAAe,EAAE,aAAa,EAAgB,MAAM,iBAAiB,CAAA;AAE7E,OAAO,KAAK,EAAC,QAAQ,EAAC,MAAM,YAAY,CAAA;AAKxC;;;GAGG;AACH,KAAK,mBAAmB,GAAG,OAAO,mBAAmB,CAAA;AAErD;;;;GAIG;AACH,MAAM,WAAW,cAAc;IAC7B,cAAc,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAC5F,aAAa,CAAC,WAAW,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IAC/E,oBAAoB,CAAC,EAAE,MAAM,MAAM,CAAA;IACnC,OAAO,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAA;IAClG,MAAM,CAAC,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAA;IACtD,eAAe,CAAC,EAAE,MAAM,MAAM,EAAE,CAAA;IAChC,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,KAAK,iBAAiB,CAAA;CACvG;AAED,MAAM,WAAW,sBAAsB;IACrC,WAAW,EAAE,MAAM,CAAA;IACnB,KAAK,EAAE,MAAM,CAAA;IACb,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,IAAI,CAAC,EAAE,OAAO,EAAE,CAAA;IAChB,KAAK,CAAC,EAAE,MAAM,CAAA;IAGd,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAA;CACzB;AAED,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IACjD,IAAI,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;IAClD,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,OAAO,KAAK,IAAI,CAAA;CACpD,CAAA;AAiBD,qBAAa,QAAQ;
|
|
1
|
+
{"version":3,"file":"JSRouter.d.ts","sourceRoot":"","sources":["../../src/services/JSRouter.ts"],"names":[],"mappings":"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"}
|
|
@@ -84,6 +84,8 @@ export class JSRouter {
|
|
|
84
84
|
* frames pass through unchanged.
|
|
85
85
|
*/
|
|
86
86
|
uiRouter = null;
|
|
87
|
+
/** Teardowns in progress, so a stop and a racing start or stop see the same one. */
|
|
88
|
+
unregistering = new Map();
|
|
87
89
|
constructor(runtime, crust, logger = defaultLogger) {
|
|
88
90
|
this.runtime = runtime;
|
|
89
91
|
this.crust = crust;
|
|
@@ -269,13 +271,26 @@ export class JSRouter {
|
|
|
269
271
|
return method;
|
|
270
272
|
}
|
|
271
273
|
/**
|
|
272
|
-
* Tear down a JSContext and unregister from the runtime.
|
|
273
|
-
*
|
|
274
|
-
*
|
|
274
|
+
* Tear down a JSContext and unregister from the runtime. The session's
|
|
275
|
+
* `onBeforeDisconnect` handlers get a short grace window first, so a
|
|
276
|
+
* miniapp can clear what it drew and end its own work while its messages
|
|
277
|
+
* still reach the host. Concurrent calls share one teardown.
|
|
275
278
|
*/
|
|
276
|
-
|
|
279
|
+
unregister(packageName) {
|
|
277
280
|
if (!this.registered.has(packageName))
|
|
278
|
-
return;
|
|
281
|
+
return Promise.resolve();
|
|
282
|
+
const inFlight = this.unregistering.get(packageName);
|
|
283
|
+
if (inFlight)
|
|
284
|
+
return inFlight;
|
|
285
|
+
const teardown = this.teardown(packageName).finally(() => this.unregistering.delete(packageName));
|
|
286
|
+
this.unregistering.set(packageName, teardown);
|
|
287
|
+
return teardown;
|
|
288
|
+
}
|
|
289
|
+
/** Resolves once an in-flight {@link unregister} of this package has finished. */
|
|
290
|
+
async whenUnregistered(packageName) {
|
|
291
|
+
await this.unregistering.get(packageName);
|
|
292
|
+
}
|
|
293
|
+
async teardown(packageName) {
|
|
279
294
|
// Cancel any pending crash-respawn before tearing down — we don't
|
|
280
295
|
// want a stale timer to re-spawn a miniapp the user just disabled.
|
|
281
296
|
const pending = this.respawnTimers.get(packageName);
|
|
@@ -283,6 +298,7 @@ export class JSRouter {
|
|
|
283
298
|
BgTimer.clearTimeout(pending);
|
|
284
299
|
this.respawnTimers.delete(packageName);
|
|
285
300
|
}
|
|
301
|
+
await this.runtime.notifyWillDisconnect(packageName, "stopped");
|
|
286
302
|
this.spawnCache.delete(packageName);
|
|
287
303
|
this.crashController?.onKill(packageName);
|
|
288
304
|
// User-initiated close/disable: end any active nav trip so the glasses
|
|
@@ -301,6 +317,15 @@ export class JSRouter {
|
|
|
301
317
|
}
|
|
302
318
|
}
|
|
303
319
|
/** List packages the router has registered. */
|
|
320
|
+
/** The user opened a running miniapp again; the source rides the next respawn too. */
|
|
321
|
+
notifyLaunch(packageName, launchSource) {
|
|
322
|
+
if (!this.registered.has(packageName))
|
|
323
|
+
return;
|
|
324
|
+
const cached = this.spawnCache.get(packageName);
|
|
325
|
+
if (cached)
|
|
326
|
+
cached.launchSource = launchSource;
|
|
327
|
+
this.runtime.sendLaunchChange(packageName, launchSource);
|
|
328
|
+
}
|
|
304
329
|
registeredPackages() {
|
|
305
330
|
return Array.from(this.registered);
|
|
306
331
|
}
|
|
@@ -397,13 +422,18 @@ export class JSRouter {
|
|
|
397
422
|
if (iface === "__error") {
|
|
398
423
|
const payload = this.tryParseArgs(msg.argsJson);
|
|
399
424
|
this.logger.error(`[${packageName}] ${method}`, payload);
|
|
425
|
+
// Crashes reach the `glassly dev` terminal too, not only console calls.
|
|
426
|
+
const summary = this.summarizeReason(payload, method);
|
|
427
|
+
const stack = payload?.stack;
|
|
428
|
+
const errorArgs = typeof stack === "string" && stack ? [summary, stack] : [summary];
|
|
429
|
+
devServerBridge.forwardLog(packageName, "error", errorArgs, Date.now(), "background");
|
|
400
430
|
if (this.crashController) {
|
|
401
431
|
// Only treat "exception" + "unhandledRejection" + "uncaught" as
|
|
402
432
|
// crash signals. `console.error` calls also flow through the
|
|
403
433
|
// log path — those don't end the JSContext.
|
|
404
434
|
const isCrash = method === "exception" || method === "unhandledRejection" || method === "uncaught";
|
|
405
435
|
if (isCrash) {
|
|
406
|
-
this.handleCrash(packageName,
|
|
436
|
+
this.handleCrash(packageName, summary);
|
|
407
437
|
}
|
|
408
438
|
}
|
|
409
439
|
return;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"JSRouter.js","sourceRoot":"","sources":["../../src/services/JSRouter.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview JSRouter — RN-side host that bridges the per-miniapp\n * JS contexts (iOS-JSC and Android-QuickJS via Zipline) into the existing\n * {@link LocalMiniappRuntime} handler set.\n *\n * Rather than re-implement the 33 dispatch arms inline, the router\n * consumes Crust's `js_message` Expo event and forwards its\n * `__bridge.send(raw)` payloads to {@link LocalMiniappRuntime.handleRawMessage}.\n * The SDK envelope shape (`{type: \"DISPLAY\", ...}` etc.) is unchanged from\n * the WebView path, so every existing handler runs verbatim. What changes\n * is the *transport*:\n *\n * - **Inbound** (background JS → host): `__dispatch(\"__bridge\", \"send\",\n * [rawJsonString])` → `js_message` event → router →\n * `LocalMiniappRuntime.handleRawMessage(packageName, raw)`.\n * - **Outbound** (host → background JS): every package registered with\n * the router gets a `sendMessage(raw)` fn that calls\n * `Crust.jsDispatchToJs(packageName, {kind: \"bridge\", raw})`.\n * The polyfill's `__deliver` recognises `kind === \"bridge\"` and calls\n * `__deliverBridgeRaw(raw)`, which routes into the SDK's\n * {@link DispatchTransport.onMessage} handler.\n *\n * Host-side handler bodies (display fan-out, mic state, transcription,\n * navigation, etc.) live untouched in `LocalMiniappRuntime.ts`.\n *\n * Cloud-message routing (`phone_stream_status`, `phone_managed_stream_status`)\n * goes straight through `LocalMiniappRuntime.handleCloudMessage` — nothing\n * for the router to do; the responses arrive inside an envelope whose\n * `sendMessage` was already registered via the same path here.\n *\n * The router also bridges native error / log / unhandled-rejection\n * events (`iface: \"__log\"`, `iface: \"__error\"`) into the standard\n * `console.*` + Sentry breadcrumb pipeline so miniapp telemetry is\n * visible without bringing up a separate sink.\n */\n\nimport type {EventSubscription} from \"expo-modules-core\"\n\nimport devServerBridge from \"./DevServerBridge\"\nimport type localMiniappRuntime from \"./LocalMiniappRuntime\"\nimport type {MiniappLaunchSource} from \"@glassly/miniapp\"\n\nimport type {InstalledMiniappManifest} from \"./LocalMiniappRuntime\"\nimport type {JSCrashController} from \"./JSCrashController\"\nimport {JSLogRingBuffer, JSLogThrottle, redactSecrets} from \"./JSLogPipeline\"\nimport {islandNotifications} from \"./NotificationsEmitter\"\nimport type {UIRouter} from \"./UIRouter\"\nimport {miniappRunningRegistry} from \"./MiniappRunningRegistry\"\n\nimport {BgTimer} from \"../utils/timers\"\n\n/** The runtime's runtime instance type — the singleton exported from\n * LocalMiniappRuntime.ts (the file's `export default` is the instance,\n * not the class).\n */\ntype LocalMiniappRuntime = typeof localMiniappRuntime\n\n/**\n * Minimal subset of the Crust native module the router uses. Keeping the\n * binding loose lets us mock the module in unit tests without bringing\n * the whole Expo module surface along.\n */\nexport interface JSCrustBinding {\n jsDispatchToJs(packageName: string, envelope: Record<string, unknown>): Promise<void> | void\n jsSetManifest(packageName: string, permissions: string[]): Promise<void> | void\n jsLoadPolyfillBundle?: () => string\n jsSpawn?: (packageName: string, polyfill: string, miniappJs: string) => Promise<boolean> | boolean\n jsKill?: (packageName: string) => Promise<void> | void\n jsAlivePackages?: () => string[]\n addListener: (event: string, handler: (payload: Record<string, unknown>) => void) => EventSubscription\n}\n\nexport interface OutboundMessagePayload {\n packageName: string\n iface: string\n method: string\n argsJson?: string\n args?: unknown[]\n reqId?: string\n // Implementation-internal: any extra fields the dispatcher attached on\n // .forwardToRn (e.g. payload metadata) are passed through verbatim.\n [extra: string]: unknown\n}\n\nexport type RouterLogger = {\n log: (message: string, payload?: unknown) => void\n warn: (message: string, payload?: unknown) => void\n error: (message: string, payload?: unknown) => void\n}\n\nconst defaultLogger: RouterLogger = {\n log: (m, p) => console.log(`[JSRouter] ${m}`, p ?? \"\"),\n\n warn: (m, p) => console.warn(`[JSRouter] ${m}`, p ?? \"\"),\n\n error: (m, p) => console.error(`[JSRouter] ${m}`, p ?? \"\"),\n}\n\ninterface SpawnCache {\n miniappJs: string\n permissions: string[]\n installedManifest?: InstalledMiniappManifest\n launchSource?: MiniappLaunchSource\n}\n\nexport class JSRouter {\n private subscription: EventSubscription | null = null\n private readonly registered: Set<string> = new Set()\n /** Cached spawn arguments so the crash controller can respawn after a backoff. */\n private readonly spawnCache: Map<string, SpawnCache> = new Map()\n /** Active respawn timers (so unregister() can cancel a pending respawn). */\n private readonly respawnTimers: Map<string, number> = new Map()\n\n /**\n * Optional crash controller. When wired, every `__error` frame from a\n * JSContext drives the state machine; an Outcome with\n * scheduleRespawnAfterMs queues a setTimeout that re-spawns the\n * miniapp's last-known JS source after the backoff delay.\n */\n crashController: JSCrashController | null = null\n\n /** Hook called when a package transitions to CRASHLOOP_DISABLED. */\n onCrashloop: ((packageName: string, reason: string) => void) | null = null\n /** Hook called on the 2nd-within-window crash (toast UX). */\n onRestartToast: ((packageName: string, reason: string) => void) | null = null\n\n /**\n * Logging plumbing. Every `__log` frame passes through `redactSecrets`\n * (token/password/etc. scrubbed), then the throttle (100/min sustained\n * per pkg, 500 burst), then lands in the ring buffer + the host\n * logger. The ring buffer holds the last 200 lines/pkg so a crash\n * report can attach \"last words\" context.\n *\n * Replace with new instances in tests; production code uses the\n * defaults.\n */\n logThrottle: JSLogThrottle = new JSLogThrottle()\n logRing: JSLogRingBuffer = new JSLogRingBuffer()\n\n /**\n * Optional UI router — when wired, `__bridge.send` envelopes whose\n * inner payload type is `UI_SEND` get routed to the bound WebView\n * instead of through LocalMiniappRuntime. Two-layer miniapps set\n * this; legacy single-bundle WebView miniapps don't and the bridge\n * frames pass through unchanged.\n */\n uiRouter: UIRouter | null = null\n\n constructor(\n private readonly runtime: LocalMiniappRuntime,\n private readonly crust: JSCrustBinding,\n private readonly logger: RouterLogger = defaultLogger,\n ) {}\n\n /**\n * Subscribe to Crust's `js_message` event. Idempotent — calling\n * start() twice attaches a single listener.\n */\n start(): void {\n if (this.subscription) return\n this.subscription = this.crust.addListener(\"js_message\", (raw) => {\n try {\n this.handleOutbound(raw as unknown as OutboundMessagePayload)\n } catch (e) {\n this.logger.error(`outbound handler threw`, {error: String(e), raw})\n }\n })\n // A background script unregistered for missing liveness pings is dead\n // weight: its subscriptions are gone (so the mic releases) while the\n // webview keeps rendering stale state. Route it through the same\n // respawn machinery as a crash so it comes back automatically, with\n // the crash controller's backoff + crash-loop protection.\n this.runtime.onLivenessTimeout = (packageName) => {\n this.handleCrash(packageName, \"liveness: missed pings\")\n }\n }\n\n /**\n * Detach the Crust subscription. The router can be restarted later\n * with start(); registrations survive (the runtime's app map is the\n * source of truth).\n */\n stop(): void {\n this.subscription?.remove()\n this.subscription = null\n this.runtime.onLivenessTimeout = null\n }\n\n /**\n * Register a JSContext with the runtime so its handlers can fire\n * `sendMessage(raw)` against the right context. The router builds a\n * `sendMessage` that calls `Crust.jsDispatchToJs(packageName,\n * {kind: \"bridge\", raw})`; the polyfill's `__deliver` then hands the\n * envelope to `DispatchTransport.onMessage` inside the miniapp.\n *\n * Mirrors `MiniappHost.registerRuntime` on the WebView side. Callers\n * (e.g. {@link spawnAndRegister} below, or the host's miniapp launch\n * pipeline) should call this once per spawn.\n */\n registerApp(\n packageName: string,\n installedManifest?: InstalledMiniappManifest,\n launchSource?: MiniappLaunchSource,\n ): void {\n this.runtime.registerApp(\n packageName,\n (raw: string) => {\n this.dispatchBridgeRaw(packageName, raw)\n },\n installedManifest,\n launchSource,\n )\n this.registered.add(packageName)\n // JSContext is the source-of-truth for \"miniapp running\". The\n // home tile / tray reads this registry to project the `running`\n // flag — UI WebView open/close is separate.\n miniappRunningRegistry.add(packageName)\n }\n\n /**\n * Convenience: spawn a JSContext via Crust, register the app, and\n * set its declared permissions. Returns true on successful spawn.\n *\n * The host's miniapp launch path\n * (`mobile/src/services/miniapps/launchLocalMiniapp.ts`) calls this\n * once per JSContext mount.\n */\n async spawnAndRegister(\n packageName: string,\n miniappJs: string,\n options?: {\n permissions?: string[]\n installedManifest?: InstalledMiniappManifest\n launchSource?: MiniappLaunchSource\n },\n ): Promise<boolean> {\n if (!this.crust.jsSpawn) {\n this.logger.warn(\"jsSpawn not available — host binding missing native function\")\n return false\n }\n const polyfill = this.crust.jsLoadPolyfillBundle?.() ?? \"\"\n if (!polyfill) {\n this.logger.warn(`no polyfill bundle loaded for ${packageName}; spawn will likely fail`)\n }\n const ok = await this.crust.jsSpawn(packageName, polyfill, miniappJs)\n if (!ok) {\n this.logger.error(`spawn failed for ${packageName}`)\n return false\n }\n // Two distinct permission gates:\n // 1. Native dispatcher (JSContext → native bridge): `jsSetManifest`\n // checks per-call iface, e.g. __dispatch(\"mic\", \"start\", ...) requires\n // MICROPHONE.\n // 2. LocalMiniappRuntime (SUBSCRIBE envelope): `registerApp(...,\n // installedManifest)` carries the full manifest so SUBSCRIBE's gate\n // can match stream → permission against declared types.\n if (options?.permissions && options.permissions.length > 0) {\n await this.crust.jsSetManifest(packageName, options.permissions)\n }\n this.registerApp(packageName, options?.installedManifest, options?.launchSource)\n // Cache spawn arguments so the crash controller can respawn the\n // same code after a backoff. permissions + manifest are cached too\n // because the native side resets setManifest on every spawn and\n // LocalMiniappRuntime's installedManifest entry is keyed by\n // connect-time registration.\n this.spawnCache.set(packageName, {\n miniappJs,\n permissions: options?.permissions ?? [],\n installedManifest: options?.installedManifest,\n launchSource: options?.launchSource,\n })\n this.crashController?.onSpawn(packageName)\n\n // Fire the `init` envelope so the polyfill's __deliver handler\n // resolves `__initCallback(sessionId)`. The SDK's\n // `registerMiniapp(handler)` wires that callback to construct\n // MiniappSession and call the user's handler. Without this\n // dispatch the user's code never runs — `registerMiniapp` just\n // assigns to a global and waits.\n const sessionId = `${packageName}-${Date.now().toString(36)}`\n void this.crust.jsDispatchToJs(packageName, {kind: \"init\", sessionId})\n\n return true\n }\n\n /**\n * Crash-controller integration. Called from the `__error` frame\n * handler. The controller returns an outcome that tells us whether\n * to respawn (with delay) or leave the context dead.\n */\n private handleCrash(packageName: string, reason: string): void {\n // The native context is dead the instant a crash is observed — invalidate\n // its CONNECT handshake NOW so waitForConnect() blocks through the respawn\n // backoff window instead of resolving immediately against the dead context\n // (an action invoked mid-backoff would otherwise be delivered to nothing).\n this.runtime.resetHandshake(packageName)\n const controller = this.crashController\n if (!controller) return\n const cached = this.spawnCache.get(packageName)\n if (!cached) {\n this.logger.warn(`crash for ${packageName} but no cached spawn args — cannot respawn`)\n controller.onCrash(packageName, reason)\n return\n }\n const outcome = controller.onCrash(packageName, reason)\n if (outcome.surfaceCrashloopBanner) {\n this.onCrashloop?.(packageName, reason)\n islandNotifications.emit({kind: \"miniapp_crashloop\", packageName, reason, timestamp: Date.now()})\n return\n }\n if (outcome.showRestartToast) {\n this.onRestartToast?.(packageName, reason)\n }\n if (outcome.scheduleRespawnAfterMs == null) return\n // Cancel any prior pending respawn before scheduling a new one.\n const existing = this.respawnTimers.get(packageName)\n if (existing) BgTimer.clearTimeout(existing)\n const timer = BgTimer.setTimeout(() => {\n this.respawnTimers.delete(packageName)\n void (async () => {\n try {\n await this.crust.jsKill?.(packageName)\n } catch {\n /* native may have already torn down */\n }\n const ok = await this.crust.jsSpawn?.(packageName, this.crust.jsLoadPolyfillBundle?.() ?? \"\", cached.miniappJs)\n if (!ok) {\n this.logger.error(`crash respawn failed for ${packageName}`)\n return\n }\n if (cached.permissions.length > 0) {\n await this.crust.jsSetManifest(packageName, cached.permissions)\n }\n this.registerApp(packageName, cached.installedManifest, cached.launchSource)\n controller.onSpawn(packageName)\n // Re-fire the init envelope so the respawned context's\n // `registerMiniapp` handler runs again.\n const sessionId = `${packageName}-${Date.now().toString(36)}`\n void this.crust.jsDispatchToJs(packageName, {kind: \"init\", sessionId})\n this.logger.log(`respawned ${packageName} after crash`)\n })()\n }, outcome.scheduleRespawnAfterMs)\n this.respawnTimers.set(packageName, timer)\n }\n\n private summarizeReason(payload: unknown, method: string): string {\n if (payload && typeof payload === \"object\" && \"message\" in (payload as Record<string, unknown>)) {\n return `${method}: ${(payload as {message: string}).message}`\n }\n return method\n }\n\n /**\n * Tear down a JSContext and unregister from the runtime. Synchronous\n * teardown — the spec drops the 50ms WILL_DISCONNECT grace window\n * because there's no transport handshake to flush in the JSC world.\n */\n async unregister(packageName: string): Promise<void> {\n if (!this.registered.has(packageName)) return\n // Cancel any pending crash-respawn before tearing down — we don't\n // want a stale timer to re-spawn a miniapp the user just disabled.\n const pending = this.respawnTimers.get(packageName)\n if (pending) {\n BgTimer.clearTimeout(pending)\n this.respawnTimers.delete(packageName)\n }\n this.spawnCache.delete(packageName)\n this.crashController?.onKill(packageName)\n // User-initiated close/disable: end any active nav trip so the glasses\n // drop out of native nav mode (crash-respawns don't take this path).\n this.runtime.unregisterApp(packageName, {endNavigation: true})\n this.registered.delete(packageName)\n // JSContext torn down → miniapp is no longer \"running\".\n miniappRunningRegistry.remove(packageName)\n if (this.crust.jsKill) {\n try {\n await this.crust.jsKill(packageName)\n } catch (e) {\n this.logger.warn(`jsKill threw for ${packageName}: ${String(e)}`)\n }\n }\n }\n\n /** List packages the router has registered. */\n registeredPackages(): string[] {\n return Array.from(this.registered)\n }\n\n /**\n * Validate that a reused background JSContext is still responsive when its\n * WebView comes foreground. The runtime owns the ping/timeout mechanics; the\n * router gates this to registered packages and keeps LocalMiniappView from\n * reaching into runtime internals.\n */\n probeForegroundLiveness(packageName: string, reason = \"foreground-open\"): void {\n if (!this.registered.has(packageName)) return\n this.runtime.probeForegroundLiveness(packageName, reason)\n }\n\n // ----------------------------------------------------------------\n // Outbound message handling\n // ----------------------------------------------------------------\n\n private handleOutbound(msg: OutboundMessagePayload): void {\n const {packageName, iface, method} = msg\n if (!packageName || !iface || !method) {\n this.logger.warn(`bad js_message — missing fields`, msg)\n return\n }\n\n // 1) Bridge frames: the SDK's DispatchTransport.send(raw) lands here.\n // Forward raw envelope into LocalMiniappRuntime.handleRawMessage\n // so every existing handler arm runs verbatim.\n if (iface === \"__bridge\" && method === \"send\") {\n const raw = this.coerceArgsToBridgeRaw(msg)\n if (raw == null) {\n this.logger.warn(`__bridge.send had no raw payload`, msg)\n return\n }\n // If the payload is a UI_SEND envelope, route it to the bound\n // WebView instead of LocalMiniappRuntime.\n // session.ui.send → DispatchTransport.send → here.\n if (this.uiRouter) {\n const innerPayload = this.peekBridgePayloadType(raw)\n if (innerPayload?.type === \"UI_SEND\") {\n this.uiRouter.routeFromBackground(packageName, innerPayload)\n return\n }\n }\n this.runtime.handleRawMessage(packageName, raw)\n return\n }\n\n // 2) Log frames — console.* rewired through host. We tag with the\n // packageName so Sentry breadcrumbs can be filtered downstream.\n // Pipeline:\n // raw args → redactSecrets → throttle decision → ring buffer\n // → host logger (which surfaces to dev console / Sentry)\n if (iface === \"__log\") {\n const rawArgs = this.tryParseArgs(msg.argsJson)\n const safeArgs = redactSecrets(rawArgs)\n const decision = this.logThrottle.consume(packageName)\n const tag = `[${packageName}]`\n const fn =\n method === \"warn\"\n ? this.logger.warn\n : method === \"error\" || method === \"fatal\"\n ? this.logger.error\n : this.logger.log\n // Emit a synthetic \"[throttled N]\" line in place of the next\n // would-be-allowed log to summarise drops.\n if (!decision.allowed) {\n if (decision.throttledLine) {\n fn(`${tag} ${decision.throttledLine}`)\n this.logRing.push(packageName, `${decision.throttledLine}`)\n }\n return\n }\n const formatted = `${tag} console.${method}`\n fn(formatted, safeArgs)\n // Stringify into the ring buffer for crash-report attachment.\n let line: string\n try {\n line = `${method}: ${JSON.stringify(safeArgs)}`\n } catch {\n line = `${method}: <unserializable>`\n }\n this.logRing.push(packageName, line)\n // Forward to the `glassly dev` sidecar (if one is connected\n // for this package). Source=\"background\" so the CLI tags lines as\n // [JSRuntime]. The bridge silently drops when no dev server is up,\n // which makes this safe to call unconditionally in prod.\n const argsForBridge = Array.isArray(safeArgs) ? (safeArgs as unknown[]) : [safeArgs]\n devServerBridge.forwardLog(packageName, method, argsForBridge, Date.now(), \"background\")\n return\n }\n\n // 3) Error / unhandled rejection frames — surface as warnings AND\n // drive the crash state machine when one is attached. The\n // controller's outcome may schedule a respawn after a backoff;\n // if it doesn't (CRASHLOOP_DISABLED), we leave the JSContext\n // dead and let the host surface a \"tap to retry\" banner.\n if (iface === \"__error\") {\n const payload = this.tryParseArgs(msg.argsJson)\n this.logger.error(`[${packageName}] ${method}`, payload)\n if (this.crashController) {\n // Only treat \"exception\" + \"unhandledRejection\" + \"uncaught\" as\n // crash signals. `console.error` calls also flow through the\n // log path — those don't end the JSContext.\n const isCrash = method === \"exception\" || method === \"unhandledRejection\" || method === \"uncaught\"\n if (isCrash) {\n this.handleCrash(packageName, this.summarizeReason(payload, method))\n }\n }\n return\n }\n\n // 4) Anything else is a `forwardToRn` from the dispatcher — a\n // handler the native dispatcher didn't know about. We don't have\n // inline handlers for any of these; the runtime's existing path\n // treats them as legacy WebView envelopes by falling through.\n // Log so unknown ifaces surface in dev.\n this.logger.log(`unhandled iface=${iface} method=${method} from ${packageName}`)\n }\n\n /**\n * The wire format for `__bridge.send` is `argsJson = JSON.stringify([raw])`\n * — a single-element array containing the original raw envelope. The\n * dispatcher passes the parsed array through as either:\n * - `msg.args` when the dispatcher unpacked (Android path that turns\n * `argsJson` into a List on the way to RN), or\n * - `msg.argsJson` (iOS path that ships the string verbatim).\n * Cover both shapes here.\n */\n /**\n * Parse a raw bridge envelope just enough to peek at the inner\n * payload's `type` field. Used by the UI_SEND interception path.\n * Returns null if the envelope isn't a valid bridge frame.\n */\n private peekBridgePayloadType(raw: string): {type: string; [k: string]: unknown} | null {\n try {\n const env = JSON.parse(raw) as {payload?: {type?: string}}\n if (env && typeof env.payload === \"object\" && env.payload && typeof env.payload.type === \"string\") {\n return env.payload as {type: string; [k: string]: unknown}\n }\n } catch {\n return null\n }\n return null\n }\n\n private coerceArgsToBridgeRaw(msg: OutboundMessagePayload): string | null {\n if (Array.isArray(msg.args)) {\n const v = msg.args[0]\n return typeof v === \"string\" ? v : null\n }\n if (typeof msg.argsJson === \"string\") {\n try {\n const parsed = JSON.parse(msg.argsJson) as unknown\n if (Array.isArray(parsed) && typeof parsed[0] === \"string\") {\n return parsed[0]\n }\n } catch {\n // fall through\n }\n }\n return null\n }\n\n private tryParseArgs(argsJson: string | undefined): unknown {\n if (!argsJson) return null\n try {\n return JSON.parse(argsJson)\n } catch {\n return argsJson\n }\n }\n\n /**\n * Push a `kind=\"bridge\"` envelope into the named JSContext's\n * `globalThis.__deliver`. Used both by the per-app `sendMessage`\n * registered via {@link registerApp} and by ad-hoc callers (e.g.\n * cloud-relayed stream-status responses route through\n * `LocalMiniappRuntime.handleCloudMessage`, which then calls the\n * `app.sendMessage(serialized)` registered above).\n */\n private dispatchBridgeRaw(packageName: string, raw: string): void {\n void this.crust.jsDispatchToJs(packageName, {kind: \"bridge\", raw})\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"JSRouter.js","sourceRoot":"","sources":["../../src/services/JSRouter.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * @fileoverview JSRouter — RN-side host that bridges the per-miniapp\n * JS contexts (iOS-JSC and Android-QuickJS via Zipline) into the existing\n * {@link LocalMiniappRuntime} handler set.\n *\n * Rather than re-implement the 33 dispatch arms inline, the router\n * consumes Crust's `js_message` Expo event and forwards its\n * `__bridge.send(raw)` payloads to {@link LocalMiniappRuntime.handleRawMessage}.\n * The SDK envelope shape (`{type: \"DISPLAY\", ...}` etc.) is unchanged from\n * the WebView path, so every existing handler runs verbatim. What changes\n * is the *transport*:\n *\n * - **Inbound** (background JS → host): `__dispatch(\"__bridge\", \"send\",\n * [rawJsonString])` → `js_message` event → router →\n * `LocalMiniappRuntime.handleRawMessage(packageName, raw)`.\n * - **Outbound** (host → background JS): every package registered with\n * the router gets a `sendMessage(raw)` fn that calls\n * `Crust.jsDispatchToJs(packageName, {kind: \"bridge\", raw})`.\n * The polyfill's `__deliver` recognises `kind === \"bridge\"` and calls\n * `__deliverBridgeRaw(raw)`, which routes into the SDK's\n * {@link DispatchTransport.onMessage} handler.\n *\n * Host-side handler bodies (display fan-out, mic state, transcription,\n * navigation, etc.) live untouched in `LocalMiniappRuntime.ts`.\n *\n * Cloud-message routing (`phone_stream_status`, `phone_managed_stream_status`)\n * goes straight through `LocalMiniappRuntime.handleCloudMessage` — nothing\n * for the router to do; the responses arrive inside an envelope whose\n * `sendMessage` was already registered via the same path here.\n *\n * The router also bridges native error / log / unhandled-rejection\n * events (`iface: \"__log\"`, `iface: \"__error\"`) into the standard\n * `console.*` + Sentry breadcrumb pipeline so miniapp telemetry is\n * visible without bringing up a separate sink.\n */\n\nimport type {EventSubscription} from \"expo-modules-core\"\n\nimport devServerBridge from \"./DevServerBridge\"\nimport type localMiniappRuntime from \"./LocalMiniappRuntime\"\nimport type {MiniappLaunchSource} from \"@glassly/miniapp\"\n\nimport type {InstalledMiniappManifest} from \"./LocalMiniappRuntime\"\nimport type {JSCrashController} from \"./JSCrashController\"\nimport {JSLogRingBuffer, JSLogThrottle, redactSecrets} from \"./JSLogPipeline\"\nimport {islandNotifications} from \"./NotificationsEmitter\"\nimport type {UIRouter} from \"./UIRouter\"\nimport {miniappRunningRegistry} from \"./MiniappRunningRegistry\"\n\nimport {BgTimer} from \"../utils/timers\"\n\n/** The runtime's runtime instance type — the singleton exported from\n * LocalMiniappRuntime.ts (the file's `export default` is the instance,\n * not the class).\n */\ntype LocalMiniappRuntime = typeof localMiniappRuntime\n\n/**\n * Minimal subset of the Crust native module the router uses. Keeping the\n * binding loose lets us mock the module in unit tests without bringing\n * the whole Expo module surface along.\n */\nexport interface JSCrustBinding {\n jsDispatchToJs(packageName: string, envelope: Record<string, unknown>): Promise<void> | void\n jsSetManifest(packageName: string, permissions: string[]): Promise<void> | void\n jsLoadPolyfillBundle?: () => string\n jsSpawn?: (packageName: string, polyfill: string, miniappJs: string) => Promise<boolean> | boolean\n jsKill?: (packageName: string) => Promise<void> | void\n jsAlivePackages?: () => string[]\n addListener: (event: string, handler: (payload: Record<string, unknown>) => void) => EventSubscription\n}\n\nexport interface OutboundMessagePayload {\n packageName: string\n iface: string\n method: string\n argsJson?: string\n args?: unknown[]\n reqId?: string\n // Implementation-internal: any extra fields the dispatcher attached on\n // .forwardToRn (e.g. payload metadata) are passed through verbatim.\n [extra: string]: unknown\n}\n\nexport type RouterLogger = {\n log: (message: string, payload?: unknown) => void\n warn: (message: string, payload?: unknown) => void\n error: (message: string, payload?: unknown) => void\n}\n\nconst defaultLogger: RouterLogger = {\n log: (m, p) => console.log(`[JSRouter] ${m}`, p ?? \"\"),\n\n warn: (m, p) => console.warn(`[JSRouter] ${m}`, p ?? \"\"),\n\n error: (m, p) => console.error(`[JSRouter] ${m}`, p ?? \"\"),\n}\n\ninterface SpawnCache {\n miniappJs: string\n permissions: string[]\n installedManifest?: InstalledMiniappManifest\n launchSource?: MiniappLaunchSource\n}\n\nexport class JSRouter {\n private subscription: EventSubscription | null = null\n private readonly registered: Set<string> = new Set()\n /** Cached spawn arguments so the crash controller can respawn after a backoff. */\n private readonly spawnCache: Map<string, SpawnCache> = new Map()\n /** Active respawn timers (so unregister() can cancel a pending respawn). */\n private readonly respawnTimers: Map<string, number> = new Map()\n\n /**\n * Optional crash controller. When wired, every `__error` frame from a\n * JSContext drives the state machine; an Outcome with\n * scheduleRespawnAfterMs queues a setTimeout that re-spawns the\n * miniapp's last-known JS source after the backoff delay.\n */\n crashController: JSCrashController | null = null\n\n /** Hook called when a package transitions to CRASHLOOP_DISABLED. */\n onCrashloop: ((packageName: string, reason: string) => void) | null = null\n /** Hook called on the 2nd-within-window crash (toast UX). */\n onRestartToast: ((packageName: string, reason: string) => void) | null = null\n\n /**\n * Logging plumbing. Every `__log` frame passes through `redactSecrets`\n * (token/password/etc. scrubbed), then the throttle (100/min sustained\n * per pkg, 500 burst), then lands in the ring buffer + the host\n * logger. The ring buffer holds the last 200 lines/pkg so a crash\n * report can attach \"last words\" context.\n *\n * Replace with new instances in tests; production code uses the\n * defaults.\n */\n logThrottle: JSLogThrottle = new JSLogThrottle()\n logRing: JSLogRingBuffer = new JSLogRingBuffer()\n\n /**\n * Optional UI router — when wired, `__bridge.send` envelopes whose\n * inner payload type is `UI_SEND` get routed to the bound WebView\n * instead of through LocalMiniappRuntime. Two-layer miniapps set\n * this; legacy single-bundle WebView miniapps don't and the bridge\n * frames pass through unchanged.\n */\n uiRouter: UIRouter | null = null\n\n /** Teardowns in progress, so a stop and a racing start or stop see the same one. */\n private readonly unregistering = new Map<string, Promise<void>>()\n\n constructor(\n private readonly runtime: LocalMiniappRuntime,\n private readonly crust: JSCrustBinding,\n private readonly logger: RouterLogger = defaultLogger,\n ) {}\n\n /**\n * Subscribe to Crust's `js_message` event. Idempotent — calling\n * start() twice attaches a single listener.\n */\n start(): void {\n if (this.subscription) return\n this.subscription = this.crust.addListener(\"js_message\", (raw) => {\n try {\n this.handleOutbound(raw as unknown as OutboundMessagePayload)\n } catch (e) {\n this.logger.error(`outbound handler threw`, {error: String(e), raw})\n }\n })\n // A background script unregistered for missing liveness pings is dead\n // weight: its subscriptions are gone (so the mic releases) while the\n // webview keeps rendering stale state. Route it through the same\n // respawn machinery as a crash so it comes back automatically, with\n // the crash controller's backoff + crash-loop protection.\n this.runtime.onLivenessTimeout = (packageName) => {\n this.handleCrash(packageName, \"liveness: missed pings\")\n }\n }\n\n /**\n * Detach the Crust subscription. The router can be restarted later\n * with start(); registrations survive (the runtime's app map is the\n * source of truth).\n */\n stop(): void {\n this.subscription?.remove()\n this.subscription = null\n this.runtime.onLivenessTimeout = null\n }\n\n /**\n * Register a JSContext with the runtime so its handlers can fire\n * `sendMessage(raw)` against the right context. The router builds a\n * `sendMessage` that calls `Crust.jsDispatchToJs(packageName,\n * {kind: \"bridge\", raw})`; the polyfill's `__deliver` then hands the\n * envelope to `DispatchTransport.onMessage` inside the miniapp.\n *\n * Mirrors `MiniappHost.registerRuntime` on the WebView side. Callers\n * (e.g. {@link spawnAndRegister} below, or the host's miniapp launch\n * pipeline) should call this once per spawn.\n */\n registerApp(\n packageName: string,\n installedManifest?: InstalledMiniappManifest,\n launchSource?: MiniappLaunchSource,\n ): void {\n this.runtime.registerApp(\n packageName,\n (raw: string) => {\n this.dispatchBridgeRaw(packageName, raw)\n },\n installedManifest,\n launchSource,\n )\n this.registered.add(packageName)\n // JSContext is the source-of-truth for \"miniapp running\". The\n // home tile / tray reads this registry to project the `running`\n // flag — UI WebView open/close is separate.\n miniappRunningRegistry.add(packageName)\n }\n\n /**\n * Convenience: spawn a JSContext via Crust, register the app, and\n * set its declared permissions. Returns true on successful spawn.\n *\n * The host's miniapp launch path\n * (`mobile/src/services/miniapps/launchLocalMiniapp.ts`) calls this\n * once per JSContext mount.\n */\n async spawnAndRegister(\n packageName: string,\n miniappJs: string,\n options?: {\n permissions?: string[]\n installedManifest?: InstalledMiniappManifest\n launchSource?: MiniappLaunchSource\n },\n ): Promise<boolean> {\n if (!this.crust.jsSpawn) {\n this.logger.warn(\"jsSpawn not available — host binding missing native function\")\n return false\n }\n const polyfill = this.crust.jsLoadPolyfillBundle?.() ?? \"\"\n if (!polyfill) {\n this.logger.warn(`no polyfill bundle loaded for ${packageName}; spawn will likely fail`)\n }\n const ok = await this.crust.jsSpawn(packageName, polyfill, miniappJs)\n if (!ok) {\n this.logger.error(`spawn failed for ${packageName}`)\n return false\n }\n // Two distinct permission gates:\n // 1. Native dispatcher (JSContext → native bridge): `jsSetManifest`\n // checks per-call iface, e.g. __dispatch(\"mic\", \"start\", ...) requires\n // MICROPHONE.\n // 2. LocalMiniappRuntime (SUBSCRIBE envelope): `registerApp(...,\n // installedManifest)` carries the full manifest so SUBSCRIBE's gate\n // can match stream → permission against declared types.\n if (options?.permissions && options.permissions.length > 0) {\n await this.crust.jsSetManifest(packageName, options.permissions)\n }\n this.registerApp(packageName, options?.installedManifest, options?.launchSource)\n // Cache spawn arguments so the crash controller can respawn the\n // same code after a backoff. permissions + manifest are cached too\n // because the native side resets setManifest on every spawn and\n // LocalMiniappRuntime's installedManifest entry is keyed by\n // connect-time registration.\n this.spawnCache.set(packageName, {\n miniappJs,\n permissions: options?.permissions ?? [],\n installedManifest: options?.installedManifest,\n launchSource: options?.launchSource,\n })\n this.crashController?.onSpawn(packageName)\n\n // Fire the `init` envelope so the polyfill's __deliver handler\n // resolves `__initCallback(sessionId)`. The SDK's\n // `registerMiniapp(handler)` wires that callback to construct\n // MiniappSession and call the user's handler. Without this\n // dispatch the user's code never runs — `registerMiniapp` just\n // assigns to a global and waits.\n const sessionId = `${packageName}-${Date.now().toString(36)}`\n void this.crust.jsDispatchToJs(packageName, {kind: \"init\", sessionId})\n\n return true\n }\n\n /**\n * Crash-controller integration. Called from the `__error` frame\n * handler. The controller returns an outcome that tells us whether\n * to respawn (with delay) or leave the context dead.\n */\n private handleCrash(packageName: string, reason: string): void {\n // The native context is dead the instant a crash is observed — invalidate\n // its CONNECT handshake NOW so waitForConnect() blocks through the respawn\n // backoff window instead of resolving immediately against the dead context\n // (an action invoked mid-backoff would otherwise be delivered to nothing).\n this.runtime.resetHandshake(packageName)\n const controller = this.crashController\n if (!controller) return\n const cached = this.spawnCache.get(packageName)\n if (!cached) {\n this.logger.warn(`crash for ${packageName} but no cached spawn args — cannot respawn`)\n controller.onCrash(packageName, reason)\n return\n }\n const outcome = controller.onCrash(packageName, reason)\n if (outcome.surfaceCrashloopBanner) {\n this.onCrashloop?.(packageName, reason)\n islandNotifications.emit({kind: \"miniapp_crashloop\", packageName, reason, timestamp: Date.now()})\n return\n }\n if (outcome.showRestartToast) {\n this.onRestartToast?.(packageName, reason)\n }\n if (outcome.scheduleRespawnAfterMs == null) return\n // Cancel any prior pending respawn before scheduling a new one.\n const existing = this.respawnTimers.get(packageName)\n if (existing) BgTimer.clearTimeout(existing)\n const timer = BgTimer.setTimeout(() => {\n this.respawnTimers.delete(packageName)\n void (async () => {\n try {\n await this.crust.jsKill?.(packageName)\n } catch {\n /* native may have already torn down */\n }\n const ok = await this.crust.jsSpawn?.(packageName, this.crust.jsLoadPolyfillBundle?.() ?? \"\", cached.miniappJs)\n if (!ok) {\n this.logger.error(`crash respawn failed for ${packageName}`)\n return\n }\n if (cached.permissions.length > 0) {\n await this.crust.jsSetManifest(packageName, cached.permissions)\n }\n this.registerApp(packageName, cached.installedManifest, cached.launchSource)\n controller.onSpawn(packageName)\n // Re-fire the init envelope so the respawned context's\n // `registerMiniapp` handler runs again.\n const sessionId = `${packageName}-${Date.now().toString(36)}`\n void this.crust.jsDispatchToJs(packageName, {kind: \"init\", sessionId})\n this.logger.log(`respawned ${packageName} after crash`)\n })()\n }, outcome.scheduleRespawnAfterMs)\n this.respawnTimers.set(packageName, timer)\n }\n\n private summarizeReason(payload: unknown, method: string): string {\n if (payload && typeof payload === \"object\" && \"message\" in (payload as Record<string, unknown>)) {\n return `${method}: ${(payload as {message: string}).message}`\n }\n return method\n }\n\n /**\n * Tear down a JSContext and unregister from the runtime. The session's\n * `onBeforeDisconnect` handlers get a short grace window first, so a\n * miniapp can clear what it drew and end its own work while its messages\n * still reach the host. Concurrent calls share one teardown.\n */\n unregister(packageName: string): Promise<void> {\n if (!this.registered.has(packageName)) return Promise.resolve()\n const inFlight = this.unregistering.get(packageName)\n if (inFlight) return inFlight\n const teardown = this.teardown(packageName).finally(() => this.unregistering.delete(packageName))\n this.unregistering.set(packageName, teardown)\n return teardown\n }\n\n /** Resolves once an in-flight {@link unregister} of this package has finished. */\n async whenUnregistered(packageName: string): Promise<void> {\n await this.unregistering.get(packageName)\n }\n\n private async teardown(packageName: string): Promise<void> {\n // Cancel any pending crash-respawn before tearing down — we don't\n // want a stale timer to re-spawn a miniapp the user just disabled.\n const pending = this.respawnTimers.get(packageName)\n if (pending) {\n BgTimer.clearTimeout(pending)\n this.respawnTimers.delete(packageName)\n }\n await this.runtime.notifyWillDisconnect(packageName, \"stopped\")\n this.spawnCache.delete(packageName)\n this.crashController?.onKill(packageName)\n // User-initiated close/disable: end any active nav trip so the glasses\n // drop out of native nav mode (crash-respawns don't take this path).\n this.runtime.unregisterApp(packageName, {endNavigation: true})\n this.registered.delete(packageName)\n // JSContext torn down → miniapp is no longer \"running\".\n miniappRunningRegistry.remove(packageName)\n if (this.crust.jsKill) {\n try {\n await this.crust.jsKill(packageName)\n } catch (e) {\n this.logger.warn(`jsKill threw for ${packageName}: ${String(e)}`)\n }\n }\n }\n\n /** List packages the router has registered. */\n /** The user opened a running miniapp again; the source rides the next respawn too. */\n notifyLaunch(packageName: string, launchSource: MiniappLaunchSource): void {\n if (!this.registered.has(packageName)) return\n const cached = this.spawnCache.get(packageName)\n if (cached) cached.launchSource = launchSource\n this.runtime.sendLaunchChange(packageName, launchSource)\n }\n\n registeredPackages(): string[] {\n return Array.from(this.registered)\n }\n\n /**\n * Validate that a reused background JSContext is still responsive when its\n * WebView comes foreground. The runtime owns the ping/timeout mechanics; the\n * router gates this to registered packages and keeps LocalMiniappView from\n * reaching into runtime internals.\n */\n probeForegroundLiveness(packageName: string, reason = \"foreground-open\"): void {\n if (!this.registered.has(packageName)) return\n this.runtime.probeForegroundLiveness(packageName, reason)\n }\n\n // ----------------------------------------------------------------\n // Outbound message handling\n // ----------------------------------------------------------------\n\n private handleOutbound(msg: OutboundMessagePayload): void {\n const {packageName, iface, method} = msg\n if (!packageName || !iface || !method) {\n this.logger.warn(`bad js_message — missing fields`, msg)\n return\n }\n\n // 1) Bridge frames: the SDK's DispatchTransport.send(raw) lands here.\n // Forward raw envelope into LocalMiniappRuntime.handleRawMessage\n // so every existing handler arm runs verbatim.\n if (iface === \"__bridge\" && method === \"send\") {\n const raw = this.coerceArgsToBridgeRaw(msg)\n if (raw == null) {\n this.logger.warn(`__bridge.send had no raw payload`, msg)\n return\n }\n // If the payload is a UI_SEND envelope, route it to the bound\n // WebView instead of LocalMiniappRuntime.\n // session.ui.send → DispatchTransport.send → here.\n if (this.uiRouter) {\n const innerPayload = this.peekBridgePayloadType(raw)\n if (innerPayload?.type === \"UI_SEND\") {\n this.uiRouter.routeFromBackground(packageName, innerPayload)\n return\n }\n }\n this.runtime.handleRawMessage(packageName, raw)\n return\n }\n\n // 2) Log frames — console.* rewired through host. We tag with the\n // packageName so Sentry breadcrumbs can be filtered downstream.\n // Pipeline:\n // raw args → redactSecrets → throttle decision → ring buffer\n // → host logger (which surfaces to dev console / Sentry)\n if (iface === \"__log\") {\n const rawArgs = this.tryParseArgs(msg.argsJson)\n const safeArgs = redactSecrets(rawArgs)\n const decision = this.logThrottle.consume(packageName)\n const tag = `[${packageName}]`\n const fn =\n method === \"warn\"\n ? this.logger.warn\n : method === \"error\" || method === \"fatal\"\n ? this.logger.error\n : this.logger.log\n // Emit a synthetic \"[throttled N]\" line in place of the next\n // would-be-allowed log to summarise drops.\n if (!decision.allowed) {\n if (decision.throttledLine) {\n fn(`${tag} ${decision.throttledLine}`)\n this.logRing.push(packageName, `${decision.throttledLine}`)\n }\n return\n }\n const formatted = `${tag} console.${method}`\n fn(formatted, safeArgs)\n // Stringify into the ring buffer for crash-report attachment.\n let line: string\n try {\n line = `${method}: ${JSON.stringify(safeArgs)}`\n } catch {\n line = `${method}: <unserializable>`\n }\n this.logRing.push(packageName, line)\n // Forward to the `glassly dev` sidecar (if one is connected\n // for this package). Source=\"background\" so the CLI tags lines as\n // [JSRuntime]. The bridge silently drops when no dev server is up,\n // which makes this safe to call unconditionally in prod.\n const argsForBridge = Array.isArray(safeArgs) ? (safeArgs as unknown[]) : [safeArgs]\n devServerBridge.forwardLog(packageName, method, argsForBridge, Date.now(), \"background\")\n return\n }\n\n // 3) Error / unhandled rejection frames — surface as warnings AND\n // drive the crash state machine when one is attached. The\n // controller's outcome may schedule a respawn after a backoff;\n // if it doesn't (CRASHLOOP_DISABLED), we leave the JSContext\n // dead and let the host surface a \"tap to retry\" banner.\n if (iface === \"__error\") {\n const payload = this.tryParseArgs(msg.argsJson)\n this.logger.error(`[${packageName}] ${method}`, payload)\n // Crashes reach the `glassly dev` terminal too, not only console calls.\n const summary = this.summarizeReason(payload, method)\n const stack = (payload as {stack?: unknown} | null)?.stack\n const errorArgs = typeof stack === \"string\" && stack ? [summary, stack] : [summary]\n devServerBridge.forwardLog(packageName, \"error\", errorArgs, Date.now(), \"background\")\n if (this.crashController) {\n // Only treat \"exception\" + \"unhandledRejection\" + \"uncaught\" as\n // crash signals. `console.error` calls also flow through the\n // log path — those don't end the JSContext.\n const isCrash = method === \"exception\" || method === \"unhandledRejection\" || method === \"uncaught\"\n if (isCrash) {\n this.handleCrash(packageName, summary)\n }\n }\n return\n }\n\n // 4) Anything else is a `forwardToRn` from the dispatcher — a\n // handler the native dispatcher didn't know about. We don't have\n // inline handlers for any of these; the runtime's existing path\n // treats them as legacy WebView envelopes by falling through.\n // Log so unknown ifaces surface in dev.\n this.logger.log(`unhandled iface=${iface} method=${method} from ${packageName}`)\n }\n\n /**\n * The wire format for `__bridge.send` is `argsJson = JSON.stringify([raw])`\n * — a single-element array containing the original raw envelope. The\n * dispatcher passes the parsed array through as either:\n * - `msg.args` when the dispatcher unpacked (Android path that turns\n * `argsJson` into a List on the way to RN), or\n * - `msg.argsJson` (iOS path that ships the string verbatim).\n * Cover both shapes here.\n */\n /**\n * Parse a raw bridge envelope just enough to peek at the inner\n * payload's `type` field. Used by the UI_SEND interception path.\n * Returns null if the envelope isn't a valid bridge frame.\n */\n private peekBridgePayloadType(raw: string): {type: string; [k: string]: unknown} | null {\n try {\n const env = JSON.parse(raw) as {payload?: {type?: string}}\n if (env && typeof env.payload === \"object\" && env.payload && typeof env.payload.type === \"string\") {\n return env.payload as {type: string; [k: string]: unknown}\n }\n } catch {\n return null\n }\n return null\n }\n\n private coerceArgsToBridgeRaw(msg: OutboundMessagePayload): string | null {\n if (Array.isArray(msg.args)) {\n const v = msg.args[0]\n return typeof v === \"string\" ? v : null\n }\n if (typeof msg.argsJson === \"string\") {\n try {\n const parsed = JSON.parse(msg.argsJson) as unknown\n if (Array.isArray(parsed) && typeof parsed[0] === \"string\") {\n return parsed[0]\n }\n } catch {\n // fall through\n }\n }\n return null\n }\n\n private tryParseArgs(argsJson: string | undefined): unknown {\n if (!argsJson) return null\n try {\n return JSON.parse(argsJson)\n } catch {\n return argsJson\n }\n }\n\n /**\n * Push a `kind=\"bridge\"` envelope into the named JSContext's\n * `globalThis.__deliver`. Used both by the per-app `sendMessage`\n * registered via {@link registerApp} and by ad-hoc callers (e.g.\n * cloud-relayed stream-status responses route through\n * `LocalMiniappRuntime.handleCloudMessage`, which then calls the\n * `app.sendMessage(serialized)` registered above).\n */\n private dispatchBridgeRaw(packageName: string, raw: string): void {\n void this.crust.jsDispatchToJs(packageName, {kind: \"bridge\", raw})\n }\n}\n"]}
|
|
@@ -208,6 +208,13 @@ declare class LocalMiniappRuntime {
|
|
|
208
208
|
* undeliverable anyway.
|
|
209
209
|
*/
|
|
210
210
|
gracefullyUnregisterApp(packageName: string, reason?: string): Promise<void>;
|
|
211
|
+
/**
|
|
212
|
+
* Send `WILL_DISCONNECT` and wait out the grace window, so the session's
|
|
213
|
+
* `beforeDisconnect` handlers run (Navigation clears its HUD and ends its
|
|
214
|
+
* trip) and their last messages land before teardown. No-op unless the
|
|
215
|
+
* app finished its handshake.
|
|
216
|
+
*/
|
|
217
|
+
notifyWillDisconnect(packageName: string, reason: string): Promise<void>;
|
|
211
218
|
unregisterApp(packageName: string, opts?: {
|
|
212
219
|
endNavigation?: boolean;
|
|
213
220
|
}): void;
|
|
@@ -797,6 +804,12 @@ declare class LocalMiniappRuntime {
|
|
|
797
804
|
* still spawning gets them once its handshake completes.
|
|
798
805
|
*/
|
|
799
806
|
deliverLink(packageName: string, params: Record<string, string>): void;
|
|
807
|
+
/**
|
|
808
|
+
* Tell a running miniapp the user opened it again and from where. The
|
|
809
|
+
* CONNECT_ACK only carries the source of the spawn, which is stale for a
|
|
810
|
+
* background app that keeps running between opens.
|
|
811
|
+
*/
|
|
812
|
+
sendLaunchChange(packageName: string, launchSource: MiniappLaunchSource): void;
|
|
800
813
|
/**
|
|
801
814
|
* Send a VISIBILITY_CHANGE push to a miniapp.
|
|
802
815
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"LocalMiniappRuntime.d.ts","sourceRoot":"","sources":["../../src/services/LocalMiniappRuntime.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAsBH,OAAO,KAAK,EAAkB,mBAAmB,EAAqB,MAAM,kBAAkB,CAAA;AA+I9F,OAAO,EAA+B,KAAK,gCAAgC,EAAC,MAAM,6BAA6B,CAAA;AAqB/G,MAAM,WAAW,wBAAwB;IACvC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB;4EACwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,EAAE,CAAC,EAAE,MAAM,CAAA;KAAC,CAAA;IAC1C,WAAW,CAAC,EAAE,KAAK,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAC,CAAC,CAAA;IAC7E,oBAAoB,CAAC,EAAE,KAAK,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAC,CAAC,CAAA;IACjF,OAAO,CAAC,EAAE,KAAK,CAAC;QAAC,EAAE,CAAC,EAAE,OAAO,CAAC;QAAC,WAAW,CAAC,EAAE,OAAO,CAAC;QAAC,UAAU,CAAC,EAAE,OAAO,CAAC;QAAC,YAAY,CAAC,EAAE,OAAO,CAAA;KAAC,CAAC,CAAA;IACpG,sEAAsE;IACtE,OAAO,CAAC,EAAE,OAAO,CAAA;CAClB;AAoDD,KAAK,wBAAwB,GAAG,OAAO,GAAG,OAAO,CAAA;
|
|
1
|
+
{"version":3,"file":"LocalMiniappRuntime.d.ts","sourceRoot":"","sources":["../../src/services/LocalMiniappRuntime.ts"],"names":[],"mappings":"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"}
|