@nanolink/operational-model 0.1.0 → 0.1.2

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 (119) hide show
  1. package/README.md +27 -2
  2. package/dist/aerospike/impl/closedLink.d.ts +17 -0
  3. package/dist/aerospike/impl/closedLink.js +56 -0
  4. package/dist/aerospike/impl/closedLink.js.map +1 -0
  5. package/dist/aerospike/impl/common.d.ts +16 -0
  6. package/dist/aerospike/impl/common.js +120 -0
  7. package/dist/aerospike/impl/common.js.map +1 -0
  8. package/dist/aerospike/impl/contained.d.ts +14 -0
  9. package/dist/aerospike/impl/contained.js +44 -0
  10. package/dist/aerospike/impl/contained.js.map +1 -0
  11. package/dist/aerospike/impl/deltaRssi.d.ts +12 -0
  12. package/dist/aerospike/impl/deltaRssi.js +38 -0
  13. package/dist/aerospike/impl/deltaRssi.js.map +1 -0
  14. package/dist/aerospike/impl/factory.d.ts +28 -0
  15. package/dist/aerospike/impl/factory.js +27 -0
  16. package/dist/aerospike/impl/factory.js.map +1 -0
  17. package/dist/aerospike/impl/gps.d.ts +16 -0
  18. package/dist/aerospike/impl/gps.js +45 -0
  19. package/dist/aerospike/impl/gps.js.map +1 -0
  20. package/dist/aerospike/impl/index.d.ts +11 -0
  21. package/dist/aerospike/impl/index.js +12 -0
  22. package/dist/aerospike/impl/index.js.map +1 -0
  23. package/dist/aerospike/impl/rssi.d.ts +14 -0
  24. package/dist/aerospike/impl/rssi.js +42 -0
  25. package/dist/aerospike/impl/rssi.js.map +1 -0
  26. package/dist/aerospike/impl/stateLink.d.ts +13 -0
  27. package/dist/aerospike/impl/stateLink.js +42 -0
  28. package/dist/aerospike/impl/stateLink.js.map +1 -0
  29. package/dist/aerospike/impl/stateTrip.d.ts +9 -0
  30. package/dist/aerospike/impl/stateTrip.js +42 -0
  31. package/dist/aerospike/impl/stateTrip.js.map +1 -0
  32. package/dist/aerospike/impl/states.d.ts +10 -0
  33. package/dist/aerospike/impl/states.js +68 -0
  34. package/dist/aerospike/impl/states.js.map +1 -0
  35. package/dist/aerospike/impl/transmitterPosition.d.ts +9 -0
  36. package/dist/aerospike/impl/transmitterPosition.js +32 -0
  37. package/dist/aerospike/impl/transmitterPosition.js.map +1 -0
  38. package/dist/aerospike/impl/trip.d.ts +10 -0
  39. package/dist/aerospike/impl/trip.js +41 -0
  40. package/dist/aerospike/impl/trip.js.map +1 -0
  41. package/dist/aerospike/impl.d.ts +1 -114
  42. package/dist/aerospike/impl.js +1 -564
  43. package/dist/aerospike/impl.js.map +1 -1
  44. package/dist/aerospike/models/closedLink.d.ts +8 -0
  45. package/dist/aerospike/models/closedLink.js +2 -0
  46. package/dist/aerospike/models/closedLink.js.map +1 -0
  47. package/dist/aerospike/models/contained.d.ts +8 -0
  48. package/dist/aerospike/models/contained.js +2 -0
  49. package/dist/aerospike/models/contained.js.map +1 -0
  50. package/dist/aerospike/models/deltaRssi.d.ts +9 -0
  51. package/dist/aerospike/models/deltaRssi.js +2 -0
  52. package/dist/aerospike/models/deltaRssi.js.map +1 -0
  53. package/dist/aerospike/models/gps.d.ts +12 -0
  54. package/dist/aerospike/models/gps.js +2 -0
  55. package/dist/aerospike/models/gps.js.map +1 -0
  56. package/dist/aerospike/models/rssi.d.ts +8 -0
  57. package/dist/aerospike/models/rssi.js +2 -0
  58. package/dist/aerospike/models/rssi.js.map +1 -0
  59. package/dist/aerospike/models/stateLink.d.ts +11 -0
  60. package/dist/aerospike/models/stateLink.js +2 -0
  61. package/dist/aerospike/models/stateLink.js.map +1 -0
  62. package/dist/aerospike/models/stateTrip.d.ts +12 -0
  63. package/dist/aerospike/models/stateTrip.js +2 -0
  64. package/dist/aerospike/models/stateTrip.js.map +1 -0
  65. package/dist/aerospike/models/states.d.ts +12 -0
  66. package/dist/aerospike/models/states.js +2 -0
  67. package/dist/aerospike/models/states.js.map +1 -0
  68. package/dist/aerospike/models/timeRange.d.ts +4 -0
  69. package/dist/aerospike/models/timeRange.js +2 -0
  70. package/dist/aerospike/models/timeRange.js.map +1 -0
  71. package/dist/aerospike/models/transmitterPosition.d.ts +8 -0
  72. package/dist/aerospike/models/transmitterPosition.js +2 -0
  73. package/dist/aerospike/models/transmitterPosition.js.map +1 -0
  74. package/dist/aerospike/models/trip.d.ts +10 -0
  75. package/dist/aerospike/models/trip.js +2 -0
  76. package/dist/aerospike/models/trip.js.map +1 -0
  77. package/dist/aerospike/models.d.ts +11 -99
  78. package/dist/aerospike/models.js +11 -2
  79. package/dist/aerospike/models.js.map +1 -1
  80. package/dist/aerospike/repositories/closedLink.d.ts +12 -0
  81. package/dist/aerospike/repositories/closedLink.js +2 -0
  82. package/dist/aerospike/repositories/closedLink.js.map +1 -0
  83. package/dist/aerospike/repositories/contained.d.ts +9 -0
  84. package/dist/aerospike/repositories/contained.js +2 -0
  85. package/dist/aerospike/repositories/contained.js.map +1 -0
  86. package/dist/aerospike/repositories/deltaRssi.d.ts +7 -0
  87. package/dist/aerospike/repositories/deltaRssi.js +2 -0
  88. package/dist/aerospike/repositories/deltaRssi.js.map +1 -0
  89. package/dist/aerospike/repositories/gps.d.ts +11 -0
  90. package/dist/aerospike/repositories/gps.js +2 -0
  91. package/dist/aerospike/repositories/gps.js.map +1 -0
  92. package/dist/aerospike/repositories/rssi.d.ts +9 -0
  93. package/dist/aerospike/repositories/rssi.js +2 -0
  94. package/dist/aerospike/repositories/rssi.js.map +1 -0
  95. package/dist/aerospike/repositories/stateLink.d.ts +8 -0
  96. package/dist/aerospike/repositories/stateLink.js +2 -0
  97. package/dist/aerospike/repositories/stateLink.js.map +1 -0
  98. package/dist/aerospike/repositories/stateTrip.d.ts +4 -0
  99. package/dist/aerospike/repositories/stateTrip.js +2 -0
  100. package/dist/aerospike/repositories/stateTrip.js.map +1 -0
  101. package/dist/aerospike/repositories/states.d.ts +5 -0
  102. package/dist/aerospike/repositories/states.js +2 -0
  103. package/dist/aerospike/repositories/states.js.map +1 -0
  104. package/dist/aerospike/repositories/transmitterPosition.d.ts +4 -0
  105. package/dist/aerospike/repositories/transmitterPosition.js +2 -0
  106. package/dist/aerospike/repositories/transmitterPosition.js.map +1 -0
  107. package/dist/aerospike/repositories/trip.d.ts +5 -0
  108. package/dist/aerospike/repositories/trip.js +2 -0
  109. package/dist/aerospike/repositories/trip.js.map +1 -0
  110. package/dist/aerospike/repositories.d.ts +20 -65
  111. package/dist/aerospike/repositories.js +10 -3
  112. package/dist/aerospike/repositories.js.map +1 -1
  113. package/dist/index.d.ts +1 -0
  114. package/dist/index.js +1 -0
  115. package/dist/index.js.map +1 -1
  116. package/dist/nats/subscriber.d.ts +23 -0
  117. package/dist/nats/subscriber.js +86 -0
  118. package/dist/nats/subscriber.js.map +1 -0
  119. package/package.json +3 -2
package/README.md CHANGED
@@ -5,7 +5,7 @@ TypeScript package providing read-only Aerospike repository interfaces and imple
5
5
  ## Install
6
6
 
7
7
  ```bash
8
- npm install
8
+ npm install @nanolink/operational-model
9
9
  ```
10
10
 
11
11
  ## Usage (read-only)
@@ -16,7 +16,7 @@ import {
16
16
  createRepositories,
17
17
  AerospikeRepositories,
18
18
  AerospikeModels,
19
- } from 'operational_model';
19
+ } from '@nanolink/operational-model';
20
20
 
21
21
  async function main() {
22
22
  const client = await createAerospikeClient({
@@ -38,6 +38,11 @@ async function main() {
38
38
  // GPS with derived speeds
39
39
  const gpsWithSpeed = await repos.gps.queryWithSpeed('device-123');
40
40
 
41
+ // Stream without buffering the entire result set
42
+ for await (const r of repos.rssi.streamAll()) {
43
+ console.log(r);
44
+ }
45
+
41
46
  console.log({ states, links, rssi, gpsWithSpeed });
42
47
 
43
48
  client.close();
@@ -58,3 +63,23 @@ main().catch((err) => {
58
63
  ## Notes
59
64
  - The package is read-only: repository implementations do not perform writes or emit events.
60
65
  - Uses msgpack for decoding embedded payloads; ensure Aerospike bins match the schema in `spec.md`.
66
+
67
+ ## NATS subscription helper
68
+
69
+ The package also includes a NATS subscriber utility using msgpack decoding by default:
70
+
71
+ ```ts
72
+ import { connect } from 'nats';
73
+ import { NatsSubscriber } from '@nanolink/operational-model';
74
+
75
+ async function listen() {
76
+ const conn = await connect({ servers: 'nats://localhost:4222' });
77
+ const sub = new NatsSubscriber<{ foo: string }>(conn, 'events');
78
+
79
+ for await (const { topic, data } of sub.subscribeGenerator()) {
80
+ console.log(topic, data);
81
+ }
82
+ }
83
+
84
+ listen();
85
+ ```
@@ -0,0 +1,17 @@
1
+ import { type AerospikeClient } from './common';
2
+ import { type ClosedLinkWithId } from '../models';
3
+ import { type ClosedLinkRepository } from '../repositories';
4
+ export declare class ClosedLinkRepositoryImpl implements ClosedLinkRepository {
5
+ private client;
6
+ private namespace;
7
+ constructor(client: AerospikeClient, namespace: string);
8
+ queryByKey(receiverTransmitter: string): Promise<ClosedLinkWithId[]>;
9
+ queryByReceiver(receiverId: string): Promise<ClosedLinkWithId[]>;
10
+ queryByTransmitter(transmitterId: string): Promise<ClosedLinkWithId[]>;
11
+ countByReceiver(receiverId: string): Promise<number>;
12
+ countByTransmitter(transmitterId: string): Promise<number>;
13
+ uniqueTransmitters(receiverId: string): Promise<string[]>;
14
+ streamByKey(receiverTransmitter: string): AsyncGenerator<ClosedLinkWithId>;
15
+ streamByReceiver(receiverId: string): AsyncGenerator<ClosedLinkWithId>;
16
+ streamByTransmitter(transmitterId: string): AsyncGenerator<ClosedLinkWithId>;
17
+ }
@@ -0,0 +1,56 @@
1
+ import { Aerospike, streamQuery, streamQueryGenerator, asNumber } from './common';
2
+ function decodeClosedLink(record) {
3
+ const b = record.bins;
4
+ return {
5
+ receiverId: b.r,
6
+ transmitterId: b.t,
7
+ start: asNumber(b.stamp) ?? 0,
8
+ end: asNumber(b.v) ?? 0,
9
+ };
10
+ }
11
+ export class ClosedLinkRepositoryImpl {
12
+ constructor(client, namespace) {
13
+ this.client = client;
14
+ this.namespace = namespace;
15
+ }
16
+ async queryByKey(receiverTransmitter) {
17
+ const where = Aerospike.filter.equal('rt', receiverTransmitter);
18
+ const records = await streamQuery(this.client, this.namespace, 'lp_closed', where);
19
+ return records.map(decodeClosedLink);
20
+ }
21
+ async queryByReceiver(receiverId) {
22
+ const where = Aerospike.filter.equal('r', receiverId);
23
+ const records = await streamQuery(this.client, this.namespace, 'lp_closed', where);
24
+ return records.map(decodeClosedLink);
25
+ }
26
+ async queryByTransmitter(transmitterId) {
27
+ const where = Aerospike.filter.equal('t', transmitterId);
28
+ const records = await streamQuery(this.client, this.namespace, 'lp_closed', where);
29
+ return records.map(decodeClosedLink);
30
+ }
31
+ async countByReceiver(receiverId) {
32
+ const items = await this.queryByReceiver(receiverId);
33
+ return items.length;
34
+ }
35
+ async countByTransmitter(transmitterId) {
36
+ const items = await this.queryByTransmitter(transmitterId);
37
+ return items.length;
38
+ }
39
+ async uniqueTransmitters(receiverId) {
40
+ const items = await this.queryByReceiver(receiverId);
41
+ return Array.from(new Set(items.map((x) => x.transmitterId)));
42
+ }
43
+ streamByKey(receiverTransmitter) {
44
+ const where = Aerospike.filter.equal('rt', receiverTransmitter);
45
+ return streamQueryGenerator(this.client, this.namespace, 'lp_closed', where, decodeClosedLink);
46
+ }
47
+ streamByReceiver(receiverId) {
48
+ const where = Aerospike.filter.equal('r', receiverId);
49
+ return streamQueryGenerator(this.client, this.namespace, 'lp_closed', where, decodeClosedLink);
50
+ }
51
+ streamByTransmitter(transmitterId) {
52
+ const where = Aerospike.filter.equal('t', transmitterId);
53
+ return streamQueryGenerator(this.client, this.namespace, 'lp_closed', where, decodeClosedLink);
54
+ }
55
+ }
56
+ //# sourceMappingURL=closedLink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"closedLink.js","sourceRoot":"","sources":["../../../src/aerospike/impl/closedLink.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import * as Aerospike from 'aerospike';
2
+ import { type GPSPosition } from '../models';
3
+ export type AerospikeClient = any;
4
+ export type AerospikeRecord = any;
5
+ export type AerospikeQuery = any;
6
+ export declare const toKey: (namespace: string, set: string, userKey: string) => any;
7
+ export declare function streamQuery(client: AerospikeClient, namespace: string, setName: string, where?: any): Promise<AerospikeRecord[]>;
8
+ export declare function streamQueryGenerator<T>(client: AerospikeClient, namespace: string, setName: string, where: any | undefined, map: (record: AerospikeRecord) => T | null): AsyncGenerator<T>;
9
+ export declare function decodeMsgpack<T>(value: any): T | null;
10
+ export declare function asNumber(value: any): number | undefined;
11
+ export declare function decodeGPSPosition(raw: any): GPSPosition | undefined;
12
+ export declare function sortByStampAscending<T extends {
13
+ stamp: number;
14
+ }>(items: T[]): T[];
15
+ export declare function haversineMeters(a: GPSPosition, b: GPSPosition): number;
16
+ export { Aerospike };
@@ -0,0 +1,120 @@
1
+ import * as Aerospike from 'aerospike';
2
+ import { decode as msgpackDecode } from '@msgpack/msgpack';
3
+ export const toKey = (namespace, set, userKey) => new Aerospike.Key(namespace, set, userKey);
4
+ export async function streamQuery(client, namespace, setName, where) {
5
+ const query = client.query(namespace, setName);
6
+ if (where) {
7
+ query.where(where);
8
+ }
9
+ return new Promise((resolve, reject) => {
10
+ const results = [];
11
+ const stream = query.foreach();
12
+ stream.on('data', (record) => results.push(record));
13
+ stream.on('error', (err) => reject(err));
14
+ stream.on('end', () => resolve(results));
15
+ });
16
+ }
17
+ export async function* streamQueryGenerator(client, namespace, setName, where, map) {
18
+ const query = client.query(namespace, setName);
19
+ if (where) {
20
+ query.where(where);
21
+ }
22
+ const buffer = [];
23
+ let ended = false;
24
+ let error;
25
+ const stream = query.foreach();
26
+ stream.on('data', (record) => {
27
+ const mapped = map(record);
28
+ if (mapped !== null) {
29
+ buffer.push(mapped);
30
+ }
31
+ });
32
+ stream.on('error', (err) => {
33
+ error = err;
34
+ ended = true;
35
+ });
36
+ stream.on('end', () => {
37
+ ended = true;
38
+ });
39
+ while (!ended || buffer.length > 0) {
40
+ if (buffer.length > 0) {
41
+ yield buffer.shift();
42
+ continue;
43
+ }
44
+ if (error) {
45
+ throw error;
46
+ }
47
+ await new Promise((res) => setTimeout(res, 10));
48
+ }
49
+ if (error) {
50
+ throw error;
51
+ }
52
+ }
53
+ export function decodeMsgpack(value) {
54
+ if (!value)
55
+ return null;
56
+ try {
57
+ if (value instanceof Uint8Array) {
58
+ return msgpackDecode(value);
59
+ }
60
+ if (Buffer.isBuffer(value)) {
61
+ return msgpackDecode(value);
62
+ }
63
+ return msgpackDecode(Uint8Array.from(value));
64
+ }
65
+ catch {
66
+ return null;
67
+ }
68
+ }
69
+ export function asNumber(value) {
70
+ if (typeof value === 'number')
71
+ return value;
72
+ if (typeof value === 'string') {
73
+ const parsed = Number(value);
74
+ return Number.isNaN(parsed) ? undefined : parsed;
75
+ }
76
+ return undefined;
77
+ }
78
+ export function decodeGPSPosition(raw) {
79
+ if (!raw)
80
+ return undefined;
81
+ if (Array.isArray(raw)) {
82
+ const [stamp, lon, lat, alt, speed, bearing, accuracy] = raw;
83
+ return {
84
+ stamp: asNumber(stamp) ?? 0,
85
+ longitude: asNumber(lon) ?? 0,
86
+ latitude: asNumber(lat) ?? 0,
87
+ altitude: alt == null ? undefined : asNumber(alt),
88
+ speed: speed == null ? undefined : asNumber(speed),
89
+ bearing: bearing == null ? undefined : asNumber(bearing),
90
+ accuracy: accuracy == null ? undefined : asNumber(accuracy),
91
+ };
92
+ }
93
+ return {
94
+ stamp: asNumber(raw.stamp ?? raw.Stamp) ?? 0,
95
+ longitude: asNumber(raw.longitude ?? raw.Longitude) ?? 0,
96
+ latitude: asNumber(raw.latitude ?? raw.Latitude) ?? 0,
97
+ altitude: raw.altitude ?? raw.Altitude,
98
+ speed: raw.speed ?? raw.Speed,
99
+ bearing: raw.bearing ?? raw.Bearing,
100
+ accuracy: raw.accuracy ?? raw.Accuracy,
101
+ };
102
+ }
103
+ export function sortByStampAscending(items) {
104
+ return [...items].sort((a, b) => (a.stamp ?? 0) - (b.stamp ?? 0));
105
+ }
106
+ export function haversineMeters(a, b) {
107
+ const toRad = (deg) => (deg * Math.PI) / 180;
108
+ const R = 6371000;
109
+ const dLat = toRad((b.latitude ?? 0) - (a.latitude ?? 0));
110
+ const dLon = toRad((b.longitude ?? 0) - (a.longitude ?? 0));
111
+ const lat1 = toRad(a.latitude ?? 0);
112
+ const lat2 = toRad(b.latitude ?? 0);
113
+ const sinDLat = Math.sin(dLat / 2);
114
+ const sinDLon = Math.sin(dLon / 2);
115
+ const h = sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon;
116
+ const c = 2 * Math.atan2(Math.sqrt(h), Math.sqrt(1 - h));
117
+ return R * c;
118
+ }
119
+ export { Aerospike };
120
+ //# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../../src/aerospike/impl/common.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { type AerospikeClient } from './common';
2
+ import { type ContainedWithId } from '../models';
3
+ import { type ContainedRepository } from '../repositories';
4
+ export declare class ContainedRepositoryImpl implements ContainedRepository {
5
+ private client;
6
+ private namespace;
7
+ constructor(client: AerospikeClient, namespace: string);
8
+ queryByKey(receiverTransmitter: string): Promise<ContainedWithId[]>;
9
+ queryByTransmitter(transmitterId: string): Promise<ContainedWithId[]>;
10
+ queryByReceiver(receiverId: string): Promise<ContainedWithId[]>;
11
+ streamByKey(receiverTransmitter: string): AsyncGenerator<ContainedWithId>;
12
+ streamByTransmitter(transmitterId: string): AsyncGenerator<ContainedWithId>;
13
+ streamByReceiver(receiverId: string): AsyncGenerator<ContainedWithId>;
14
+ }
@@ -0,0 +1,44 @@
1
+ import { Aerospike, streamQuery, streamQueryGenerator, asNumber } from './common';
2
+ function decodeContained(record) {
3
+ const b = record.bins;
4
+ return {
5
+ receiverId: b.r,
6
+ transmitterId: b.t,
7
+ start: asNumber(b.st) ?? 0,
8
+ end: asNumber(b.en) ?? 0,
9
+ };
10
+ }
11
+ export class ContainedRepositoryImpl {
12
+ constructor(client, namespace) {
13
+ this.client = client;
14
+ this.namespace = namespace;
15
+ }
16
+ async queryByKey(receiverTransmitter) {
17
+ const where = Aerospike.filter.equal('rt', receiverTransmitter);
18
+ const records = await streamQuery(this.client, this.namespace, 'contained', where);
19
+ return records.map(decodeContained);
20
+ }
21
+ async queryByTransmitter(transmitterId) {
22
+ const where = Aerospike.filter.equal('t', transmitterId);
23
+ const records = await streamQuery(this.client, this.namespace, 'contained', where);
24
+ return records.map(decodeContained);
25
+ }
26
+ async queryByReceiver(receiverId) {
27
+ const where = Aerospike.filter.equal('r', receiverId);
28
+ const records = await streamQuery(this.client, this.namespace, 'contained', where);
29
+ return records.map(decodeContained);
30
+ }
31
+ streamByKey(receiverTransmitter) {
32
+ const where = Aerospike.filter.equal('rt', receiverTransmitter);
33
+ return streamQueryGenerator(this.client, this.namespace, 'contained', where, decodeContained);
34
+ }
35
+ streamByTransmitter(transmitterId) {
36
+ const where = Aerospike.filter.equal('t', transmitterId);
37
+ return streamQueryGenerator(this.client, this.namespace, 'contained', where, decodeContained);
38
+ }
39
+ streamByReceiver(receiverId) {
40
+ const where = Aerospike.filter.equal('r', receiverId);
41
+ return streamQueryGenerator(this.client, this.namespace, 'contained', where, decodeContained);
42
+ }
43
+ }
44
+ //# sourceMappingURL=contained.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"contained.js","sourceRoot":"","sources":["../../../src/aerospike/impl/contained.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAA8C,WAAW,EAAE,oBAAoB,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAI9H,SAAS,eAAe,CAAC,MAAuB;IAC9C,MAAM,CAAC,GAAG,MAAM,CAAC,IAA2B,CAAC;IAC7C,OAAO;QACL,UAAU,EAAE,CAAC,CAAC,CAAC;QACf,aAAa,EAAE,CAAC,CAAC,CAAC;QAClB,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC;QAC1B,GAAG,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC;KACzB,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,uBAAuB;IAClC,YAAoB,MAAuB,EAAU,SAAiB;QAAlD,WAAM,GAAN,MAAM,CAAiB;QAAU,cAAS,GAAT,SAAS,CAAQ;IAAG,CAAC;IAE1E,KAAK,CAAC,UAAU,CAAC,mBAA2B;QAC1C,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;QAChE,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;QACnF,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,aAAqB;QAC5C,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;QACnF,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACtC,CAAC;IAED,KAAK,CAAC,eAAe,CAAC,UAAkB;QACtC,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QACtD,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;QACnF,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;IACtC,CAAC;IAED,WAAW,CAAC,mBAA2B;QACrC,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;QAChE,OAAO,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;IAChG,CAAC;IAED,mBAAmB,CAAC,aAAqB;QACvC,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QACzD,OAAO,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;IAChG,CAAC;IAED,gBAAgB,CAAC,UAAkB;QACjC,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;QACtD,OAAO,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;IAChG,CAAC;CACF"}
@@ -0,0 +1,12 @@
1
+ import { type AerospikeClient } from './common';
2
+ import { type DeltaRSSIWithId } from '../models';
3
+ import { type DeltaRSSIRepository } from '../repositories';
4
+ export declare class DeltaRSSIRepositoryImpl implements DeltaRSSIRepository {
5
+ private client;
6
+ private namespace;
7
+ constructor(client: AerospikeClient, namespace: string);
8
+ queryByKey(receiverTransmitter: string): Promise<DeltaRSSIWithId[]>;
9
+ queryByLink(receiverTransmitter: string, linkStart: number): Promise<DeltaRSSIWithId[]>;
10
+ streamByKey(receiverTransmitter: string): AsyncGenerator<DeltaRSSIWithId>;
11
+ streamByLink(receiverTransmitter: string, linkStart: number): AsyncGenerator<DeltaRSSIWithId>;
12
+ }
@@ -0,0 +1,38 @@
1
+ import { Aerospike, streamQuery, streamQueryGenerator, asNumber, sortByStampAscending } from './common';
2
+ function decodeDeltaRSSI(record) {
3
+ const b = record.bins;
4
+ return {
5
+ receiverId: b.r,
6
+ transmitterId: b.t,
7
+ stamp: asNumber(b.stamp) ?? 0,
8
+ value: asNumber(b.v) ?? 0,
9
+ linkStart: asNumber(b.l) ?? 0,
10
+ };
11
+ }
12
+ export class DeltaRSSIRepositoryImpl {
13
+ constructor(client, namespace) {
14
+ this.client = client;
15
+ this.namespace = namespace;
16
+ }
17
+ async queryByKey(receiverTransmitter) {
18
+ const where = Aerospike.filter.equal('rt', receiverTransmitter);
19
+ const records = await streamQuery(this.client, this.namespace, 'delta_rssi', where);
20
+ return sortByStampAscending(records.map(decodeDeltaRSSI));
21
+ }
22
+ async queryByLink(receiverTransmitter, linkStart) {
23
+ const lrt = `${receiverTransmitter}@${linkStart}`;
24
+ const where = Aerospike.filter.equal('lrt', lrt);
25
+ const records = await streamQuery(this.client, this.namespace, 'delta_rssi', where);
26
+ return sortByStampAscending(records.map(decodeDeltaRSSI));
27
+ }
28
+ streamByKey(receiverTransmitter) {
29
+ const where = Aerospike.filter.equal('rt', receiverTransmitter);
30
+ return streamQueryGenerator(this.client, this.namespace, 'delta_rssi', where, decodeDeltaRSSI);
31
+ }
32
+ streamByLink(receiverTransmitter, linkStart) {
33
+ const lrt = `${receiverTransmitter}@${linkStart}`;
34
+ const where = Aerospike.filter.equal('lrt', lrt);
35
+ return streamQueryGenerator(this.client, this.namespace, 'delta_rssi', where, decodeDeltaRSSI);
36
+ }
37
+ }
38
+ //# sourceMappingURL=deltaRssi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deltaRssi.js","sourceRoot":"","sources":["../../../src/aerospike/impl/deltaRssi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAA8C,WAAW,EAAE,oBAAoB,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAIpJ,SAAS,eAAe,CAAC,MAAuB;IAC9C,MAAM,CAAC,GAAG,MAAM,CAAC,IAA2B,CAAC;IAC7C,OAAO;QACL,UAAU,EAAE,CAAC,CAAC,CAAC;QACf,aAAa,EAAE,CAAC,CAAC,CAAC;QAClB,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;QAC7B,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QACzB,SAAS,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;KAC9B,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,uBAAuB;IAClC,YAAoB,MAAuB,EAAU,SAAiB;QAAlD,WAAM,GAAN,MAAM,CAAiB;QAAU,cAAS,GAAT,SAAS,CAAQ;IAAG,CAAC;IAE1E,KAAK,CAAC,UAAU,CAAC,mBAA2B;QAC1C,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;QAChE,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;QACpF,OAAO,oBAAoB,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,mBAA2B,EAAE,SAAiB;QAC9D,MAAM,GAAG,GAAG,GAAG,mBAAmB,IAAI,SAAS,EAAE,CAAC;QAClD,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACjD,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,YAAY,EAAE,KAAK,CAAC,CAAC;QACpF,OAAO,oBAAoB,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC,CAAC;IAC5D,CAAC;IAED,WAAW,CAAC,mBAA2B;QACrC,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;QAChE,OAAO,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;IACjG,CAAC;IAED,YAAY,CAAC,mBAA2B,EAAE,SAAiB;QACzD,MAAM,GAAG,GAAG,GAAG,mBAAmB,IAAI,SAAS,EAAE,CAAC;QAClD,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;QACjD,OAAO,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;IACjG,CAAC;CACF"}
@@ -0,0 +1,28 @@
1
+ import { StatesRepositoryImpl } from './states';
2
+ import { StateLinkRepositoryImpl } from './stateLink';
3
+ import { ClosedLinkRepositoryImpl } from './closedLink';
4
+ import { RSSIRepositoryImpl } from './rssi';
5
+ import { DeltaRSSIRepositoryImpl } from './deltaRssi';
6
+ import { GPSRepositoryImpl } from './gps';
7
+ import { TripRepositoryImpl } from './trip';
8
+ import { StateTripRepositoryImpl } from './stateTrip';
9
+ import { ContainedRepositoryImpl } from './contained';
10
+ import { TransmitterPositionRepositoryImpl } from './transmitterPosition';
11
+ import { type AerospikeClient } from './common';
12
+ export type RepositoryFactoryOptions = {
13
+ client: AerospikeClient;
14
+ namespace: string;
15
+ };
16
+ export declare function createRepositories(opts: RepositoryFactoryOptions): {
17
+ states: StatesRepositoryImpl;
18
+ stateLinks: StateLinkRepositoryImpl;
19
+ closedLinks: ClosedLinkRepositoryImpl;
20
+ rssi: RSSIRepositoryImpl;
21
+ deltaRssi: DeltaRSSIRepositoryImpl;
22
+ gps: GPSRepositoryImpl;
23
+ trips: TripRepositoryImpl;
24
+ stateTrips: StateTripRepositoryImpl;
25
+ contained: ContainedRepositoryImpl;
26
+ transmitterPos: TransmitterPositionRepositoryImpl;
27
+ };
28
+ export { StatesRepositoryImpl, StateLinkRepositoryImpl, ClosedLinkRepositoryImpl, RSSIRepositoryImpl, DeltaRSSIRepositoryImpl, GPSRepositoryImpl, TripRepositoryImpl, StateTripRepositoryImpl, ContainedRepositoryImpl, TransmitterPositionRepositoryImpl, };
@@ -0,0 +1,27 @@
1
+ import { StatesRepositoryImpl } from './states';
2
+ import { StateLinkRepositoryImpl } from './stateLink';
3
+ import { ClosedLinkRepositoryImpl } from './closedLink';
4
+ import { RSSIRepositoryImpl } from './rssi';
5
+ import { DeltaRSSIRepositoryImpl } from './deltaRssi';
6
+ import { GPSRepositoryImpl } from './gps';
7
+ import { TripRepositoryImpl } from './trip';
8
+ import { StateTripRepositoryImpl } from './stateTrip';
9
+ import { ContainedRepositoryImpl } from './contained';
10
+ import { TransmitterPositionRepositoryImpl } from './transmitterPosition';
11
+ export function createRepositories(opts) {
12
+ const { client, namespace } = opts;
13
+ return {
14
+ states: new StatesRepositoryImpl(client, namespace),
15
+ stateLinks: new StateLinkRepositoryImpl(client, namespace),
16
+ closedLinks: new ClosedLinkRepositoryImpl(client, namespace),
17
+ rssi: new RSSIRepositoryImpl(client, namespace),
18
+ deltaRssi: new DeltaRSSIRepositoryImpl(client, namespace),
19
+ gps: new GPSRepositoryImpl(client, namespace),
20
+ trips: new TripRepositoryImpl(client, namespace),
21
+ stateTrips: new StateTripRepositoryImpl(client, namespace),
22
+ contained: new ContainedRepositoryImpl(client, namespace),
23
+ transmitterPos: new TransmitterPositionRepositoryImpl(client, namespace),
24
+ };
25
+ }
26
+ export { StatesRepositoryImpl, StateLinkRepositoryImpl, ClosedLinkRepositoryImpl, RSSIRepositoryImpl, DeltaRSSIRepositoryImpl, GPSRepositoryImpl, TripRepositoryImpl, StateTripRepositoryImpl, ContainedRepositoryImpl, TransmitterPositionRepositoryImpl, };
27
+ //# sourceMappingURL=factory.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"factory.js","sourceRoot":"","sources":["../../../src/aerospike/impl/factory.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,wBAAwB,EAAE,MAAM,cAAc,CAAC;AACxD,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,OAAO,CAAC;AAC1C,OAAO,EAAE,kBAAkB,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AACtD,OAAO,EAAE,iCAAiC,EAAE,MAAM,uBAAuB,CAAC;AAQ1E,MAAM,UAAU,kBAAkB,CAAC,IAA8B;IAC/D,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;IACnC,OAAO;QACL,MAAM,EAAE,IAAI,oBAAoB,CAAC,MAAM,EAAE,SAAS,CAAC;QACnD,UAAU,EAAE,IAAI,uBAAuB,CAAC,MAAM,EAAE,SAAS,CAAC;QAC1D,WAAW,EAAE,IAAI,wBAAwB,CAAC,MAAM,EAAE,SAAS,CAAC;QAC5D,IAAI,EAAE,IAAI,kBAAkB,CAAC,MAAM,EAAE,SAAS,CAAC;QAC/C,SAAS,EAAE,IAAI,uBAAuB,CAAC,MAAM,EAAE,SAAS,CAAC;QACzD,GAAG,EAAE,IAAI,iBAAiB,CAAC,MAAM,EAAE,SAAS,CAAC;QAC7C,KAAK,EAAE,IAAI,kBAAkB,CAAC,MAAM,EAAE,SAAS,CAAC;QAChD,UAAU,EAAE,IAAI,uBAAuB,CAAC,MAAM,EAAE,SAAS,CAAC;QAC1D,SAAS,EAAE,IAAI,uBAAuB,CAAC,MAAM,EAAE,SAAS,CAAC;QACzD,cAAc,EAAE,IAAI,iCAAiC,CAAC,MAAM,EAAE,SAAS,CAAC;KACzE,CAAC;AACJ,CAAC;AAED,OAAO,EACL,oBAAoB,EACpB,uBAAuB,EACvB,wBAAwB,EACxB,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,EACjB,kBAAkB,EAClB,uBAAuB,EACvB,uBAAuB,EACvB,iCAAiC,GAClC,CAAC"}
@@ -0,0 +1,16 @@
1
+ import { type AerospikeClient } from './common';
2
+ import { type GPSPositionWithId } from '../models';
3
+ import { type GPSRepository } from '../repositories';
4
+ export declare class GPSRepositoryImpl implements GPSRepository {
5
+ private client;
6
+ private namespace;
7
+ constructor(client: AerospikeClient, namespace: string);
8
+ queryById(id: string): Promise<GPSPositionWithId[]>;
9
+ queryWithSpeed(id: string): Promise<Array<{
10
+ position: GPSPositionWithId;
11
+ speed: number;
12
+ dist: number;
13
+ dt: number;
14
+ }>>;
15
+ streamById(id: string): AsyncGenerator<GPSPositionWithId>;
16
+ }
@@ -0,0 +1,45 @@
1
+ import { Aerospike, streamQuery, streamQueryGenerator, decodeMsgpack, decodeGPSPosition, asNumber, sortByStampAscending, haversineMeters } from './common';
2
+ function decodeGPSRecord(record) {
3
+ const b = record.bins;
4
+ const gpsRaw = decodeMsgpack(b.v) ?? b.v;
5
+ const gps = decodeGPSPosition(gpsRaw);
6
+ if (!gps)
7
+ return null;
8
+ gps.stamp = asNumber(b.stamp) ?? gps.stamp;
9
+ return {
10
+ id: b.id,
11
+ ...gps,
12
+ };
13
+ }
14
+ export class GPSRepositoryImpl {
15
+ constructor(client, namespace) {
16
+ this.client = client;
17
+ this.namespace = namespace;
18
+ }
19
+ async queryById(id) {
20
+ const where = Aerospike.filter.equal('id', id);
21
+ const records = await streamQuery(this.client, this.namespace, 'rpkg_gps', where);
22
+ const decoded = records
23
+ .map(decodeGPSRecord)
24
+ .filter((x) => x !== null);
25
+ return sortByStampAscending(decoded);
26
+ }
27
+ async queryWithSpeed(id) {
28
+ const positions = await this.queryById(id);
29
+ const result = [];
30
+ for (let i = 0; i < positions.length - 1; i++) {
31
+ const a = positions[i];
32
+ const b = positions[i + 1];
33
+ const dist = haversineMeters(a, b);
34
+ const dt = Math.max(1, (b.stamp ?? 0) - (a.stamp ?? 0));
35
+ const speed = dist / dt;
36
+ result.push({ position: a, speed, dist, dt });
37
+ }
38
+ return result;
39
+ }
40
+ streamById(id) {
41
+ const where = Aerospike.filter.equal('id', id);
42
+ return streamQueryGenerator(this.client, this.namespace, 'rpkg_gps', where, decodeGPSRecord);
43
+ }
44
+ }
45
+ //# sourceMappingURL=gps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"gps.js","sourceRoot":"","sources":["../../../src/aerospike/impl/gps.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAA8C,WAAW,EAAE,oBAAoB,EAAE,aAAa,EAAE,iBAAiB,EAAE,QAAQ,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAIvM,SAAS,eAAe,CAAC,MAAuB;IAC9C,MAAM,CAAC,GAAG,MAAM,CAAC,IAA2B,CAAC;IAC7C,MAAM,MAAM,GAAG,aAAa,CAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;IACtC,IAAI,CAAC,GAAG;QAAE,OAAO,IAAI,CAAC;IACtB,GAAG,CAAC,KAAK,GAAG,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,KAAK,CAAC;IAC3C,OAAO;QACL,EAAE,EAAE,CAAC,CAAC,EAAE;QACR,GAAG,GAAG;KACP,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,iBAAiB;IAC5B,YAAoB,MAAuB,EAAU,SAAiB;QAAlD,WAAM,GAAN,MAAM,CAAiB;QAAU,cAAS,GAAT,SAAS,CAAQ;IAAG,CAAC;IAE1E,KAAK,CAAC,SAAS,CAAC,EAAU;QACxB,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;QAClF,MAAM,OAAO,GAAG,OAAO;aACpB,GAAG,CAAC,eAAe,CAAC;aACpB,MAAM,CAAC,CAAC,CAAC,EAA0B,EAAE,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC;QACrD,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC;IAED,KAAK,CAAC,cAAc,CAAC,EAAU;QAC7B,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAoF,EAAE,CAAC;QACnG,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;YAC9C,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YACvB,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAC3B,MAAM,IAAI,GAAG,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YACnC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC;YACxD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAE,CAAC;YACxB,MAAM,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,EAAE,CAAC,CAAC;QAChD,CAAC;QACD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,UAAU,CAAC,EAAU;QACnB,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QAC/C,OAAO,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,eAAe,CAAC,CAAC;IAC/F,CAAC;CACF"}
@@ -0,0 +1,11 @@
1
+ export * from './factory';
2
+ export * from './states';
3
+ export * from './stateLink';
4
+ export * from './closedLink';
5
+ export * from './rssi';
6
+ export * from './deltaRssi';
7
+ export * from './gps';
8
+ export * from './trip';
9
+ export * from './stateTrip';
10
+ export * from './contained';
11
+ export * from './transmitterPosition';
@@ -0,0 +1,12 @@
1
+ export * from './factory';
2
+ export * from './states';
3
+ export * from './stateLink';
4
+ export * from './closedLink';
5
+ export * from './rssi';
6
+ export * from './deltaRssi';
7
+ export * from './gps';
8
+ export * from './trip';
9
+ export * from './stateTrip';
10
+ export * from './contained';
11
+ export * from './transmitterPosition';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/aerospike/impl/index.ts"],"names":[],"mappings":"AAAA,cAAc,WAAW,CAAC;AAC1B,cAAc,UAAU,CAAC;AACzB,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,cAAc,OAAO,CAAC;AACtB,cAAc,QAAQ,CAAC;AACvB,cAAc,aAAa,CAAC;AAC5B,cAAc,aAAa,CAAC;AAC5B,cAAc,uBAAuB,CAAC"}
@@ -0,0 +1,14 @@
1
+ import { type AerospikeClient } from './common';
2
+ import { type RSSIWithId } from '../models';
3
+ import { type RSSIRepository } from '../repositories';
4
+ export declare class RSSIRepositoryImpl implements RSSIRepository {
5
+ private client;
6
+ private namespace;
7
+ constructor(client: AerospikeClient, namespace: string);
8
+ queryByKey(receiverTransmitter: string): Promise<RSSIWithId[]>;
9
+ queryByTransmitter(transmitterId: string): Promise<RSSIWithId[]>;
10
+ queryAll(): Promise<RSSIWithId[]>;
11
+ streamByKey(receiverTransmitter: string): AsyncGenerator<RSSIWithId>;
12
+ streamByTransmitter(transmitterId: string): AsyncGenerator<RSSIWithId>;
13
+ streamAll(): AsyncGenerator<RSSIWithId>;
14
+ }
@@ -0,0 +1,42 @@
1
+ import { Aerospike, streamQuery, streamQueryGenerator, asNumber, sortByStampAscending } from './common';
2
+ function decodeRSSI(record) {
3
+ const b = record.bins;
4
+ return {
5
+ receiverId: b.r,
6
+ transmitterId: b.t,
7
+ stamp: asNumber(b.stamp) ?? 0,
8
+ value: asNumber(b.v) ?? 0,
9
+ };
10
+ }
11
+ export class RSSIRepositoryImpl {
12
+ constructor(client, namespace) {
13
+ this.client = client;
14
+ this.namespace = namespace;
15
+ }
16
+ async queryByKey(receiverTransmitter) {
17
+ const where = Aerospike.filter.equal('rt', receiverTransmitter);
18
+ const records = await streamQuery(this.client, this.namespace, 'rpkg_rssi', where);
19
+ return sortByStampAscending(records.map(decodeRSSI));
20
+ }
21
+ async queryByTransmitter(transmitterId) {
22
+ const where = Aerospike.filter.equal('t', transmitterId);
23
+ const records = await streamQuery(this.client, this.namespace, 'rpkg_rssi', where);
24
+ return sortByStampAscending(records.map(decodeRSSI));
25
+ }
26
+ async queryAll() {
27
+ const records = await streamQuery(this.client, this.namespace, 'rpkg_rssi');
28
+ return sortByStampAscending(records.map(decodeRSSI));
29
+ }
30
+ streamByKey(receiverTransmitter) {
31
+ const where = Aerospike.filter.equal('rt', receiverTransmitter);
32
+ return streamQueryGenerator(this.client, this.namespace, 'rpkg_rssi', where, decodeRSSI);
33
+ }
34
+ streamByTransmitter(transmitterId) {
35
+ const where = Aerospike.filter.equal('t', transmitterId);
36
+ return streamQueryGenerator(this.client, this.namespace, 'rpkg_rssi', where, decodeRSSI);
37
+ }
38
+ streamAll() {
39
+ return streamQueryGenerator(this.client, this.namespace, 'rpkg_rssi', undefined, decodeRSSI);
40
+ }
41
+ }
42
+ //# sourceMappingURL=rssi.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rssi.js","sourceRoot":"","sources":["../../../src/aerospike/impl/rssi.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAA8C,WAAW,EAAE,oBAAoB,EAAE,QAAQ,EAAE,oBAAoB,EAAE,MAAM,UAAU,CAAC;AAIpJ,SAAS,UAAU,CAAC,MAAuB;IACzC,MAAM,CAAC,GAAG,MAAM,CAAC,IAA2B,CAAC;IAC7C,OAAO;QACL,UAAU,EAAE,CAAC,CAAC,CAAC;QACf,aAAa,EAAE,CAAC,CAAC,CAAC;QAClB,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;QAC7B,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;KAC1B,CAAC;AACJ,CAAC;AAED,MAAM,OAAO,kBAAkB;IAC7B,YAAoB,MAAuB,EAAU,SAAiB;QAAlD,WAAM,GAAN,MAAM,CAAiB;QAAU,cAAS,GAAT,SAAS,CAAQ;IAAG,CAAC;IAE1E,KAAK,CAAC,UAAU,CAAC,mBAA2B;QAC1C,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;QAChE,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;QACnF,OAAO,oBAAoB,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,kBAAkB,CAAC,aAAqB;QAC5C,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QACzD,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC;QACnF,OAAO,oBAAoB,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;IACvD,CAAC;IAED,KAAK,CAAC,QAAQ;QACZ,MAAM,OAAO,GAAG,MAAM,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QAC5E,OAAO,oBAAoB,CAAC,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC;IACvD,CAAC;IAED,WAAW,CAAC,mBAA2B;QACrC,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,EAAE,mBAAmB,CAAC,CAAC;QAChE,OAAO,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IAC3F,CAAC;IAED,mBAAmB,CAAC,aAAqB;QACvC,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC;QACzD,OAAO,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,KAAK,EAAE,UAAU,CAAC,CAAC;IAC3F,CAAC;IAED,SAAS;QACP,OAAO,oBAAoB,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,SAAS,EAAE,WAAW,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;IAC/F,CAAC;CACF"}