Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 2 additions & 5 deletions api/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -752,11 +752,8 @@ def get(self, request, format=None):
currency=currency, type=type, status=Order.Status.PUB
)

if len(queryset) == 0:
return Response(
{"not_found": "No orders found, be the first to make one"},
status=status.HTTP_404_NOT_FOUND,
)
if not queryset.exists():
return Response([], status=status.HTTP_200_OK)

book_data = []
for order in queryset:
Expand Down
17 changes: 7 additions & 10 deletions frontend/src/models/Coordinator.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -196,16 +196,13 @@ export class Coordinator {
apiClient
.get(this.url, `/api/book/`, undefined, true)
.then((data) => {
if (!data?.not_found) {
this.book = (data as PublicOrder[]).reduce<Record<string, PublicOrder>>((book, order) => {
order.coordinatorShortAlias = this.shortAlias;
return { ...book, [`${this.shortAlias}${order.id}`]: order };
}, {});
void this.generateAllMakerAvatars();
onDataLoad();
} else {
onDataLoad();
}
const orders = Array.isArray(data) ? data : [];
this.book = orders.reduce<Record<string, PublicOrder>>((book, order) => {
order.coordinatorShortAlias = this.shortAlias;
return { ...book, [`${this.shortAlias}${order.id}`]: order };
}, {});
Comment on lines +200 to +203

@alicecoordinator alicecoordinator Feb 11, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using reduce here causes the complexity of this code to be quadratic. The alternative code below is linear:

Suggested change
this.book = orders.reduce<Record<string, PublicOrder>>((book, order) => {
order.coordinatorShortAlias = this.shortAlias;
return { ...book, [`${this.shortAlias}${order.id}`]: order };
}, {});
this.book = Object.fromEntries(
orders.map((order) => [
`${this.shortAlias}${order.id}`,
{ ...order, coordinatorShortAlias: this.shortAlias }
]),
);

Check this test:

interface PublicOrder {
    id: number;
    coordinatorShortAlias?: string;
}

class OrderBook {
    private book: Record<string, PublicOrder> = {};
    private readonly shortAlias: string = 'Alice';

    methodA(data: PublicOrder | PublicOrder[]): Record<string, PublicOrder> {
        const orders = Array.isArray(data) ? data : [];
        this.book = orders.reduce<Record<string, PublicOrder>>((book, order) => {
            order.coordinatorShortAlias = this.shortAlias;
            return { ...book, [`${this.shortAlias}${order.id}`]: order };
        }, {});
        return this.book;
    }

    methodB(data: PublicOrder | PublicOrder[]): Record<string, PublicOrder> {
        const orders = Array.isArray(data) ? data : [];
        this.book = Object.fromEntries(
            orders.map((order) => [`${this.shortAlias}${order.id}`, { ...order, coordinatorShortAlias: this.shortAlias }]),
        );
        return this.book;
    }
}

function perfTest(name: string, fn: (data: PublicOrder | PublicOrder[]) => Record<string, PublicOrder>, data: PublicOrder | PublicOrder[]) {
    const start = performance.now();
    fn(data);
    const end = performance.now();
    console.log(`${name} execution time: ${end - start} ms`);
}

const orderBook = new OrderBook();
const testData: PublicOrder[] = Array.from({ length: 5000 }, (_, i) => ({ id: i + 1 }));

perfTest('methodA', (data) => orderBook.methodA(data), testData);
perfTest('methodB', (data) => orderBook.methodB(data), testData);

Result:

methodA execution time: 4536.81159 ms
methodB execution time: 8.232476000000133 ms

void this.generateAllMakerAvatars();
onDataLoad();
})
.catch((e) => {
console.log(e);
Expand Down
12 changes: 12 additions & 0 deletions tests/test_trade_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -2019,6 +2019,18 @@ def test_book(self):
# Cancel order to avoid leaving pending HTLCs after a successful test
trade.cancel_order()

def test_book_empty(self):
"""
Tests public book view when there are no public orders.
"""
path = reverse("book")

response = self.client.get(path)
data = response.json()

self.assertEqual(response.status_code, 200)
self.assertEqual(data, [])

def test_robot_creation_with_valid_nostr_pubkey(self):
"""
Test that a robot can be created with a valid 64-character hex nostr pubkey.
Expand Down
Loading