@lotics/app-sdk 0.100.1 → 0.101.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/AGENTS.md +32 -47
  2. package/dist/agent_stream.d.ts +131 -0
  3. package/dist/ask_ai.d.ts +27 -0
  4. package/dist/attachments.d.ts +58 -0
  5. package/dist/chunk-ARV5FAU5.js +1132 -0
  6. package/dist/comments.d.ts +89 -0
  7. package/dist/error_report.d.ts +9 -0
  8. package/dist/folder_pick.d.ts +8 -0
  9. package/dist/geolocation.d.ts +42 -0
  10. package/dist/hooks.d.ts +251 -0
  11. package/dist/{src/index.d.ts → index.d.ts} +13 -22
  12. package/dist/index.js +31331 -0
  13. package/dist/index.js.LEGAL.txt +11 -0
  14. package/dist/members.d.ts +32 -0
  15. package/dist/mock.d.ts +37 -0
  16. package/dist/mount.d.ts +19 -0
  17. package/dist/new_record.d.ts +37 -0
  18. package/dist/open_app.d.ts +12 -0
  19. package/dist/open_external.d.ts +10 -0
  20. package/dist/overlay.d.ts +25 -0
  21. package/dist/queries.d.ts +231 -0
  22. package/dist/recording.d.ts +47 -0
  23. package/dist/recording_state.d.ts +43 -0
  24. package/dist/rename_file.d.ts +13 -0
  25. package/dist/router.d.ts +10 -0
  26. package/dist/router.js +97 -0
  27. package/dist/row.d.ts +87 -0
  28. package/dist/rpc.d.ts +114 -0
  29. package/dist/select.d.ts +24 -0
  30. package/dist/shared_types.d.ts +8 -0
  31. package/dist/store.d.ts +43 -0
  32. package/dist/types.d.ts +36 -0
  33. package/dist/upload/optimize.d.ts +30 -0
  34. package/dist/upload/pipeline.d.ts +36 -0
  35. package/dist/upload/transport.d.ts +19 -0
  36. package/dist/url_params.d.ts +55 -0
  37. package/dist/use_recents.d.ts +15 -0
  38. package/dist/{src/use_url_state.d.ts → use_url_state.d.ts} +0 -2
  39. package/dist/viewer.d.ts +41 -0
  40. package/dist/written.d.ts +79 -0
  41. package/docs/ai.md +74 -133
  42. package/docs/data_fetching.md +209 -290
  43. package/docs/files.md +61 -51
  44. package/docs/members_and_options.md +92 -62
  45. package/docs/mutations.md +136 -205
  46. package/docs/navigation_and_state.md +26 -35
  47. package/docs/queries.md +144 -207
  48. package/docs/recipes.md +21 -45
  49. package/docs/runtime.md +74 -137
  50. package/docs/security.md +8 -11
  51. package/docs/workflows.md +189 -174
  52. package/package.json +27 -28
  53. package/dist/src/agent_stream.d.ts +0 -200
  54. package/dist/src/agent_stream.js +0 -314
  55. package/dist/src/ask_ai.d.ts +0 -40
  56. package/dist/src/ask_ai.js +0 -35
  57. package/dist/src/attachments.d.ts +0 -68
  58. package/dist/src/attachments.js +0 -93
  59. package/dist/src/comments.d.ts +0 -127
  60. package/dist/src/comments.js +0 -192
  61. package/dist/src/download.js +0 -54
  62. package/dist/src/geolocation.d.ts +0 -64
  63. package/dist/src/geolocation.js +0 -96
  64. package/dist/src/hooks.d.ts +0 -781
  65. package/dist/src/hooks.js +0 -860
  66. package/dist/src/index.js +0 -34
  67. package/dist/src/members.d.ts +0 -105
  68. package/dist/src/members.js +0 -62
  69. package/dist/src/mock.d.ts +0 -118
  70. package/dist/src/mock.js +0 -124
  71. package/dist/src/mount.d.ts +0 -47
  72. package/dist/src/mount.js +0 -34
  73. package/dist/src/new_record.d.ts +0 -74
  74. package/dist/src/new_record.js +0 -117
  75. package/dist/src/open_app.d.ts +0 -15
  76. package/dist/src/open_app.js +0 -18
  77. package/dist/src/open_external.d.ts +0 -16
  78. package/dist/src/open_external.js +0 -19
  79. package/dist/src/recording.d.ts +0 -59
  80. package/dist/src/recording.js +0 -30
  81. package/dist/src/recording_state.d.ts +0 -59
  82. package/dist/src/recording_state.js +0 -94
  83. package/dist/src/router.d.ts +0 -17
  84. package/dist/src/router.js +0 -144
  85. package/dist/src/row.d.ts +0 -159
  86. package/dist/src/row.js +0 -254
  87. package/dist/src/rpc.d.ts +0 -207
  88. package/dist/src/rpc.js +0 -904
  89. package/dist/src/select.d.ts +0 -48
  90. package/dist/src/select.js +0 -40
  91. package/dist/src/types.d.ts +0 -115
  92. package/dist/src/types.js +0 -1
  93. package/dist/src/upload/optimize.d.ts +0 -54
  94. package/dist/src/upload/optimize.js +0 -207
  95. package/dist/src/upload/pipeline.d.ts +0 -55
  96. package/dist/src/upload/pipeline.js +0 -52
  97. package/dist/src/upload/transport.d.ts +0 -42
  98. package/dist/src/upload/transport.js +0 -128
  99. package/dist/src/url_params.d.ts +0 -93
  100. package/dist/src/url_params.js +0 -215
  101. package/dist/src/use_optimistic.d.ts +0 -27
  102. package/dist/src/use_optimistic.js +0 -27
  103. package/dist/src/use_recents.d.ts +0 -19
  104. package/dist/src/use_recents.js +0 -71
  105. package/dist/src/use_url_state.js +0 -73
  106. package/dist/src/viewer.d.ts +0 -26
  107. package/dist/src/viewer.js +0 -47
  108. /package/dist/{src/download.d.ts → download.d.ts} +0 -0
@@ -1,96 +0,0 @@
1
- /**
2
- * Device location for geofenced app actions.
3
- *
4
- * The host grants the app iframe the `geolocation` Permissions-Policy, so app
5
- * code reads the device position directly through the browser — no RPC bridge.
6
- * This module wraps that with permission handling, a timeout, and a geofence
7
- * check, and returns a STRUCTURED outcome (`denied` / `unavailable` / `outside`)
8
- * so the app renders its own guidance. A terse, untranslated "permission denied"
9
- * dead-end is the single biggest reason a geofenced check-in fails in the field,
10
- * so the messaging belongs to the app, not buried in here.
11
- *
12
- * Self-contained on purpose: `@lotics/app-sdk` is published to npm with a minimal
13
- * dependency set and cannot pull in the private `@lotics/shared`, so the haversine
14
- * lives here rather than being imported.
15
- */
16
- const EARTH_RADIUS_M = 6_371_000;
17
- function toRadians(degrees) {
18
- return (degrees * Math.PI) / 180;
19
- }
20
- /** Great-circle distance between two coordinates, in meters (haversine). */
21
- function distanceMeters(lat1, lon1, lat2, lon2) {
22
- const dLat = toRadians(lat2 - lat1);
23
- const dLon = toRadians(lon2 - lon1);
24
- const a = Math.sin(dLat / 2) * Math.sin(dLat / 2) +
25
- Math.cos(toRadians(lat1)) * Math.cos(toRadians(lat2)) * Math.sin(dLon / 2) * Math.sin(dLon / 2);
26
- return EARTH_RADIUS_M * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
27
- }
28
- /** True when `[latitude, longitude]` falls within `zone`'s radius of its center. */
29
- export function isWithinZone(latitude, longitude, zone) {
30
- const [centerLat, centerLon] = zone.coordinates;
31
- return distanceMeters(latitude, longitude, centerLat, centerLon) <= zone.radius;
32
- }
33
- async function readPermissionState() {
34
- // The Permissions API is unavailable on some browsers (notably older Safari);
35
- // fall back to `null` and let `getCurrentPosition` surface the real state.
36
- if (typeof navigator === "undefined" || !navigator.permissions?.query)
37
- return null;
38
- try {
39
- const status = await navigator.permissions.query({ name: "geolocation" });
40
- return status.state;
41
- }
42
- catch {
43
- return null;
44
- }
45
- }
46
- function getPosition(timeoutMs) {
47
- return new Promise((resolve, reject) => {
48
- navigator.geolocation.getCurrentPosition(resolve, reject, {
49
- enableHighAccuracy: false,
50
- timeout: timeoutMs,
51
- maximumAge: 0,
52
- });
53
- });
54
- }
55
- /**
56
- * Get the device position and check it against the allowed zones.
57
- *
58
- * Returns `{ ok: true, coords }` when a fix lands inside any zone — the app can
59
- * forward `coords` to a workflow to record where the action happened. Otherwise
60
- * `{ ok: false, reason }`; render guidance per `reason`. An empty `zones` array
61
- * means "no geofence" and resolves `ok` with the raw position (use it for a
62
- * plain location read).
63
- *
64
- * ```tsx
65
- * const r = await requestGeofencedLocation(DEPOTS);
66
- * if (!r.ok) return showGeofenceError(r.reason);
67
- * await chamCong();
68
- * ```
69
- */
70
- export async function requestGeofencedLocation(zones, opts) {
71
- const timeoutMs = opts?.timeoutMs ?? 15_000;
72
- if (typeof navigator === "undefined" || !navigator.geolocation) {
73
- return { ok: false, reason: "unavailable" };
74
- }
75
- // Fast-path a hard denial: once blocked, the browser will not re-prompt, so
76
- // calling getCurrentPosition would just hang until the timeout.
77
- if ((await readPermissionState()) === "denied") {
78
- return { ok: false, reason: "denied" };
79
- }
80
- let position;
81
- try {
82
- position = await getPosition(timeoutMs);
83
- }
84
- catch (err) {
85
- const code = err?.code;
86
- // 1 = PERMISSION_DENIED; 2 = POSITION_UNAVAILABLE; 3 = TIMEOUT.
87
- return { ok: false, reason: code === 1 ? "denied" : "unavailable" };
88
- }
89
- const coords = {
90
- latitude: position.coords.latitude,
91
- longitude: position.coords.longitude,
92
- accuracy: position.coords.accuracy,
93
- };
94
- const inside = zones.length === 0 || zones.some((z) => isWithinZone(coords.latitude, coords.longitude, z));
95
- return inside ? { ok: true, coords } : { ok: false, reason: "outside" };
96
- }