data-structure-typed 2.5.0 → 2.5.2
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/.vitepress/cache/deps_temp_51f5f1b0/chunk-7OIKW5WK.js +12984 -0
- package/.vitepress/cache/deps_temp_51f5f1b0/package.json +3 -0
- package/.vitepress/cache/deps_temp_51f5f1b0/vitepress___@vue_devtools-api.js +4505 -0
- package/.vitepress/cache/deps_temp_51f5f1b0/vitepress___@vueuse_core.js +9731 -0
- package/.vitepress/cache/deps_temp_51f5f1b0/vue.js +347 -0
- package/CHANGELOG.md +5 -1
- package/README.md +124 -29
- package/dist/cjs/binary-tree.cjs +26282 -0
- package/dist/cjs/graph.cjs +5422 -0
- package/dist/cjs/hash.cjs +1310 -0
- package/dist/cjs/heap.cjs +1602 -0
- package/dist/cjs/index.cjs +31257 -14673
- package/dist/cjs/linked-list.cjs +4576 -0
- package/dist/cjs/matrix.cjs +1080 -0
- package/dist/cjs/priority-queue.cjs +1376 -0
- package/dist/cjs/queue.cjs +4264 -0
- package/dist/cjs/stack.cjs +907 -0
- package/dist/cjs/trie.cjs +1223 -0
- package/dist/cjs-legacy/binary-tree.cjs +26319 -0
- package/dist/cjs-legacy/graph.cjs +5420 -0
- package/dist/cjs-legacy/hash.cjs +1310 -0
- package/dist/cjs-legacy/heap.cjs +1599 -0
- package/dist/cjs-legacy/index.cjs +31268 -14679
- package/dist/cjs-legacy/linked-list.cjs +4582 -0
- package/dist/cjs-legacy/matrix.cjs +1083 -0
- package/dist/cjs-legacy/priority-queue.cjs +1374 -0
- package/dist/cjs-legacy/queue.cjs +4262 -0
- package/dist/cjs-legacy/stack.cjs +907 -0
- package/dist/cjs-legacy/trie.cjs +1222 -0
- package/dist/esm/binary-tree.mjs +26267 -0
- package/dist/esm/graph.mjs +5409 -0
- package/dist/esm/hash.mjs +1307 -0
- package/dist/esm/heap.mjs +1596 -0
- package/dist/esm/index.mjs +31254 -14674
- package/dist/esm/linked-list.mjs +4569 -0
- package/dist/esm/matrix.mjs +1076 -0
- package/dist/esm/priority-queue.mjs +1372 -0
- package/dist/esm/queue.mjs +4260 -0
- package/dist/esm/stack.mjs +905 -0
- package/dist/esm/trie.mjs +1220 -0
- package/dist/esm-legacy/binary-tree.mjs +26304 -0
- package/dist/esm-legacy/graph.mjs +5407 -0
- package/dist/esm-legacy/hash.mjs +1307 -0
- package/dist/esm-legacy/heap.mjs +1593 -0
- package/dist/esm-legacy/index.mjs +31265 -14680
- package/dist/esm-legacy/linked-list.mjs +4575 -0
- package/dist/esm-legacy/matrix.mjs +1079 -0
- package/dist/esm-legacy/priority-queue.mjs +1370 -0
- package/dist/esm-legacy/queue.mjs +4258 -0
- package/dist/esm-legacy/stack.mjs +905 -0
- package/dist/esm-legacy/trie.mjs +1219 -0
- package/dist/types/common/error.d.ts +9 -0
- package/dist/types/common/index.d.ts +1 -1
- package/dist/types/data-structures/base/index.d.ts +1 -0
- package/dist/types/data-structures/base/iterable-entry-base.d.ts +8 -8
- package/dist/types/data-structures/base/linear-base.d.ts +3 -3
- package/dist/types/data-structures/binary-tree/avl-tree.d.ts +288 -0
- package/dist/types/data-structures/binary-tree/binary-indexed-tree.d.ts +336 -0
- package/dist/types/data-structures/binary-tree/binary-tree.d.ts +618 -18
- package/dist/types/data-structures/binary-tree/bst.d.ts +676 -1
- package/dist/types/data-structures/binary-tree/red-black-tree.d.ts +456 -0
- package/dist/types/data-structures/binary-tree/segment-tree.d.ts +144 -1
- package/dist/types/data-structures/binary-tree/tree-map.d.ts +3307 -399
- package/dist/types/data-structures/binary-tree/tree-multi-map.d.ts +3285 -360
- package/dist/types/data-structures/binary-tree/tree-multi-set.d.ts +2674 -325
- package/dist/types/data-structures/binary-tree/tree-set.d.ts +3072 -287
- package/dist/types/data-structures/graph/abstract-graph.d.ts +4 -4
- package/dist/types/data-structures/graph/directed-graph.d.ts +240 -0
- package/dist/types/data-structures/graph/undirected-graph.d.ts +216 -0
- package/dist/types/data-structures/hash/hash-map.d.ts +274 -10
- package/dist/types/data-structures/heap/heap.d.ts +336 -0
- package/dist/types/data-structures/linked-list/doubly-linked-list.d.ts +411 -3
- package/dist/types/data-structures/linked-list/singly-linked-list.d.ts +363 -3
- package/dist/types/data-structures/linked-list/skip-linked-list.d.ts +434 -2
- package/dist/types/data-structures/matrix/matrix.d.ts +192 -0
- package/dist/types/data-structures/queue/deque.d.ts +364 -4
- package/dist/types/data-structures/queue/queue.d.ts +288 -0
- package/dist/types/data-structures/stack/stack.d.ts +240 -0
- package/dist/types/data-structures/trie/trie.d.ts +292 -4
- package/dist/types/interfaces/graph.d.ts +1 -1
- package/dist/types/types/common.d.ts +2 -2
- package/dist/types/types/data-structures/binary-tree/bst.d.ts +1 -0
- package/dist/types/types/data-structures/binary-tree/tree-map.d.ts +5 -0
- package/dist/types/types/data-structures/binary-tree/tree-multi-set.d.ts +4 -0
- package/dist/types/types/data-structures/binary-tree/tree-set.d.ts +4 -0
- package/dist/types/types/data-structures/heap/heap.d.ts +1 -0
- package/dist/types/types/data-structures/priority-queue/priority-queue.d.ts +1 -0
- package/dist/types/types/utils/validate-type.d.ts +4 -4
- package/dist/umd/data-structure-typed.js +31196 -14608
- package/dist/umd/data-structure-typed.min.js +11 -5
- package/docs-site-docusaurus/README.md +41 -0
- package/docs-site-docusaurus/docs/api/README.md +52 -0
- package/docs-site-docusaurus/docs/api/classes/AVLTree.md +6644 -0
- package/docs-site-docusaurus/docs/api/classes/AVLTreeNode.md +282 -0
- package/docs-site-docusaurus/docs/api/classes/AbstractGraph.md +2266 -0
- package/docs-site-docusaurus/docs/api/classes/BST.md +6293 -0
- package/docs-site-docusaurus/docs/api/classes/BSTNode.md +333 -0
- package/docs-site-docusaurus/docs/api/classes/BinaryIndexedTree.md +455 -0
- package/docs-site-docusaurus/docs/api/classes/BinaryTree.md +4647 -0
- package/docs-site-docusaurus/docs/api/classes/BinaryTreeNode.md +331 -0
- package/docs-site-docusaurus/docs/api/classes/Deque.md +2767 -0
- package/docs-site-docusaurus/docs/api/classes/DirectedGraph.md +2999 -0
- package/docs-site-docusaurus/docs/api/classes/DoublyLinkedList.md +2685 -0
- package/docs-site-docusaurus/docs/api/classes/DoublyLinkedListNode.md +221 -0
- package/docs-site-docusaurus/docs/api/classes/FibonacciHeap.md +253 -0
- package/docs-site-docusaurus/docs/api/classes/FibonacciHeapNode.md +21 -0
- package/docs-site-docusaurus/docs/api/classes/HashMap.md +1333 -0
- package/docs-site-docusaurus/docs/api/classes/Heap.md +1881 -0
- package/docs-site-docusaurus/docs/api/classes/IterableElementBase.md +800 -0
- package/docs-site-docusaurus/docs/api/classes/IterableEntryBase.md +644 -0
- package/docs-site-docusaurus/docs/api/classes/LinearBase.md +1632 -0
- package/docs-site-docusaurus/docs/api/classes/LinearLinkedBase.md +1853 -0
- package/docs-site-docusaurus/docs/api/classes/LinkedHashMap.md +1108 -0
- package/docs-site-docusaurus/docs/api/classes/LinkedListNode.md +156 -0
- package/docs-site-docusaurus/docs/api/classes/LinkedListQueue.md +2824 -0
- package/docs-site-docusaurus/docs/api/classes/MapGraph.md +2929 -0
- package/docs-site-docusaurus/docs/api/classes/Matrix.md +1026 -0
- package/docs-site-docusaurus/docs/api/classes/MaxHeap.md +1866 -0
- package/docs-site-docusaurus/docs/api/classes/MaxPriorityQueue.md +1883 -0
- package/docs-site-docusaurus/docs/api/classes/MinHeap.md +1879 -0
- package/docs-site-docusaurus/docs/api/classes/MinPriorityQueue.md +1882 -0
- package/docs-site-docusaurus/docs/api/classes/Navigator.md +109 -0
- package/docs-site-docusaurus/docs/api/classes/PriorityQueue.md +1839 -0
- package/docs-site-docusaurus/docs/api/classes/Queue.md +2244 -0
- package/docs-site-docusaurus/docs/api/classes/RedBlackTree.md +6888 -0
- package/docs-site-docusaurus/docs/api/classes/SegmentTree.md +372 -0
- package/docs-site-docusaurus/docs/api/classes/SinglyLinkedList.md +2897 -0
- package/docs-site-docusaurus/docs/api/classes/SinglyLinkedListNode.md +169 -0
- package/docs-site-docusaurus/docs/api/classes/SkipList.md +1229 -0
- package/docs-site-docusaurus/docs/api/classes/Stack.md +1573 -0
- package/docs-site-docusaurus/docs/api/classes/TreeMap.md +1389 -0
- package/docs-site-docusaurus/docs/api/classes/TreeMultiMap.md +1591 -0
- package/docs-site-docusaurus/docs/api/classes/TreeSet.md +1246 -0
- package/docs-site-docusaurus/docs/api/classes/Trie.md +1708 -0
- package/docs-site-docusaurus/docs/api/classes/TrieNode.md +199 -0
- package/docs-site-docusaurus/docs/api/classes/UndirectedGraph.md +2979 -0
- package/docs-site-docusaurus/docs/guide/_category_.json +6 -0
- package/docs-site-docusaurus/docs/guide/architecture.md +615 -0
- package/docs-site-docusaurus/docs/guide/concepts.md +451 -0
- package/docs-site-docusaurus/docs/guide/faq.md +180 -0
- package/docs-site-docusaurus/docs/guide/guides.md +597 -0
- package/docs-site-docusaurus/docs/guide/installation.md +62 -0
- package/docs-site-docusaurus/docs/guide/integrations.md +825 -0
- package/docs-site-docusaurus/docs/guide/overview.md +645 -0
- package/docs-site-docusaurus/docs/guide/performance.md +835 -0
- package/docs-site-docusaurus/docs/guide/quick-start.md +104 -0
- package/docs-site-docusaurus/docs/guide/use-cases/_category_.json +6 -0
- package/docs-site-docusaurus/docs/guide/use-cases/array-sort-alternative.md +158 -0
- package/docs-site-docusaurus/docs/guide/use-cases/heap-vs-sorting.md +92 -0
- package/docs-site-docusaurus/docs/guide/use-cases/map-vs-treemap.md +151 -0
- package/docs-site-docusaurus/docs/guide/use-cases/priority-queue-typescript.md +113 -0
- package/docs-site-docusaurus/docs/guide/use-cases/treemap-javascript.md +151 -0
- package/docs-site-docusaurus/docusaurus.config.ts +159 -0
- package/docs-site-docusaurus/fix-mdx-generics.mjs +75 -0
- package/docs-site-docusaurus/package-lock.json +18667 -0
- package/docs-site-docusaurus/package.json +50 -0
- package/docs-site-docusaurus/prefix-class-to-methods.mjs +48 -0
- package/docs-site-docusaurus/sidebars.ts +23 -0
- package/docs-site-docusaurus/sort-protected.mjs +87 -0
- package/docs-site-docusaurus/src/css/custom.css +96 -0
- package/docs-site-docusaurus/src/pages/index.module.css +13 -0
- package/docs-site-docusaurus/src/pages/index.tsx +120 -0
- package/docs-site-docusaurus/src/pages/markdown-page.md +7 -0
- package/docs-site-docusaurus/src/theme/TOCItems/index.tsx +34 -0
- package/docs-site-docusaurus/static/.nojekyll +0 -0
- package/docs-site-docusaurus/static/img/docusaurus-social-card.jpg +0 -0
- package/docs-site-docusaurus/static/img/docusaurus.png +0 -0
- package/docs-site-docusaurus/static/img/favicon.ico +0 -0
- package/docs-site-docusaurus/static/img/favicon.png +0 -0
- package/docs-site-docusaurus/static/img/logo-180.png +0 -0
- package/docs-site-docusaurus/static/img/logo.jpg +0 -0
- package/docs-site-docusaurus/static/img/logo.png +0 -0
- package/docs-site-docusaurus/static/img/logo.svg +1 -0
- package/docs-site-docusaurus/static/img/og-image.png +0 -0
- package/docs-site-docusaurus/static/img/undraw_docusaurus_mountain.svg +171 -0
- package/docs-site-docusaurus/static/img/undraw_docusaurus_react.svg +170 -0
- package/docs-site-docusaurus/static/img/undraw_docusaurus_tree.svg +40 -0
- package/docs-site-docusaurus/static/llms.txt +37 -0
- package/docs-site-docusaurus/static/robots.txt +4 -0
- package/docs-site-docusaurus/typedoc.json +23 -0
- package/llms.txt +37 -0
- package/package.json +159 -55
- package/src/common/error.ts +19 -1
- package/src/common/index.ts +1 -1
- package/src/data-structures/base/index.ts +1 -0
- package/src/data-structures/base/iterable-element-base.ts +3 -2
- package/src/data-structures/base/iterable-entry-base.ts +8 -8
- package/src/data-structures/base/linear-base.ts +3 -3
- package/src/data-structures/binary-tree/avl-tree.ts +287 -0
- package/src/data-structures/binary-tree/binary-indexed-tree.ts +327 -5
- package/src/data-structures/binary-tree/binary-tree.ts +581 -6
- package/src/data-structures/binary-tree/bst.ts +922 -7
- package/src/data-structures/binary-tree/red-black-tree.ts +453 -0
- package/src/data-structures/binary-tree/segment-tree.ts +139 -2
- package/src/data-structures/binary-tree/tree-map.ts +3300 -495
- package/src/data-structures/binary-tree/tree-multi-map.ts +3384 -563
- package/src/data-structures/binary-tree/tree-multi-set.ts +2757 -493
- package/src/data-structures/binary-tree/tree-set.ts +3122 -440
- package/src/data-structures/graph/abstract-graph.ts +6 -6
- package/src/data-structures/graph/directed-graph.ts +230 -0
- package/src/data-structures/graph/undirected-graph.ts +207 -0
- package/src/data-structures/hash/hash-map.ts +270 -19
- package/src/data-structures/heap/heap.ts +326 -4
- package/src/data-structures/heap/max-heap.ts +2 -2
- package/src/data-structures/linked-list/doubly-linked-list.ts +394 -3
- package/src/data-structures/linked-list/singly-linked-list.ts +348 -3
- package/src/data-structures/linked-list/skip-linked-list.ts +421 -7
- package/src/data-structures/matrix/matrix.ts +194 -10
- package/src/data-structures/priority-queue/max-priority-queue.ts +2 -2
- package/src/data-structures/queue/deque.ts +350 -5
- package/src/data-structures/queue/queue.ts +276 -0
- package/src/data-structures/stack/stack.ts +230 -0
- package/src/data-structures/trie/trie.ts +283 -7
- package/src/interfaces/graph.ts +1 -1
- package/src/types/common.ts +2 -2
- package/src/types/data-structures/binary-tree/bst.ts +1 -0
- package/src/types/data-structures/binary-tree/tree-map.ts +6 -0
- package/src/types/data-structures/binary-tree/tree-multi-set.ts +5 -0
- package/src/types/data-structures/binary-tree/tree-set.ts +5 -0
- package/src/types/data-structures/heap/heap.ts +1 -0
- package/src/types/data-structures/priority-queue/priority-queue.ts +1 -0
- package/src/types/utils/validate-type.ts +4 -4
- package/vercel.json +6 -0
- package/dist/leetcode/avl-tree-counter.mjs +0 -2957
- package/dist/leetcode/avl-tree-multi-map.mjs +0 -2889
- package/dist/leetcode/avl-tree.mjs +0 -2720
- package/dist/leetcode/binary-tree.mjs +0 -1594
- package/dist/leetcode/bst.mjs +0 -2398
- package/dist/leetcode/deque.mjs +0 -683
- package/dist/leetcode/directed-graph.mjs +0 -1733
- package/dist/leetcode/doubly-linked-list.mjs +0 -709
- package/dist/leetcode/hash-map.mjs +0 -493
- package/dist/leetcode/heap.mjs +0 -542
- package/dist/leetcode/max-heap.mjs +0 -375
- package/dist/leetcode/max-priority-queue.mjs +0 -383
- package/dist/leetcode/min-heap.mjs +0 -363
- package/dist/leetcode/min-priority-queue.mjs +0 -371
- package/dist/leetcode/priority-queue.mjs +0 -363
- package/dist/leetcode/queue.mjs +0 -943
- package/dist/leetcode/red-black-tree.mjs +0 -2765
- package/dist/leetcode/singly-linked-list.mjs +0 -754
- package/dist/leetcode/stack.mjs +0 -217
- package/dist/leetcode/tree-counter.mjs +0 -3039
- package/dist/leetcode/tree-multi-map.mjs +0 -2913
- package/dist/leetcode/trie.mjs +0 -413
- package/dist/leetcode/undirected-graph.mjs +0 -1650
|
@@ -0,0 +1,825 @@
|
|
|
1
|
+
---
|
|
2
|
+
sidebar_label: "INTEGRATIONS"
|
|
3
|
+
description: "Integrate data-structure-typed with React, Express, NestJS, and other frameworks. Production-ready patterns."
|
|
4
|
+
title: "Framework Integrations — React, Express, NestJS"
|
|
5
|
+
keywords: [data-structure-typed react, typescript data structures express, nestjs data structures, production patterns]
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
# INTEGRATIONS
|
|
9
|
+
|
|
10
|
+
How to use data-structure-typed with React, Express, Nest.js, and other frameworks.
|
|
11
|
+
|
|
12
|
+
**[Back to README](/.md) • [Code Examples](/guide/guides.md) • [Performance](/guide/performance.md)**
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Table of Contents
|
|
17
|
+
|
|
18
|
+
1. [React Integration](#react-integration)
|
|
19
|
+
2. [Express Integration](#express-integration)
|
|
20
|
+
3. [Nest.js Integration](#nestjs-integration)
|
|
21
|
+
4. [TypeScript Configuration](#typescript-configuration)
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
## React Integration
|
|
26
|
+
|
|
27
|
+
### Use Case: Sorted State Management
|
|
28
|
+
|
|
29
|
+
```tsx
|
|
30
|
+
import { useCallback, useMemo, useState } from 'react';
|
|
31
|
+
import { RedBlackTree } from 'data-structure-typed';
|
|
32
|
+
|
|
33
|
+
interface TodoItem {
|
|
34
|
+
id: number;
|
|
35
|
+
text: string;
|
|
36
|
+
completed: boolean;
|
|
37
|
+
priority: number;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/**
|
|
41
|
+
* ╔═════════════════════════════════════════════════════════════════════════╗
|
|
42
|
+
* ║ PERFORMANCE COMPARISON TABLE ║
|
|
43
|
+
* ╠═════════════════╦═══════════════════╦═════════════════╦═════════════════╣
|
|
44
|
+
* ║ Operation ║ RedBlackTree ║ Array ║ Speedup ║
|
|
45
|
+
* ╠═════════════════╬═══════════════════╬═════════════════╬═════════════════╣
|
|
46
|
+
* ║ Add todo ║ O(log n) ║ O(n log n) ║ Often much faster* ║
|
|
47
|
+
* ║ Delete todo ║ O(log n) ║ O(n) ║ Often faster* ║
|
|
48
|
+
* ║ Keep sorted ║ Automatic ✓ ║ Manual sort ✗ ║ Less code ║
|
|
49
|
+
* ║ Rebalancing ║ Self-balancing ✓ ║ N/A ║ N/A ║
|
|
50
|
+
* ╠═════════════════╩═══════════════════╩═════════════════╩══════════════════╣
|
|
51
|
+
* ║ *See PERFORMANCE.md for measured benchmarks and how results scale. ║
|
|
52
|
+
* ╚═════════════════════════════════════════════════════════════════════════╝
|
|
53
|
+
*/
|
|
54
|
+
export default function TodoApp() {
|
|
55
|
+
const [text, setText] = useState('');
|
|
56
|
+
const [priority, setPriority] = useState(5);
|
|
57
|
+
|
|
58
|
+
const [todos, setTodos] = useState(() =>
|
|
59
|
+
new RedBlackTree<TodoItem>([], {
|
|
60
|
+
// Comparator ensures todos are ALWAYS sorted by priority (descending)
|
|
61
|
+
// RedBlackTree maintains this order automatically on every insertion
|
|
62
|
+
// With Array, you'd need to manually sort() after each add → expensive!
|
|
63
|
+
comparator: (a, b) => b.priority - a.priority
|
|
64
|
+
}));
|
|
65
|
+
|
|
66
|
+
const addTodo = useCallback(() => {
|
|
67
|
+
if (!text.trim()) return;
|
|
68
|
+
|
|
69
|
+
setTodos((prev) => {
|
|
70
|
+
const next = prev.clone();
|
|
71
|
+
|
|
72
|
+
// This insertion maintains sorted order automatically
|
|
73
|
+
// The Red-Black Tree algorithm handles all the balancing
|
|
74
|
+
next.add({
|
|
75
|
+
id: Date.now(),
|
|
76
|
+
text: text.trim(),
|
|
77
|
+
completed: false,
|
|
78
|
+
priority: Math.max(1, Math.min(10, priority)),
|
|
79
|
+
});
|
|
80
|
+
return next;
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
}, [text, priority]);
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Delete a todo efficiently
|
|
87
|
+
*
|
|
88
|
+
* Performance Analysis:
|
|
89
|
+
* ──────────────────
|
|
90
|
+
* ✅ RedBlackTree.delete(): O(log n)
|
|
91
|
+
* - For 1000 items: ~10 tree operations
|
|
92
|
+
* - No need to shift array elements
|
|
93
|
+
* - Red-Black Tree rebalances automatically
|
|
94
|
+
*
|
|
95
|
+
* ❌ Array Alternative:
|
|
96
|
+
* - Array.findIndex(): O(n) to find the item
|
|
97
|
+
* - Array.splice(): O(n) to remove and shift all elements
|
|
98
|
+
* - For 1000 items: ~500 operations per delete
|
|
99
|
+
* - Note: Actual wall-clock impact depends on your workload (rendering, GC, object shapes, etc.).
|
|
100
|
+
*/
|
|
101
|
+
const deleteTodo = useCallback((todo: TodoItem) => {
|
|
102
|
+
setTodos((prev) => {
|
|
103
|
+
const next = prev.clone();
|
|
104
|
+
next.delete(todo); // ← O(log n) deletion
|
|
105
|
+
return next;
|
|
106
|
+
});
|
|
107
|
+
}, []);
|
|
108
|
+
|
|
109
|
+
const todoList = useMemo(() => [...todos.keys()], [todos]);
|
|
110
|
+
|
|
111
|
+
return (
|
|
112
|
+
<div className="todo-app">
|
|
113
|
+
<h2>Priority Todos (Auto-Sorted)</h2>
|
|
114
|
+
<div className="input-section">
|
|
115
|
+
<input
|
|
116
|
+
type="text"
|
|
117
|
+
placeholder="Todo text"
|
|
118
|
+
value={text}
|
|
119
|
+
onChange={(e) => setText(e.target.value)}
|
|
120
|
+
/>
|
|
121
|
+
<input
|
|
122
|
+
type="number"
|
|
123
|
+
min="1"
|
|
124
|
+
max="10"
|
|
125
|
+
placeholder="Priority (1-10)"
|
|
126
|
+
value={priority}
|
|
127
|
+
onChange={(e) =>
|
|
128
|
+
setPriority(Math.max(1, Math.min(10, Number(e.target.value))))
|
|
129
|
+
}
|
|
130
|
+
/>
|
|
131
|
+
<button onClick={addTodo} disabled={!text.trim()}>
|
|
132
|
+
Add Todo
|
|
133
|
+
</button>
|
|
134
|
+
</div>
|
|
135
|
+
<ul className="todo-list">
|
|
136
|
+
{todoList.map((todo) => (
|
|
137
|
+
<li key={todo.id} className={todo.completed ? 'completed' : ''}>
|
|
138
|
+
<input
|
|
139
|
+
type="checkbox"
|
|
140
|
+
checked={todo.completed}
|
|
141
|
+
onChange={() => {
|
|
142
|
+
setTodos((prev) => {
|
|
143
|
+
const next = prev.clone();
|
|
144
|
+
|
|
145
|
+
// Delete the old todo object
|
|
146
|
+
next.delete(todo);
|
|
147
|
+
next.add({ ...todo, completed: !todo.completed });
|
|
148
|
+
return next;
|
|
149
|
+
});
|
|
150
|
+
}}
|
|
151
|
+
/>
|
|
152
|
+
<span>{todo.text}</span>
|
|
153
|
+
<span className="priority">P{todo.priority}</span>
|
|
154
|
+
<button onClick={() => deleteTodo(todo)}>Delete</button>
|
|
155
|
+
</li>
|
|
156
|
+
))}
|
|
157
|
+
</ul>
|
|
158
|
+
</div>
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
---
|
|
164
|
+
|
|
165
|
+
## Express Integration
|
|
166
|
+
|
|
167
|
+
### Use Case: LRU Cache Middleware
|
|
168
|
+
|
|
169
|
+
```javascript
|
|
170
|
+
const {DoublyLinkedList} = require('data-structure-typed');
|
|
171
|
+
|
|
172
|
+
class LRUCache {
|
|
173
|
+
constructor(capacity = 100) {
|
|
174
|
+
this.cache = new Map();
|
|
175
|
+
this.order = new DoublyLinkedList();
|
|
176
|
+
this.capacity = capacity;
|
|
177
|
+
}
|
|
178
|
+
get(key) {
|
|
179
|
+
if (!this.cache.has(key))
|
|
180
|
+
return null;
|
|
181
|
+
const { value, node } = this.cache.get(key);
|
|
182
|
+
// Move to end (most recently used)
|
|
183
|
+
this.order.delete(node);
|
|
184
|
+
const newNode = this.order.push(key);
|
|
185
|
+
this.cache.set(key, { value, node: newNode });
|
|
186
|
+
return value;
|
|
187
|
+
}
|
|
188
|
+
set(key, value) {
|
|
189
|
+
if (this.cache.has(key)) {
|
|
190
|
+
this.get(key); // Mark as recently used
|
|
191
|
+
this.cache.get(key).value = value;
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
if (this.cache.size >= this.capacity) {
|
|
195
|
+
const lru = this.order.shift();
|
|
196
|
+
this.cache.delete(lru);
|
|
197
|
+
}
|
|
198
|
+
const node = this.order.push(key);
|
|
199
|
+
this.cache.set(key, { value, node });
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
module.exports = LRUCache;
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
```javascript
|
|
207
|
+
// Usage in Express
|
|
208
|
+
const app = express();
|
|
209
|
+
const responseCache = new LRUCache(50);
|
|
210
|
+
app.use((req, res, next) => {
|
|
211
|
+
const cachedResponse = responseCache.get(req.url);
|
|
212
|
+
if (cachedResponse) {
|
|
213
|
+
return res.status(cachedResponse.status).json(cachedResponse.data);
|
|
214
|
+
}
|
|
215
|
+
// Wrap original send to cache response
|
|
216
|
+
const originalSend = res.send;
|
|
217
|
+
res.send = function (data) {
|
|
218
|
+
responseCache.set(req.url, { status: res.statusCode, data });
|
|
219
|
+
return originalSend.call(this, data);
|
|
220
|
+
};
|
|
221
|
+
next();
|
|
222
|
+
});
|
|
223
|
+
app.get('/api/data', (req, res) => {
|
|
224
|
+
res.json({ message: 'Cached response' });
|
|
225
|
+
});
|
|
226
|
+
app.listen(3000);
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
### Use Case: Rate Limiting with Deque
|
|
230
|
+
|
|
231
|
+
```typescript
|
|
232
|
+
import { Deque } from 'data-structure-typed';
|
|
233
|
+
|
|
234
|
+
class RateLimiter {
|
|
235
|
+
private requests = new Map<string, Deque<number>>();
|
|
236
|
+
private limit: number;
|
|
237
|
+
private windowMs: number;
|
|
238
|
+
|
|
239
|
+
constructor(limit: number = 100, windowMs: number = 60000) {
|
|
240
|
+
this.limit = limit;
|
|
241
|
+
this.windowMs = windowMs;
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
isAllowed(clientId: string): boolean {
|
|
245
|
+
const now = Date.now();
|
|
246
|
+
|
|
247
|
+
if (!this.requests.has(clientId)) {
|
|
248
|
+
this.requests.set(clientId, new Deque());
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
const deque = this.requests.get(clientId)!;
|
|
252
|
+
|
|
253
|
+
// Remove old requests outside window
|
|
254
|
+
while (!deque.isEmpty && deque.peekFirst()! < now - this.windowMs) {
|
|
255
|
+
deque.shift();
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
// Check limit
|
|
259
|
+
if (deque.size >= this.limit) {
|
|
260
|
+
return false;
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
// Add new request
|
|
264
|
+
deque.push(now);
|
|
265
|
+
return true;
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Usage in Express
|
|
270
|
+
const app = express();
|
|
271
|
+
const limiter = new RateLimiter(10, 60000); // 10 requests per minute
|
|
272
|
+
|
|
273
|
+
app.use((req: Request, res: Response, next: Function) => {
|
|
274
|
+
const clientId = req.ip;
|
|
275
|
+
|
|
276
|
+
if (!limiter.isAllowed(clientId)) {
|
|
277
|
+
return res.status(429).json({ error: 'Too many requests' });
|
|
278
|
+
}
|
|
279
|
+
|
|
280
|
+
next();
|
|
281
|
+
});
|
|
282
|
+
|
|
283
|
+
app.get('/api/data', (req, res) => {
|
|
284
|
+
res.json({ data: 'Your data here' });
|
|
285
|
+
});
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Nest.js Integration
|
|
291
|
+
|
|
292
|
+
### Use Case: Product Price Index Service
|
|
293
|
+
|
|
294
|
+
```typescript
|
|
295
|
+
import {
|
|
296
|
+
BadRequestException,
|
|
297
|
+
Injectable,
|
|
298
|
+
NotFoundException,
|
|
299
|
+
} from '@nestjs/common';
|
|
300
|
+
|
|
301
|
+
import { Range, RedBlackTree } from 'data-structure-typed';
|
|
302
|
+
|
|
303
|
+
export interface Product {
|
|
304
|
+
id: string;
|
|
305
|
+
name: string;
|
|
306
|
+
price: number;
|
|
307
|
+
quantity: number;
|
|
308
|
+
category: string;
|
|
309
|
+
lastUpdated?: Date;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
/** KEY INSIGHT: Use compound keys to solve the problem of "multiple products at the same price" */
|
|
313
|
+
interface CompositeKey {
|
|
314
|
+
price: number;
|
|
315
|
+
productId: string;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
export type TierName = 'budget' | 'mid-range' | 'premium';
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* Product Price Index Service using Red-Black Tree with Composite Keys
|
|
322
|
+
*
|
|
323
|
+
* ⭐ Performance vs Alternatives:
|
|
324
|
+
*
|
|
325
|
+
* Operation | RBTree(this approach) | Array | HashMap + Sort
|
|
326
|
+
* -------------------|-----------------------|-----------|---------------
|
|
327
|
+
* Range Query | O(log n + k) | O(n) | O(k log k)
|
|
328
|
+
* Point Lookup | O(1) | O(1) | O(1)
|
|
329
|
+
* Insert/Update | O(log n) | O(n) | O(log n)
|
|
330
|
+
* Sort by Price | O(n) | O(n log n)| O(n log n)
|
|
331
|
+
* Multiple at Price | ✓ Supported | ✓ | Complex
|
|
332
|
+
*
|
|
333
|
+
* Advantages:
|
|
334
|
+
* - O(1) idToKeyMap lookup + O(log n) tree operations
|
|
335
|
+
* - Automatic ordering without post-sort
|
|
336
|
+
* - Efficient range queries for pricing tiers
|
|
337
|
+
* - Low memory footprint vs duplicate maps
|
|
338
|
+
*/
|
|
339
|
+
@Injectable()
|
|
340
|
+
export class ProductPriceIndexService {
|
|
341
|
+
private priceIndex: RedBlackTree<CompositeKey, Product>;
|
|
342
|
+
private idToKeyMap: Map<string, CompositeKey>;
|
|
343
|
+
|
|
344
|
+
constructor() {
|
|
345
|
+
this.priceIndex = new RedBlackTree([], {
|
|
346
|
+
comparator: (a: CompositeKey, b: CompositeKey) => {
|
|
347
|
+
const priceCmp = a.price - b.price;
|
|
348
|
+
if (priceCmp !== 0) return priceCmp;
|
|
349
|
+
return a.productId.localeCompare(b.productId);
|
|
350
|
+
},
|
|
351
|
+
});
|
|
352
|
+
this.idToKeyMap = new Map();
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
/** Time Complexity: O(log n) */
|
|
356
|
+
addProduct(product: Product): Product {
|
|
357
|
+
if (this.idToKeyMap.has(product.id))
|
|
358
|
+
throw new BadRequestException(`Product ${product.id} already exists`);
|
|
359
|
+
|
|
360
|
+
product.lastUpdated = new Date();
|
|
361
|
+
|
|
362
|
+
const key: CompositeKey = {
|
|
363
|
+
price: product.price,
|
|
364
|
+
productId: product.id,
|
|
365
|
+
};
|
|
366
|
+
|
|
367
|
+
this.priceIndex.add(key, product);
|
|
368
|
+
this.idToKeyMap.set(product.id, key);
|
|
369
|
+
|
|
370
|
+
return product;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
/** Time Complexity: O(log n) */
|
|
374
|
+
updateProduct(productId: string, updates: Partial<Product>): Product {
|
|
375
|
+
const oldKey = this.idToKeyMap.get(productId);
|
|
376
|
+
if (oldKey === undefined)
|
|
377
|
+
throw new NotFoundException(`Product ${productId} not found`);
|
|
378
|
+
|
|
379
|
+
const existing = this.priceIndex.get(oldKey);
|
|
380
|
+
if (!existing)
|
|
381
|
+
throw new NotFoundException(`Product ${productId} not found`);
|
|
382
|
+
|
|
383
|
+
const updated: Product = {
|
|
384
|
+
...existing,
|
|
385
|
+
...updates,
|
|
386
|
+
id: existing.id,
|
|
387
|
+
lastUpdated: new Date(),
|
|
388
|
+
};
|
|
389
|
+
|
|
390
|
+
const newPrice = updates.price ?? existing.price;
|
|
391
|
+
|
|
392
|
+
this.priceIndex.delete(oldKey);
|
|
393
|
+
const currentKey: CompositeKey = {
|
|
394
|
+
price: newPrice,
|
|
395
|
+
productId,
|
|
396
|
+
};
|
|
397
|
+
this.priceIndex.set(currentKey, updated);
|
|
398
|
+
this.idToKeyMap.set(productId, currentKey);
|
|
399
|
+
|
|
400
|
+
return updated;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/** Time Complexity: O(1) */
|
|
404
|
+
getProductById(productId: string): Product {
|
|
405
|
+
const key = this.idToKeyMap.get(productId);
|
|
406
|
+
|
|
407
|
+
if (key === undefined)
|
|
408
|
+
throw new NotFoundException(`Product ${productId} not found`);
|
|
409
|
+
|
|
410
|
+
return this.priceIndex.get(key)!;
|
|
411
|
+
}
|
|
412
|
+
|
|
413
|
+
/** Time Complexity: O(log n + k) */
|
|
414
|
+
getProductsByPriceRange(minPrice: number, maxPrice: number): Product[] {
|
|
415
|
+
const range = new Range(
|
|
416
|
+
{ price: minPrice, productId: '' },
|
|
417
|
+
{ price: maxPrice, productId: '\uffff' },
|
|
418
|
+
true, // includeLow
|
|
419
|
+
true, // includeHigh
|
|
420
|
+
);
|
|
421
|
+
|
|
422
|
+
const keys = this.priceIndex.rangeSearch(range, (n) => n.key);
|
|
423
|
+
return keys.map((key) => this.priceIndex.get(key)!);
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
/** Time Complexity: O(log n) */
|
|
427
|
+
getHighestPricedProductWithinBudget(maxBudget: number): Product | null {
|
|
428
|
+
const key: CompositeKey = {
|
|
429
|
+
price: maxBudget,
|
|
430
|
+
productId: '\uffff',
|
|
431
|
+
};
|
|
432
|
+
const floorKey = this.priceIndex.floor(key);
|
|
433
|
+
return floorKey ? this.priceIndex.get(floorKey)! : null;
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
/** Time O(log n) */
|
|
437
|
+
getCheapestProductAbovePrice(minPrice: number): Product | null {
|
|
438
|
+
const key: CompositeKey = {
|
|
439
|
+
price: minPrice,
|
|
440
|
+
productId: '\uffff',
|
|
441
|
+
};
|
|
442
|
+
const higherKey = this.priceIndex.higher(key);
|
|
443
|
+
return higherKey ? this.priceIndex.get(higherKey)! : null;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
/** Time Complexity: O(log n + k) */
|
|
447
|
+
getProductsByTier(tierName: TierName): Product[] {
|
|
448
|
+
const tiers = {
|
|
449
|
+
budget: [0, 50],
|
|
450
|
+
'mid-range': [50, 200],
|
|
451
|
+
premium: [200, Infinity],
|
|
452
|
+
};
|
|
453
|
+
|
|
454
|
+
const [min, max] = tiers[tierName];
|
|
455
|
+
return this.getProductsByPriceRange(min, max);
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/** Time Complexity: O(log n + k + m) */
|
|
459
|
+
getProductsByPriceAndCategory(
|
|
460
|
+
minPrice: number,
|
|
461
|
+
maxPrice: number,
|
|
462
|
+
category: string,
|
|
463
|
+
): Product[] {
|
|
464
|
+
const priceRangeProducts = this.getProductsByPriceRange(minPrice, maxPrice);
|
|
465
|
+
return priceRangeProducts.filter(
|
|
466
|
+
(p) => p.category.toLowerCase() === category.toLowerCase(),
|
|
467
|
+
);
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
/** Time Complexity: O((log n + k) * log n) */
|
|
471
|
+
applyDiscountToRange(
|
|
472
|
+
minPrice: number,
|
|
473
|
+
maxPrice: number,
|
|
474
|
+
discountPercent: number,
|
|
475
|
+
): Product[] {
|
|
476
|
+
const products = this.getProductsByPriceRange(minPrice, maxPrice);
|
|
477
|
+
const updated: Product[] = [];
|
|
478
|
+
|
|
479
|
+
for (const product of products) {
|
|
480
|
+
const newPrice = product.price * (1 - discountPercent / 100);
|
|
481
|
+
const updatedProduct = this.updateProduct(product.id, {
|
|
482
|
+
price: newPrice,
|
|
483
|
+
});
|
|
484
|
+
updated.push(updatedProduct);
|
|
485
|
+
}
|
|
486
|
+
|
|
487
|
+
return updated;
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
/** Time Complexity: O(log n) */
|
|
491
|
+
deleteProduct(productId: string): void {
|
|
492
|
+
const key = this.idToKeyMap.get(productId);
|
|
493
|
+
|
|
494
|
+
if (key === undefined)
|
|
495
|
+
throw new NotFoundException(`Product ${productId} not found`);
|
|
496
|
+
|
|
497
|
+
this.priceIndex.delete(key);
|
|
498
|
+
this.idToKeyMap.delete(productId);
|
|
499
|
+
}
|
|
500
|
+
|
|
501
|
+
/** Time Complexity: O(n) */
|
|
502
|
+
getStatistics(): {
|
|
503
|
+
totalProducts: number;
|
|
504
|
+
priceRange: { min: number; max: number };
|
|
505
|
+
averagePrice: number;
|
|
506
|
+
totalValue: number;
|
|
507
|
+
} {
|
|
508
|
+
if (this.idToKeyMap.size === 0) {
|
|
509
|
+
return {
|
|
510
|
+
totalProducts: 0,
|
|
511
|
+
priceRange: { min: 0, max: 0 },
|
|
512
|
+
averagePrice: 0,
|
|
513
|
+
totalValue: 0,
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
let minPrice = Infinity;
|
|
518
|
+
let maxPrice = -Infinity;
|
|
519
|
+
let totalValue = 0;
|
|
520
|
+
let totalProducts = 0;
|
|
521
|
+
|
|
522
|
+
let entry = this.priceIndex.getLeftMost((node) => node);
|
|
523
|
+
|
|
524
|
+
while (entry) {
|
|
525
|
+
const product = this.priceIndex.get(entry.key);
|
|
526
|
+
if (product) {
|
|
527
|
+
minPrice = Math.min(minPrice, product.price);
|
|
528
|
+
maxPrice = Math.max(maxPrice, product.price);
|
|
529
|
+
totalValue += product.price * product.quantity;
|
|
530
|
+
totalProducts += product.quantity;
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
entry = this.priceIndex.higher(entry.key, (node) => node);
|
|
534
|
+
}
|
|
535
|
+
|
|
536
|
+
return {
|
|
537
|
+
totalProducts: totalProducts,
|
|
538
|
+
priceRange: { min: minPrice, max: maxPrice },
|
|
539
|
+
averagePrice: totalValue / totalProducts,
|
|
540
|
+
totalValue,
|
|
541
|
+
};
|
|
542
|
+
}
|
|
543
|
+
|
|
544
|
+
/** Time Complexity: O(n) */
|
|
545
|
+
getAllProductsSortedByPrice(): Product[] {
|
|
546
|
+
const products: Product[] = [];
|
|
547
|
+
let curNode = this.priceIndex.getLeftMost((node) => node);
|
|
548
|
+
|
|
549
|
+
while (curNode) {
|
|
550
|
+
if (curNode.key) products.push(this.priceIndex.get(curNode.key)!);
|
|
551
|
+
curNode = this.priceIndex.higher(curNode.key, (node) => node);
|
|
552
|
+
}
|
|
553
|
+
|
|
554
|
+
return products;
|
|
555
|
+
}
|
|
556
|
+
|
|
557
|
+
/** O(1) */
|
|
558
|
+
getProductCount(): number {
|
|
559
|
+
return this.idToKeyMap.size;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/** O(1) */
|
|
563
|
+
hasProduct(productId: string): boolean {
|
|
564
|
+
return this.idToKeyMap.has(productId);
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
/** O(n) */
|
|
568
|
+
getAllProductIds(): string[] {
|
|
569
|
+
return [...this.idToKeyMap.keys()];
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
```
|
|
574
|
+
|
|
575
|
+
### Use Case: Task Queue Controller
|
|
576
|
+
|
|
577
|
+
```typescript
|
|
578
|
+
import { Controller, Post, Body, Get } from '@nestjs/common';
|
|
579
|
+
import { MaxPriorityQueue } from 'data-structure-typed';
|
|
580
|
+
|
|
581
|
+
export interface QueuedTask {
|
|
582
|
+
id: string;
|
|
583
|
+
action: string;
|
|
584
|
+
priority: number;
|
|
585
|
+
createdAt: Date;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
@Controller('tasks')
|
|
589
|
+
export class TaskController {
|
|
590
|
+
private taskQueue = new MaxPriorityQueue<QueuedTask>([], {
|
|
591
|
+
comparator: (a, b) => a.priority - b.priority,
|
|
592
|
+
});
|
|
593
|
+
|
|
594
|
+
@Post('add')
|
|
595
|
+
addTask(@Body() task: QueuedTask): { success: boolean; queueSize: number } {
|
|
596
|
+
this.taskQueue.add(task);
|
|
597
|
+
return {
|
|
598
|
+
success: true,
|
|
599
|
+
queueSize: this.taskQueue.size,
|
|
600
|
+
};
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
@Post('process')
|
|
604
|
+
processNext(): { success: boolean; task: QueuedTask | null } {
|
|
605
|
+
const task = this.taskQueue.poll();
|
|
606
|
+
return {
|
|
607
|
+
success: !!task,
|
|
608
|
+
task: task || null,
|
|
609
|
+
};
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
@Get('queue-size')
|
|
613
|
+
getQueueSize(): { size: number } {
|
|
614
|
+
return { size: this.taskQueue.size };
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
```
|
|
618
|
+
|
|
619
|
+
---
|
|
620
|
+
|
|
621
|
+
## TypeScript Configuration
|
|
622
|
+
|
|
623
|
+
### tsconfig.json for data-structure-typed
|
|
624
|
+
|
|
625
|
+
```json
|
|
626
|
+
{
|
|
627
|
+
"compilerOptions": {
|
|
628
|
+
"target": "ES2020",
|
|
629
|
+
"module": "ES2020",
|
|
630
|
+
"lib": ["ES2020", "DOM"],
|
|
631
|
+
"strict": true,
|
|
632
|
+
"esModuleInterop": true,
|
|
633
|
+
"skipLibCheck": true,
|
|
634
|
+
"forceConsistentCasingInFileNames": true,
|
|
635
|
+
"resolveJsonModule": true,
|
|
636
|
+
"declaration": true,
|
|
637
|
+
"declarationMap": true,
|
|
638
|
+
"sourceMap": true
|
|
639
|
+
}
|
|
640
|
+
}
|
|
641
|
+
```
|
|
642
|
+
|
|
643
|
+
### Package.json Setup
|
|
644
|
+
|
|
645
|
+
```json
|
|
646
|
+
{
|
|
647
|
+
"dependencies": {
|
|
648
|
+
"data-structure-typed": "^latest"
|
|
649
|
+
},
|
|
650
|
+
"devDependencies": {
|
|
651
|
+
"typescript": "^5.0.0",
|
|
652
|
+
"@types/node": "^latest"
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
```
|
|
656
|
+
|
|
657
|
+
---
|
|
658
|
+
|
|
659
|
+
## Import Patterns
|
|
660
|
+
|
|
661
|
+
### All Structures
|
|
662
|
+
|
|
663
|
+
```typescript
|
|
664
|
+
import {
|
|
665
|
+
// Trees
|
|
666
|
+
BST,
|
|
667
|
+
AVLTree,
|
|
668
|
+
RedBlackTree,
|
|
669
|
+
BSTNode,
|
|
670
|
+
TreeMultiMap,
|
|
671
|
+
|
|
672
|
+
// Linear
|
|
673
|
+
Stack,
|
|
674
|
+
Queue,
|
|
675
|
+
Deque,
|
|
676
|
+
LinkedList,
|
|
677
|
+
SinglyLinkedList,
|
|
678
|
+
DoublyLinkedList,
|
|
679
|
+
|
|
680
|
+
// Heap
|
|
681
|
+
Heap,
|
|
682
|
+
MinHeap,
|
|
683
|
+
MaxHeap,
|
|
684
|
+
MinPriorityQueue,
|
|
685
|
+
MaxPriorityQueue,
|
|
686
|
+
|
|
687
|
+
// Special
|
|
688
|
+
Trie,
|
|
689
|
+
DirectedGraph,
|
|
690
|
+
UndirectedGraph,
|
|
691
|
+
|
|
692
|
+
// Utilities
|
|
693
|
+
SegmentTree,
|
|
694
|
+
FenwickTree
|
|
695
|
+
} from 'data-structure-typed';
|
|
696
|
+
```
|
|
697
|
+
|
|
698
|
+
### Module Systems
|
|
699
|
+
|
|
700
|
+
```js
|
|
701
|
+
// ES Module (ESM)
|
|
702
|
+
import { RedBlackTree } from 'data-structure-typed';
|
|
703
|
+
|
|
704
|
+
// CommonJS
|
|
705
|
+
const { RedBlackTree } = require('data-structure-typed');
|
|
706
|
+
|
|
707
|
+
// TypeScript with full typing
|
|
708
|
+
import { RedBlackTree } from 'data-structure-typed/dist/esm/red-black-tree';
|
|
709
|
+
|
|
710
|
+
// CDN (for browsers)
|
|
711
|
+
<script src="https://cdn.jsdelivr.net/npm/data-structure-typed/dist/umd/data-structure-typed.min.js"></script>
|
|
712
|
+
<script>
|
|
713
|
+
const tree = new DataStructureTyped.RedBlackTree();
|
|
714
|
+
</script>
|
|
715
|
+
```
|
|
716
|
+
|
|
717
|
+
---
|
|
718
|
+
|
|
719
|
+
## Common Integration Patterns
|
|
720
|
+
|
|
721
|
+
### Pattern 1: Dependency Injection (Nest.js)
|
|
722
|
+
|
|
723
|
+
```typescript
|
|
724
|
+
import { Module } from '@nestjs/common';
|
|
725
|
+
import { ProductInventoryService } from './product-inventory.service';
|
|
726
|
+
|
|
727
|
+
@Module({
|
|
728
|
+
providers: [ProductInventoryService],
|
|
729
|
+
exports: [ProductInventoryService]
|
|
730
|
+
})
|
|
731
|
+
export class ProductInventoryModule {}
|
|
732
|
+
|
|
733
|
+
// Use in other services
|
|
734
|
+
@Injectable()
|
|
735
|
+
export class OutherService {
|
|
736
|
+
constructor(private inventoryService: ProductInventoryService) {}
|
|
737
|
+
|
|
738
|
+
async addProduct(product: Product): Promise<void> {
|
|
739
|
+
this.inventoryService.addProduct(product);
|
|
740
|
+
}
|
|
741
|
+
}
|
|
742
|
+
```
|
|
743
|
+
|
|
744
|
+
### Pattern 2: React Hooks
|
|
745
|
+
|
|
746
|
+
```tsx
|
|
747
|
+
import {useCallback, useRef, useState} from 'react';
|
|
748
|
+
import {RedBlackTree} from 'data-structure-typed';
|
|
749
|
+
|
|
750
|
+
function useSortedList<T>(initialData: T[] = []) {
|
|
751
|
+
const treeRef = useRef(new RedBlackTree<number, T>(initialData));
|
|
752
|
+
const [, setUpdateTrigger] = useState({});
|
|
753
|
+
|
|
754
|
+
const add = useCallback((index: number, item: T) => {
|
|
755
|
+
treeRef.current.set(index, item);
|
|
756
|
+
setUpdateTrigger({});
|
|
757
|
+
}, []);
|
|
758
|
+
|
|
759
|
+
const remove = useCallback((index: number) => {
|
|
760
|
+
treeRef.current.delete(index);
|
|
761
|
+
setUpdateTrigger({});
|
|
762
|
+
}, []);
|
|
763
|
+
|
|
764
|
+
const getAll = useCallback(() => {
|
|
765
|
+
return [...treeRef.current.values()];
|
|
766
|
+
}, []);
|
|
767
|
+
|
|
768
|
+
return {add, remove, getAll};
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
// Usage
|
|
772
|
+
function MyComponent() {
|
|
773
|
+
const {add, remove, getAll} = useSortedList<string>([]);
|
|
774
|
+
|
|
775
|
+
return (
|
|
776
|
+
<div>
|
|
777
|
+
<button onClick={() => add(1, 'Item 1')}>Add Item</button>
|
|
778
|
+
<ul>
|
|
779
|
+
{getAll().map((item, i) => (
|
|
780
|
+
<li key={i} onClick={() => remove(i)}>{item}</li>
|
|
781
|
+
))}
|
|
782
|
+
</ul>
|
|
783
|
+
</div>
|
|
784
|
+
);
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
export default MyComponent;
|
|
788
|
+
```
|
|
789
|
+
|
|
790
|
+
---
|
|
791
|
+
|
|
792
|
+
## Troubleshooting
|
|
793
|
+
|
|
794
|
+
### Issue: Import Error
|
|
795
|
+
|
|
796
|
+
```typescript
|
|
797
|
+
// ❌ Wrong
|
|
798
|
+
import RedBlackTree from 'data-structure-typed';
|
|
799
|
+
|
|
800
|
+
// ✅ Correct
|
|
801
|
+
import { RedBlackTree } from 'data-structure-typed';
|
|
802
|
+
```
|
|
803
|
+
|
|
804
|
+
### Issue: Type Not Found
|
|
805
|
+
|
|
806
|
+
```shell
|
|
807
|
+
// Make sure TypeScript configuration is correct
|
|
808
|
+
// and you have the latest type definitions
|
|
809
|
+
npm update data-structure-typed
|
|
810
|
+
```
|
|
811
|
+
|
|
812
|
+
### Issue: Performance in Development
|
|
813
|
+
|
|
814
|
+
```shell
|
|
815
|
+
// Development mode is slower due to hot reload
|
|
816
|
+
// Use production build for benchmarking:
|
|
817
|
+
npm run build
|
|
818
|
+
NODE_ENV=production node your-app.js
|
|
819
|
+
```
|
|
820
|
+
|
|
821
|
+
---
|
|
822
|
+
|
|
823
|
+
**Need more examples?** Check [GUIDES.md](/guide/guides.md) for more patterns.
|
|
824
|
+
|
|
825
|
+
**Performance questions?** See [PERFORMANCE.md](/guide/performance.md).
|