@faybl/utils 0.0.0-stage → 1.0.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.
package/README.md CHANGED
@@ -1,3 +1,33 @@
1
- # Temporary Holding Version
1
+ # @faybl/utils
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Generic JavaScript for Faybl services and web apps.
4
+
5
+ ```
6
+ npm install @faybl/utils
7
+ ```
8
+
9
+ ## History
10
+
11
+ `fetchHistory` reads a channel's history through a faybl-client as an array in
12
+ ascending time, each point with `ts` and `pl`, which is what a chart draws.
13
+
14
+ ```js
15
+ import { fetchHistory, fetchHistoryLast } from '@faybl/utils';
16
+
17
+ const { data } = await fetchHistory({ client, rid, from, to });
18
+ const newest = await fetchHistoryLast({ client, rid });
19
+ ```
20
+
21
+ It decides `ascending` and `reverse` for data-history from the range:
22
+
23
+ | Asked for | Returns |
24
+ | ---------------------------- | ------------------------------------------------- |
25
+ | `from`, with or without `to` | the range, from its start |
26
+ | `limit` and `from` | the first `limit` points from `from` |
27
+ | `limit` without `from` | the newest `limit` points, before `to` when given |
28
+ | nothing | from the oldest point |
29
+
30
+ `samplingInterval`, `downsamplingMethod` and `timeZone` are passed on. Empty
31
+ values are left out, and nothing else reaches data-history.
32
+
33
+ `fetchHistoryLast` is the newest point, before `to` when given, or `undefined`.
package/package.json CHANGED
@@ -1,6 +1,26 @@
1
1
  {
2
2
  "name": "@faybl/utils",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.0",
4
+ "description": "Generic JavaScript for Faybl services and web apps",
5
+ "license": "TBD",
6
+ "author": "Arcturitech",
7
+ "type": "module",
8
+ "exports": {
9
+ ".": "./src/index.js"
10
+ },
11
+ "files": [
12
+ "src"
13
+ ],
14
+ "sideEffects": false,
15
+ "publishConfig": {
16
+ "access": "public"
17
+ },
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "https://gitlab.com/arcturitech/faybl/utils/utils-js.git",
21
+ "directory": "packages/utils"
22
+ },
23
+ "engines": {
24
+ "node": ">=22"
25
+ }
26
+ }
package/src/history.js ADDED
@@ -0,0 +1,57 @@
1
+ const readOptionKeys = [
2
+ 'from',
3
+ 'to',
4
+ 'limit',
5
+ 'samplingInterval',
6
+ 'downsamplingMethod',
7
+ 'timeZone',
8
+ ];
9
+
10
+ // Empty values are left out: forms hand over '' for a bound nobody set.
11
+ const givenOptions = (params) =>
12
+ Object.fromEntries(readOptionKeys.filter((key) => params[key]).map((key) => [key, params[key]]));
13
+
14
+ // From `from`, or with no limit, an ascending read is already in order. A limit
15
+ // without `from` must take the newest points, so that read is descending and
16
+ // reversed back.
17
+ const readOrder = ({ from, limit }) => {
18
+ const ascending = Boolean(from || !limit);
19
+ return { ascending, reverse: !ascending };
20
+ };
21
+
22
+ /**
23
+ * Reads a channel's history as an array in ascending time, each point with
24
+ * `ts` and `pl`. A `limit` without `from` takes the newest points.
25
+ * @param {object} params
26
+ * @param {object} params.client faybl-client to read through
27
+ * @param {string} params.rid rid of the channel
28
+ * @param {string} [params.from] ISO timestamp the range starts at
29
+ * @param {string} [params.to] ISO timestamp the range ends at
30
+ * @param {number} [params.limit] Most points to return
31
+ * @param {number} [params.samplingInterval] Downsampling interval in seconds
32
+ * @param {string} [params.downsamplingMethod] How a sampling interval is reduced
33
+ * @param {string} [params.timeZone] Time zone of the returned timestamps
34
+ * @returns {Promise<{ count: number, timeZone: string, data: Array<{ ts: string, pl: unknown }> }>}
35
+ */
36
+ export const fetchHistory = (params = {}) => {
37
+ const { client, rid } = params;
38
+ if (!rid) return Promise.reject(Error('Missing rid'));
39
+ if (!client) return Promise.reject(Error('Missing client'));
40
+ return client.channel.read({
41
+ rid,
42
+ projection: ['ts', 'pl'],
43
+ ...givenOptions(params),
44
+ ...readOrder(params),
45
+ });
46
+ };
47
+
48
+ /**
49
+ * The newest point of a channel, or the newest before `to`; undefined when
50
+ * there is none.
51
+ * @param {object} params Same as for `fetchHistory`, without `from` and `limit`
52
+ * @returns {Promise<{ ts: string, pl: unknown } | undefined>}
53
+ */
54
+ export const fetchHistoryLast = async (params = {}) => {
55
+ const { data: [point] = [] } = await fetchHistory({ ...params, limit: 1 });
56
+ return point;
57
+ };
package/src/index.js ADDED
@@ -0,0 +1 @@
1
+ export { fetchHistory, fetchHistoryLast } from './history.js';