@mongrov/analytics 0.5.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (224) hide show
  1. package/README.md +23 -10
  2. package/UPGRADING.md +370 -0
  3. package/dist/core/device-events.d.ts +14 -0
  4. package/dist/core/device-events.d.ts.map +1 -0
  5. package/dist/core/device-events.js +13 -0
  6. package/dist/core/device-events.js.map +1 -0
  7. package/dist/core/errors.d.ts +1 -1
  8. package/dist/core/errors.d.ts.map +1 -1
  9. package/dist/core/errors.js.map +1 -1
  10. package/dist/core/extensions.d.ts +21 -4
  11. package/dist/core/extensions.d.ts.map +1 -1
  12. package/dist/core/extensions.js +21 -4
  13. package/dist/core/extensions.js.map +1 -1
  14. package/dist/core/factory.d.ts.map +1 -1
  15. package/dist/core/factory.js +124 -18
  16. package/dist/core/factory.js.map +1 -1
  17. package/dist/core/hooks.js +1 -1
  18. package/dist/core/hooks.js.map +1 -1
  19. package/dist/core/index.d.ts +11 -1
  20. package/dist/core/index.d.ts.map +1 -1
  21. package/dist/core/index.js +14 -0
  22. package/dist/core/index.js.map +1 -1
  23. package/dist/core/insight.d.ts +44 -0
  24. package/dist/core/insight.d.ts.map +1 -0
  25. package/dist/core/insight.js +62 -0
  26. package/dist/core/insight.js.map +1 -0
  27. package/dist/core/machine.d.ts.map +1 -1
  28. package/dist/core/machine.js +9 -1
  29. package/dist/core/machine.js.map +1 -1
  30. package/dist/core/metric_metadata.d.ts +57 -2
  31. package/dist/core/metric_metadata.d.ts.map +1 -1
  32. package/dist/core/metric_metadata.js +36 -8
  33. package/dist/core/metric_metadata.js.map +1 -1
  34. package/dist/core/migrations.d.ts +6 -0
  35. package/dist/core/migrations.d.ts.map +1 -1
  36. package/dist/core/migrations.js +92 -4
  37. package/dist/core/migrations.js.map +1 -1
  38. package/dist/core/retention.d.ts +44 -13
  39. package/dist/core/retention.d.ts.map +1 -1
  40. package/dist/core/retention.js +50 -22
  41. package/dist/core/retention.js.map +1 -1
  42. package/dist/core/schemas.d.ts +74 -3
  43. package/dist/core/schemas.d.ts.map +1 -1
  44. package/dist/core/schemas.js +168 -5
  45. package/dist/core/schemas.js.map +1 -1
  46. package/dist/core/table_metadata.d.ts.map +1 -1
  47. package/dist/core/table_metadata.js +4 -0
  48. package/dist/core/table_metadata.js.map +1 -1
  49. package/dist/core/types.d.ts +45 -10
  50. package/dist/core/types.d.ts.map +1 -1
  51. package/dist/core/warehouse.d.ts +28 -0
  52. package/dist/core/warehouse.d.ts.map +1 -1
  53. package/dist/core/warehouse.js +44 -0
  54. package/dist/core/warehouse.js.map +1 -1
  55. package/dist/core/watermark-cache.d.ts +75 -0
  56. package/dist/core/watermark-cache.d.ts.map +1 -0
  57. package/dist/core/watermark-cache.js +0 -0
  58. package/dist/core/watermark-cache.js.map +1 -0
  59. package/dist/rules/__fakes__/fakeEngine.d.ts +2 -0
  60. package/dist/rules/__fakes__/fakeEngine.d.ts.map +1 -1
  61. package/dist/rules/__fakes__/fakeEngine.js +4 -0
  62. package/dist/rules/__fakes__/fakeEngine.js.map +1 -1
  63. package/dist/rules/baseline-reader.d.ts +55 -0
  64. package/dist/rules/baseline-reader.d.ts.map +1 -0
  65. package/dist/rules/baseline-reader.js +111 -0
  66. package/dist/rules/baseline-reader.js.map +1 -0
  67. package/dist/rules/compiler.d.ts +36 -1
  68. package/dist/rules/compiler.d.ts.map +1 -1
  69. package/dist/rules/compiler.js +185 -39
  70. package/dist/rules/compiler.js.map +1 -1
  71. package/dist/rules/defaults/luminx.d.ts.map +1 -1
  72. package/dist/rules/defaults/luminx.js +8 -0
  73. package/dist/rules/defaults/luminx.js.map +1 -1
  74. package/dist/rules/defaults/viva.d.ts.map +1 -1
  75. package/dist/rules/defaults/viva.js +7 -0
  76. package/dist/rules/defaults/viva.js.map +1 -1
  77. package/dist/rules/defaults/yogaring.d.ts.map +1 -1
  78. package/dist/rules/defaults/yogaring.js +7 -0
  79. package/dist/rules/defaults/yogaring.js.map +1 -1
  80. package/dist/rules/defaults/ziva.d.ts.map +1 -1
  81. package/dist/rules/defaults/ziva.js +100 -24
  82. package/dist/rules/defaults/ziva.js.map +1 -1
  83. package/dist/rules/evaluator.d.ts +14 -3
  84. package/dist/rules/evaluator.d.ts.map +1 -1
  85. package/dist/rules/evaluator.js +157 -5
  86. package/dist/rules/evaluator.js.map +1 -1
  87. package/dist/rules/factory.d.ts.map +1 -1
  88. package/dist/rules/factory.js +5 -1
  89. package/dist/rules/factory.js.map +1 -1
  90. package/dist/rules/index.d.ts +2 -1
  91. package/dist/rules/index.d.ts.map +1 -1
  92. package/dist/rules/index.js +2 -1
  93. package/dist/rules/index.js.map +1 -1
  94. package/dist/rules/schema.d.ts +78 -7
  95. package/dist/rules/schema.d.ts.map +1 -1
  96. package/dist/rules/schema.js +44 -0
  97. package/dist/rules/schema.js.map +1 -1
  98. package/dist/rules/types.d.ts +16 -1
  99. package/dist/rules/types.d.ts.map +1 -1
  100. package/dist/rules/validator.d.ts.map +1 -1
  101. package/dist/rules/validator.js +56 -0
  102. package/dist/rules/validator.js.map +1 -1
  103. package/dist/sync/baseline-compute.d.ts +63 -0
  104. package/dist/sync/baseline-compute.d.ts.map +1 -0
  105. package/dist/sync/baseline-compute.js +211 -0
  106. package/dist/sync/baseline-compute.js.map +1 -0
  107. package/dist/sync/events.d.ts +19 -5
  108. package/dist/sync/events.d.ts.map +1 -1
  109. package/dist/sync/events.js +17 -0
  110. package/dist/sync/events.js.map +1 -1
  111. package/dist/sync/factory.d.ts +25 -4
  112. package/dist/sync/factory.d.ts.map +1 -1
  113. package/dist/sync/factory.js +109 -15
  114. package/dist/sync/factory.js.map +1 -1
  115. package/dist/sync/fetcher.d.ts +15 -2
  116. package/dist/sync/fetcher.d.ts.map +1 -1
  117. package/dist/sync/fetcher.js +59 -11
  118. package/dist/sync/fetcher.js.map +1 -1
  119. package/dist/sync/flusher.d.ts +52 -2
  120. package/dist/sync/flusher.d.ts.map +1 -1
  121. package/dist/sync/flusher.js +78 -9
  122. package/dist/sync/flusher.js.map +1 -1
  123. package/dist/sync/index.d.ts +4 -2
  124. package/dist/sync/index.d.ts.map +1 -1
  125. package/dist/sync/index.js +1 -0
  126. package/dist/sync/index.js.map +1 -1
  127. package/dist/sync/mapper/activity.d.ts.map +1 -1
  128. package/dist/sync/mapper/activity.js +2 -1
  129. package/dist/sync/mapper/activity.js.map +1 -1
  130. package/dist/sync/mapper/battery.d.ts +14 -7
  131. package/dist/sync/mapper/battery.d.ts.map +1 -1
  132. package/dist/sync/mapper/battery.js +13 -7
  133. package/dist/sync/mapper/battery.js.map +1 -1
  134. package/dist/sync/mapper/firmware.d.ts.map +1 -1
  135. package/dist/sync/mapper/firmware.js +4 -1
  136. package/dist/sync/mapper/firmware.js.map +1 -1
  137. package/dist/sync/mapper/ring-config.js +1 -1
  138. package/dist/sync/mapper/ring-config.js.map +1 -1
  139. package/dist/sync/mapper/schema.d.ts +411 -0
  140. package/dist/sync/mapper/schema.d.ts.map +1 -0
  141. package/dist/sync/mapper/schema.js +128 -0
  142. package/dist/sync/mapper/schema.js.map +1 -0
  143. package/dist/sync/mapper/sleep.d.ts +58 -13
  144. package/dist/sync/mapper/sleep.d.ts.map +1 -1
  145. package/dist/sync/mapper/sleep.js +141 -44
  146. package/dist/sync/mapper/sleep.js.map +1 -1
  147. package/dist/sync/mapper/types.d.ts +75 -10
  148. package/dist/sync/mapper/types.d.ts.map +1 -1
  149. package/dist/sync/scheduler.d.ts +7 -0
  150. package/dist/sync/scheduler.d.ts.map +1 -1
  151. package/dist/sync/scheduler.js +14 -0
  152. package/dist/sync/scheduler.js.map +1 -1
  153. package/dist/tools/__fakes__/engine.d.ts +2 -0
  154. package/dist/tools/__fakes__/engine.d.ts.map +1 -1
  155. package/dist/tools/__fakes__/engine.js +10 -0
  156. package/dist/tools/__fakes__/engine.js.map +1 -1
  157. package/dist/tools/authorize.d.ts +19 -12
  158. package/dist/tools/authorize.d.ts.map +1 -1
  159. package/dist/tools/authorize.js +31 -40
  160. package/dist/tools/authorize.js.map +1 -1
  161. package/dist/tools/factory.d.ts +2 -0
  162. package/dist/tools/factory.d.ts.map +1 -1
  163. package/dist/tools/factory.js +12 -1
  164. package/dist/tools/factory.js.map +1 -1
  165. package/dist/tools/formatters/copy-guidelines.d.ts +57 -0
  166. package/dist/tools/formatters/copy-guidelines.d.ts.map +1 -0
  167. package/dist/tools/formatters/copy-guidelines.js +110 -0
  168. package/dist/tools/formatters/copy-guidelines.js.map +1 -0
  169. package/dist/tools/formatters/index.d.ts +14 -0
  170. package/dist/tools/formatters/index.d.ts.map +1 -0
  171. package/dist/tools/formatters/index.js +14 -0
  172. package/dist/tools/formatters/index.js.map +1 -0
  173. package/dist/tools/formatters/spo2.d.ts +21 -0
  174. package/dist/tools/formatters/spo2.d.ts.map +1 -0
  175. package/dist/tools/formatters/spo2.js +79 -0
  176. package/dist/tools/formatters/spo2.js.map +1 -0
  177. package/dist/tools/{formatters.d.ts → formatters/text.d.ts} +1 -1
  178. package/dist/tools/formatters/text.d.ts.map +1 -0
  179. package/dist/tools/{formatters.js → formatters/text.js} +1 -1
  180. package/dist/tools/formatters/text.js.map +1 -0
  181. package/dist/tools/impls/activity.d.ts +2 -2
  182. package/dist/tools/impls/activity.js +7 -3
  183. package/dist/tools/impls/activity.js.map +1 -1
  184. package/dist/tools/impls/anomaly.d.ts +2 -2
  185. package/dist/tools/impls/anomaly.js +8 -4
  186. package/dist/tools/impls/anomaly.js.map +1 -1
  187. package/dist/tools/impls/compare.d.ts +2 -2
  188. package/dist/tools/impls/compare.js +8 -4
  189. package/dist/tools/impls/compare.js.map +1 -1
  190. package/dist/tools/impls/hrv.d.ts +2 -2
  191. package/dist/tools/impls/hrv.js +6 -2
  192. package/dist/tools/impls/hrv.js.map +1 -1
  193. package/dist/tools/impls/insights.d.ts +4 -4
  194. package/dist/tools/impls/insights.d.ts.map +1 -1
  195. package/dist/tools/impls/insights.js +10 -3
  196. package/dist/tools/impls/insights.js.map +1 -1
  197. package/dist/tools/impls/sleep.d.ts +2 -2
  198. package/dist/tools/impls/sleep.js +6 -2
  199. package/dist/tools/impls/sleep.js.map +1 -1
  200. package/dist/tools/impls/spo2.d.ts +52 -0
  201. package/dist/tools/impls/spo2.d.ts.map +1 -0
  202. package/dist/tools/impls/spo2.js +65 -0
  203. package/dist/tools/impls/spo2.js.map +1 -0
  204. package/dist/tools/index.d.ts +1 -0
  205. package/dist/tools/index.d.ts.map +1 -1
  206. package/dist/tools/index.js +4 -0
  207. package/dist/tools/index.js.map +1 -1
  208. package/dist/tools/mcp/guard.d.ts +28 -11
  209. package/dist/tools/mcp/guard.d.ts.map +1 -1
  210. package/dist/tools/mcp/guard.js +45 -15
  211. package/dist/tools/mcp/guard.js.map +1 -1
  212. package/dist/tools/mcp/index.d.ts +1 -1
  213. package/dist/tools/mcp/index.d.ts.map +1 -1
  214. package/dist/tools/mcp/index.js +1 -1
  215. package/dist/tools/mcp/index.js.map +1 -1
  216. package/dist/tools/mcp/server.d.ts.map +1 -1
  217. package/dist/tools/mcp/server.js +4 -0
  218. package/dist/tools/mcp/server.js.map +1 -1
  219. package/dist/tools/mcp/transports/http.d.ts.map +1 -1
  220. package/dist/tools/mcp/transports/http.js +4 -0
  221. package/dist/tools/mcp/transports/http.js.map +1 -1
  222. package/package.json +8 -5
  223. package/dist/tools/formatters.d.ts.map +0 -1
  224. package/dist/tools/formatters.js.map +0 -1
package/README.md CHANGED
@@ -6,16 +6,29 @@ Per-family (or per-tenant) warehouses attached as DuckDB catalogs. Zero-copy
6
6
  reads against R2 Iceberg tables. Headless core with optional React hooks and
7
7
  UI subpaths.
8
8
 
9
- Status: **0.3.0** — Phases 1 7 landed on the core engine plus the full
10
- `@mongrov/analytics/sync` subpath (mapper buffer flusher watermark →
11
- pusher fetcher scheduler factory + hooks). T-18 / T-28 integration
12
- suites green against the MinIO + Iceberg REST docker stack (10 cases + 3
13
- round trips). 0.3.0 additionally lands SCD-2 `device_config` support:
14
- `RingConfigTranslator`, `PendingClosesStore`, `R2Pusher.pushCloses`, and
15
- a rewritten sink that closes prior configs both locally and against the
16
- remote Iceberg zone. **Breaking**: `DeviceConfigRow` shape changed
17
- (`metric` `data_type`, `start_hour`/`end_hour` `start_time`/`end_time`,
18
- added `weeks`) — see the `ringConfigTranslator` section below.
9
+ Status: **0.7.0** — Sprint 5 hardening. Core engine, `/sync`, `/rules`,
10
+ `/tools` and `/tools/mcp` subpaths all landed; 727 tests green, plus the
11
+ T-18 / T-28 integration suites against the MinIO + Iceberg REST docker
12
+ stack.
13
+
14
+ 0.7.0 lands: `icu` extension, `v_{table}` union views (local-unpushed +
15
+ remote), `user_baseline` with day-first quantiles, `batch:complete` batch
16
+ lifecycle, rules `context` / `consecutive` / `user_setting` targets, the
17
+ `getSpO2` tool, and copy guardrails on every formatter.
18
+
19
+ **Breaking** — see [UPGRADING.md](./UPGRADING.md) for rewrites. Headlines:
20
+ mapped sleep row shapes now match the DDL (they did not before, and sleep
21
+ flushes were writing NULLs into NOT NULL columns); `AnalyticsEngine` gained
22
+ `getFamilyMembers()` and `dismissInsight()`; rule and tool SQL now reads
23
+ `v_{table}` views, so an attach is required; rules evaluate once per batch
24
+ rather than per table.
25
+
26
+ > Historical note (0.3.0): SCD-2 `device_config` support inverted the
27
+ > ring-config mapping direction — `DeviceConfigRow` moved from `metric` to
28
+ > `data_type`, with a consumer-supplied `RingConfigTranslator` producing the
29
+ > firmware enum from our metric names. Sprint 5 §2 intended to reverse this
30
+ > (`metric VARCHAR`), but the change is **blocked**: the spec's firmware
31
+ > codes do not match the real JStyle codes. See UPGRADING §12.
19
32
 
20
33
  ## Features
21
34
 
package/UPGRADING.md ADDED
@@ -0,0 +1,370 @@
1
+ # Upgrading
2
+
3
+ ## 0.6.0 → 0.7.0 (Sprint 5 coordinated release)
4
+
5
+ This is a **coordinated release**. Upgrade all four together — the packages
6
+ share contracts that changed in lockstep:
7
+
8
+ | Package | From | To |
9
+ |---|---|---|
10
+ | `@mongrov/analytics` | 0.6.0 | **0.7.0** |
11
+ | `@mongrov/data-access` | 0.1.0 | **0.2.0** |
12
+ | `@mongrov/types` | 0.4.0 | **0.5.0** |
13
+ | `@mongrov/device` | 0.1.1 | **0.2.0** |
14
+
15
+ > The Sprint 5 spec named these 0.2.0 / 0.2.0 / 0.4.0 / 0.2.0. Those targets
16
+ > were unreachable: analytics had already shipped 0.2.0→0.6.0 across five
17
+ > post-Sprint-4 releases, and types had reached 0.4.0 without ever landing
18
+ > the Sprint 3 §18 content. Versions are next-minor-from-actual.
19
+
20
+ ---
21
+
22
+ ## 1. Breaking: mapped sleep row shapes
23
+
24
+ **Who is affected:** anyone who consumes `MappedBatch` directly, supplies
25
+ `columnOrder` for sleep tables, or has snapshot tests over mapper output.
26
+
27
+ The sleep mapper had drifted from the DDL it writes to and was emitting rows
28
+ the `sleep_session` table could not accept. If you were flushing sleep data,
29
+ it was failing (or writing NULLs into NOT NULL columns) — this release fixes
30
+ that, and the row types changed as a result.
31
+
32
+ ```diff
33
+ interface SleepSessionRow {
34
+ session_id: string
35
+ - ts: Date // no such column; DDL partitions on day(ts_start)
36
+ - start_ts: Date
37
+ - end_ts: Date
38
+ + ts_start: Date
39
+ + ts_end: Date
40
+ + total_minutes: number // NOT NULL — was never produced
41
+ + deep_minutes: number | null
42
+ + rem_minutes: number | null
43
+ + light_minutes: number | null
44
+ + awake_minutes: number | null
45
+ + avg_confidence: number | null
46
+ night_of: Date
47
+ }
48
+
49
+ interface SleepStageRow {
50
+ - stage: string // firmware block_type leaked into an INTEGER column
51
+ + stage: number // 1=awake, 2=light, 3=deep, 5=rem
52
+ - confidence: number
53
+ + confidence: number | null
54
+ }
55
+
56
+ interface SleepRawRow {
57
+ - payload: FirmwareSleepRow // no such column
58
+ + ts_session_start: Date
59
+ + quality: number // NOT NULL; derived from confidence when
60
+ + unit_length: number | null // firmware omits it
61
+ }
62
+ ```
63
+
64
+ Two smaller removals in the same pass — both were keys with no column:
65
+
66
+ ```diff
67
+ -interface ActivityBucketRow { steps: number; … } // steps live on `activity`
68
+ -interface DeviceConfigRow { ts: Date; … } // axis is valid_from/valid_to
69
+ ```
70
+
71
+ **Migrating `columnOrder`:** if you hand-wrote sleep entries, regenerate them
72
+ from the DDL. Column names now match exactly, so
73
+ `columnOrder[table].map(c => row[c])` works without translation.
74
+
75
+ **Behaviour changes worth knowing:**
76
+
77
+ - Session boundaries come from the firmware's own `start`/`end` fields, not
78
+ min/max of block instants. Deriving from blocks under-reported any session
79
+ whose first or last minutes went unclassified.
80
+ - `primary` blocks produce **no** `sleep_stage` row. The DDL enum has no code
81
+ for them and they read as the session envelope rather than a stage. All
82
+ blocks are still preserved in `sleep_raw`. *Open question with the firmware
83
+ team — see `analytics-sync/tasks.md` T-06.*
84
+
85
+ A new contract test (`mapper/__tests__/ddl-contract.test.ts`) parses
86
+ `core/schemas.ts` and asserts every mapped row's keys are real columns and
87
+ every NOT NULL column is populated. If you extend the mapper, it will tell
88
+ you when you drift.
89
+
90
+ ---
91
+
92
+ ## 2. Breaking: `AnalyticsEngine` gained two methods
93
+
94
+ **Who is affected:** anyone implementing `AnalyticsEngine` — test fakes,
95
+ custom adapters.
96
+
97
+ ```diff
98
+ interface AnalyticsEngine {
99
+
100
+ + getFamilyMembers(): Promise<string[]>
101
+ + dismissInsight(args: { insightId: string; userId: string }): Promise<void>
102
+ }
103
+ ```
104
+
105
+ `getFamilyMembers()` closes a principle-39 gap: the rules evaluator and the
106
+ AI-tools authorize hook each held their own wire to family membership. Now
107
+ both go through the engine, which delegates to the `familyMembersProvider`
108
+ you configured at `createAnalytics` and caches for 60s.
109
+
110
+ Minimal fake:
111
+
112
+ ```ts
113
+ const engine: AnalyticsEngine = {
114
+ …,
115
+ async getFamilyMembers() { return ['alice', 'bob'] },
116
+ async dismissInsight() {},
117
+ }
118
+ ```
119
+
120
+ ---
121
+
122
+ ## 3. Breaking: authorize hooks no longer fall back to SQL
123
+
124
+ `familyScopeAuthorize` / `orgScopeAuthorize` previously fell back to
125
+ `SELECT 1 FROM family_member …` when no provider was passed. **No DDL in this
126
+ package ever created that table**, so the fallback could only throw and fail
127
+ closed — silently denying every cross-member query on any install that did
128
+ not pass a provider explicitly.
129
+
130
+ ```diff
131
+ -familyScopeAuthorize(analytics) // used a phantom table
132
+ +familyScopeAuthorize(analytics) // uses engine roster
133
+ familyScopeAuthorize(analytics, { familyMembersProvider }) // still wins
134
+ ```
135
+
136
+ If you relied on the SQL path, wire `familyMembersProvider` at
137
+ `createAnalytics` instead. Membership lives in the RxDB Family doc, not
138
+ DuckDB.
139
+
140
+ ---
141
+
142
+ ## 4. Breaking: generated SQL reads `v_{table}` views
143
+
144
+ Rule SQL and tool SQL now target the union views instead of raw catalogs.
145
+ This is what lets a rule fire on data flushed locally but not yet pushed to
146
+ R2 — i.e. this morning's sync.
147
+
148
+ **Consequence:** the views must exist. They are created on `attach()` and
149
+ dropped on `detach()`, so anything executing rule or tool SQL against a
150
+ non-attached engine now fails where it previously read stale remote rows.
151
+
152
+ View bodies inline `brand` and `family_id`, because DuckDB views cannot bind
153
+ parameters. That makes per-attach recreation a **correctness** requirement,
154
+ not housekeeping — a brand switch reusing old views would serve the previous
155
+ tenant's rows. Handled automatically; do not cache view DDL yourself.
156
+
157
+ `insight` is deliberately *not* viewed — it is local-authoritative.
158
+
159
+ ---
160
+
161
+ ## 5. Behaviour change: rules evaluate on `batch:complete`
162
+
163
+ Rules previously evaluated once per table, on each `{table}:insert`. They now
164
+ evaluate once per batch. **Default is the new behaviour.**
165
+
166
+ This fixes a real race: a `context: 'asleep'` rule JOINs `v_sleep_session`,
167
+ and firing it the moment `spo2` flushed let it evaluate against a night whose
168
+ sleep rows were still buffered.
169
+
170
+ ```ts
171
+ createSyncManager({
172
+ …,
173
+ strictBatchOrdering: false, // opt out — restores per-table triggering
174
+ })
175
+ ```
176
+
177
+ Only opt out if you need lower evaluation latency **and** ship no
178
+ context-JOIN or `consecutive` rules.
179
+
180
+ Per-table `{table}:insert` events still fire — they drive cache
181
+ invalidation, which wants to refresh as early as possible. `batch:complete`
182
+ is additional, not a replacement.
183
+
184
+ ---
185
+
186
+ ## 6. New config: `userTimezoneProvider`
187
+
188
+ Day-first baselines bucket by **local** day, so they need each user's IANA
189
+ zone. `User.timezone` lives in auth/RxDB where this package cannot reach it.
190
+
191
+ ```ts
192
+ createSyncManager({
193
+ …,
194
+ userTimezoneProvider: async (userId) => (await getUser(userId))?.timezone,
195
+ })
196
+ ```
197
+
198
+ Unwired, it falls back to the device zone — wrong for a travelling user or
199
+ one whose profile zone differs from their device. Baselines still compute;
200
+ they just bucket by the wrong midnight.
201
+
202
+ ---
203
+
204
+ ## 7. Rules schema additions
205
+
206
+ Additive — existing rules keep parsing. New fields:
207
+
208
+ ```toml
209
+ context = "asleep" # 'any' (default) | 'asleep' | 'resting'
210
+ consecutive = 3 # require N adjacent breaching samples
211
+
212
+ [rule.target]
213
+ type = "user_setting" # threshold read from KVStore at eval time
214
+ key = "user:spo2SafeLevel"
215
+ defaultValue = 90
216
+ ```
217
+
218
+ `user_setting` is what makes a user-configurable threshold work without
219
+ per-user rule rows: the compiled SQL is threshold-agnostic, and the evaluator
220
+ binds `analytics:{userId}:{key}` at eval time, falling back to `defaultValue`.
221
+
222
+ Two constraints the validator now enforces:
223
+
224
+ - `consecutive` is **rejected with baseline targets**. Baselines resolve
225
+ per-window, not per-sample; there is no correct query shape, so it throws
226
+ rather than emitting something subtly wrong.
227
+ - `consecutive × sampling_minutes` must fit the window, or the rule could
228
+ never fire.
229
+
230
+ **Ziva catalog rule ids changed.** Throttle state is keyed by rule id, so
231
+ existing throttle counters for the renamed rules are orphaned (they expire
232
+ naturally):
233
+
234
+ | Was | Now |
235
+ |---|---|
236
+ | `ziva.sleep-deprivation-3d` | `ziva.sleep-deprivation-3` |
237
+ | `ziva.stress-elevated` | `ziva.stress-elevated-day` |
238
+ | `ziva.activity-low-24h` | `ziva.low-activity-week` |
239
+
240
+ `ziva.hrv-drop-30` and `ziva.stress-elevated-day` also switched from
241
+ `absolute` to `baseline_percent` / `baseline_stddev` targets — a fixed HRV
242
+ threshold is meaningless across users.
243
+
244
+ Also note `registry.register()` is **async**. An un-awaited call silently
245
+ no-ops:
246
+
247
+ ```diff
248
+ -rules.register(zivaDefaults)
249
+ +await rules.register(zivaDefaults)
250
+ ```
251
+
252
+ ---
253
+
254
+ ## 8. Copy guardrails — contract for tool authors
255
+
256
+ Every tool formatter must call `assertNoBanTerms(text, formatterName)` on its
257
+ return path. Tool output lands in an LLM's context, and the model repeats
258
+ whatever register it finds there.
259
+
260
+ ```ts
261
+ import { assertNoBanTerms } from '@mongrov/analytics/tools'
262
+
263
+ function finalize(text: string, rowCount: number): ToolResult {
264
+ assertNoBanTerms(text, 'myTool')
265
+ return { text, rowCount, bytes: formatBytes(text) }
266
+ }
267
+ ```
268
+
269
+ It throws `FormatterCopyError` on any banned medical term. Matching is
270
+ leading-boundary, so `desaturation` also catches `desaturations` — over-
271
+ blocking is the right bias here. `applyPreferredLanguage(text)` rewrites the
272
+ common phrasings, but it is a convenience, not a substitute: the guard still
273
+ runs afterwards.
274
+
275
+ This applies to text you did not author. An insight row titled *"Nocturnal
276
+ desaturation detected"* interpolated into `getInsights` output fails the tool
277
+ call — which is the point.
278
+
279
+ ---
280
+
281
+ ## 9. `@mongrov/data-access` 0.2.0
282
+
283
+ `RequestContext` shape:
284
+
285
+ ```diff
286
+ interface RequestContext {
287
+ - requesterUserId: string
288
+ + userId: string // canonical — queries bind it as $userId
289
+ brand: string
290
+ familyId: string
291
+ + timezone: string // bound as $tz by every day-grouped query
292
+ now: () => Date
293
+ }
294
+ ```
295
+
296
+ Both are required. Update your `DataAccessProvider` context factory.
297
+
298
+ The remaining 0.2.0 items (`asyncFetch`, `fetching` hook state,
299
+ JOIN-invalidation validator, `transform` field, `MutationContext.analytics`)
300
+ were already implemented before this release; 0.2.0 records the version.
301
+
302
+ ---
303
+
304
+ ## 10. `@mongrov/types` 0.5.0
305
+
306
+ Additive. Lands the Sprint 3 §18 layer every Sprint 4 feature was written
307
+ against but which never shipped: `Brand`, `Family`, `User`,
308
+ `AnalyticsDevice`, `SensorSink`, `FirmwareExport`, `MapperContext`,
309
+ `EventBus`, and the seven missing `AnalyticsQuerySchemas`.
310
+
311
+ **`AnalyticsDevice`, not `Device`.** `types/device.ts` already exports a
312
+ `Device` describing the BLE transport's view (adapterId, connection state,
313
+ RSSI). Both are legitimate and neither is a superset — one is the durable
314
+ tenancy record sensor rows key against, the other is the live connection
315
+ handle. The existing `Device` is unchanged.
316
+
317
+ `DEVICE_EVENT_TYPES` and its payload schemas now live here canonically
318
+ (`@mongrov/types/device-events`); `@mongrov/analytics` re-exports them. This
319
+ is what lets `@mongrov/device` emit events the analytics engine will store
320
+ without depending on the engine.
321
+
322
+ **Packaging change: dual CJS/ESM emit.** `dist/` is now `dist/esm` +
323
+ `dist/cjs`, each with its own `type` marker, and every export declares
324
+ `import` / `require` / `types` conditions. Previously the package emitted
325
+ ESM only and declared no `require` condition — which nothing noticed,
326
+ because every cross-package import was type-only and therefore erased at
327
+ compile. The first *value* import from a subpath (`device-events`,
328
+ `analytics-queries`) failed to resolve under CommonJS.
329
+
330
+ If you deep-imported `@mongrov/types/dist/...` — don't; use the subpath
331
+ exports. `main` / `module` / `types` now point into the split trees.
332
+
333
+ ---
334
+
335
+ ## 11. Migrations
336
+
337
+ One new migration runs automatically on attach:
338
+
339
+ | Version | What |
340
+ |---|---|
341
+ | v4 | `user_baseline` table (local catalog only) |
342
+
343
+ **Numbering note.** The Sprint 5 spec called this "migration v3" and
344
+ specified a "v4" adding `insight.dismissed_at`. Versions 2 and 3 were already
345
+ spent (`device_battery`, `insight` v2 rebuild), and `dismissed_at` already
346
+ ships in the baseline DDL with migration v3 backfilling it — so the ALTER
347
+ would have been a no-op against an existing column.
348
+
349
+ `user_baseline` and `sync_watermark` are **local-only** — never created in
350
+ the attached R2 zone. Baselines are derived data, cheap to recompute, and
351
+ pushing them would invite two devices in one family to race on the same
352
+ composite PK.
353
+
354
+ ---
355
+
356
+ ## 12. Known gaps in this release
357
+
358
+ Documented so you do not go looking:
359
+
360
+ - **`device_config` still uses `data_type SMALLINT`.** Sprint 5 §2's change
361
+ to `metric VARCHAR` is blocked: the spec's firmware codes (1/2/4) do not
362
+ match the real JStyle codes (`HR:0, SLEEP:1, SPO2:3, HRV:8, ACTIVITY:9,
363
+ TEMPERATURE:14`), and SpO₂/temperature are separate schedules — so the
364
+ "fan-out `data_type=2` into two rows" the task describes may not correspond
365
+ to real hardware behaviour. Unresolved with the firmware team.
366
+ - **`@mongrov/device` sync events are emitter-only.** `createSyncEventEmitter`
367
+ and the `DeviceEventSink` port ship and are usable stand-alone, but the sync
368
+ machine that would call them is D5 work and does not exist yet.
369
+ - **`transform` is declared but not resolved** by the data-access dispatcher.
370
+ Queries declaring it will not produce derived output fields yet.
@@ -0,0 +1,14 @@
1
+ /**
2
+ * `device_event.event_type` enum + per-type payload schemas (Sprint 5 §6).
3
+ *
4
+ * **Re-export only.** The canonical definition lives in
5
+ * `@mongrov/types/device-events` so that `@mongrov/device` — which must
6
+ * never depend on the analytics engine — can emit events this engine will
7
+ * store, against the same contract.
8
+ *
9
+ * Kept as a module here so analytics consumers get one import surface, and
10
+ * so the `core/index.ts` export list stays stable.
11
+ */
12
+ export { decodeDeviceEventPayload, DEVICE_EVENT_PAYLOAD_SCHEMAS, DEVICE_EVENT_TYPES, encodeDeviceEventPayload, isDeviceEventType, SyncTrigger, } from '@mongrov/types/device-events';
13
+ export type { DeviceEventPayload, DeviceEventType, SyncTriggerValue, } from '@mongrov/types/device-events';
14
+ //# sourceMappingURL=device-events.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-events.d.ts","sourceRoot":"","sources":["../../src/core/device-events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,wBAAwB,EACxB,4BAA4B,EAC5B,kBAAkB,EAClB,wBAAwB,EACxB,iBAAiB,EACjB,WAAW,GACZ,MAAM,8BAA8B,CAAA;AAErC,YAAY,EACV,kBAAkB,EAClB,eAAe,EACf,gBAAgB,GACjB,MAAM,8BAA8B,CAAA"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * `device_event.event_type` enum + per-type payload schemas (Sprint 5 §6).
3
+ *
4
+ * **Re-export only.** The canonical definition lives in
5
+ * `@mongrov/types/device-events` so that `@mongrov/device` — which must
6
+ * never depend on the analytics engine — can emit events this engine will
7
+ * store, against the same contract.
8
+ *
9
+ * Kept as a module here so analytics consumers get one import surface, and
10
+ * so the `core/index.ts` export list stays stable.
11
+ */
12
+ export { decodeDeviceEventPayload, DEVICE_EVENT_PAYLOAD_SCHEMAS, DEVICE_EVENT_TYPES, encodeDeviceEventPayload, isDeviceEventType, SyncTrigger, } from '@mongrov/types/device-events';
13
+ //# sourceMappingURL=device-events.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"device-events.js","sourceRoot":"","sources":["../../src/core/device-events.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,wBAAwB,EACxB,4BAA4B,EAC5B,kBAAkB,EAClB,wBAAwB,EACxB,iBAAiB,EACjB,WAAW,GACZ,MAAM,8BAA8B,CAAA"}
@@ -5,7 +5,7 @@
5
5
  * ships the class and code union so stubs can throw typed errors from
6
6
  * day one; downstream phases add more codes without breaking imports.
7
7
  */
8
- export type AnalyticsErrorCode = 'engine_open_failed' | 'extension_load_failed' | 'attach_failed' | 'detach_failed' | 'token_vendor_failed' | 'migration_failed' | 'retention_failed' | 'query_failed' | 'not_attached' | 'not_ready' | 'not_implemented';
8
+ export type AnalyticsErrorCode = 'engine_open_failed' | 'extension_load_failed' | 'attach_failed' | 'detach_failed' | 'token_vendor_failed' | 'migration_failed' | 'retention_failed' | 'family_members_failed' | 'query_failed' | 'not_attached' | 'not_ready' | 'not_implemented';
9
9
  export declare class AnalyticsError extends Error {
10
10
  readonly code: AnalyticsErrorCode;
11
11
  readonly cause?: unknown;
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,kBAAkB,GAC1B,oBAAoB,GACpB,uBAAuB,GACvB,eAAe,GACf,eAAe,GACf,qBAAqB,GACrB,kBAAkB,GAClB,kBAAkB,GAClB,cAAc,GACd,cAAc,GACd,WAAW,GACX,iBAAiB,CAAA;AAErB,qBAAa,cAAe,SAAQ,KAAK;IACvC,SAAgB,IAAI,EAAE,kBAAkB,CAAA;IACxC,SAAgB,KAAK,CAAC,EAAE,OAAO,CAAA;gBAEnB,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAMvE;AAED;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,cAAc;gBACzC,MAAM,EAAE,MAAM;CAI3B"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,MAAM,MAAM,kBAAkB,GAC1B,oBAAoB,GACpB,uBAAuB,GACvB,eAAe,GACf,eAAe,GACf,qBAAqB,GACrB,kBAAkB,GAClB,kBAAkB,GAClB,uBAAuB,GACvB,cAAc,GACd,cAAc,GACd,WAAW,GACX,iBAAiB,CAAA;AAErB,qBAAa,cAAe,SAAQ,KAAK;IACvC,SAAgB,IAAI,EAAE,kBAAkB,CAAA;IACxC,SAAgB,KAAK,CAAC,EAAE,OAAO,CAAA;gBAEnB,IAAI,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO;CAMvE;AAED;;;GAGG;AACH,qBAAa,mBAAoB,SAAQ,cAAc;gBACzC,MAAM,EAAE,MAAM;CAI3B"}
@@ -1 +1 @@
1
- {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAeH,MAAM,OAAO,cAAe,SAAQ,KAAK;IAIvC,YAAY,IAAwB,EAAE,OAAe,EAAE,KAAe;QACpE,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAA;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,mBAAoB,SAAQ,cAAc;IACrD,YAAY,MAAc;QACxB,KAAK,CAAC,iBAAiB,EAAE,GAAG,MAAM,qBAAqB,CAAC,CAAA;QACxD,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAA;IACnC,CAAC;CACF"}
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/core/errors.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAgBH,MAAM,OAAO,cAAe,SAAQ,KAAK;IAIvC,YAAY,IAAwB,EAAE,OAAe,EAAE,KAAe;QACpE,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAA;QAC5B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,mBAAoB,SAAQ,cAAc;IACrD,YAAY,MAAc;QACxB,KAAK,CAAC,iBAAiB,EAAE,GAAG,MAAM,qBAAqB,CAAC,CAAA;QACxD,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAA;IACnC,CAAC;CACF"}
@@ -18,10 +18,27 @@
18
18
  */
19
19
  import type { HybridDuckDB } from './engine';
20
20
  import type { AnalyticsMode } from './types';
21
- /** Extensions required for R2 Iceberg attach, in load order. */
22
- export declare const REQUIRED_EXTENSIONS: readonly ["httpfs", "iceberg", "parquet"];
23
- /** Extensions required for local-only mode (no remote sync, no iceberg). */
24
- export declare const LOCAL_EXTENSIONS: readonly ["parquet"];
21
+ /**
22
+ * Extensions required for R2 Iceberg attach, in load order.
23
+ *
24
+ * `icu` sits between `httpfs` and `iceberg` per Sprint 5 T-01. It is not
25
+ * optional: every registry query and every baseline computation groups by
26
+ * local day via `timezone($tz, ts)` / `date_trunc('day', timezone(...))`,
27
+ * and DuckDB's `timezone()` with a named IANA zone resolves only when
28
+ * `icu` is loaded. Without it those queries fail at parse time rather than
29
+ * silently returning UTC-grouped rows.
30
+ */
31
+ export declare const REQUIRED_EXTENSIONS: readonly ["httpfs", "icu", "iceberg", "parquet"];
32
+ /**
33
+ * Extensions required for local-only mode (no remote sync, no iceberg).
34
+ *
35
+ * `icu` is here too, and deliberately so: local mode skips `httpfs` +
36
+ * `iceberg` to avoid the AWSSDK/vcpkg build burden, but it does NOT skip
37
+ * timezone-aware queries — a local-only install still renders day charts
38
+ * and computes day-first baselines. Omitting `icu` here would make those
39
+ * paths work on R2 installs and fail on local ones.
40
+ */
41
+ export declare const LOCAL_EXTENSIONS: readonly ["icu", "parquet"];
25
42
  export type RequiredExtension = (typeof REQUIRED_EXTENSIONS)[number];
26
43
  /**
27
44
  * Issue `INSTALL <ext>; LOAD <ext>;` for each mode-appropriate extension
@@ -1 +1 @@
1
- {"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../../src/core/extensions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE5C,gEAAgE;AAChE,eAAO,MAAM,mBAAmB,2CAA4C,CAAA;AAE5E,4EAA4E;AAC5E,eAAO,MAAM,gBAAgB,sBAAuB,CAAA;AAEpD,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAA;AAQpE;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,YAAY,EAChB,IAAI,GAAE,aAAoB,GACzB,OAAO,CAAC,IAAI,CAAC,CA2Bf;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,CAEzE"}
1
+ {"version":3,"file":"extensions.d.ts","sourceRoot":"","sources":["../../src/core/extensions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAC5C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAA;AAE5C;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,kDAAmD,CAAA;AAEnF;;;;;;;;GAQG;AACH,eAAO,MAAM,gBAAgB,6BAA8B,CAAA;AAE3D,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,mBAAmB,CAAC,CAAC,MAAM,CAAC,CAAA;AAQpE;;;;;;;;;;;;GAYG;AACH,wBAAsB,mBAAmB,CACvC,EAAE,EAAE,YAAY,EAChB,IAAI,GAAE,aAAoB,GACzB,OAAO,CAAC,IAAI,CAAC,CA2Bf;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,EAAE,EAAE,YAAY,GAAG,WAAW,CAAC,MAAM,CAAC,CAEzE"}
@@ -17,10 +17,27 @@
17
17
  * calls, and DuckDB itself no-ops re-loads, so calling twice is safe.
18
18
  */
19
19
  import { AnalyticsError } from './errors';
20
- /** Extensions required for R2 Iceberg attach, in load order. */
21
- export const REQUIRED_EXTENSIONS = ['httpfs', 'iceberg', 'parquet'];
22
- /** Extensions required for local-only mode (no remote sync, no iceberg). */
23
- export const LOCAL_EXTENSIONS = ['parquet'];
20
+ /**
21
+ * Extensions required for R2 Iceberg attach, in load order.
22
+ *
23
+ * `icu` sits between `httpfs` and `iceberg` per Sprint 5 T-01. It is not
24
+ * optional: every registry query and every baseline computation groups by
25
+ * local day via `timezone($tz, ts)` / `date_trunc('day', timezone(...))`,
26
+ * and DuckDB's `timezone()` with a named IANA zone resolves only when
27
+ * `icu` is loaded. Without it those queries fail at parse time rather than
28
+ * silently returning UTC-grouped rows.
29
+ */
30
+ export const REQUIRED_EXTENSIONS = ['httpfs', 'icu', 'iceberg', 'parquet'];
31
+ /**
32
+ * Extensions required for local-only mode (no remote sync, no iceberg).
33
+ *
34
+ * `icu` is here too, and deliberately so: local mode skips `httpfs` +
35
+ * `iceberg` to avoid the AWSSDK/vcpkg build burden, but it does NOT skip
36
+ * timezone-aware queries — a local-only install still renders day charts
37
+ * and computes day-first baselines. Omitting `icu` here would make those
38
+ * paths work on R2 installs and fail on local ones.
39
+ */
40
+ export const LOCAL_EXTENSIONS = ['icu', 'parquet'];
24
41
  /**
25
42
  * Tracks which extensions this process has already booted. Keyed by
26
43
  * `HybridDuckDB` instance to keep isolation across engines in tests.
@@ -1 +1 @@
1
- {"version":3,"file":"extensions.js","sourceRoot":"","sources":["../../src/core/extensions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAIzC,gEAAgE;AAChE,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,SAAS,CAAU,CAAA;AAE5E,4EAA4E;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,SAAS,CAAU,CAAA;AAIpD;;;GAGG;AACH,MAAM,UAAU,GAAG,IAAI,OAAO,EAA6B,CAAA;AAE3D;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,EAAgB,EAChB,OAAsB,IAAI;IAE1B,IAAI,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,IAAI,GAAG,EAAE,CAAA;QAClB,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IAC5B,CAAC;IAED,MAAM,UAAU,GACZ,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,mBAAmB,CAAA;IAE7D,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACpB,SAAQ;QACV,CAAC;QACD,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,OAAO,CAAC,WAAW,GAAG,GAAG,CAAC,CAAA;YACnC,MAAM,EAAE,CAAC,OAAO,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAA;QAClC,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,IAAI,cAAc,CACtB,uBAAuB,EACvB,oCAAoC,GAAG,EAAE,EACzC,KAAK,CACN,CAAA;QACH,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACjB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAAgB;IAClD,OAAO,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,GAAG,EAAE,CAAA;AACxC,CAAC"}
1
+ {"version":3,"file":"extensions.js","sourceRoot":"","sources":["../../src/core/extensions.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAIzC;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,SAAS,CAAU,CAAA;AAEnF;;;;;;;;GAQG;AACH,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,KAAK,EAAE,SAAS,CAAU,CAAA;AAI3D;;;GAGG;AACH,MAAM,UAAU,GAAG,IAAI,OAAO,EAA6B,CAAA;AAE3D;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,EAAgB,EAChB,OAAsB,IAAI;IAE1B,IAAI,MAAM,GAAG,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAA;IAC/B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,GAAG,IAAI,GAAG,EAAE,CAAA;QAClB,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,MAAM,CAAC,CAAA;IAC5B,CAAC;IAED,MAAM,UAAU,GACZ,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,gBAAgB,CAAC,CAAC,CAAC,mBAAmB,CAAA;IAE7D,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,IAAI,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;YACpB,SAAQ;QACV,CAAC;QACD,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,OAAO,CAAC,WAAW,GAAG,GAAG,CAAC,CAAA;YACnC,MAAM,EAAE,CAAC,OAAO,CAAC,QAAQ,GAAG,GAAG,CAAC,CAAA;QAClC,CAAC;QACD,OAAO,KAAK,EAAE,CAAC;YACb,MAAM,IAAI,cAAc,CACtB,uBAAuB,EACvB,oCAAoC,GAAG,EAAE,EACzC,KAAK,CACN,CAAA;QACH,CAAC;QACD,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACjB,CAAC;AACH,CAAC;AAED;;;;;GAKG;AACH,MAAM,UAAU,mBAAmB,CAAC,EAAgB;IAClD,OAAO,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,IAAI,IAAI,GAAG,EAAE,CAAA;AACxC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/core/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAkB,MAAM,UAAU,CAAA;AAe7D,OAAO,KAAK,EAEV,eAAe,EACf,eAAe,EAKhB,MAAM,SAAS,CAAA;AAgChB;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,6EAA6E;IAC7E,aAAa,CAAC,EAAE,aAAa,CAAA;CAC9B;AAwED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,eAAe,EACvB,QAAQ,GAAE,uBAA4B,GACrC,eAAe,CA8QjB"}
1
+ {"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/core/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAKH,OAAO,KAAK,EAAE,aAAa,EAAkB,MAAM,UAAU,CAAA;AAgB7D,OAAO,KAAK,EAEV,eAAe,EACf,eAAe,EAKhB,MAAM,SAAS,CAAA;AAkChB;;;;;GAKG;AACH,MAAM,WAAW,uBAAuB;IACtC,6EAA6E;IAC7E,aAAa,CAAC,EAAE,aAAa,CAAA;CAC9B;AAwED,wBAAgB,eAAe,CAC7B,MAAM,EAAE,eAAe,EACvB,QAAQ,GAAE,uBAA4B,GACrC,eAAe,CAoYjB"}