@synnaxlabs/client 0.26.7 → 0.27.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 (125) hide show
  1. package/.turbo/turbo-build.log +7 -7
  2. package/README.md +36 -10
  3. package/api/client.api.md +3077 -0
  4. package/api-extractor.json +7 -0
  5. package/dist/access/client.d.ts +0 -1
  6. package/dist/access/payload.d.ts +0 -1
  7. package/dist/auth/auth.d.ts +0 -1
  8. package/dist/channel/client.d.ts +6 -2
  9. package/dist/channel/client.d.ts.map +1 -1
  10. package/dist/channel/creator.d.ts +0 -1
  11. package/dist/channel/payload.d.ts +4 -1
  12. package/dist/channel/payload.d.ts.map +1 -1
  13. package/dist/channel/retriever.d.ts +0 -1
  14. package/dist/channel/writer.d.ts +0 -1
  15. package/dist/client.cjs +17 -17
  16. package/dist/client.d.ts +6 -7
  17. package/dist/client.d.ts.map +1 -1
  18. package/dist/client.js +2006 -1745
  19. package/dist/connection/checker.d.ts +0 -1
  20. package/dist/control/client.d.ts +0 -1
  21. package/dist/control/client.d.ts.map +1 -1
  22. package/dist/control/state.d.ts +0 -1
  23. package/dist/errors.d.ts +0 -1
  24. package/dist/framer/adapter.d.ts +0 -1
  25. package/dist/framer/client.d.ts +0 -1
  26. package/dist/framer/deleter.d.ts +0 -1
  27. package/dist/framer/frame.d.ts +11 -12
  28. package/dist/framer/iterator.d.ts +0 -1
  29. package/dist/framer/streamProxy.d.ts +0 -1
  30. package/dist/framer/streamer.d.ts +0 -1
  31. package/dist/framer/writer.d.ts +0 -1
  32. package/dist/framer/writer.d.ts.map +1 -1
  33. package/dist/hardware/client.d.ts +0 -1
  34. package/dist/hardware/device/client.d.ts +0 -1
  35. package/dist/hardware/device/payload.d.ts +0 -1
  36. package/dist/hardware/device/payload.d.ts.map +1 -1
  37. package/dist/hardware/rack/client.d.ts +0 -1
  38. package/dist/hardware/rack/payload.d.ts +0 -1
  39. package/dist/hardware/rack/payload.d.ts.map +1 -1
  40. package/dist/hardware/task/client.d.ts +0 -1
  41. package/dist/hardware/task/payload.d.ts +0 -1
  42. package/dist/hardware/task/payload.d.ts.map +1 -1
  43. package/dist/label/client.d.ts +8 -6
  44. package/dist/label/client.d.ts.map +1 -1
  45. package/dist/label/payload.d.ts +0 -1
  46. package/dist/label/retriever.d.ts +0 -1
  47. package/dist/label/retriever.d.ts.map +1 -1
  48. package/dist/label/writer.d.ts +32 -2
  49. package/dist/label/writer.d.ts.map +1 -1
  50. package/dist/ontology/client.d.ts +124 -11
  51. package/dist/ontology/client.d.ts.map +1 -1
  52. package/dist/ontology/group/client.d.ts +0 -1
  53. package/dist/ontology/group/group.d.ts +0 -1
  54. package/dist/ontology/group/payload.d.ts +0 -1
  55. package/dist/ontology/group/writer.d.ts +0 -1
  56. package/dist/ontology/payload.d.ts +5 -1
  57. package/dist/ontology/payload.d.ts.map +1 -1
  58. package/dist/ontology/writer.d.ts +4 -5
  59. package/dist/ontology/writer.d.ts.map +1 -1
  60. package/dist/ranger/alias.d.ts +0 -1
  61. package/dist/ranger/client.d.ts +55 -14
  62. package/dist/ranger/client.d.ts.map +1 -1
  63. package/dist/ranger/external.d.ts +1 -1
  64. package/dist/ranger/external.d.ts.map +1 -1
  65. package/dist/ranger/kv.d.ts +42 -5
  66. package/dist/ranger/kv.d.ts.map +1 -1
  67. package/dist/ranger/payload.d.ts +5 -2
  68. package/dist/ranger/payload.d.ts.map +1 -1
  69. package/dist/ranger/writer.d.ts +107 -2
  70. package/dist/ranger/writer.d.ts.map +1 -1
  71. package/dist/setupspecs.d.ts +0 -1
  72. package/dist/signals/observable.d.ts +0 -1
  73. package/dist/transport.d.ts +0 -1
  74. package/dist/user/client.d.ts +0 -1
  75. package/dist/user/payload.d.ts +0 -1
  76. package/dist/util/retrieve.d.ts +0 -1
  77. package/dist/util/telem.d.ts +0 -1
  78. package/dist/util/zod.d.ts +0 -1
  79. package/dist/workspace/client.d.ts +0 -1
  80. package/dist/workspace/lineplot/client.d.ts +0 -1
  81. package/dist/workspace/lineplot/payload.d.ts +0 -1
  82. package/dist/workspace/lineplot/retriever.d.ts +0 -1
  83. package/dist/workspace/lineplot/writer.d.ts +0 -1
  84. package/dist/workspace/payload.d.ts +0 -1
  85. package/dist/workspace/retriever.d.ts +0 -1
  86. package/dist/workspace/schematic/client.d.ts +0 -1
  87. package/dist/workspace/schematic/payload.d.ts +0 -1
  88. package/dist/workspace/schematic/retriever.d.ts +0 -1
  89. package/dist/workspace/schematic/writer.d.ts +0 -1
  90. package/dist/workspace/writer.d.ts +0 -1
  91. package/package.json +14 -12
  92. package/src/access/access.spec.ts +11 -11
  93. package/src/channel/batchRetriever.spec.ts +2 -0
  94. package/src/channel/channel.spec.ts +51 -31
  95. package/src/channel/client.ts +7 -0
  96. package/src/channel/payload.ts +1 -0
  97. package/src/client.ts +4 -3
  98. package/src/control/client.ts +9 -0
  99. package/src/errors.spec.ts +9 -0
  100. package/src/framer/frame.spec.ts +2 -2
  101. package/src/framer/frame.ts +22 -22
  102. package/src/framer/writer.ts +2 -1
  103. package/src/hardware/device/payload.ts +9 -0
  104. package/src/hardware/rack/payload.ts +9 -0
  105. package/src/hardware/task/payload.ts +9 -0
  106. package/src/label/client.ts +49 -19
  107. package/src/label/label.spec.ts +9 -0
  108. package/src/label/retriever.ts +2 -1
  109. package/src/label/writer.ts +11 -3
  110. package/src/ontology/client.ts +214 -13
  111. package/src/ontology/payload.ts +4 -0
  112. package/src/ontology/writer.ts +26 -12
  113. package/src/ranger/client.ts +204 -28
  114. package/src/ranger/external.ts +1 -1
  115. package/src/ranger/kv.ts +50 -11
  116. package/src/ranger/payload.ts +9 -5
  117. package/src/ranger/ranger.spec.ts +114 -49
  118. package/src/ranger/writer.ts +7 -2
  119. package/vite.config.ts +1 -1
  120. package/dist/ranger/active.d.ts +0 -11
  121. package/dist/ranger/active.d.ts.map +0 -1
  122. package/dist/ranger/range.d.ts +0 -32
  123. package/dist/ranger/range.d.ts.map +0 -1
  124. package/src/ranger/active.ts +0 -74
  125. package/src/ranger/range.ts +0 -98
@@ -1,6 +1,5 @@
1
1
  import { UnaryClient } from '@synnaxlabs/freighter';
2
2
  import { Params, Workspace } from './payload';
3
-
4
3
  export declare class Retriever {
5
4
  private static readonly ENDPOINT;
6
5
  private readonly client;
@@ -2,7 +2,6 @@ import { UnaryClient } from '@synnaxlabs/freighter';
2
2
  import { UnknownRecord } from '@synnaxlabs/x/record';
3
3
  import { Key, Params, Schematic } from './payload';
4
4
  import { NewSchematic } from './writer';
5
-
6
5
  export declare class Client {
7
6
  private readonly writer;
8
7
  private readonly retriever;
@@ -1,7 +1,6 @@
1
1
  import { UnknownRecord } from '@synnaxlabs/x/record';
2
2
  import { z } from 'zod';
3
3
  import { ontology } from '../../ontology';
4
-
5
4
  export declare const keyZ: z.ZodString;
6
5
  export type Key = z.infer<typeof keyZ>;
7
6
  export type Params = Key | Key[];
@@ -1,6 +1,5 @@
1
1
  import { UnaryClient } from '@synnaxlabs/freighter';
2
2
  import { Params, Schematic } from './payload';
3
-
4
3
  export declare class Retriever {
5
4
  private readonly ENDPOINT;
6
5
  private readonly client;
@@ -2,7 +2,6 @@ import { UnaryClient } from '@synnaxlabs/freighter';
2
2
  import { UnknownRecord } from '@synnaxlabs/x/record';
3
3
  import { z } from 'zod';
4
4
  import { Key, Params, Schematic } from './payload';
5
-
6
5
  export declare const newSchematicZ: z.ZodEffects<z.ZodObject<{
7
6
  name: z.ZodString;
8
7
  key: z.ZodOptional<z.ZodString>;
@@ -2,7 +2,6 @@ import { UnaryClient } from '@synnaxlabs/freighter';
2
2
  import { UnknownRecord } from '@synnaxlabs/x/record';
3
3
  import { z } from 'zod';
4
4
  import { Workspace } from './payload';
5
-
6
5
  declare const newWorkspaceZ: z.ZodEffects<z.ZodObject<{
7
6
  name: z.ZodString;
8
7
  key: z.ZodOptional<z.ZodString>;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@synnaxlabs/client",
3
3
  "private": false,
4
- "version": "0.26.7",
4
+ "version": "0.27.0",
5
5
  "type": "module",
6
6
  "description": "The Client Library for Synnax",
7
7
  "repository": "https://github.com/synnaxlabs/synnax/tree/main/client/ts",
@@ -18,19 +18,19 @@
18
18
  "dependencies": {
19
19
  "async-mutex": "^0.5.0",
20
20
  "zod": "3.23.8",
21
- "@synnaxlabs/freighter": "0.26.7",
22
- "@synnaxlabs/x": "0.26.7"
21
+ "@synnaxlabs/freighter": "0.27.0",
22
+ "@synnaxlabs/x": "0.27.0"
23
23
  },
24
24
  "devDependencies": {
25
- "@types/node": "^20.14.9",
26
- "@vitest/coverage-v8": "^1.6.0",
27
- "eslint": "^9.6.0",
28
- "typescript": "^5.5.3",
29
- "vite": "5.3.3",
30
- "vitest": "^1.6.0",
25
+ "@types/node": "^22.2.0",
26
+ "@vitest/coverage-v8": "^2.0.5",
27
+ "eslint": "^9.9.0",
28
+ "typescript": "^5.5.4",
29
+ "vite": "5.4.0",
30
+ "vitest": "^2.0.5",
31
31
  "@synnaxlabs/tsconfig": "0.0.2",
32
- "eslint-config-synnaxlabs": "0.0.1",
33
- "@synnaxlabs/vite-plugin": "0.0.1"
32
+ "@synnaxlabs/vite-plugin": "0.0.1",
33
+ "eslint-config-synnaxlabs": "0.0.1"
34
34
  },
35
35
  "peerDependencies": {
36
36
  "zod": "^3.23.8"
@@ -44,6 +44,8 @@
44
44
  "test": "vitest",
45
45
  "cov": "vitest --coverage",
46
46
  "lint": "eslint \"src/**/*.ts*\"",
47
- "fix": "eslint \"src/**/*.ts*\" --fix"
47
+ "fix": "eslint \"src/**/*.ts*\" --fix",
48
+ "genApi": "tsc --noEmit && vite build && npx api-extractor run --local",
49
+ "checkApi": "tsc --noEmit && vite build && npx api-extractor run"
48
50
  }
49
51
  }
@@ -23,7 +23,7 @@ const client = newClient();
23
23
 
24
24
  describe("Policy", () => {
25
25
  describe("create", () => {
26
- test("create one", async () => {
26
+ test.skip("create one", async () => {
27
27
  const policy = await client.access.create({
28
28
  subjects: [{ type: UserOntologyType, key: "1" }],
29
29
  objects: [
@@ -40,7 +40,7 @@ describe("Policy", () => {
40
40
  ]);
41
41
  expect(policy.actions).toEqual(["update"]);
42
42
  });
43
- test("create many", async () => {
43
+ test.skip("create many", async () => {
44
44
  const policies = await client.access.create([
45
45
  {
46
46
  subjects: [{ type: UserOntologyType, key: "10" }],
@@ -62,11 +62,11 @@ describe("Policy", () => {
62
62
  actions: ["update"],
63
63
  },
64
64
  ]);
65
- expect(policies.length).toEqual(2);
65
+ expect(policies.length).toEqual(3);
66
66
  expect(policies[0].subjects[0].key).toEqual("10");
67
67
  expect(policies[1].subjects[1].key).toEqual("21");
68
68
  });
69
- test("create instances of policies", async () => {
69
+ test.skip("create instances of policies", async () => {
70
70
  const policy = {
71
71
  key: undefined,
72
72
  subjects: [
@@ -85,7 +85,7 @@ describe("Policy", () => {
85
85
  expect(p.key).not.toEqual(policy.key);
86
86
  });
87
87
  });
88
- test("retrieve by subject", async () => {
88
+ test.skip("retrieve by subject", async () => {
89
89
  const key1 = id.id();
90
90
  const policies = [
91
91
  {
@@ -120,13 +120,13 @@ describe("Policy", () => {
120
120
  expect(p).toHaveLength(2);
121
121
  expect([p[0].actions, p[1].actions].sort()).toEqual([["delete"], ["update"]]);
122
122
  });
123
- test("retrieve by subject - not found", async () => {
123
+ test.skip("retrieve by subject - not found", async () => {
124
124
  const res = await client.access.retrieve({ type: UserOntologyType, key: "999" });
125
125
  expect(res).toHaveLength(0);
126
126
  });
127
127
 
128
128
  describe("delete", async () => {
129
- test("delete one", async () => {
129
+ test.skip("delete one", async () => {
130
130
  const id1 = id.id();
131
131
  const id2 = id.id();
132
132
  const id3 = id.id();
@@ -163,7 +163,7 @@ describe("Policy", () => {
163
163
  expect(res).toHaveLength(1);
164
164
  expect(res[0].actions).toEqual(["delete"]);
165
165
  });
166
- test("delete many", async () => {
166
+ test.skip("delete many", async () => {
167
167
  const id1 = id.id();
168
168
  const id2 = id.id();
169
169
  const id3 = id.id();
@@ -203,7 +203,7 @@ describe("Policy", () => {
203
203
  });
204
204
  });
205
205
  describe("registration", async () => {
206
- test("register a user", async () => {
206
+ test.skip("register a user", async () => {
207
207
  const username = id.id();
208
208
  await client.user.register(username, "pwd1");
209
209
  new Synnax({
@@ -213,14 +213,14 @@ describe("Policy", () => {
213
213
  password: "pwd1",
214
214
  });
215
215
  });
216
- test("duplicate username", async () => {
216
+ test.skip("duplicate username", async () => {
217
217
  const username = id.id();
218
218
  await client.user.register(username, "pwd1");
219
219
  await expect(client.user.register(username, "pwd1")).rejects.toThrow(AuthError);
220
220
  });
221
221
  });
222
222
  describe("privilege", async () => {
223
- test("new user", async () => {
223
+ test.skip("new user", async () => {
224
224
  const username = id.id();
225
225
  const user2 = await client.user.register(username, "pwd1");
226
226
  expect(user2).toBeDefined();
@@ -55,6 +55,7 @@ describe("channelRetriever", () => {
55
55
  rate: Rate.hz(1),
56
56
  leaseholder: 1,
57
57
  index: 0,
58
+ virtual: false,
58
59
  }));
59
60
  });
60
61
  const retriever = new DebouncedBatchRetriever(base, 10);
@@ -81,6 +82,7 @@ describe("channelRetriever", () => {
81
82
  rate: Rate.hz(1),
82
83
  leaseholder: 1,
83
84
  index: 0,
85
+ virtual: false,
84
86
  }));
85
87
  });
86
88
  const retriever = new DebouncedBatchRetriever(base, 10);
@@ -30,6 +30,7 @@ describe("Channel", () => {
30
30
  expect(channel.rate).toEqual(Rate.hz(1));
31
31
  expect(channel.dataType).toEqual(DataType.FLOAT32);
32
32
  });
33
+
33
34
  test("create index and indexed pair", async () => {
34
35
  const one = await client.channels.create({
35
36
  name: "Time",
@@ -44,6 +45,7 @@ describe("Channel", () => {
44
45
  });
45
46
  expect(two.key).not.toEqual(0);
46
47
  });
48
+
47
49
  test("create many", async () => {
48
50
  const channels = await client.channels.create([
49
51
  {
@@ -63,6 +65,7 @@ describe("Channel", () => {
63
65
  expect(channels[0].name).toEqual("test1");
64
66
  expect(channels[1].name).toEqual("test2");
65
67
  });
68
+
66
69
  test("create instances of channels", async () => {
67
70
  const timeIndexChannel = await client.channels.create({
68
71
  name: "time",
@@ -89,6 +92,20 @@ describe("Channel", () => {
89
92
  });
90
93
  await client.channels.create([sensorOne, sensorTwo, sensorThree]);
91
94
  });
95
+
96
+ describe("virtual", () => {
97
+ it("should create a virtual channel", async () => {
98
+ const channel = await client.channels.create({
99
+ name: "test",
100
+ dataType: DataType.JSON,
101
+ virtual: true,
102
+ });
103
+ expect(channel.virtual).toEqual(true);
104
+ const retrieved = await client.channels.retrieve(channel.key);
105
+ expect(retrieved.virtual).toBeTruthy();
106
+ });
107
+ });
108
+
92
109
  describe("retrieveIfNameExists", () => {
93
110
  it("should retrieve the existing channel when it exists", async () => {
94
111
  const name = `test-${Math.random()}-${TimeStamp.now().valueOf()}`;
@@ -159,38 +176,41 @@ describe("Channel", () => {
159
176
  });
160
177
  });
161
178
  });
162
- test("retrieve by key", async () => {
163
- const channel = await client.channels.create({
164
- name: "test",
165
- leaseholder: 1,
166
- rate: Rate.hz(1),
167
- dataType: DataType.FLOAT32,
179
+
180
+ describe("retrieve", () => {
181
+ test("retrieve by key", async () => {
182
+ const channel = await client.channels.create({
183
+ name: "test",
184
+ leaseholder: 1,
185
+ rate: Rate.hz(1),
186
+ dataType: DataType.FLOAT32,
187
+ });
188
+ const retrieved = await client.channels.retrieve(channel.key);
189
+ expect(retrieved.name).toEqual("test");
190
+ expect(retrieved.leaseholder).toEqual(1);
191
+ expect(retrieved.rate).toEqual(Rate.hz(1));
192
+ expect(retrieved.dataType).toEqual(DataType.FLOAT32);
193
+ });
194
+ test("retrieve by key - not found", async () => {
195
+ await expect(
196
+ async () => await client.channels.retrieve("1-1000"),
197
+ ).rejects.toThrow(QueryError);
198
+ });
199
+ test("retrieve by name", async () => {
200
+ const retrieved = await client.channels.retrieve(["test"]);
201
+ expect(retrieved.length).toBeGreaterThan(0);
202
+ retrieved.forEach((ch) => expect(ch.name).toEqual("test"));
203
+ });
204
+ test("retrieve by key - not found", async () => {
205
+ await expect(
206
+ async () => await client.channels.retrieve("1-1000"),
207
+ ).rejects.toThrow(NotFoundError);
208
+ });
209
+ test("retrieve by name", async () => {
210
+ const retrieved = await client.channels.retrieve(["test"]);
211
+ expect(retrieved.length).toBeGreaterThan(0);
212
+ retrieved.forEach((ch) => expect(ch.name).toEqual("test"));
168
213
  });
169
- const retrieved = await client.channels.retrieve(channel.key);
170
- expect(retrieved.name).toEqual("test");
171
- expect(retrieved.leaseholder).toEqual(1);
172
- expect(retrieved.rate).toEqual(Rate.hz(1));
173
- expect(retrieved.dataType).toEqual(DataType.FLOAT32);
174
- });
175
- test("retrieve by key - not found", async () => {
176
- await expect(async () => await client.channels.retrieve("1-1000")).rejects.toThrow(
177
- QueryError,
178
- );
179
- });
180
- test("retrieve by name", async () => {
181
- const retrieved = await client.channels.retrieve(["test"]);
182
- expect(retrieved.length).toBeGreaterThan(0);
183
- retrieved.forEach((ch) => expect(ch.name).toEqual("test"));
184
- });
185
- test("retrieve by key - not found", async () => {
186
- await expect(async () => await client.channels.retrieve("1-1000")).rejects.toThrow(
187
- NotFoundError,
188
- );
189
- });
190
- test("retrieve by name", async () => {
191
- const retrieved = await client.channels.retrieve(["test"]);
192
- expect(retrieved.length).toBeGreaterThan(0);
193
- retrieved.forEach((ch) => expect(ch.name).toEqual("test"));
194
214
  });
195
215
 
196
216
  describe("delete", async () => {
@@ -101,6 +101,11 @@ export class Channel {
101
101
  * should not be relied upon in the current version of Synnax.
102
102
  */
103
103
  readonly alias: string | undefined;
104
+ /**
105
+ * Whether the channel is virtual. Virtual channels do not store any data in the
106
+ * database, but can still be used for streaming purposes.
107
+ */
108
+ readonly virtual: boolean;
104
109
 
105
110
  constructor({
106
111
  dataType,
@@ -111,6 +116,7 @@ export class Channel {
111
116
  isIndex = false,
112
117
  index = 0,
113
118
  internal = false,
119
+ virtual = false,
114
120
  frameClient,
115
121
  alias,
116
122
  }: NewPayload & {
@@ -126,6 +132,7 @@ export class Channel {
126
132
  this.isIndex = isIndex;
127
133
  this.internal = internal;
128
134
  this.alias = alias;
135
+ this.virtual = virtual;
129
136
  this._frameClient = frameClient ?? null;
130
137
  }
131
138
 
@@ -30,6 +30,7 @@ export const payload = z.object({
30
30
  index: z.number(),
31
31
  isIndex: z.boolean(),
32
32
  internal: z.boolean(),
33
+ virtual: z.boolean(),
33
34
  alias: z.string().optional(),
34
35
  });
35
36
 
package/src/client.ts CHANGED
@@ -44,8 +44,8 @@ export const synnaxPropsZ = z.object({
44
44
  required_error: "Port is required",
45
45
  }),
46
46
  ),
47
- username: z.string().optional(),
48
- password: z.string().optional(),
47
+ username: z.string().min(1, "Username is required"),
48
+ password: z.string().min(1, "Password is required"),
49
49
  connectivityPollFrequency: TimeSpan.z.default(TimeSpan.seconds(30)),
50
50
  secure: z.boolean().optional().default(false),
51
51
  name: z.string().optional(),
@@ -125,13 +125,14 @@ export default class Synnax extends framer.Client {
125
125
  this.control = new control.Client(this);
126
126
  this.ontology = new ontology.Client(transport.unary, this);
127
127
  const rangeWriter = new ranger.Writer(this.transport.unary);
128
- this.labels = new label.Client(this.transport.unary, this);
128
+ this.labels = new label.Client(this.transport.unary, this, this.ontology);
129
129
  this.ranges = new ranger.Client(
130
130
  this,
131
131
  rangeWriter,
132
132
  this.transport.unary,
133
133
  chRetriever,
134
134
  this.labels,
135
+ this.ontology,
135
136
  );
136
137
  this.access = new access.Client(this.transport.unary);
137
138
  this.user = new user.Client(this.transport.unary);
@@ -1,3 +1,12 @@
1
+ // Copyright 2024 Synnax Labs, Inc.
2
+ //
3
+ // Use of this software is governed by the Business Source License included in the file
4
+ // licenses/BSL.txt.
5
+ //
6
+ // As of the Change Date specified in that file, in accordance with the Business Source
7
+ // License, use of this software will be governed by the Apache License, Version 2.0,
8
+ // included in the file licenses/APL.txt.
9
+
1
10
  import { StateTracker } from "@/control/state";
2
11
  import { framer } from "@/framer";
3
12
 
@@ -1,3 +1,12 @@
1
+ // Copyright 2024 Synnax Labs, Inc.
2
+ //
3
+ // Use of this software is governed by the Business Source License included in the file
4
+ // licenses/BSL.txt.
5
+ //
6
+ // As of the Change Date specified in that file, in accordance with the Business Source
7
+ // License, use of this software will be governed by the Apache License, Version 2.0,
8
+ // included in the file licenses/APL.txt.
9
+
1
10
  import { MatchableErrorType } from "@synnaxlabs/freighter/src/errors";
2
11
  import { describe, expect, test } from "vitest";
3
12
 
@@ -156,7 +156,7 @@ describe("framer.Frame", () => {
156
156
  });
157
157
 
158
158
  describe("weaklyAligned", () => {
159
- it("should return true if all keys have the same timerange", () => {
159
+ it("should return true if all keys have the same time range", () => {
160
160
  const f = new framer.Frame(
161
161
  new Map([
162
162
  [
@@ -182,7 +182,7 @@ describe("framer.Frame", () => {
182
182
  expect(f.isWeaklyAligned).toEqual(true);
183
183
  });
184
184
 
185
- it("should return false if any key has a different timerange", () => {
185
+ it("should return false if any key has a different time range", () => {
186
186
  const f = new framer.Frame(
187
187
  new Map([
188
188
  [
@@ -39,17 +39,17 @@ const columnType = (columns: Params): ColumnType => {
39
39
  return "name";
40
40
  };
41
41
 
42
- const validateMatchedColsAndArrays = (columns: Params, arrays: Series[]): void => {
42
+ const validateMatchedColsAndSeries = (columns: Params, series: Series[]): void => {
43
43
  const colsArr = toArray(columns);
44
- if (colsArr.length === arrays.length) return;
44
+ if (colsArr.length === series.length) return;
45
45
  const colType = columnType(columns);
46
46
  if (columnType === null)
47
47
  throw new ValidationError(
48
48
  "[Frame] - channel keys or names must be provided when constructing a frame.",
49
49
  );
50
50
  throw new ValidationError(
51
- `[Frame] - ${colType as string}s and arrays must be the same length.
52
- Got ${colsArr.length} ${colType as string}s and ${arrays.length} arrays.`,
51
+ `[Frame] - ${colType as string}s and series must be the same length.
52
+ Got ${colsArr.length} ${colType as string}s and ${series.length} series.`,
53
53
  );
54
54
  };
55
55
 
@@ -65,15 +65,15 @@ export type CrudeFrame =
65
65
  *
66
66
  * Frames have two important characteristics: alignment and orientation.
67
67
  *
68
- * A frame's alignment defines how correlated the arrays for different channels in the
68
+ * A frame's alignment defines how correlated the series for different channels in the
69
69
  * frame are:
70
70
  *
71
- * - A frame is weakly aligned if it meets the time range occupied by all arrays of a
71
+ * - A frame is weakly aligned if the time range occupied by all series of a
72
72
  * particular channel is the same for all channels in the frame. This means that the
73
- * arrays for a particular channel can have gaps between them.
73
+ * series for a particular channel can have gaps between them.
74
74
  *
75
75
  * - A strongly aligned frame means that all channels share the same rate/index and
76
- * there are no gaps in time between arrays. Strongly aligned frames are natural
76
+ * there are no gaps in time between series. Strongly aligned frames are natural
77
77
  * to interpret, as the values in a particular 'row' of the frame share the same
78
78
  * timestamp. All frames written to Synnax must be strongly aligned.
79
79
  *
@@ -85,7 +85,7 @@ export type CrudeFrame =
85
85
  *
86
86
  * - Horizontal frames have a single channel, and are strongly aligned by default.
87
87
  * A horizontal frame typically has a single array (in which case, it's also 'square'),
88
- * although it can have multiple arrays if all the arrays are continuous in time.
88
+ * although it can have multiple series if all the series are continuous in time.
89
89
  *
90
90
  * - Vertical frames are strongly aligned and have on or more channels, but ONLY a single
91
91
  * array per channel. Synnax requires that all frames written to the database are
@@ -98,7 +98,7 @@ export class Frame {
98
98
  readonly columns: Keys | Names = [];
99
99
  readonly series: Series[] = [];
100
100
 
101
- constructor(columnsOrData: Params | CrudeFrame = [], arrays: Series | Series[] = []) {
101
+ constructor(columnsOrData: Params | CrudeFrame = [], series: Series | Series[] = []) {
102
102
  if (columnsOrData instanceof Frame) {
103
103
  this.columns = columnsOrData.columns;
104
104
  this.series = columnsOrData.series;
@@ -117,9 +117,9 @@ export class Frame {
117
117
  if (isObject) {
118
118
  if ("keys" in columnsOrData && "series" in columnsOrData) {
119
119
  const data_ = columnsOrData as FramePayload;
120
- const arrays = data_.series.map((a) => seriesFromPayload(a));
121
- validateMatchedColsAndArrays(data_.keys, arrays);
122
- data_.keys.forEach((key, i) => this.push(key, arrays[i]));
120
+ const series = data_.series.map((a) => seriesFromPayload(a));
121
+ validateMatchedColsAndSeries(data_.keys, series);
122
+ data_.keys.forEach((key, i) => this.push(key, series[i]));
123
123
  } else
124
124
  Object.entries(columnsOrData).forEach(([k, v]) => {
125
125
  const key = parseInt(k);
@@ -129,21 +129,21 @@ export class Frame {
129
129
  return;
130
130
  }
131
131
 
132
- // Construction from a set of arrays and columns.
132
+ // Construction from a set of series and columns.
133
133
  if (
134
134
  Array.isArray(columnsOrData) ||
135
135
  ["string", "number"].includes(typeof columnsOrData)
136
136
  ) {
137
- const data_ = toArray(arrays);
137
+ const data_ = toArray(series);
138
138
  const cols = toArray(columnsOrData) as Keys | Names;
139
- validateMatchedColsAndArrays(cols, data_);
139
+ validateMatchedColsAndSeries(cols, data_);
140
140
  data_.forEach((d, i) => this.push(cols[i], d));
141
141
  return;
142
142
  }
143
143
 
144
144
  throw new ValidationError(
145
145
  `[Frame] - invalid frame construction parameters. data parameter ust be a frame
146
- payload, a list of lazy arrays, a lazy array, a map, or a record keyed by channel
146
+ payload, a list of lazy series, a lazy array, a map, or a record keyed by channel
147
147
  name. keys parameter must be a set of channel keys or channel names.`,
148
148
  );
149
149
  }
@@ -218,8 +218,8 @@ export class Frame {
218
218
  /**
219
219
  * @returns true if the frame is horizontal. Horizontal frames have a single channel,
220
220
  * and are strongly aligned by default.A horizontal frame typically has a single array
221
- * (in which case, it's also 'square'), although it can have multiple arrays if all
222
- * the arrays are continuous in time.
221
+ * (in which case, it's also 'square'), although it can have multiple series if all
222
+ * the series are continuous in time.
223
223
  */
224
224
  get isHorizontal(): boolean {
225
225
  return this.uniqueColumns.length === 1;
@@ -235,8 +235,8 @@ export class Frame {
235
235
 
236
236
  /**
237
237
  * @returns true if the frame is weakly aligned. A frame is weakly aligned if it meets
238
- * the time range occupied by all arrays of a particular channel is the same for all
239
- * channels in the frame. This means that the arrays for a particular channel can have
238
+ * the time range occupied by all series of a particular channel is the same for all
239
+ * channels in the frame. This means that the series for a particular channel can have
240
240
  * gaps between them.
241
241
  */
242
242
  get isWeaklyAligned(): boolean {
@@ -266,7 +266,7 @@ export class Frame {
266
266
  }
267
267
 
268
268
  /**
269
- * @returns lazy arrays matching the given channel key or name.
269
+ * @returns lazy series matching the given channel key or name.
270
270
  * @param key the channel key or name.
271
271
  */
272
272
  get(key: KeyOrName): MultiSeries;
@@ -54,7 +54,8 @@ const constructWriterMode = (mode: CrudeWriterMode): WriterMode => {
54
54
  case "persistStream":
55
55
  return WriterMode.PersistStream;
56
56
  default:
57
- return mode;
57
+ if (typeof mode === "number" && mode in WriterMode) return mode;
58
+ throw new Error(`invalid writer mode: ${mode}`);
58
59
  }
59
60
  };
60
61
 
@@ -1,3 +1,12 @@
1
+ // Copyright 2024 Synnax Labs, Inc.
2
+ //
3
+ // Use of this software is governed by the Business Source License included in the file
4
+ // licenses/BSL.txt.
5
+ //
6
+ // As of the Change Date specified in that file, in accordance with the Business Source
7
+ // License, use of this software will be governed by the Apache License, Version 2.0,
8
+ // included in the file licenses/APL.txt.
9
+
1
10
  import { binary, UnknownRecord } from "@synnaxlabs/x";
2
11
  import { z } from "zod";
3
12
 
@@ -1,3 +1,12 @@
1
+ // Copyright 2024 Synnax Labs, Inc.
2
+ //
3
+ // Use of this software is governed by the Business Source License included in the file
4
+ // licenses/BSL.txt.
5
+ //
6
+ // As of the Change Date specified in that file, in accordance with the Business Source
7
+ // License, use of this software will be governed by the Apache License, Version 2.0,
8
+ // included in the file licenses/APL.txt.
9
+
1
10
  import { z } from "zod";
2
11
 
3
12
  import { ontology } from "@/ontology";
@@ -1,3 +1,12 @@
1
+ // Copyright 2024 Synnax Labs, Inc.
2
+ //
3
+ // Use of this software is governed by the Business Source License included in the file
4
+ // licenses/BSL.txt.
5
+ //
6
+ // As of the Change Date specified in that file, in accordance with the Business Source
7
+ // License, use of this software will be governed by the Apache License, Version 2.0,
8
+ // included in the file licenses/APL.txt.
9
+
1
10
  import { binary, observe, UnknownRecord } from "@synnaxlabs/x";
2
11
  import { z } from "zod";
3
12