Skip to content

Commit 4786a8a

Browse files
authored
Merge pull request #19 from objectwow/dev
Merge to main
2 parents 26155d4 + 652b12e commit 4786a8a

6 files changed

Lines changed: 24 additions & 40 deletions

File tree

README.md

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ export interface JoinDataParam {
103103
local: LocalParam;
104104

105105
/**
106-
* Object(s) or an asynchronous callback function that returns the data from the source.
106+
* Objects or an asynchronous callback function that returns the data from the source.
107107
*/
108108
from: FromParam;
109109

@@ -128,9 +128,10 @@ export interface JoinDataParam {
128128
asMap?: AsMap;
129129
}
130130

131+
export type LocalParam = object | object[];
132+
131133
export type FromParam =
132-
| ((localFieldValues: Primitive[], metadata: any) => any)
133-
| object
134+
| ((localFieldValues: Primitive[], metadata: any) => object[])
134135
| object[];
135136

136137
export type AsMap =
@@ -146,15 +147,15 @@ The join method in `@objectwow/join` offers better performance compared to the j
146147
### Traditional Approach (Database, Krakend, Hasura, GraphQL):
147148

148149
1. Loop through the original array.
149-
2. `For each element, make a call` to the table/service containing the related data by its ID.
150+
2. `For each element, make a call` to the `database/internal/external service` containing the related data by its `UID` (unique identifier).
150151
3. Combine the data from both sources.
151152
4. This results in a time complexity of `O(n x m)`, where `n` is the number of elements in the original array, and `m` is the number of elements fetched from the related table or service.
152153

153154
### @objectwow/join Approach:
154155

155-
1. Provides a `callback function` where the input is `an array of IDs`, allowing the developer to fetch related data from the table/service in a `single call`.
156-
2. Uses JavaScript’s `new Map` to optimize the process, reducing the time complexity from O(m) to O(1), where m is the number of elements retrieved..
157-
3. Combines the data efficiently after retrieving it in bulk through a `single call`.
156+
1. Provides a `callback function` where the input is `UIDs`, allowing the developer to fetch related data from the `database/internal/external service` in a `single call`.
157+
2. Uses JavaScript’s `new Map` to optimize the process, reducing the time complexity from O(m) to O(1), where `m` is the number of elements retrieved..
158+
3. Combines the data efficiently after retrieving it in bulk through a single call.
158159
4. This results in a time complexity of O(n), where `n` is the number of elements in the original array.
159160

160161
By fetching related data in bulk and leveraging efficient JavaScript data structures, `@objectwow/join` minimizes redundant calls and improves overall performance.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@objectwow/join",
3-
"version": "0.2.5",
3+
"version": "0.3.0",
44
"license": "MIT",
55
"description": "Join objects with functionality similar to MongoDB's $lookup",
66
"publishConfig": {

src/core.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -244,18 +244,22 @@ export class JoinData {
244244
metadata?: any
245245
): Promise<any[]> {
246246
if (typeOf(from) === Types.Object) {
247-
return [from];
247+
throw new Error("from must be an array of objects");
248248
}
249249

250250
if (typeOf(from) === Types.Array) {
251-
return from as any[];
251+
return from as object[];
252252
}
253253

254-
const result = await (from as Function)(localFieldValues, metadata);
255-
const fromArr =
256-
typeOf(result) === Types.Array ? (result as object[]) : [result];
254+
if (typeOf(from) === Types.Function) {
255+
const result = await (from as Function)(localFieldValues, metadata);
257256

258-
return fromArr;
257+
if (typeOf(result) === Types.Array) {
258+
return result as object[];
259+
}
260+
}
261+
262+
throw new Error("from must be an array of objects");
259263
}
260264

261265
protected generateResult(

src/type.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,7 @@ export type LocalValue = any | any[];
55
export type LocalParam = object | object[];
66

77
export type FromParam =
8-
| ((localFieldValues: Primitive[], metadata: any) => any)
9-
| object
8+
| ((localFieldValues: Primitive[], metadata: any) => object[])
109
| object[];
1110

1211
export type AsMap =
@@ -24,7 +23,7 @@ export interface JoinDataParam {
2423
local: LocalParam;
2524

2625
/**
27-
* Object(s) or an asynchronous callback function that returns the data from the source.
26+
* Objects or an asynchronous callback function that returns the data from the source.
2827
*/
2928
from: FromParam;
3029

tests/core.spec.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ describe("JoinData - execute method full coverage", () => {
6969
];
7070

7171
const param: JoinDataParam = {
72-
from: fromFn,
72+
from: await fromFn(),
7373
local: [{ id: 1 }, { id: 2 }],
7474
localField: "id",
7575
fromField: "id",
@@ -98,7 +98,7 @@ describe("JoinData - execute method full coverage", () => {
9898
];
9999

100100
const param: JoinDataParam = {
101-
from: fromFn,
101+
from: await fromFn(),
102102
local: [{ id: 1 }, { id: 2 }],
103103
localField: "id",
104104
fromField: "id",
@@ -164,7 +164,7 @@ describe("JoinData - execute method full coverage", () => {
164164
{ id: 2, items: [101, 201] },
165165
];
166166

167-
const from = async () => [
167+
const from = () => [
168168
{ id: 101, product: "Product 101" },
169169
{ id: 102, product: "Product 102" },
170170
{ id: 201, product: "Product 201" },

tests/singleton.spec.ts

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -33,24 +33,4 @@ describe("SingletonJoinData and joinData", () => {
3333
expect(instance1).not.toBe(instance2);
3434
});
3535
});
36-
37-
describe("joinData function", () => {
38-
it("should call the execute method of the JoinData instance with the correct parameters", async () => {
39-
const params: JoinDataParam = {
40-
from: () => ({}),
41-
local: {},
42-
localField: "id",
43-
fromField: "foreignId",
44-
as: "result",
45-
};
46-
47-
const expectedResult: JoinDataResult = {
48-
joinFailedValues: [],
49-
allSuccess: true,
50-
};
51-
52-
const result = await joinData(params);
53-
expect(result).toEqual(expectedResult);
54-
});
55-
});
5636
});

0 commit comments

Comments
 (0)