@mongrov/analytics 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (43) hide show
  1. package/README.md +64 -5
  2. package/dist/core/index.d.ts +2 -0
  3. package/dist/core/index.d.ts.map +1 -1
  4. package/dist/core/index.js +4 -0
  5. package/dist/core/index.js.map +1 -1
  6. package/dist/core/table_metadata.d.ts +37 -0
  7. package/dist/core/table_metadata.d.ts.map +1 -0
  8. package/dist/core/table_metadata.js +51 -0
  9. package/dist/core/table_metadata.js.map +1 -0
  10. package/dist/sync/factory.d.ts +8 -0
  11. package/dist/sync/factory.d.ts.map +1 -1
  12. package/dist/sync/factory.js +121 -3
  13. package/dist/sync/factory.js.map +1 -1
  14. package/dist/sync/fetcher.d.ts.map +1 -1
  15. package/dist/sync/fetcher.js +13 -9
  16. package/dist/sync/fetcher.js.map +1 -1
  17. package/dist/sync/index.d.ts +2 -1
  18. package/dist/sync/index.d.ts.map +1 -1
  19. package/dist/sync/index.js +2 -0
  20. package/dist/sync/index.js.map +1 -1
  21. package/dist/sync/mapper/firmware.d.ts +14 -3
  22. package/dist/sync/mapper/firmware.d.ts.map +1 -1
  23. package/dist/sync/mapper/firmware.js +22 -1
  24. package/dist/sync/mapper/firmware.js.map +1 -1
  25. package/dist/sync/mapper/ring-config.d.ts +27 -13
  26. package/dist/sync/mapper/ring-config.d.ts.map +1 -1
  27. package/dist/sync/mapper/ring-config.js +29 -16
  28. package/dist/sync/mapper/ring-config.js.map +1 -1
  29. package/dist/sync/mapper/types.d.ts +35 -3
  30. package/dist/sync/mapper/types.d.ts.map +1 -1
  31. package/dist/sync/pending_closes.d.ts +30 -0
  32. package/dist/sync/pending_closes.d.ts.map +1 -0
  33. package/dist/sync/pending_closes.js +83 -0
  34. package/dist/sync/pending_closes.js.map +1 -0
  35. package/dist/sync/pusher.d.ts +21 -0
  36. package/dist/sync/pusher.d.ts.map +1 -1
  37. package/dist/sync/pusher.js +59 -3
  38. package/dist/sync/pusher.js.map +1 -1
  39. package/dist/sync/scheduler.d.ts +7 -0
  40. package/dist/sync/scheduler.d.ts.map +1 -1
  41. package/dist/sync/scheduler.js +1 -0
  42. package/dist/sync/scheduler.js.map +1 -1
  43. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"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"}
@@ -34,4 +34,6 @@ export { reconstructSleepSessions, } from './mapper/sleep';
34
34
  export { mapSpo2 } from './mapper/spo2';
35
35
  export { mapTemperature } from './mapper/temperature';
36
36
  export { computeNightOf, parseTimestamp } from './mapper/time';
37
+ // SCD-2 pending closes (Phase G+).
38
+ export { PendingClosesStore } from './pending_closes';
37
39
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,+BAA+B;AAC/B,OAAO,EAAE,YAAY,EAA2B,MAAM,UAAU,CAAA;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAS1C,8CAA8C;AAC9C,OAAO,EAEL,cAAc,GAEf,MAAM,aAAa,CAAA;AACpB,OAAO,EAEL,QAAQ,GAET,MAAM,UAAU,CAAA;AACjB,OAAO,EAIL,SAAS,GAEV,MAAM,WAAW,CAAA;AAElB,gCAAgC;AAChC,OAAO,EACL,mBAAmB,EACnB,YAAY,EAEZ,gBAAgB,EAGhB,wBAAwB,GAGzB,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,SAAS,EAAsB,MAAM,UAAU,CAAA;AACxD,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,GAEd,MAAM,YAAY,CAAA;AAEnB,wCAAwC;AACxC,OAAO,EAAE,iBAAiB,EAAgC,MAAM,WAAW,CAAA;AAO3E,OAAO,EAAE,YAAY,EAA0B,cAAc,EAAE,MAAM,WAAW,CAAA;AAChF,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAEtE,mCAAmC;AACnC,OAAO,EACL,eAAe,EACf,cAAc,GAKf,MAAM,UAAU,CAAA;AAEjB,uBAAuB;AACvB,OAAO,EAQL,aAAa,GAEd,MAAM,aAAa,CAAA;AAEpB,qBAAqB;AACrB,OAAO,EAAE,WAAW,EAA0B,MAAM,mBAAmB,CAAA;AACvE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC5D,OAAO,EAEL,iBAAiB,GAElB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAEL,aAAa,GAEd,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAEL,wBAAwB,GACzB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/sync/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,+BAA+B;AAC/B,OAAO,EAAE,YAAY,EAA2B,MAAM,UAAU,CAAA;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAS1C,8CAA8C;AAC9C,OAAO,EAEL,cAAc,GAEf,MAAM,aAAa,CAAA;AACpB,OAAO,EAEL,QAAQ,GAET,MAAM,UAAU,CAAA;AACjB,OAAO,EAIL,SAAS,GAEV,MAAM,WAAW,CAAA;AAElB,gCAAgC;AAChC,OAAO,EACL,mBAAmB,EACnB,YAAY,EAEZ,gBAAgB,EAGhB,wBAAwB,GAGzB,MAAM,WAAW,CAAA;AAClB,OAAO,EAAE,SAAS,EAAsB,MAAM,UAAU,CAAA;AACxD,OAAO,EACL,kBAAkB,EAClB,gBAAgB,EAChB,aAAa,GAEd,MAAM,YAAY,CAAA;AAEnB,wCAAwC;AACxC,OAAO,EAAE,iBAAiB,EAAgC,MAAM,WAAW,CAAA;AAO3E,OAAO,EAAE,YAAY,EAA0B,cAAc,EAAE,MAAM,WAAW,CAAA;AAChF,OAAO,EAAE,aAAa,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AAEtE,mCAAmC;AACnC,OAAO,EACL,eAAe,EACf,cAAc,GAKf,MAAM,UAAU,CAAA;AAEjB,uBAAuB;AACvB,OAAO,EAQL,aAAa,GAEd,MAAM,aAAa,CAAA;AAEpB,qBAAqB;AACrB,OAAO,EAAE,WAAW,EAA0B,MAAM,mBAAmB,CAAA;AACvE,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAC5D,OAAO,EAEL,iBAAiB,GAElB,MAAM,mBAAmB,CAAA;AAC1B,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAA;AACrC,OAAO,EAEL,aAAa,GAEd,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAEL,wBAAwB,GACzB,MAAM,gBAAgB,CAAA;AACvB,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAA;AACrD,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AA6B9D,mCAAmC;AACnC,OAAO,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA"}
@@ -14,12 +14,23 @@
14
14
  * shape contract.
15
15
  */
16
16
  import { type RingConfigClose } from './ring-config';
17
- import type { DeviceConfigRow, FirmwareExport, MappedBatch, MapperContext } from './types';
17
+ import type { DeviceConfigRow, FirmwareExport, MappedBatch, MapperContext, RingConfigTranslator } from './types';
18
18
  export interface MapFirmwareOptions {
19
19
  /** Override for deterministic tests. Defaults to `new Date()`. */
20
20
  now?: Date;
21
- /** SCD-2 prior-config map — see `mapRingConfig`. */
22
- activePriorConfigs?: ReadonlyMap<string, DeviceConfigRow>;
21
+ /**
22
+ * SCD-2 prior-config map keyed by `data_type` (integer) — see
23
+ * `mapRingConfig`. Required whenever `fw.ring` is non-empty; the mapper
24
+ * skips ring-config translation entirely when this is absent and `fw.ring`
25
+ * has no windows.
26
+ */
27
+ activePriorConfigs?: ReadonlyMap<number, DeviceConfigRow>;
28
+ /**
29
+ * Consumer-provided translation from firmware ring metrics to schema
30
+ * fields. Required if `fw.ring.automaticMonitoringData` has entries;
31
+ * skipped (empty inserts + closes) if absent.
32
+ */
33
+ translator?: RingConfigTranslator;
23
34
  }
24
35
  export interface FirmwareMappedBatch extends MappedBatch {
25
36
  device_config_closes: RingConfigClose[];
@@ -1 +1 @@
1
- {"version":3,"file":"firmware.d.ts","sourceRoot":"","sources":["../../../src/sync/mapper/firmware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AAInE,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,WAAW,EACX,aAAa,EACd,MAAM,SAAS,CAAA;AAEhB,MAAM,WAAW,kBAAkB;IACjC,kEAAkE;IAClE,GAAG,CAAC,EAAE,IAAI,CAAA;IACV,oDAAoD;IACpD,kBAAkB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;CAC1D;AAED,MAAM,WAAW,mBAAoB,SAAQ,WAAW;IACtD,oBAAoB,EAAE,eAAe,EAAE,CAAA;CACxC;AAED,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,cAAc,EAClB,GAAG,EAAE,aAAa,EAClB,IAAI,GAAE,kBAAuB,GAC5B,mBAAmB,CAuBrB"}
1
+ {"version":3,"file":"firmware.d.ts","sourceRoot":"","sources":["../../../src/sync/mapper/firmware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAMH,OAAO,EAAiB,KAAK,eAAe,EAAE,MAAM,eAAe,CAAA;AAInE,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,WAAW,EACX,aAAa,EACb,oBAAoB,EACrB,MAAM,SAAS,CAAA;AAEhB,MAAM,WAAW,kBAAkB;IACjC,kEAAkE;IAClE,GAAG,CAAC,EAAE,IAAI,CAAA;IACV;;;;;OAKG;IACH,kBAAkB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;IACzD;;;;OAIG;IACH,UAAU,CAAC,EAAE,oBAAoB,CAAA;CAClC;AAED,MAAM,WAAW,mBAAoB,SAAQ,WAAW;IACtD,oBAAoB,EAAE,eAAe,EAAE,CAAA;CACxC;AAED,wBAAgB,iBAAiB,CAC/B,EAAE,EAAE,cAAc,EAClB,GAAG,EAAE,aAAa,EAClB,IAAI,GAAE,kBAAuB,GAC5B,mBAAmB,CAmBrB"}
@@ -24,7 +24,7 @@ import { mapTemperature } from './temperature';
24
24
  export function mapFirmwareExport(fw, ctx, opts = {}) {
25
25
  const activity = mapActivity(fw.activitydetails ?? [], ctx);
26
26
  const sleep = reconstructSleepSessions(fw.sleep_processed ?? [], ctx);
27
- const config = mapRingConfig(fw.ring ?? { automaticMonitoringData: [] }, ctx, opts);
27
+ const config = mapRingConfigIfPossible(fw, ctx, opts);
28
28
  return {
29
29
  hrv: mapHrv(fw.hrv_table ?? [], ctx),
30
30
  heart_rate: mapHeartRate(fw.heartrate ?? [], ctx),
@@ -40,4 +40,25 @@ export function mapFirmwareExport(fw, ctx, opts = {}) {
40
40
  device_config_closes: config.closes,
41
41
  };
42
42
  }
43
+ /**
44
+ * Guard around `mapRingConfig`. When the firmware has no ring windows and no
45
+ * translator is supplied, we short-circuit to an empty result rather than
46
+ * threading a required-translator error through every synthetic firmware
47
+ * call site that doesn't touch device_config (e.g. unit fixtures for other
48
+ * sub-mappers).
49
+ */
50
+ function mapRingConfigIfPossible(fw, ctx, opts) {
51
+ const windows = fw.ring?.automaticMonitoringData ?? [];
52
+ if (windows.length === 0 && !opts.translator) {
53
+ return { inserts: [], closes: [] };
54
+ }
55
+ if (!opts.translator) {
56
+ throw new Error('mapFirmwareExport: firmware ring.automaticMonitoringData has entries but no `translator` was provided in options');
57
+ }
58
+ return mapRingConfig(fw.ring ?? { automaticMonitoringData: [] }, ctx, {
59
+ now: opts.now,
60
+ activePriorConfigs: opts.activePriorConfigs,
61
+ translator: opts.translator,
62
+ });
63
+ }
43
64
  //# sourceMappingURL=firmware.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"firmware.js","sourceRoot":"","sources":["../../../src/sync/mapper/firmware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,aAAa,EAAwB,MAAM,eAAe,CAAA;AACnE,OAAO,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AAmB9C,MAAM,UAAU,iBAAiB,CAC/B,EAAkB,EAClB,GAAkB,EAClB,OAA2B,EAAE;IAE7B,MAAM,QAAQ,GAAG,WAAW,CAAC,EAAE,CAAC,eAAe,IAAI,EAAE,EAAE,GAAG,CAAC,CAAA;IAC3D,MAAM,KAAK,GAAG,wBAAwB,CAAC,EAAE,CAAC,eAAe,IAAI,EAAE,EAAE,GAAG,CAAC,CAAA;IACrE,MAAM,MAAM,GAAG,aAAa,CAC1B,EAAE,CAAC,IAAI,IAAI,EAAE,uBAAuB,EAAE,EAAE,EAAE,EAC1C,GAAG,EACH,IAAI,CACL,CAAA;IAED,OAAO;QACL,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,SAAS,IAAI,EAAE,EAAE,GAAG,CAAC;QACpC,UAAU,EAAE,YAAY,CAAC,EAAE,CAAC,SAAS,IAAI,EAAE,EAAE,GAAG,CAAC;QACjD,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,EAAE,GAAG,CAAC;QACjC,WAAW,EAAE,cAAc,CAAC,EAAE,CAAC,iBAAiB,IAAI,EAAE,EAAE,GAAG,CAAC;QAC5D,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,eAAe,EAAE,QAAQ,CAAC,eAAe;QACzC,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,YAAY,EAAE,UAAU,CAAC,EAAE,CAAC,aAAa,IAAI,EAAE,EAAE,GAAG,CAAC;QACrD,aAAa,EAAE,MAAM,CAAC,OAAO;QAC7B,oBAAoB,EAAE,MAAM,CAAC,MAAM;KACpC,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"firmware.js","sourceRoot":"","sources":["../../../src/sync/mapper/firmware.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,WAAW,CAAA;AACtC,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,MAAM,EAAE,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,aAAa,EAAwB,MAAM,eAAe,CAAA;AACnE,OAAO,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAA;AAClD,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAA;AAChC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAA;AA+B9C,MAAM,UAAU,iBAAiB,CAC/B,EAAkB,EAClB,GAAkB,EAClB,OAA2B,EAAE;IAE7B,MAAM,QAAQ,GAAG,WAAW,CAAC,EAAE,CAAC,eAAe,IAAI,EAAE,EAAE,GAAG,CAAC,CAAA;IAC3D,MAAM,KAAK,GAAG,wBAAwB,CAAC,EAAE,CAAC,eAAe,IAAI,EAAE,EAAE,GAAG,CAAC,CAAA;IACrE,MAAM,MAAM,GAAG,uBAAuB,CAAC,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,CAAA;IAErD,OAAO;QACL,GAAG,EAAE,MAAM,CAAC,EAAE,CAAC,SAAS,IAAI,EAAE,EAAE,GAAG,CAAC;QACpC,UAAU,EAAE,YAAY,CAAC,EAAE,CAAC,SAAS,IAAI,EAAE,EAAE,GAAG,CAAC;QACjD,IAAI,EAAE,OAAO,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,EAAE,GAAG,CAAC;QACjC,WAAW,EAAE,cAAc,CAAC,EAAE,CAAC,iBAAiB,IAAI,EAAE,EAAE,GAAG,CAAC;QAC5D,QAAQ,EAAE,QAAQ,CAAC,QAAQ;QAC3B,eAAe,EAAE,QAAQ,CAAC,eAAe;QACzC,aAAa,EAAE,KAAK,CAAC,aAAa;QAClC,WAAW,EAAE,KAAK,CAAC,WAAW;QAC9B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,YAAY,EAAE,UAAU,CAAC,EAAE,CAAC,aAAa,IAAI,EAAE,EAAE,GAAG,CAAC;QACrD,aAAa,EAAE,MAAM,CAAC,OAAO;QAC7B,oBAAoB,EAAE,MAAM,CAAC,MAAM;KACpC,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,uBAAuB,CAC9B,EAAkB,EAClB,GAAkB,EAClB,IAAwB;IAExB,MAAM,OAAO,GAAG,EAAE,CAAC,IAAI,EAAE,uBAAuB,IAAI,EAAE,CAAA;IACtD,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QAC7C,OAAO,EAAE,OAAO,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAA;IACpC,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,CAAC;QACrB,MAAM,IAAI,KAAK,CACb,kHAAkH,CACnH,CAAA;IACH,CAAC;IACD,OAAO,aAAa,CAClB,EAAE,CAAC,IAAI,IAAI,EAAE,uBAAuB,EAAE,EAAE,EAAE,EAC1C,GAAG,EACH;QACE,GAAG,EAAE,IAAI,CAAC,GAAG;QACb,kBAAkB,EAAE,IAAI,CAAC,kBAAkB;QAC3C,UAAU,EAAE,IAAI,CAAC,UAAU;KAC5B,CACF,CAAA;AACH,CAAC"}
@@ -7,27 +7,41 @@
7
7
  * the new insert.
8
8
  *
9
9
  * Closing prior config (SCD-2 semantics):
10
- * The mapper accepts an optional `activePriorConfigs` map keyed by metric
11
- * name. For every metric that shows up in the new firmware snapshot, if a
12
- * prior config was open, the mapper emits a `close` entry so the flusher
13
- * can `UPDATE ... SET valid_to = now()` before the INSERT lands. Metrics
14
- * present in the prior map but absent from the new firmware are left open
15
- * (the ring is silent on them, not disabling them).
10
+ * The mapper accepts an optional `activePriorConfigs` map keyed by
11
+ * `data_type` (integer, produced via the translator). For every metric that
12
+ * shows up in the new firmware snapshot, if a prior config was open, the
13
+ * mapper emits a `close` entry so the sink can `UPDATE ... SET valid_to =
14
+ * now()` locally before the INSERT lands, and enqueue the same directive
15
+ * for the next remote push cycle. Metrics present in the prior map but
16
+ * absent from the new firmware are left open (the ring is silent on them,
17
+ * not disabling them).
16
18
  *
17
- * The mapper stays pure: no engine access, no clock reads beyond the
18
- * injected `now` (defaults to `new Date()` for production).
19
+ * Translation:
20
+ * The mapper cannot invent `data_type` integers or `start_time`/`end_time`
21
+ * strings on its own — those are consumer-specific enumerations. Callers
22
+ * MUST pass a `RingConfigTranslator` in `opts` (see `mapper/types.ts`).
23
+ * Without a translator the mapper cannot produce a schema-shaped row, so
24
+ * the option is required — TypeScript enforces this at every call site.
25
+ *
26
+ * The mapper stays pure: no engine access, no clock reads beyond the injected
27
+ * `now` (defaults to `new Date()` for production).
19
28
  */
20
- import type { DeviceConfigRow, FirmwareRingConfig, MapperContext } from './types';
29
+ import type { DeviceConfigRow, FirmwareRingConfig, MapperContext, RingConfigTranslator } from './types';
21
30
  export interface RingConfigClose {
22
- metric: string;
31
+ device_id: string;
32
+ data_type: number;
23
33
  valid_to: Date;
24
34
  }
25
35
  export interface MapRingConfigResult {
26
36
  inserts: DeviceConfigRow[];
27
37
  closes: RingConfigClose[];
28
38
  }
29
- export declare function mapRingConfig(fw: FirmwareRingConfig, ctx: MapperContext, opts?: {
39
+ export interface MapRingConfigOptions {
30
40
  now?: Date;
31
- activePriorConfigs?: ReadonlyMap<string, DeviceConfigRow>;
32
- }): MapRingConfigResult;
41
+ /** Prior open configs for this device, keyed by `data_type`. */
42
+ activePriorConfigs?: ReadonlyMap<number, DeviceConfigRow>;
43
+ /** Required — consumer-provided translation from firmware to schema. */
44
+ translator: RingConfigTranslator;
45
+ }
46
+ export declare function mapRingConfig(fw: FirmwareRingConfig, ctx: MapperContext, opts: MapRingConfigOptions): MapRingConfigResult;
33
47
  //# sourceMappingURL=ring-config.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ring-config.d.ts","sourceRoot":"","sources":["../../../src/sync/mapper/ring-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EACV,eAAe,EAEf,kBAAkB,EAClB,aAAa,EACd,MAAM,SAAS,CAAA;AAEhB,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,QAAQ,EAAE,IAAI,CAAA;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,eAAe,EAAE,CAAA;IAC1B,MAAM,EAAE,eAAe,EAAE,CAAA;CAC1B;AAED,wBAAgB,aAAa,CAC3B,EAAE,EAAE,kBAAkB,EACtB,GAAG,EAAE,aAAa,EAClB,IAAI,GAAE;IACJ,GAAG,CAAC,EAAE,IAAI,CAAA;IACV,kBAAkB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;CACrD,GACL,mBAAmB,CAerB"}
1
+ {"version":3,"file":"ring-config.d.ts","sourceRoot":"","sources":["../../../src/sync/mapper/ring-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,OAAO,KAAK,EACV,eAAe,EAEf,kBAAkB,EAClB,aAAa,EACb,oBAAoB,EACrB,MAAM,SAAS,CAAA;AAEhB,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,IAAI,CAAA;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,eAAe,EAAE,CAAA;IAC1B,MAAM,EAAE,eAAe,EAAE,CAAA;CAC1B;AAED,MAAM,WAAW,oBAAoB;IACnC,GAAG,CAAC,EAAE,IAAI,CAAA;IACV,gEAAgE;IAChE,kBAAkB,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,eAAe,CAAC,CAAA;IACzD,wEAAwE;IACxE,UAAU,EAAE,oBAAoB,CAAA;CACjC;AAED,wBAAgB,aAAa,CAC3B,EAAE,EAAE,kBAAkB,EACtB,GAAG,EAAE,aAAa,EAClB,IAAI,EAAE,oBAAoB,GACzB,mBAAmB,CAiBrB"}
@@ -7,40 +7,53 @@
7
7
  * the new insert.
8
8
  *
9
9
  * Closing prior config (SCD-2 semantics):
10
- * The mapper accepts an optional `activePriorConfigs` map keyed by metric
11
- * name. For every metric that shows up in the new firmware snapshot, if a
12
- * prior config was open, the mapper emits a `close` entry so the flusher
13
- * can `UPDATE ... SET valid_to = now()` before the INSERT lands. Metrics
14
- * present in the prior map but absent from the new firmware are left open
15
- * (the ring is silent on them, not disabling them).
10
+ * The mapper accepts an optional `activePriorConfigs` map keyed by
11
+ * `data_type` (integer, produced via the translator). For every metric that
12
+ * shows up in the new firmware snapshot, if a prior config was open, the
13
+ * mapper emits a `close` entry so the sink can `UPDATE ... SET valid_to =
14
+ * now()` locally before the INSERT lands, and enqueue the same directive
15
+ * for the next remote push cycle. Metrics present in the prior map but
16
+ * absent from the new firmware are left open (the ring is silent on them,
17
+ * not disabling them).
16
18
  *
17
- * The mapper stays pure: no engine access, no clock reads beyond the
18
- * injected `now` (defaults to `new Date()` for production).
19
+ * Translation:
20
+ * The mapper cannot invent `data_type` integers or `start_time`/`end_time`
21
+ * strings on its own — those are consumer-specific enumerations. Callers
22
+ * MUST pass a `RingConfigTranslator` in `opts` (see `mapper/types.ts`).
23
+ * Without a translator the mapper cannot produce a schema-shaped row, so
24
+ * the option is required — TypeScript enforces this at every call site.
25
+ *
26
+ * The mapper stays pure: no engine access, no clock reads beyond the injected
27
+ * `now` (defaults to `new Date()` for production).
19
28
  */
20
- export function mapRingConfig(fw, ctx, opts = {}) {
29
+ export function mapRingConfig(fw, ctx, opts) {
21
30
  const now = opts.now ?? new Date();
22
31
  const prior = opts.activePriorConfigs ?? new Map();
32
+ const translator = opts.translator;
23
33
  const inserts = [];
24
34
  const closes = [];
25
35
  for (const window of fw.automaticMonitoringData ?? []) {
26
- inserts.push(toRow(window, ctx, now));
27
- if (prior.has(window.metric)) {
28
- closes.push({ metric: window.metric, valid_to: now });
36
+ const dataType = translator.metricToDataType(window.metric);
37
+ inserts.push(toRow(window, ctx, now, dataType, translator));
38
+ if (prior.has(dataType)) {
39
+ closes.push({ device_id: ctx.deviceId, data_type: dataType, valid_to: now });
29
40
  }
30
41
  }
31
42
  return { inserts, closes };
32
43
  }
33
- function toRow(window, ctx, now) {
44
+ function toRow(window, ctx, now, dataType, translator) {
45
+ const fields = translator.windowToSchemaFields(window);
34
46
  return {
35
47
  ts: now,
36
48
  brand: ctx.brand,
37
49
  family_id: ctx.familyId,
38
50
  user_id: ctx.userId,
39
51
  device_id: ctx.deviceId,
40
- metric: window.metric,
52
+ data_type: dataType,
41
53
  interval_minutes: window.interval_minutes,
42
- start_hour: window.start_hour,
43
- end_hour: window.end_hour,
54
+ start_time: fields.start_time,
55
+ end_time: fields.end_time,
56
+ weeks: fields.weeks,
44
57
  valid_from: now,
45
58
  valid_to: null,
46
59
  };
@@ -1 +1 @@
1
- {"version":3,"file":"ring-config.js","sourceRoot":"","sources":["../../../src/sync/mapper/ring-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAmBH,MAAM,UAAU,aAAa,CAC3B,EAAsB,EACtB,GAAkB,EAClB,OAGI,EAAE;IAEN,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAA;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,IAAI,IAAI,GAAG,EAA2B,CAAA;IAE3E,MAAM,OAAO,GAAsB,EAAE,CAAA;IACrC,MAAM,MAAM,GAAsB,EAAE,CAAA;IAEpC,KAAK,MAAM,MAAM,IAAI,EAAE,CAAC,uBAAuB,IAAI,EAAE,EAAE,CAAC;QACtD,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,CAAC,CAAA;QACrC,IAAI,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YAC7B,MAAM,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAA;QACvD,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAA;AAC5B,CAAC;AAED,SAAS,KAAK,CACZ,MAAgC,EAChC,GAAkB,EAClB,GAAS;IAET,OAAO;QACL,EAAE,EAAE,GAAG;QACP,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,SAAS,EAAE,GAAG,CAAC,QAAQ;QACvB,OAAO,EAAE,GAAG,CAAC,MAAM;QACnB,SAAS,EAAE,GAAG,CAAC,QAAQ;QACvB,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,UAAU,EAAE,GAAG;QACf,QAAQ,EAAE,IAAI;KACf,CAAA;AACH,CAAC"}
1
+ {"version":3,"file":"ring-config.js","sourceRoot":"","sources":["../../../src/sync/mapper/ring-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AA6BH,MAAM,UAAU,aAAa,CAC3B,EAAsB,EACtB,GAAkB,EAClB,IAA0B;IAE1B,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,IAAI,EAAE,CAAA;IAClC,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,IAAI,IAAI,GAAG,EAA2B,CAAA;IAC3E,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAA;IAElC,MAAM,OAAO,GAAsB,EAAE,CAAA;IACrC,MAAM,MAAM,GAAsB,EAAE,CAAA;IAEpC,KAAK,MAAM,MAAM,IAAI,EAAE,CAAC,uBAAuB,IAAI,EAAE,EAAE,CAAC;QACtD,MAAM,QAAQ,GAAG,UAAU,CAAC,gBAAgB,CAAC,MAAM,CAAC,MAAM,CAAC,CAAA;QAC3D,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,GAAG,EAAE,GAAG,EAAE,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAA;QAC3D,IAAI,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxB,MAAM,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,GAAG,CAAC,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAA;QAC9E,CAAC;IACH,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,CAAA;AAC5B,CAAC;AAED,SAAS,KAAK,CACZ,MAAgC,EAChC,GAAkB,EAClB,GAAS,EACT,QAAgB,EAChB,UAAgC;IAEhC,MAAM,MAAM,GAAG,UAAU,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAA;IACtD,OAAO;QACL,EAAE,EAAE,GAAG;QACP,KAAK,EAAE,GAAG,CAAC,KAAK;QAChB,SAAS,EAAE,GAAG,CAAC,QAAQ;QACvB,OAAO,EAAE,GAAG,CAAC,MAAM;QACnB,SAAS,EAAE,GAAG,CAAC,QAAQ;QACvB,SAAS,EAAE,QAAQ;QACnB,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;QACzC,UAAU,EAAE,MAAM,CAAC,UAAU;QAC7B,QAAQ,EAAE,MAAM,CAAC,QAAQ;QACzB,KAAK,EAAE,MAAM,CAAC,KAAK;QACnB,UAAU,EAAE,GAAG;QACf,QAAQ,EAAE,IAAI;KACf,CAAA;AACH,CAAC"}
@@ -127,14 +127,46 @@ export interface DeviceEventRow extends BaseRow {
127
127
  event_type: string;
128
128
  payload: Record<string, unknown>;
129
129
  }
130
+ /**
131
+ * `device_config` warehouse row shape (SCD-2). Column names match the DDL in
132
+ * `core/schemas.ts` exactly so that a `row[c]` lookup keyed by
133
+ * `columnOrder.device_config` produces the correct positional appender input.
134
+ *
135
+ * Fields that the firmware doesn't natively speak in schema terms
136
+ * (`data_type`, `start_time`, `end_time`, `weeks`) are produced by a
137
+ * consumer-provided `RingConfigTranslator` (see below).
138
+ */
130
139
  export interface DeviceConfigRow extends BaseRow {
131
- metric: string;
140
+ data_type: number;
132
141
  interval_minutes: number;
133
- start_hour: number;
134
- end_hour: number;
142
+ start_time: string | null;
143
+ end_time: string | null;
144
+ weeks: number | null;
135
145
  valid_from: Date;
136
146
  valid_to: Date | null;
137
147
  }
148
+ /**
149
+ * Consumer-provided translation from firmware ring-config semantics to
150
+ * warehouse schema semantics. Required at `createSyncManager()` time whenever
151
+ * the subscribed tables include `'device_config'`.
152
+ *
153
+ * Split into three responsibilities so the mapper can:
154
+ * - materialize `data_type` per insert (`metricToDataType`);
155
+ * - key `activePriorConfigs` by `data_type` when reading local state
156
+ * (`dataTypeToMetric` — round-trips the enum for callers that want to
157
+ * surface metric names in logs or diagnostics);
158
+ * - compute the schema-shaped time fields per firmware window
159
+ * (`windowToSchemaFields`).
160
+ */
161
+ export interface RingConfigTranslator {
162
+ metricToDataType: (metric: string) => number;
163
+ dataTypeToMetric: (dataType: number) => string;
164
+ windowToSchemaFields: (window: FirmwareMonitoringWindow) => {
165
+ start_time: string | null;
166
+ end_time: string | null;
167
+ weeks: number | null;
168
+ };
169
+ }
138
170
  export interface MappedBatch {
139
171
  hrv: HrvRow[];
140
172
  heart_rate: HeartRateRow[];
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/sync/mapper/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/sync/mapper/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Pending SCD-2 closes queue (T-08 continuation).
3
+ *
4
+ * `mapRingConfig` emits `RingConfigClose[]` whenever a firmware ring-config
5
+ * snapshot supersedes a currently-open `device_config` row. Local UPDATE
6
+ * fires in-line inside `pushFirmware`; the remote UPDATE (against the
7
+ * Iceberg zone via DuckDB) runs on the next scheduler cycle so it inherits
8
+ * the same retry/backoff semantics as the INSERT pusher.
9
+ *
10
+ * Between those two moments the sink parks the close directives here. The
11
+ * enqueue happens *before* local UPDATE so a crash in between leaves a
12
+ * replay-safe record — the remote UPDATE is idempotent thanks to the
13
+ * `valid_to IS NULL` guard in `R2Pusher.pushCloses`.
14
+ *
15
+ * Key convention:
16
+ * `analytics:pending_closes:{brand}:{tenantId}` → JSON array of the
17
+ * serialized close shape.
18
+ *
19
+ * Serialization: `Date → ISO string`, restored to `Date` on drain.
20
+ */
21
+ import type { AttachContext, KVStore } from '../core/types';
22
+ import type { RingConfigClose } from './mapper/ring-config';
23
+ export declare class PendingClosesStore {
24
+ #private;
25
+ constructor(kv: KVStore);
26
+ enqueue(ctx: Pick<AttachContext, 'brand' | 'tenantId'>, closes: readonly RingConfigClose[]): Promise<void>;
27
+ drain(ctx: Pick<AttachContext, 'brand' | 'tenantId'>): Promise<RingConfigClose[]>;
28
+ requeue(ctx: Pick<AttachContext, 'brand' | 'tenantId'>, closes: readonly RingConfigClose[]): Promise<void>;
29
+ }
30
+ //# sourceMappingURL=pending_closes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pending_closes.d.ts","sourceRoot":"","sources":["../../src/sync/pending_closes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AAE3D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AA8B3D,qBAAa,kBAAkB;;gBAGjB,EAAE,EAAE,OAAO;IAIjB,OAAO,CACX,GAAG,EAAE,IAAI,CAAC,aAAa,EAAE,OAAO,GAAG,UAAU,CAAC,EAC9C,MAAM,EAAE,SAAS,eAAe,EAAE,GACjC,OAAO,CAAC,IAAI,CAAC;IAQV,KAAK,CACT,GAAG,EAAE,IAAI,CAAC,aAAa,EAAE,OAAO,GAAG,UAAU,CAAC,GAC7C,OAAO,CAAC,eAAe,EAAE,CAAC;IAQvB,OAAO,CACX,GAAG,EAAE,IAAI,CAAC,aAAa,EAAE,OAAO,GAAG,UAAU,CAAC,EAC9C,MAAM,EAAE,SAAS,eAAe,EAAE,GACjC,OAAO,CAAC,IAAI,CAAC;CAQjB"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Pending SCD-2 closes queue (T-08 continuation).
3
+ *
4
+ * `mapRingConfig` emits `RingConfigClose[]` whenever a firmware ring-config
5
+ * snapshot supersedes a currently-open `device_config` row. Local UPDATE
6
+ * fires in-line inside `pushFirmware`; the remote UPDATE (against the
7
+ * Iceberg zone via DuckDB) runs on the next scheduler cycle so it inherits
8
+ * the same retry/backoff semantics as the INSERT pusher.
9
+ *
10
+ * Between those two moments the sink parks the close directives here. The
11
+ * enqueue happens *before* local UPDATE so a crash in between leaves a
12
+ * replay-safe record — the remote UPDATE is idempotent thanks to the
13
+ * `valid_to IS NULL` guard in `R2Pusher.pushCloses`.
14
+ *
15
+ * Key convention:
16
+ * `analytics:pending_closes:{brand}:{tenantId}` → JSON array of the
17
+ * serialized close shape.
18
+ *
19
+ * Serialization: `Date → ISO string`, restored to `Date` on drain.
20
+ */
21
+ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
22
+ if (kind === "m") throw new TypeError("Private method is not writable");
23
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
24
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
25
+ return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
26
+ };
27
+ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
28
+ if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
29
+ if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
30
+ return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
31
+ };
32
+ var _PendingClosesStore_kv;
33
+ const KEY_PREFIX = 'analytics:pending_closes';
34
+ function key(ctx) {
35
+ return `${KEY_PREFIX}:${ctx.brand}:${ctx.tenantId}`;
36
+ }
37
+ function serialize(close) {
38
+ return {
39
+ device_id: close.device_id,
40
+ data_type: close.data_type,
41
+ valid_to: close.valid_to.toISOString(),
42
+ };
43
+ }
44
+ function deserialize(row) {
45
+ return {
46
+ device_id: row.device_id,
47
+ data_type: row.data_type,
48
+ valid_to: new Date(row.valid_to),
49
+ };
50
+ }
51
+ export class PendingClosesStore {
52
+ constructor(kv) {
53
+ _PendingClosesStore_kv.set(this, void 0);
54
+ __classPrivateFieldSet(this, _PendingClosesStore_kv, kv, "f");
55
+ }
56
+ async enqueue(ctx, closes) {
57
+ if (closes.length === 0)
58
+ return;
59
+ const k = key(ctx);
60
+ const existing = (await __classPrivateFieldGet(this, _PendingClosesStore_kv, "f").get(k)) ?? [];
61
+ const next = [...existing, ...closes.map(serialize)];
62
+ await __classPrivateFieldGet(this, _PendingClosesStore_kv, "f").set(k, next);
63
+ }
64
+ async drain(ctx) {
65
+ const k = key(ctx);
66
+ const rows = (await __classPrivateFieldGet(this, _PendingClosesStore_kv, "f").get(k)) ?? [];
67
+ if (rows.length === 0)
68
+ return [];
69
+ await __classPrivateFieldGet(this, _PendingClosesStore_kv, "f").delete(k);
70
+ return rows.map(deserialize);
71
+ }
72
+ async requeue(ctx, closes) {
73
+ if (closes.length === 0)
74
+ return;
75
+ const k = key(ctx);
76
+ const existing = (await __classPrivateFieldGet(this, _PendingClosesStore_kv, "f").get(k)) ?? [];
77
+ // Prepend the requeued closes so the next drain retries them first.
78
+ const next = [...closes.map(serialize), ...existing];
79
+ await __classPrivateFieldGet(this, _PendingClosesStore_kv, "f").set(k, next);
80
+ }
81
+ }
82
+ _PendingClosesStore_kv = new WeakMap();
83
+ //# sourceMappingURL=pending_closes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pending_closes.js","sourceRoot":"","sources":["../../src/sync/pending_closes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;;;;;;;;;;;;;AAMH,MAAM,UAAU,GAAG,0BAA0B,CAAA;AAQ7C,SAAS,GAAG,CAAC,GAA8C;IACzD,OAAO,GAAG,UAAU,IAAI,GAAG,CAAC,KAAK,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAA;AACrD,CAAC;AAED,SAAS,SAAS,CAAC,KAAsB;IACvC,OAAO;QACL,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,SAAS,EAAE,KAAK,CAAC,SAAS;QAC1B,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,WAAW,EAAE;KACvC,CAAA;AACH,CAAC;AAED,SAAS,WAAW,CAAC,GAAoB;IACvC,OAAO;QACL,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,QAAQ,EAAE,IAAI,IAAI,CAAC,GAAG,CAAC,QAAQ,CAAC;KACjC,CAAA;AACH,CAAC;AAED,MAAM,OAAO,kBAAkB;IAG7B,YAAY,EAAW;QAFd,yCAAY;QAGnB,uBAAA,IAAI,0BAAO,EAAE,MAAA,CAAA;IACf,CAAC;IAED,KAAK,CAAC,OAAO,CACX,GAA8C,EAC9C,MAAkC;QAElC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QAC/B,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;QAClB,MAAM,QAAQ,GAAG,CAAC,MAAM,uBAAA,IAAI,8BAAI,CAAC,GAAG,CAAoB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;QACjE,MAAM,IAAI,GAAG,CAAC,GAAG,QAAQ,EAAE,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAA;QACpD,MAAM,uBAAA,IAAI,8BAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;IAC7B,CAAC;IAED,KAAK,CAAC,KAAK,CACT,GAA8C;QAE9C,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;QAClB,MAAM,IAAI,GAAG,CAAC,MAAM,uBAAA,IAAI,8BAAI,CAAC,GAAG,CAAoB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;QAC7D,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAA;QAChC,MAAM,uBAAA,IAAI,8BAAI,CAAC,MAAM,CAAC,CAAC,CAAC,CAAA;QACxB,OAAO,IAAI,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;IAC9B,CAAC;IAED,KAAK,CAAC,OAAO,CACX,GAA8C,EAC9C,MAAkC;QAElC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;YAAE,OAAM;QAC/B,MAAM,CAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAA;QAClB,MAAM,QAAQ,GAAG,CAAC,MAAM,uBAAA,IAAI,8BAAI,CAAC,GAAG,CAAoB,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;QACjE,oEAAoE;QACpE,MAAM,IAAI,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,GAAG,QAAQ,CAAC,CAAA;QACpD,MAAM,uBAAA,IAAI,8BAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,CAAA;IAC7B,CAAC;CACF"}
@@ -19,6 +19,7 @@ import type { HybridDuckDB } from '../core/engine';
19
19
  import type { AttachContext } from '../core/types';
20
20
  import { SyncError } from './errors';
21
21
  import type { PushEmitter } from './events';
22
+ import type { RingConfigClose } from './mapper/ring-config';
22
23
  import type { WatermarkStore } from './watermark';
23
24
  export interface PushResult {
24
25
  table: string;
@@ -54,6 +55,26 @@ export declare class R2Pusher {
54
55
  #private;
55
56
  constructor(config: R2PusherConfig);
56
57
  push(table: string, ctx: AttachContext): Promise<PushResult>;
58
+ /**
59
+ * SCD-2 close directives → remote UPDATE (T-08 continuation).
60
+ *
61
+ * Each close becomes:
62
+ * UPDATE <remote>.device_config
63
+ * SET valid_to = $valid_to
64
+ * WHERE device_id = $device_id
65
+ * AND data_type = $data_type
66
+ * AND family_id = $family_id
67
+ * AND valid_to IS NULL
68
+ *
69
+ * The `valid_to IS NULL` guard makes replaying the same close a no-op,
70
+ * which is what lets the `PendingClosesStore` + scheduler retry cycle
71
+ * survive crashes between local UPDATE and remote UPDATE.
72
+ *
73
+ * 401 handling mirrors `#pushOrCatch`: one `refreshToken()` + retry, then
74
+ * surface `token_expired`. Other errors surface `push_failed` and leave
75
+ * the caller responsible for requeueing.
76
+ */
77
+ pushCloses(closes: readonly RingConfigClose[], ctx: AttachContext): Promise<PushResult>;
57
78
  pushAll(tables: readonly string[], ctx: AttachContext): Promise<PushResult[]>;
58
79
  }
59
80
  //# sourceMappingURL=pusher.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pusher.d.ts","sourceRoot":"","sources":["../../src/sync/pusher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAC3C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,EAAE,EAAE,OAAO,CAAA;IACX,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,YAAY,CAAA;IACpB,SAAS,EAAE,cAAc,CAAA;IACzB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAClC;;;OAGG;IACH,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAA;IACjC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IAC1D,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IAC3D;;;OAGG;IACH,IAAI,CAAC,EAAE,WAAW,CAAA;CACnB;AAYD,qBAAa,QAAQ;;gBASP,MAAM,EAAE,cAAc;IAU5B,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC;IAwB5D,OAAO,CACX,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,GAAG,EAAE,aAAa,GACjB,OAAO,CAAC,UAAU,EAAE,CAAC;CAkEzB"}
1
+ {"version":3,"file":"pusher.d.ts","sourceRoot":"","sources":["../../src/sync/pusher.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAA;AAElD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,UAAU,CAAA;AACpC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAC3D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAEjD,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,MAAM,CAAA;IACb,UAAU,EAAE,MAAM,CAAA;IAClB,EAAE,EAAE,OAAO,CAAA;IACX,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,YAAY,CAAA;IACpB,SAAS,EAAE,cAAc,CAAA;IACzB,6EAA6E;IAC7E,YAAY,CAAC,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;IAClC;;;OAGG;IACH,KAAK,CAAC,EAAE,CAAC,GAAG,EAAE,OAAO,KAAK,OAAO,CAAA;IACjC;;;;;OAKG;IACH,UAAU,CAAC,EAAE,CAAC,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IAC1D,WAAW,CAAC,EAAE,CAAC,GAAG,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,KAAK,MAAM,CAAA;IAC3D;;;OAGG;IACH,IAAI,CAAC,EAAE,WAAW,CAAA;CACnB;AAYD,qBAAa,QAAQ;;gBASP,MAAM,EAAE,cAAc;IAU5B,IAAI,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,aAAa,GAAG,OAAO,CAAC,UAAU,CAAC;IAwBlE;;;;;;;;;;;;;;;;;;OAkBG;IACG,UAAU,CACd,MAAM,EAAE,SAAS,eAAe,EAAE,EAClC,GAAG,EAAE,aAAa,GACjB,OAAO,CAAC,UAAU,CAAC;IAiDhB,OAAO,CACX,MAAM,EAAE,SAAS,MAAM,EAAE,EACzB,GAAG,EAAE,aAAa,GACjB,OAAO,CAAC,UAAU,EAAE,CAAC;CAmEzB"}
@@ -26,7 +26,8 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
26
26
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
27
27
  return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
28
28
  };
29
- var _R2Pusher_instances, _R2Pusher_engine, _R2Pusher_watermark, _R2Pusher_refreshToken, _R2Pusher_is401, _R2Pusher_localTable, _R2Pusher_remoteTable, _R2Pusher_emit, _R2Pusher_pushOrCatch, _R2Pusher_pushOnce, _R2Pusher_toFailure;
29
+ var _R2Pusher_instances, _R2Pusher_engine, _R2Pusher_watermark, _R2Pusher_refreshToken, _R2Pusher_is401, _R2Pusher_localTable, _R2Pusher_remoteTable, _R2Pusher_emit, _R2Pusher_pushOrCatch, _R2Pusher_pushClosesOrCatch, _R2Pusher_pushClosesOnce, _R2Pusher_pushOnce, _R2Pusher_toFailure;
30
+ import { timeColumnFor } from '../core/table_metadata';
30
31
  import { SyncError } from './errors';
31
32
  const DEFAULT_IS_401 = (err) => {
32
33
  if (!err || typeof err !== 'object')
@@ -59,6 +60,30 @@ export class R2Pusher {
59
60
  __classPrivateFieldGet(this, _R2Pusher_emit, "f")?.call(this, result);
60
61
  return result;
61
62
  }
63
+ /**
64
+ * SCD-2 close directives → remote UPDATE (T-08 continuation).
65
+ *
66
+ * Each close becomes:
67
+ * UPDATE <remote>.device_config
68
+ * SET valid_to = $valid_to
69
+ * WHERE device_id = $device_id
70
+ * AND data_type = $data_type
71
+ * AND family_id = $family_id
72
+ * AND valid_to IS NULL
73
+ *
74
+ * The `valid_to IS NULL` guard makes replaying the same close a no-op,
75
+ * which is what lets the `PendingClosesStore` + scheduler retry cycle
76
+ * survive crashes between local UPDATE and remote UPDATE.
77
+ *
78
+ * 401 handling mirrors `#pushOrCatch`: one `refreshToken()` + retry, then
79
+ * surface `token_expired`. Other errors surface `push_failed` and leave
80
+ * the caller responsible for requeueing.
81
+ */
82
+ async pushCloses(closes, ctx) {
83
+ const result = await __classPrivateFieldGet(this, _R2Pusher_instances, "m", _R2Pusher_pushClosesOrCatch).call(this, closes, ctx);
84
+ __classPrivateFieldGet(this, _R2Pusher_emit, "f")?.call(this, result);
85
+ return result;
86
+ }
62
87
  async pushAll(tables, ctx) {
63
88
  const settled = await Promise.allSettled(tables.map(t => this.push(t, ctx)));
64
89
  return settled.map((r, i) => {
@@ -87,18 +112,49 @@ _R2Pusher_engine = new WeakMap(), _R2Pusher_watermark = new WeakMap(), _R2Pusher
87
112
  }
88
113
  return __classPrivateFieldGet(this, _R2Pusher_instances, "m", _R2Pusher_toFailure).call(this, table, err, 'push_failed');
89
114
  }
115
+ }, _R2Pusher_pushClosesOrCatch = async function _R2Pusher_pushClosesOrCatch(closes, ctx) {
116
+ try {
117
+ return await __classPrivateFieldGet(this, _R2Pusher_instances, "m", _R2Pusher_pushClosesOnce).call(this, closes, ctx);
118
+ }
119
+ catch (err) {
120
+ if (__classPrivateFieldGet(this, _R2Pusher_is401, "f").call(this, err) && __classPrivateFieldGet(this, _R2Pusher_refreshToken, "f")) {
121
+ try {
122
+ await __classPrivateFieldGet(this, _R2Pusher_refreshToken, "f").call(this);
123
+ return await __classPrivateFieldGet(this, _R2Pusher_instances, "m", _R2Pusher_pushClosesOnce).call(this, closes, ctx);
124
+ }
125
+ catch (retryErr) {
126
+ return __classPrivateFieldGet(this, _R2Pusher_instances, "m", _R2Pusher_toFailure).call(this, 'device_config', retryErr, 'token_expired');
127
+ }
128
+ }
129
+ return __classPrivateFieldGet(this, _R2Pusher_instances, "m", _R2Pusher_toFailure).call(this, 'device_config', err, 'push_failed');
130
+ }
131
+ }, _R2Pusher_pushClosesOnce = async function _R2Pusher_pushClosesOnce(closes, ctx) {
132
+ if (closes.length === 0) {
133
+ return { table: 'device_config', rowsPushed: 0, ok: true };
134
+ }
135
+ const remote = __classPrivateFieldGet(this, _R2Pusher_remoteTable, "f").call(this, ctx, 'device_config');
136
+ for (const close of closes) {
137
+ await __classPrivateFieldGet(this, _R2Pusher_engine, "f").execute(`UPDATE ${remote} SET valid_to = $valid_to WHERE device_id = $device_id AND data_type = $data_type AND family_id = $family_id AND valid_to IS NULL`, {
138
+ valid_to: close.valid_to.toISOString(),
139
+ device_id: close.device_id,
140
+ data_type: close.data_type,
141
+ family_id: ctx.tenantId,
142
+ });
143
+ }
144
+ return { table: 'device_config', rowsPushed: closes.length, ok: true };
90
145
  }, _R2Pusher_pushOnce = async function _R2Pusher_pushOnce(table, ctx) {
146
+ const tsCol = timeColumnFor(table);
91
147
  const watermark = await __classPrivateFieldGet(this, _R2Pusher_watermark, "f").get(ctx.brand, ctx.tenantId, table, 'push');
92
148
  const local = __classPrivateFieldGet(this, _R2Pusher_localTable, "f").call(this, ctx, table);
93
149
  const remote = __classPrivateFieldGet(this, _R2Pusher_remoteTable, "f").call(this, ctx, table);
94
150
  // Max ts to advance the watermark to. Null result → no new rows.
95
- const maxRows = await __classPrivateFieldGet(this, _R2Pusher_engine, "f").execute(`SELECT MAX(ts) AS max_ts, COUNT(*) AS row_count FROM ${local} WHERE ts > $watermark AND family_id = $familyId`, { watermark: watermark.toISOString(), familyId: ctx.tenantId });
151
+ const maxRows = await __classPrivateFieldGet(this, _R2Pusher_engine, "f").execute(`SELECT MAX(${tsCol}) AS max_ts, COUNT(*) AS row_count FROM ${local} WHERE ${tsCol} > $watermark AND family_id = $familyId`, { watermark: watermark.toISOString(), familyId: ctx.tenantId });
96
152
  const first = maxRows[0];
97
153
  const rowCount = Number(first?.row_count ?? 0);
98
154
  if (rowCount === 0) {
99
155
  return { table, rowsPushed: 0, ok: true };
100
156
  }
101
- await __classPrivateFieldGet(this, _R2Pusher_engine, "f").execute(`INSERT INTO ${remote} SELECT * FROM ${local} WHERE ts > $watermark AND family_id = $familyId`, { watermark: watermark.toISOString(), familyId: ctx.tenantId });
157
+ await __classPrivateFieldGet(this, _R2Pusher_engine, "f").execute(`INSERT INTO ${remote} SELECT * FROM ${local} WHERE ${tsCol} > $watermark AND family_id = $familyId`, { watermark: watermark.toISOString(), familyId: ctx.tenantId });
102
158
  if (first?.max_ts) {
103
159
  const nextWatermark = new Date(first.max_ts);
104
160
  if (!Number.isNaN(nextWatermark.getTime())) {
@@ -1 +1 @@
1
- {"version":3,"file":"pusher.js","sourceRoot":"","sources":["../../src/sync/pusher.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"pusher.js","sourceRoot":"","sources":["../../src/sync/pusher.ts"],"names":[],"mappings":"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"}