@peers-app/peers-sdk 0.14.0 → 0.15.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/dist/context/data-context.d.ts +4 -4
- package/dist/context/data-context.js +1 -1
- package/dist/context/index.d.ts +3 -3
- package/dist/context/index.js +4 -0
- package/dist/context/user-context-singleton.js +13 -14
- package/dist/context/user-context.d.ts +4 -4
- package/dist/context/user-context.js +48 -31
- package/dist/data/assistants.d.ts +1 -1
- package/dist/data/assistants.js +35 -24
- package/dist/data/change-tracking.d.ts +8 -8
- package/dist/data/change-tracking.js +45 -39
- package/dist/data/channels.js +5 -5
- package/dist/data/data-locks.d.ts +2 -2
- package/dist/data/data-locks.js +21 -23
- package/dist/data/data-locks.test.js +73 -75
- package/dist/data/device-sync-info.d.ts +1 -1
- package/dist/data/device-sync-info.js +4 -4
- package/dist/data/devices.d.ts +1 -1
- package/dist/data/devices.js +9 -12
- package/dist/data/embeddings.js +14 -11
- package/dist/data/files/file-read-stream.d.ts +2 -2
- package/dist/data/files/file-read-stream.js +23 -14
- package/dist/data/files/file-write-stream.d.ts +2 -2
- package/dist/data/files/file-write-stream.js +8 -8
- package/dist/data/files/file.types.d.ts +2 -2
- package/dist/data/files/file.types.js +17 -11
- package/dist/data/files/files.d.ts +6 -6
- package/dist/data/files/files.js +17 -19
- package/dist/data/files/files.test.js +213 -214
- package/dist/data/files/index.d.ts +4 -4
- package/dist/data/files/index.js +4 -4
- package/dist/data/group-member-roles.js +2 -2
- package/dist/data/group-members.d.ts +5 -5
- package/dist/data/group-members.js +27 -18
- package/dist/data/group-members.test.js +73 -73
- package/dist/data/group-permissions.d.ts +3 -3
- package/dist/data/group-permissions.js +13 -11
- package/dist/data/group-share.d.ts +2 -2
- package/dist/data/group-share.js +29 -24
- package/dist/data/groups.d.ts +4 -4
- package/dist/data/groups.js +27 -19
- package/dist/data/groups.test.js +44 -44
- package/dist/data/index.d.ts +6 -6
- package/dist/data/index.js +6 -6
- package/dist/data/knowledge/peer-types.js +9 -9
- package/dist/data/messages.d.ts +5 -5
- package/dist/data/messages.js +43 -30
- package/dist/data/orm/client-proxy.data-source.d.ts +4 -4
- package/dist/data/orm/client-proxy.data-source.js +10 -12
- package/dist/data/orm/cursor.d.ts +1 -1
- package/dist/data/orm/cursor.js +2 -2
- package/dist/data/orm/cursor.test.js +92 -93
- package/dist/data/orm/data-query.d.ts +3 -3
- package/dist/data/orm/data-query.js +24 -18
- package/dist/data/orm/data-query.mongo.d.ts +1 -1
- package/dist/data/orm/data-query.mongo.js +49 -51
- package/dist/data/orm/data-query.mongo.test.js +173 -204
- package/dist/data/orm/data-query.sqlite.d.ts +1 -1
- package/dist/data/orm/data-query.sqlite.js +84 -73
- package/dist/data/orm/data-query.sqlite.test.js +164 -176
- package/dist/data/orm/data-query.test.js +216 -224
- package/dist/data/orm/decorators.js +3 -3
- package/dist/data/orm/dependency-injection.test.js +53 -56
- package/dist/data/orm/doc.d.ts +4 -4
- package/dist/data/orm/doc.js +17 -21
- package/dist/data/orm/event-registry.d.ts +1 -1
- package/dist/data/orm/event-registry.test.js +16 -16
- package/dist/data/orm/factory.d.ts +2 -2
- package/dist/data/orm/factory.js +33 -33
- package/dist/data/orm/index.d.ts +10 -10
- package/dist/data/orm/index.js +10 -10
- package/dist/data/orm/multi-cursors.d.ts +1 -1
- package/dist/data/orm/multi-cursors.js +6 -6
- package/dist/data/orm/multi-cursors.test.js +152 -144
- package/dist/data/orm/sql.data-source.d.ts +7 -7
- package/dist/data/orm/sql.data-source.js +88 -93
- package/dist/data/orm/sql.data-source.test.js +109 -101
- package/dist/data/orm/subscribable.data-source.d.ts +4 -4
- package/dist/data/orm/subscribable.data-source.js +5 -5
- package/dist/data/orm/table-container-events.test.js +34 -26
- package/dist/data/orm/table-container.d.ts +6 -6
- package/dist/data/orm/table-container.js +33 -21
- package/dist/data/orm/table-container.test.js +64 -53
- package/dist/data/orm/table-definitions.system.d.ts +3 -3
- package/dist/data/orm/table-definitions.system.js +3 -3
- package/dist/data/orm/table-definitions.type.d.ts +5 -5
- package/dist/data/orm/table-dependencies.d.ts +2 -2
- package/dist/data/orm/table.d.ts +5 -5
- package/dist/data/orm/table.event-source.test.js +105 -115
- package/dist/data/orm/table.js +35 -34
- package/dist/data/orm/types.d.ts +3 -3
- package/dist/data/orm/types.js +26 -25
- package/dist/data/orm/types.test.js +166 -92
- package/dist/data/package-permissions.d.ts +1 -1
- package/dist/data/package-permissions.js +2 -2
- package/dist/data/package-version-permissions.d.ts +1 -1
- package/dist/data/package-version-permissions.js +2 -2
- package/dist/data/package-versions.d.ts +9 -9
- package/dist/data/package-versions.js +47 -33
- package/dist/data/packages.d.ts +2 -2
- package/dist/data/packages.js +36 -18
- package/dist/data/packages.utils.d.ts +2 -2
- package/dist/data/packages.utils.js +4 -4
- package/dist/data/persistent-vars.d.ts +15 -15
- package/dist/data/persistent-vars.js +165 -154
- package/dist/data/table-definitions-table.d.ts +5 -5
- package/dist/data/table-definitions-table.js +13 -12
- package/dist/data/tool-tests.js +6 -6
- package/dist/data/tools.js +29 -19
- package/dist/data/user-permissions.d.ts +1 -1
- package/dist/data/user-permissions.js +5 -5
- package/dist/data/user-permissions.test.js +90 -88
- package/dist/data/user-trust-levels.js +10 -10
- package/dist/data/users.d.ts +4 -4
- package/dist/data/users.js +16 -15
- package/dist/data/voice-messages.d.ts +2 -2
- package/dist/data/voice-messages.js +13 -13
- package/dist/data/welcome-modal.pvar.js +3 -1
- package/dist/data/workflow-logs.js +26 -18
- package/dist/data/workflow-runs.d.ts +6 -6
- package/dist/data/workflow-runs.js +70 -44
- package/dist/data/workflows.d.ts +2 -2
- package/dist/data/workflows.js +7 -9
- package/dist/device/binary-peer-connection-v2.d.ts +7 -7
- package/dist/device/binary-peer-connection-v2.js +32 -28
- package/dist/device/binary-peer-connection-v2.test.js +80 -67
- package/dist/device/binary-peer-connection.d.ts +7 -7
- package/dist/device/binary-peer-connection.js +29 -28
- package/dist/device/binary-peer-connection.test.js +35 -31
- package/dist/device/connection.d.ts +5 -5
- package/dist/device/connection.js +59 -48
- package/dist/device/connection.test.js +74 -68
- package/dist/device/device-election.d.ts +2 -2
- package/dist/device/device-election.js +25 -20
- package/dist/device/device-election.test.js +35 -36
- package/dist/device/device.d.ts +2 -2
- package/dist/device/device.js +10 -4
- package/dist/device/device.test.js +16 -17
- package/dist/device/get-trust-level-fn.d.ts +2 -2
- package/dist/device/get-trust-level-fn.js +22 -11
- package/dist/device/get-trust-level-fn.test.js +58 -58
- package/dist/device/socket-io-binary-peer.d.ts +1 -1
- package/dist/device/socket-io-binary-peer.js +16 -13
- package/dist/device/socket.type.d.ts +2 -2
- package/dist/device/streamed-socket.d.ts +2 -2
- package/dist/device/streamed-socket.js +8 -8
- package/dist/device/streamed-socket.test.js +40 -40
- package/dist/device/tx-encoding.test.js +77 -77
- package/dist/events.d.ts +1 -1
- package/dist/events.js +5 -2
- package/dist/group-invite/group-invite.js +110 -19
- package/dist/group-invite/group-invite.pvars.d.ts +2 -2
- package/dist/group-invite/group-invite.pvars.js +21 -13
- package/dist/group-invite/group-invite.types.d.ts +1 -1
- package/dist/group-invite/index.d.ts +3 -3
- package/dist/group-invite/index.js +1 -1
- package/dist/index.d.ts +25 -24
- package/dist/index.js +30 -25
- package/dist/keys.d.ts +3 -3
- package/dist/keys.js +31 -30
- package/dist/keys.test.js +69 -61
- package/dist/logging/console-logger.d.ts +1 -1
- package/dist/logging/console-logger.js +35 -40
- package/dist/logging/console-logger.test.js +115 -115
- package/dist/logging/console-logs.table.d.ts +3 -3
- package/dist/logging/console-logs.table.js +28 -23
- package/dist/mentions.js +16 -12
- package/dist/observable.d.ts +2 -2
- package/dist/observable.js +15 -9
- package/dist/observable.test.js +47 -47
- package/dist/package-loader/get-require.js +3 -4
- package/dist/package-loader/package-loader.d.ts +2 -2
- package/dist/package-loader/package-loader.js +52 -34
- package/dist/peers-ui/peers-ui.d.ts +2 -2
- package/dist/peers-ui/peers-ui.js +2 -4
- package/dist/peers-ui/peers-ui.types.d.ts +3 -3
- package/dist/peers-ui/peers-ui.types.js +0 -1
- package/dist/rpc-types.d.ts +61 -59
- package/dist/rpc-types.js +61 -55
- package/dist/serial-json.d.ts +1 -1
- package/dist/serial-json.js +50 -43
- package/dist/serial-json.test.js +22 -22
- package/dist/system-ids.js +8 -8
- package/dist/tools/index.d.ts +1 -1
- package/dist/tools/tools-factory.d.ts +1 -1
- package/dist/tools/tools-factory.js +2 -2
- package/dist/types/assistant-runner-args.d.ts +3 -3
- package/dist/types/peer-device.d.ts +1 -1
- package/dist/types/peers-package.d.ts +3 -3
- package/dist/types/workflow-logger.d.ts +1 -1
- package/dist/types/workflow-run-context.d.ts +4 -4
- package/dist/types/workflow.d.ts +4 -4
- package/dist/types/workflow.js +27 -14
- package/dist/types/zod-types.d.ts +2 -1
- package/dist/types/zod-types.js +9 -3
- package/dist/user-connect/connection-code.d.ts +1 -1
- package/dist/user-connect/connection-code.js +7 -7
- package/dist/user-connect/connection-code.test.js +106 -106
- package/dist/user-connect/index.d.ts +3 -3
- package/dist/user-connect/index.js +1 -1
- package/dist/user-connect/user-connect.pvars.js +13 -11
- package/dist/user-connect/user-connect.types.d.ts +3 -3
- package/dist/users.query.d.ts +2 -2
- package/dist/users.query.js +40 -30
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +34 -32
- package/dist/utils.test.js +12 -8
- package/dist/workflow-log-formatter.d.ts +1 -1
- package/dist/workflow-log-formatter.js +17 -18
- package/package.json +14 -8
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
const
|
|
3
|
+
const field_type_1 = require("../../types/field-type");
|
|
4
4
|
const data_query_1 = require("./data-query");
|
|
5
5
|
const factory_1 = require("./factory");
|
|
6
|
-
const
|
|
6
|
+
const multi_cursors_1 = require("./multi-cursors");
|
|
7
7
|
function createMockCursor(items) {
|
|
8
8
|
let index = 0;
|
|
9
9
|
const cursor = {
|
|
10
10
|
value: null,
|
|
11
|
-
next: async (
|
|
11
|
+
next: async (_skipPast) => {
|
|
12
12
|
if (index >= items.length) {
|
|
13
13
|
cursor.value = null;
|
|
14
14
|
return null;
|
|
@@ -20,8 +20,8 @@ function createMockCursor(items) {
|
|
|
20
20
|
};
|
|
21
21
|
return (0, data_query_1.iterableCursor)(cursor);
|
|
22
22
|
}
|
|
23
|
-
describe(
|
|
24
|
-
it(
|
|
23
|
+
describe("cursorUnion", () => {
|
|
24
|
+
it("should return items from first cursor, then second cursor in order", async () => {
|
|
25
25
|
const cursor1 = createMockCursor([1, 2, 3]);
|
|
26
26
|
const cursor2 = createMockCursor([4, 5, 6]);
|
|
27
27
|
const unionCursor = (0, multi_cursors_1.cursorUnion)([cursor1, cursor2]);
|
|
@@ -31,7 +31,7 @@ describe('cursorUnion', () => {
|
|
|
31
31
|
}
|
|
32
32
|
expect(results).toEqual([1, 2, 3, 4, 5, 6]);
|
|
33
33
|
});
|
|
34
|
-
it(
|
|
34
|
+
it("should handle empty cursors gracefully", async () => {
|
|
35
35
|
const cursor1 = createMockCursor([1, 2]);
|
|
36
36
|
const cursor2 = createMockCursor([]);
|
|
37
37
|
const cursor3 = createMockCursor([3, 4]);
|
|
@@ -42,7 +42,7 @@ describe('cursorUnion', () => {
|
|
|
42
42
|
}
|
|
43
43
|
expect(results).toEqual([1, 2, 3, 4]);
|
|
44
44
|
});
|
|
45
|
-
it(
|
|
45
|
+
it("should return empty result when all cursors are empty", async () => {
|
|
46
46
|
const cursor1 = createMockCursor([]);
|
|
47
47
|
const cursor2 = createMockCursor([]);
|
|
48
48
|
const unionCursor = (0, multi_cursors_1.cursorUnion)([cursor1, cursor2]);
|
|
@@ -52,16 +52,16 @@ describe('cursorUnion', () => {
|
|
|
52
52
|
}
|
|
53
53
|
expect(results).toEqual([]);
|
|
54
54
|
});
|
|
55
|
-
it(
|
|
56
|
-
const cursor1 = createMockCursor([
|
|
55
|
+
it("should work with single cursor", async () => {
|
|
56
|
+
const cursor1 = createMockCursor(["a", "b", "c"]);
|
|
57
57
|
const unionCursor = (0, multi_cursors_1.cursorUnion)([cursor1]);
|
|
58
58
|
const results = [];
|
|
59
59
|
for await (const item of unionCursor) {
|
|
60
60
|
results.push(item);
|
|
61
61
|
}
|
|
62
|
-
expect(results).toEqual([
|
|
62
|
+
expect(results).toEqual(["a", "b", "c"]);
|
|
63
63
|
});
|
|
64
|
-
it(
|
|
64
|
+
it("should work with no cursors", async () => {
|
|
65
65
|
const unionCursor = (0, multi_cursors_1.cursorUnion)([]);
|
|
66
66
|
const results = [];
|
|
67
67
|
for await (const item of unionCursor) {
|
|
@@ -69,7 +69,7 @@ describe('cursorUnion', () => {
|
|
|
69
69
|
}
|
|
70
70
|
expect(results).toEqual([]);
|
|
71
71
|
});
|
|
72
|
-
it(
|
|
72
|
+
it("should work with manual next() calls", async () => {
|
|
73
73
|
const cursor1 = createMockCursor([10, 20]);
|
|
74
74
|
const cursor2 = createMockCursor([30, 40]);
|
|
75
75
|
const unionCursor = (0, multi_cursors_1.cursorUnion)([cursor1, cursor2]);
|
|
@@ -79,118 +79,126 @@ describe('cursorUnion', () => {
|
|
|
79
79
|
}
|
|
80
80
|
expect(results).toEqual([10, 20, 30, 40]);
|
|
81
81
|
});
|
|
82
|
-
it(
|
|
83
|
-
const cursor1 = createMockCursor([
|
|
84
|
-
|
|
82
|
+
it("should handle different data types", async () => {
|
|
83
|
+
const cursor1 = createMockCursor([
|
|
84
|
+
{ id: 1, name: "John" },
|
|
85
|
+
{ id: 2, name: "Jane" },
|
|
86
|
+
]);
|
|
87
|
+
const cursor2 = createMockCursor([{ id: 3, name: "Bob" }]);
|
|
85
88
|
const unionCursor = (0, multi_cursors_1.cursorUnion)([cursor1, cursor2]);
|
|
86
89
|
const results = [];
|
|
87
90
|
for await (const item of unionCursor) {
|
|
88
91
|
results.push(item);
|
|
89
92
|
}
|
|
90
93
|
expect(results).toEqual([
|
|
91
|
-
{ id: 1, name:
|
|
92
|
-
{ id: 2, name:
|
|
93
|
-
{ id: 3, name:
|
|
94
|
+
{ id: 1, name: "John" },
|
|
95
|
+
{ id: 2, name: "Jane" },
|
|
96
|
+
{ id: 3, name: "Bob" },
|
|
94
97
|
]);
|
|
95
98
|
});
|
|
96
|
-
it(
|
|
97
|
-
const cursor1 = createMockCursor([
|
|
98
|
-
const cursor2 = createMockCursor([
|
|
99
|
+
it("should maintain cursor.value correctly", async () => {
|
|
100
|
+
const cursor1 = createMockCursor(["first", "second"]);
|
|
101
|
+
const cursor2 = createMockCursor(["third"]);
|
|
99
102
|
const unionCursor = (0, multi_cursors_1.cursorUnion)([cursor1, cursor2]);
|
|
100
103
|
// First item
|
|
101
104
|
await unionCursor.next();
|
|
102
|
-
expect(unionCursor.value).toBe(
|
|
105
|
+
expect(unionCursor.value).toBe("first");
|
|
103
106
|
// Second item
|
|
104
107
|
await unionCursor.next();
|
|
105
|
-
expect(unionCursor.value).toBe(
|
|
108
|
+
expect(unionCursor.value).toBe("second");
|
|
106
109
|
// Third item (from second cursor)
|
|
107
110
|
await unionCursor.next();
|
|
108
|
-
expect(unionCursor.value).toBe(
|
|
111
|
+
expect(unionCursor.value).toBe("third");
|
|
109
112
|
// End of data
|
|
110
113
|
const result = await unionCursor.next();
|
|
111
114
|
expect(result).toBeNull();
|
|
112
115
|
expect(unionCursor.value).toBeNull();
|
|
113
116
|
});
|
|
114
117
|
});
|
|
115
|
-
function createMockDataSource(items, tableName, primaryKeyName =
|
|
118
|
+
function createMockDataSource(items, tableName, primaryKeyName = "id") {
|
|
116
119
|
return (0, factory_1.arrayAsTable)(items, {
|
|
117
120
|
name: tableName,
|
|
118
|
-
primaryKeyName
|
|
121
|
+
primaryKeyName,
|
|
119
122
|
});
|
|
120
123
|
}
|
|
121
|
-
describe(
|
|
122
|
-
it(
|
|
123
|
-
const a = { id: 1, name:
|
|
124
|
-
const b = { id: 2, name:
|
|
125
|
-
expect((0, multi_cursors_1.sortLikeSQL)([
|
|
126
|
-
expect((0, multi_cursors_1.sortLikeSQL)([
|
|
127
|
-
expect((0, multi_cursors_1.sortLikeSQL)([
|
|
128
|
-
});
|
|
129
|
-
it(
|
|
130
|
-
const a = { id: 1, name:
|
|
131
|
-
const b = { id: 2, name:
|
|
132
|
-
expect((0, multi_cursors_1.sortLikeSQL)([
|
|
133
|
-
expect((0, multi_cursors_1.sortLikeSQL)([
|
|
134
|
-
expect((0, multi_cursors_1.sortLikeSQL)([
|
|
135
|
-
});
|
|
136
|
-
it(
|
|
137
|
-
const a = { name:
|
|
138
|
-
const b = { name:
|
|
139
|
-
const c = { name:
|
|
124
|
+
describe("sortLikeSQL", () => {
|
|
125
|
+
it("should sort by ascending field correctly", () => {
|
|
126
|
+
const a = { id: 1, name: "Alice" };
|
|
127
|
+
const b = { id: 2, name: "Bob" };
|
|
128
|
+
expect((0, multi_cursors_1.sortLikeSQL)(["id"], a, b)).toBe(-1); // a < b
|
|
129
|
+
expect((0, multi_cursors_1.sortLikeSQL)(["id"], b, a)).toBe(1); // b > a
|
|
130
|
+
expect((0, multi_cursors_1.sortLikeSQL)(["id"], a, a)).toBe(0); // a === a
|
|
131
|
+
});
|
|
132
|
+
it("should sort by descending field correctly", () => {
|
|
133
|
+
const a = { id: 1, name: "Alice" };
|
|
134
|
+
const b = { id: 2, name: "Bob" };
|
|
135
|
+
expect((0, multi_cursors_1.sortLikeSQL)(["-id"], a, b)).toBe(1); // a > b (desc)
|
|
136
|
+
expect((0, multi_cursors_1.sortLikeSQL)(["-id"], b, a)).toBe(-1); // b < a (desc)
|
|
137
|
+
expect((0, multi_cursors_1.sortLikeSQL)(["-id"], a, a)).toBe(0); // a === a
|
|
138
|
+
});
|
|
139
|
+
it("should handle multiple sort fields", () => {
|
|
140
|
+
const a = { name: "Alice", age: 25 };
|
|
141
|
+
const b = { name: "Alice", age: 30 };
|
|
142
|
+
const c = { name: "Bob", age: 25 };
|
|
140
143
|
// First by name, then by age
|
|
141
|
-
expect((0, multi_cursors_1.sortLikeSQL)([
|
|
142
|
-
expect((0, multi_cursors_1.sortLikeSQL)([
|
|
143
|
-
expect((0, multi_cursors_1.sortLikeSQL)([
|
|
144
|
+
expect((0, multi_cursors_1.sortLikeSQL)(["name", "age"], a, b)).toBe(-1); // same name, a.age < b.age
|
|
145
|
+
expect((0, multi_cursors_1.sortLikeSQL)(["name", "age"], a, c)).toBe(-1); // a.name < c.name
|
|
146
|
+
expect((0, multi_cursors_1.sortLikeSQL)(["name", "age"], c, a)).toBe(1); // c.name > a.name
|
|
144
147
|
});
|
|
145
|
-
it(
|
|
148
|
+
it("should handle null/undefined values like SQL", () => {
|
|
146
149
|
const a = { id: 1, name: null };
|
|
147
|
-
const b = { id: 2, name:
|
|
150
|
+
const b = { id: 2, name: "Bob" };
|
|
148
151
|
const c = { id: 3 }; // name is undefined
|
|
149
|
-
expect((0, multi_cursors_1.sortLikeSQL)([
|
|
150
|
-
expect((0, multi_cursors_1.sortLikeSQL)([
|
|
151
|
-
expect((0, multi_cursors_1.sortLikeSQL)([
|
|
152
|
+
expect((0, multi_cursors_1.sortLikeSQL)(["name"], a, b)).toBe(-1); // null < string (treated as -Infinity)
|
|
153
|
+
expect((0, multi_cursors_1.sortLikeSQL)(["name"], c, b)).toBe(-1); // undefined < string (treated as -Infinity)
|
|
154
|
+
expect((0, multi_cursors_1.sortLikeSQL)(["name"], a, c)).toBe(0); // null === undefined (both -Infinity)
|
|
152
155
|
});
|
|
153
156
|
});
|
|
154
|
-
describe(
|
|
155
|
-
it(
|
|
157
|
+
describe("queryMerge", () => {
|
|
158
|
+
it("should merge data from multiple sources in sorted order", async () => {
|
|
156
159
|
const dataSource1 = createMockDataSource([
|
|
157
|
-
{ id: 1, name:
|
|
158
|
-
{ id: 3, name:
|
|
159
|
-
{ id: 5, name:
|
|
160
|
-
],
|
|
160
|
+
{ id: 1, name: "Alice" },
|
|
161
|
+
{ id: 3, name: "Charlie" },
|
|
162
|
+
{ id: 5, name: "Eve" },
|
|
163
|
+
], "table1");
|
|
161
164
|
const dataSource2 = createMockDataSource([
|
|
162
|
-
{ id: 2, name:
|
|
163
|
-
{ id: 4, name:
|
|
164
|
-
{ id: 6, name:
|
|
165
|
-
],
|
|
165
|
+
{ id: 2, name: "Bob" },
|
|
166
|
+
{ id: 4, name: "David" },
|
|
167
|
+
{ id: 6, name: "Frank" },
|
|
168
|
+
], "table2");
|
|
166
169
|
const cursor = (0, multi_cursors_1.queryMerge)([dataSource1, dataSource2]);
|
|
167
170
|
const results = [];
|
|
168
171
|
for await (const item of cursor) {
|
|
169
172
|
results.push(item);
|
|
170
173
|
}
|
|
171
|
-
expect(results.map(r => r.id)).toEqual([1, 2, 3, 4, 5, 6]);
|
|
172
|
-
expect(results.map(r => r.name)).toEqual([
|
|
174
|
+
expect(results.map((r) => r.id)).toEqual([1, 2, 3, 4, 5, 6]);
|
|
175
|
+
expect(results.map((r) => r.name)).toEqual([
|
|
176
|
+
"Alice",
|
|
177
|
+
"Bob",
|
|
178
|
+
"Charlie",
|
|
179
|
+
"David",
|
|
180
|
+
"Eve",
|
|
181
|
+
"Frank",
|
|
182
|
+
]);
|
|
173
183
|
});
|
|
174
|
-
it(
|
|
184
|
+
it("should handle empty data sources", async () => {
|
|
175
185
|
const dataSource1 = (0, factory_1.arrayAsTable)([], {
|
|
176
|
-
name:
|
|
177
|
-
primaryKeyName:
|
|
186
|
+
name: "table1",
|
|
187
|
+
primaryKeyName: "id",
|
|
178
188
|
fields: [
|
|
179
|
-
{ name:
|
|
180
|
-
{ name:
|
|
181
|
-
]
|
|
189
|
+
{ name: "id", type: field_type_1.FieldType.number },
|
|
190
|
+
{ name: "name", type: field_type_1.FieldType.string },
|
|
191
|
+
],
|
|
182
192
|
});
|
|
183
|
-
const dataSource2 = createMockDataSource([
|
|
184
|
-
{ id: 1, name: 'Alice' },
|
|
185
|
-
], 'table2');
|
|
193
|
+
const dataSource2 = createMockDataSource([{ id: 1, name: "Alice" }], "table2");
|
|
186
194
|
const cursor = (0, multi_cursors_1.queryMerge)([dataSource1, dataSource2]);
|
|
187
195
|
const results = [];
|
|
188
196
|
for await (const item of cursor) {
|
|
189
197
|
results.push(item);
|
|
190
198
|
}
|
|
191
|
-
expect(results).toEqual([{ id: 1, name:
|
|
199
|
+
expect(results).toEqual([{ id: 1, name: "Alice" }]);
|
|
192
200
|
});
|
|
193
|
-
it(
|
|
201
|
+
it("should handle no data sources", async () => {
|
|
194
202
|
const cursor = (0, multi_cursors_1.queryMerge)([]);
|
|
195
203
|
const results = [];
|
|
196
204
|
for await (const item of cursor) {
|
|
@@ -198,51 +206,51 @@ describe('queryMerge', () => {
|
|
|
198
206
|
}
|
|
199
207
|
expect(results).toEqual([]);
|
|
200
208
|
});
|
|
201
|
-
it(
|
|
209
|
+
it("should respect custom sort order", async () => {
|
|
202
210
|
// Use pre-sorted data to avoid arrayAsTable sorting issues
|
|
203
211
|
const dataSource1 = createMockDataSource([
|
|
204
|
-
{ id: 1, name:
|
|
205
|
-
{ id: 3, name:
|
|
206
|
-
],
|
|
212
|
+
{ id: 1, name: "Alice", age: 30 },
|
|
213
|
+
{ id: 3, name: "Charlie", age: 25 },
|
|
214
|
+
], "table1");
|
|
207
215
|
const dataSource2 = createMockDataSource([
|
|
208
|
-
{ id: 2, name:
|
|
209
|
-
{ id: 4, name:
|
|
210
|
-
],
|
|
216
|
+
{ id: 2, name: "Bob", age: 28 },
|
|
217
|
+
{ id: 4, name: "David", age: 22 },
|
|
218
|
+
], "table2");
|
|
211
219
|
// Sort by name ascending - data sources already have data in correct order
|
|
212
|
-
const cursor = (0, multi_cursors_1.queryMerge)([dataSource1, dataSource2], {}, { sortBy: [
|
|
220
|
+
const cursor = (0, multi_cursors_1.queryMerge)([dataSource1, dataSource2], {}, { sortBy: ["name"] });
|
|
213
221
|
const results = [];
|
|
214
222
|
for await (const item of cursor) {
|
|
215
223
|
results.push(item);
|
|
216
224
|
}
|
|
217
|
-
expect(results.map(r => r.name)).toEqual([
|
|
225
|
+
expect(results.map((r) => r.name)).toEqual(["Alice", "Bob", "Charlie", "David"]);
|
|
218
226
|
});
|
|
219
|
-
it(
|
|
227
|
+
it("should work with single data source", async () => {
|
|
220
228
|
const dataSource = createMockDataSource([
|
|
221
|
-
{ id: 1, name:
|
|
222
|
-
{ id: 2, name:
|
|
223
|
-
{ id: 3, name:
|
|
224
|
-
],
|
|
229
|
+
{ id: 1, name: "Alice" },
|
|
230
|
+
{ id: 2, name: "Bob" },
|
|
231
|
+
{ id: 3, name: "Charlie" },
|
|
232
|
+
], "table1");
|
|
225
233
|
const cursor = (0, multi_cursors_1.queryMerge)([dataSource]);
|
|
226
234
|
const results = [];
|
|
227
235
|
for await (const item of cursor) {
|
|
228
236
|
results.push(item);
|
|
229
237
|
}
|
|
230
238
|
// Should be sorted by id (default primary key sort)
|
|
231
|
-
expect(results.map(r => r.id)).toEqual([1, 2, 3]);
|
|
239
|
+
expect(results.map((r) => r.id)).toEqual([1, 2, 3]);
|
|
232
240
|
});
|
|
233
|
-
it(
|
|
234
|
-
const dataSource1 = createMockDataSource([{ id: 1, name:
|
|
235
|
-
const dataSource2 = createMockDataSource([{ id: 2, name:
|
|
241
|
+
it("should work with manual next() calls", async () => {
|
|
242
|
+
const dataSource1 = createMockDataSource([{ id: 1, name: "Alice" }], "table1");
|
|
243
|
+
const dataSource2 = createMockDataSource([{ id: 2, name: "Bob" }], "table2");
|
|
236
244
|
const cursor = (0, multi_cursors_1.queryMerge)([dataSource1, dataSource2]);
|
|
237
245
|
const results = [];
|
|
238
246
|
while (await cursor.next()) {
|
|
239
247
|
results.push(cursor.value);
|
|
240
248
|
}
|
|
241
|
-
expect(results.map(r => r?.id)).toEqual([1, 2]);
|
|
249
|
+
expect(results.map((r) => r?.id)).toEqual([1, 2]);
|
|
242
250
|
});
|
|
243
251
|
});
|
|
244
|
-
describe(
|
|
245
|
-
it(
|
|
252
|
+
describe("cursorMap", () => {
|
|
253
|
+
it("should map cursor values using synchronous function", async () => {
|
|
246
254
|
const sourceCursor = createMockCursor([1, 2, 3, 4, 5]);
|
|
247
255
|
const mappedCursor = (0, multi_cursors_1.cursorMap)(sourceCursor, (x) => x * 2);
|
|
248
256
|
const results = [];
|
|
@@ -251,24 +259,24 @@ describe('cursorMap', () => {
|
|
|
251
259
|
}
|
|
252
260
|
expect(results).toEqual([2, 4, 6, 8, 10]);
|
|
253
261
|
});
|
|
254
|
-
it(
|
|
255
|
-
const sourceCursor = createMockCursor([
|
|
262
|
+
it("should map cursor values using async function", async () => {
|
|
263
|
+
const sourceCursor = createMockCursor(["a", "b", "c"]);
|
|
256
264
|
const mappedCursor = (0, multi_cursors_1.cursorMap)(sourceCursor, async (x) => {
|
|
257
265
|
// Simulate async operation
|
|
258
|
-
await new Promise(resolve => setTimeout(resolve, 1));
|
|
266
|
+
await new Promise((resolve) => setTimeout(resolve, 1));
|
|
259
267
|
return x.toUpperCase();
|
|
260
268
|
});
|
|
261
269
|
const results = [];
|
|
262
270
|
for await (const item of mappedCursor) {
|
|
263
271
|
results.push(item);
|
|
264
272
|
}
|
|
265
|
-
expect(results).toEqual([
|
|
273
|
+
expect(results).toEqual(["A", "B", "C"]);
|
|
266
274
|
});
|
|
267
|
-
it(
|
|
275
|
+
it("should transform data types correctly", async () => {
|
|
268
276
|
const sourceCursor = createMockCursor([
|
|
269
|
-
{ id: 1, name:
|
|
270
|
-
{ id: 2, name:
|
|
271
|
-
{ id: 3, name:
|
|
277
|
+
{ id: 1, name: "Alice", age: 25 },
|
|
278
|
+
{ id: 2, name: "Bob", age: 30 },
|
|
279
|
+
{ id: 3, name: "Charlie", age: 35 },
|
|
272
280
|
]);
|
|
273
281
|
const mappedCursor = (0, multi_cursors_1.cursorMap)(sourceCursor, (person) => `${person.name} is ${person.age} years old`);
|
|
274
282
|
const results = [];
|
|
@@ -276,12 +284,12 @@ describe('cursorMap', () => {
|
|
|
276
284
|
results.push(item);
|
|
277
285
|
}
|
|
278
286
|
expect(results).toEqual([
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
287
|
+
"Alice is 25 years old",
|
|
288
|
+
"Bob is 30 years old",
|
|
289
|
+
"Charlie is 35 years old",
|
|
282
290
|
]);
|
|
283
291
|
});
|
|
284
|
-
it(
|
|
292
|
+
it("should handle empty cursors", async () => {
|
|
285
293
|
const sourceCursor = createMockCursor([]);
|
|
286
294
|
const mappedCursor = (0, multi_cursors_1.cursorMap)(sourceCursor, (x) => x * 2);
|
|
287
295
|
const results = [];
|
|
@@ -290,7 +298,7 @@ describe('cursorMap', () => {
|
|
|
290
298
|
}
|
|
291
299
|
expect(results).toEqual([]);
|
|
292
300
|
});
|
|
293
|
-
it(
|
|
301
|
+
it("should work with manual next() calls", async () => {
|
|
294
302
|
const sourceCursor = createMockCursor([10, 20, 30]);
|
|
295
303
|
const mappedCursor = (0, multi_cursors_1.cursorMap)(sourceCursor, (x) => x / 10);
|
|
296
304
|
const results = [];
|
|
@@ -299,8 +307,8 @@ describe('cursorMap', () => {
|
|
|
299
307
|
}
|
|
300
308
|
expect(results).toEqual([1, 2, 3]);
|
|
301
309
|
});
|
|
302
|
-
it(
|
|
303
|
-
const sourceCursor = createMockCursor([
|
|
310
|
+
it("should maintain cursor.value correctly", async () => {
|
|
311
|
+
const sourceCursor = createMockCursor(["hello", "world"]);
|
|
304
312
|
const mappedCursor = (0, multi_cursors_1.cursorMap)(sourceCursor, (x) => x.length);
|
|
305
313
|
// First item
|
|
306
314
|
await mappedCursor.next();
|
|
@@ -313,11 +321,11 @@ describe('cursorMap', () => {
|
|
|
313
321
|
expect(result).toBeNull();
|
|
314
322
|
expect(mappedCursor.value).toBeNull();
|
|
315
323
|
});
|
|
316
|
-
it(
|
|
324
|
+
it("should handle async errors in map function", async () => {
|
|
317
325
|
const sourceCursor = createMockCursor([1, 2, 3]);
|
|
318
326
|
const mappedCursor = (0, multi_cursors_1.cursorMap)(sourceCursor, async (x) => {
|
|
319
327
|
if (x === 2) {
|
|
320
|
-
throw new Error(
|
|
328
|
+
throw new Error("Test error");
|
|
321
329
|
}
|
|
322
330
|
return x * 2;
|
|
323
331
|
});
|
|
@@ -330,19 +338,19 @@ describe('cursorMap', () => {
|
|
|
330
338
|
}
|
|
331
339
|
catch (error) {
|
|
332
340
|
errorCaught = true;
|
|
333
|
-
expect(error.message).toBe(
|
|
341
|
+
expect(error.message).toBe("Test error");
|
|
334
342
|
}
|
|
335
343
|
expect(errorCaught).toBe(true);
|
|
336
344
|
expect(results).toEqual([2]); // Only first item before error
|
|
337
345
|
});
|
|
338
|
-
it(
|
|
346
|
+
it("should throw error when skipPast is used", async () => {
|
|
339
347
|
const sourceCursor = createMockCursor([1, 2, 3]);
|
|
340
348
|
const mappedCursor = (0, multi_cursors_1.cursorMap)(sourceCursor, (x) => x * 2);
|
|
341
|
-
await expect(mappedCursor.next(4)).rejects.toThrow(
|
|
349
|
+
await expect(mappedCursor.next(4)).rejects.toThrow("skipPast is not supported for cursorMap since the mapped cursor has a different type than the source cursor");
|
|
342
350
|
});
|
|
343
351
|
});
|
|
344
|
-
describe(
|
|
345
|
-
it(
|
|
352
|
+
describe("cursorFilter", () => {
|
|
353
|
+
it("should filter cursor values using synchronous predicate", async () => {
|
|
346
354
|
const sourceCursor = createMockCursor([1, 2, 3, 4, 5, 6]);
|
|
347
355
|
const filteredCursor = (0, multi_cursors_1.cursorFilter)(sourceCursor, (x) => x % 2 === 0);
|
|
348
356
|
const results = [];
|
|
@@ -351,25 +359,25 @@ describe('cursorFilter', () => {
|
|
|
351
359
|
}
|
|
352
360
|
expect(results).toEqual([2, 4, 6]);
|
|
353
361
|
});
|
|
354
|
-
it(
|
|
355
|
-
const sourceCursor = createMockCursor([
|
|
362
|
+
it("should filter cursor values using async predicate", async () => {
|
|
363
|
+
const sourceCursor = createMockCursor(["apple", "banana", "cherry", "date"]);
|
|
356
364
|
const filteredCursor = (0, multi_cursors_1.cursorFilter)(sourceCursor, async (x) => {
|
|
357
365
|
// Simulate async operation
|
|
358
|
-
await new Promise(resolve => setTimeout(resolve, 1));
|
|
366
|
+
await new Promise((resolve) => setTimeout(resolve, 1));
|
|
359
367
|
return x.length > 5;
|
|
360
368
|
});
|
|
361
369
|
const results = [];
|
|
362
370
|
for await (const item of filteredCursor) {
|
|
363
371
|
results.push(item);
|
|
364
372
|
}
|
|
365
|
-
expect(results).toEqual([
|
|
373
|
+
expect(results).toEqual(["banana", "cherry"]);
|
|
366
374
|
});
|
|
367
|
-
it(
|
|
375
|
+
it("should filter objects based on properties", async () => {
|
|
368
376
|
const sourceCursor = createMockCursor([
|
|
369
|
-
{ id: 1, name:
|
|
370
|
-
{ id: 2, name:
|
|
371
|
-
{ id: 3, name:
|
|
372
|
-
{ id: 4, name:
|
|
377
|
+
{ id: 1, name: "Alice", age: 25 },
|
|
378
|
+
{ id: 2, name: "Bob", age: 30 },
|
|
379
|
+
{ id: 3, name: "Charlie", age: 35 },
|
|
380
|
+
{ id: 4, name: "David", age: 20 },
|
|
373
381
|
]);
|
|
374
382
|
const filteredCursor = (0, multi_cursors_1.cursorFilter)(sourceCursor, (person) => person.age >= 30);
|
|
375
383
|
const results = [];
|
|
@@ -377,11 +385,11 @@ describe('cursorFilter', () => {
|
|
|
377
385
|
results.push(item);
|
|
378
386
|
}
|
|
379
387
|
expect(results).toEqual([
|
|
380
|
-
{ id: 2, name:
|
|
381
|
-
{ id: 3, name:
|
|
388
|
+
{ id: 2, name: "Bob", age: 30 },
|
|
389
|
+
{ id: 3, name: "Charlie", age: 35 },
|
|
382
390
|
]);
|
|
383
391
|
});
|
|
384
|
-
it(
|
|
392
|
+
it("should handle empty cursors", async () => {
|
|
385
393
|
const sourceCursor = createMockCursor([]);
|
|
386
394
|
const filteredCursor = (0, multi_cursors_1.cursorFilter)(sourceCursor, (x) => x > 0);
|
|
387
395
|
const results = [];
|
|
@@ -390,7 +398,7 @@ describe('cursorFilter', () => {
|
|
|
390
398
|
}
|
|
391
399
|
expect(results).toEqual([]);
|
|
392
400
|
});
|
|
393
|
-
it(
|
|
401
|
+
it("should handle cursors where no items match filter", async () => {
|
|
394
402
|
const sourceCursor = createMockCursor([1, 2, 3, 4, 5]);
|
|
395
403
|
const filteredCursor = (0, multi_cursors_1.cursorFilter)(sourceCursor, (x) => x > 10);
|
|
396
404
|
const results = [];
|
|
@@ -399,7 +407,7 @@ describe('cursorFilter', () => {
|
|
|
399
407
|
}
|
|
400
408
|
expect(results).toEqual([]);
|
|
401
409
|
});
|
|
402
|
-
it(
|
|
410
|
+
it("should work with manual next() calls", async () => {
|
|
403
411
|
const sourceCursor = createMockCursor([10, 15, 20, 25, 30]);
|
|
404
412
|
const filteredCursor = (0, multi_cursors_1.cursorFilter)(sourceCursor, (x) => x >= 20);
|
|
405
413
|
const results = [];
|
|
@@ -408,33 +416,33 @@ describe('cursorFilter', () => {
|
|
|
408
416
|
}
|
|
409
417
|
expect(results).toEqual([20, 25, 30]);
|
|
410
418
|
});
|
|
411
|
-
it(
|
|
412
|
-
const sourceCursor = createMockCursor([
|
|
419
|
+
it("should maintain cursor.value correctly", async () => {
|
|
420
|
+
const sourceCursor = createMockCursor(["hello", "hi", "world", "test"]);
|
|
413
421
|
const filteredCursor = (0, multi_cursors_1.cursorFilter)(sourceCursor, (x) => x.length > 3);
|
|
414
422
|
// First item
|
|
415
423
|
await filteredCursor.next();
|
|
416
|
-
expect(filteredCursor.value).toBe(
|
|
417
|
-
// Second item
|
|
424
|
+
expect(filteredCursor.value).toBe("hello");
|
|
425
|
+
// Second item
|
|
418
426
|
await filteredCursor.next();
|
|
419
|
-
expect(filteredCursor.value).toBe(
|
|
427
|
+
expect(filteredCursor.value).toBe("world");
|
|
420
428
|
// Third item
|
|
421
429
|
await filteredCursor.next();
|
|
422
|
-
expect(filteredCursor.value).toBe(
|
|
430
|
+
expect(filteredCursor.value).toBe("test");
|
|
423
431
|
// End of data
|
|
424
432
|
const result = await filteredCursor.next();
|
|
425
433
|
expect(result).toBeNull();
|
|
426
434
|
expect(filteredCursor.value).toBeNull();
|
|
427
435
|
});
|
|
428
|
-
it(
|
|
436
|
+
it("should throw error when skipPast is used", async () => {
|
|
429
437
|
const sourceCursor = createMockCursor([1, 2, 3]);
|
|
430
438
|
const filteredCursor = (0, multi_cursors_1.cursorFilter)(sourceCursor, (x) => x > 1);
|
|
431
|
-
await expect(filteredCursor.next(2)).rejects.toThrow(
|
|
439
|
+
await expect(filteredCursor.next(2)).rejects.toThrow("skipPast is not supported for cursorFilter since filtering changes the cursor iteration order");
|
|
432
440
|
});
|
|
433
|
-
it(
|
|
441
|
+
it("should handle async errors in filter function", async () => {
|
|
434
442
|
const sourceCursor = createMockCursor([1, 2, 3]);
|
|
435
443
|
const filteredCursor = (0, multi_cursors_1.cursorFilter)(sourceCursor, async (x) => {
|
|
436
444
|
if (x === 2) {
|
|
437
|
-
throw new Error(
|
|
445
|
+
throw new Error("Filter error");
|
|
438
446
|
}
|
|
439
447
|
return x > 0;
|
|
440
448
|
});
|
|
@@ -447,7 +455,7 @@ describe('cursorFilter', () => {
|
|
|
447
455
|
}
|
|
448
456
|
catch (error) {
|
|
449
457
|
errorCaught = true;
|
|
450
|
-
expect(error.message).toBe(
|
|
458
|
+
expect(error.message).toBe("Filter error");
|
|
451
459
|
}
|
|
452
460
|
expect(errorCaught).toBe(true);
|
|
453
461
|
expect(results).toEqual([1]); // Only first item before error
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { z } from "zod";
|
|
2
|
-
import { Emitter } from "../../events";
|
|
3
|
-
import { FieldType, IField } from "../../types/field-type";
|
|
4
|
-
import { DataFilter, ICursorIterable, IDataQueryParams, IDataSource } from "./data-query";
|
|
5
|
-
import { ISqlDb } from "./sql-db";
|
|
6
|
-
import { IDataChangedEvent } from "./subscribable.data-source";
|
|
7
|
-
import { ITableMetaData } from "./types";
|
|
1
|
+
import type { z } from "zod";
|
|
2
|
+
import type { Emitter } from "../../events";
|
|
3
|
+
import type { FieldType, IField } from "../../types/field-type";
|
|
4
|
+
import { type DataFilter, type ICursorIterable, type IDataQueryParams, type IDataSource } from "./data-query";
|
|
5
|
+
import type { ISqlDb } from "./sql-db";
|
|
6
|
+
import type { IDataChangedEvent } from "./subscribable.data-source";
|
|
7
|
+
import { type ITableMetaData } from "./types";
|
|
8
8
|
export declare class SQLDataSource<T extends {
|
|
9
9
|
[key: string]: any;
|
|
10
10
|
}> implements IDataSource<T> {
|