@bepalo/router 1.11.32 → 1.12.33

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 (72) hide show
  1. package/dist/cjs/framework.d.ts +2 -4
  2. package/dist/cjs/framework.d.ts.map +1 -1
  3. package/dist/cjs/framework.js +4 -6
  4. package/dist/cjs/framework.js.map +1 -1
  5. package/dist/cjs/helpers.d.ts +2 -2
  6. package/dist/cjs/helpers.d.ts.map +1 -1
  7. package/dist/cjs/helpers.js +1 -1
  8. package/dist/cjs/helpers.js.map +1 -1
  9. package/dist/cjs/index.d.ts +5 -5
  10. package/dist/cjs/index.d.ts.map +1 -1
  11. package/dist/cjs/index.js +5 -5
  12. package/dist/cjs/index.js.map +1 -1
  13. package/dist/cjs/middlewares.d.ts +2 -2
  14. package/dist/cjs/middlewares.d.ts.map +1 -1
  15. package/dist/cjs/middlewares.js +24 -24
  16. package/dist/cjs/middlewares.js.map +1 -1
  17. package/dist/cjs/router.d.ts +2 -2
  18. package/dist/cjs/router.d.ts.map +1 -1
  19. package/dist/cjs/router.js +8 -8
  20. package/dist/cjs/router.js.map +1 -1
  21. package/dist/cjs/types.d.ts +1 -1
  22. package/dist/cjs/types.d.ts.map +1 -1
  23. package/dist/cjs/upload-stream.d.ts +1 -1
  24. package/dist/cjs/upload-stream.d.ts.map +1 -1
  25. package/dist/cjs/upload-stream.js +7 -7
  26. package/dist/cjs/upload-stream.js.map +1 -1
  27. package/dist/framework.d.ts +2 -4
  28. package/dist/framework.d.ts.map +1 -1
  29. package/dist/framework.js +4 -6
  30. package/dist/framework.js.map +1 -1
  31. package/dist/helpers.d.ts +2 -2
  32. package/dist/helpers.d.ts.map +1 -1
  33. package/dist/helpers.js +1 -1
  34. package/dist/helpers.js.map +1 -1
  35. package/dist/index.d.ts +5 -5
  36. package/dist/index.d.ts.map +1 -1
  37. package/dist/index.js +5 -5
  38. package/dist/index.js.map +1 -1
  39. package/dist/middlewares.d.ts +2 -2
  40. package/dist/middlewares.d.ts.map +1 -1
  41. package/dist/middlewares.js +24 -24
  42. package/dist/middlewares.js.map +1 -1
  43. package/dist/router.d.ts +2 -2
  44. package/dist/router.d.ts.map +1 -1
  45. package/dist/router.js +8 -8
  46. package/dist/router.js.map +1 -1
  47. package/dist/types.d.ts +1 -1
  48. package/dist/types.d.ts.map +1 -1
  49. package/dist/upload-stream.d.ts +1 -1
  50. package/dist/upload-stream.d.ts.map +1 -1
  51. package/dist/upload-stream.js +7 -7
  52. package/dist/upload-stream.js.map +1 -1
  53. package/package.json +8 -1
  54. package/src/framework.deno.ts +194 -0
  55. package/src/framework.ts +197 -0
  56. package/src/helpers.ts +829 -0
  57. package/src/index.ts +5 -0
  58. package/src/list.ts +462 -0
  59. package/src/middlewares.deno.ts +851 -0
  60. package/src/middlewares.ts +851 -0
  61. package/src/router.ts +993 -0
  62. package/src/tree.ts +139 -0
  63. package/src/types.ts +197 -0
  64. package/src/upload-stream.ts +661 -0
  65. package/dist/cjs/framework.deno.d.ts +0 -31
  66. package/dist/cjs/framework.deno.d.ts.map +0 -1
  67. package/dist/cjs/framework.deno.js +0 -245
  68. package/dist/cjs/framework.deno.js.map +0 -1
  69. package/dist/framework.deno.d.ts +0 -31
  70. package/dist/framework.deno.d.ts.map +0 -1
  71. package/dist/framework.deno.js +0 -245
  72. package/dist/framework.deno.js.map +0 -1
package/src/index.ts ADDED
@@ -0,0 +1,5 @@
1
+ export * from "./types.ts";
2
+ export * from "./router.ts";
3
+ export * from "./helpers.ts";
4
+ export * from "./middlewares.ts";
5
+ export * from "./framework.ts";
package/src/list.ts ADDED
@@ -0,0 +1,462 @@
1
+ /**
2
+ * @file A minimal and efficient implementation of a doubly-linked list with node-level access.
3
+ * @author Natnael Eshetu
4
+ * @exports List
5
+ * @exports ListNode
6
+ */
7
+
8
+ /**
9
+ * A node in a doubly linked list.
10
+ * @template T
11
+ */
12
+ export class ListNode<T> {
13
+ /**
14
+ * Creates a new ListNode.
15
+ * @param {T} value - Value held by this node.
16
+ * @param {ListNode<T>} [prev] - Previous node in the list.
17
+ * @param {ListNode<T>} [next] - Next node in the list.
18
+ */
19
+ constructor(
20
+ public value: T,
21
+ public prev?: ListNode<T>,
22
+ public next?: ListNode<T>,
23
+ ) {}
24
+ }
25
+
26
+ export class List<T> {
27
+ // Private fields
28
+ #first?: ListNode<T> = undefined;
29
+ #last?: ListNode<T> = undefined;
30
+ #size: number = 0;
31
+
32
+ /**
33
+ * Creates a new List instance. If an iterable is provided, pushes all values into the list.
34
+ * @param {Iterable<T>} [iterable] - Optional iterable of values to initialize the list.
35
+ */
36
+ constructor(iterable?: Iterable<T>) {
37
+ if (iterable) {
38
+ for (const value of iterable) {
39
+ this.push(value);
40
+ }
41
+ }
42
+ }
43
+
44
+ /**
45
+ * Iterates over the values in the list from first to last.
46
+ * @returns {IterableIterator<T>}
47
+ */
48
+ *[Symbol.iterator](): IterableIterator<T> {
49
+ for (let it = this.#first; it != null; it = it.next) {
50
+ yield it.value;
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Alias for [Symbol.iterator].
56
+ * @returns {IterableIterator<T>}
57
+ */
58
+ *entries(): IterableIterator<T> {
59
+ for (let it = this.#first; it != null; it = it.next) {
60
+ yield it.value;
61
+ }
62
+ }
63
+
64
+ /**
65
+ * Iterates over the list nodes (including value, prev, and next).
66
+ * @returns {IterableIterator<ListNode<T>>}
67
+ */
68
+ *iterator(): IterableIterator<ListNode<T>> {
69
+ for (let it = this.#first; it != null; it = it.next) {
70
+ yield it;
71
+ }
72
+ }
73
+
74
+ /**
75
+ * Iterates over the list nodes in reverse (last to first).
76
+ * @returns {IterableIterator<ListNode<T>>}
77
+ */
78
+ *reverseIterator(): IterableIterator<ListNode<T>> {
79
+ for (let it = this.#last; it != null; it = it.prev) {
80
+ yield it;
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Converts the list to an array of values.
86
+ * @returns {T[]}
87
+ */
88
+ toArray(): T[] {
89
+ const values: T[] = new Array(this.#size);
90
+ for (let it = this.#first, i = 0; it != null; it = it.next, i++) {
91
+ values[i] = it.value;
92
+ }
93
+ return values;
94
+ }
95
+
96
+ /**
97
+ * Serializes the list to a JSON-compatible array.
98
+ * @returns {T[]}
99
+ */
100
+ toJSON(): T[] {
101
+ return this.toArray();
102
+ }
103
+
104
+ /**
105
+ * Returns a stringified JSON representation of the list.
106
+ * @returns {string}
107
+ */
108
+ toString(): string {
109
+ return JSON.stringify(this.toArray());
110
+ }
111
+
112
+ /** @returns {T[]} The list in array form */
113
+ [Symbol.for("nodejs.util.inspect.custom")](): T[] {
114
+ return this.toArray();
115
+ }
116
+
117
+ /** @returns {T[]} The list in array form */
118
+ [Symbol.toPrimitive](_hint?: string): T[] {
119
+ return this.toArray();
120
+ }
121
+
122
+ /** @returns {number} Current size of the list */
123
+ get size(): number {
124
+ return this.#size;
125
+ }
126
+
127
+ /** @returns {ListNode<T>|undefined} First node in the list */
128
+ get first(): ListNode<T> | undefined {
129
+ return this.#first;
130
+ }
131
+
132
+ /** @returns {ListNode<T>|undefined} Last node in the list */
133
+ get last(): ListNode<T> | undefined {
134
+ return this.#last;
135
+ }
136
+
137
+ /**
138
+ * Removes and returns the first value in the list.
139
+ * @returns {T | undefined}
140
+ */
141
+ popFirst(): T | undefined {
142
+ const value = this.#first?.value;
143
+ if (this.#first == null || this.#last == null) { // empty
144
+ return undefined;
145
+ } else if (this.#first == this.#last) { // one element
146
+ this.#first = undefined;
147
+ this.#last = undefined;
148
+ this.#size--;
149
+ } else { // many elements
150
+ this.#first = this.#first.next;
151
+ if (this.#first != null) {
152
+ this.#first.prev = undefined;
153
+ }
154
+ this.#size--;
155
+ }
156
+ return value;
157
+ }
158
+
159
+ /**
160
+ * Removes and returns the last value in the list.
161
+ * @returns {T | undefined}
162
+ */
163
+ pop(): T | undefined {
164
+ const value = this.#last?.value;
165
+ if (this.#first == null || this.#last == null) { // empty
166
+ return undefined;
167
+ } else if (this.#first == this.#last) { // one element
168
+ this.#first = undefined;
169
+ this.#last = undefined;
170
+ this.#size--;
171
+ } else { // many elements
172
+ this.#last = this.#last.prev;
173
+ if (this.#last != null) {
174
+ this.#last.next = undefined;
175
+ }
176
+ this.#size--;
177
+ }
178
+ return value;
179
+ }
180
+
181
+ /**
182
+ * Appends a new value to the end of the list.
183
+ * @param {T} value - Value to append.
184
+ * @returns {ListNode<T>} The inserted node.
185
+ */
186
+ push(value: T): ListNode<T> {
187
+ const node = new ListNode<T>(value);
188
+ if (this.#first == null || this.#last == null) { // empty
189
+ this.#first = this.#last = node;
190
+ } else { // many elements
191
+ node.prev = this.#last;
192
+ this.#last.next = node;
193
+ this.#last = node;
194
+ }
195
+ this.#size++;
196
+ return node;
197
+ }
198
+
199
+ /**
200
+ * Prepends a new value to the beginning of the list.
201
+ * @param {T} value - Value to prepend.
202
+ * @returns {ListNode<T>} The inserted node.
203
+ */
204
+ pushStart(value: T): ListNode<T> {
205
+ const node = new ListNode<T>(value);
206
+ if (this.#first == null || this.#last == null) { // empty
207
+ this.#first = this.#last = node;
208
+ } else { // many elements
209
+ node.next = this.#first;
210
+ this.#first.prev = node;
211
+ this.#first = node;
212
+ }
213
+ this.#size++;
214
+ return node;
215
+ }
216
+
217
+ /**
218
+ * Inserts an existing node after the target node.
219
+ * @param {ListNode<T>} node - Node to insert.
220
+ * @param {ListNode<T>} targetNode - Node to insert after.
221
+ * @returns {ListNode<T>} The inserted node.
222
+ */
223
+ insertNodeAfter(node: ListNode<T>, targetNode: ListNode<T>): ListNode<T> {
224
+ node.prev = targetNode;
225
+ node.next = targetNode.next;
226
+ if (targetNode.next != null) {
227
+ targetNode.next.prev = node;
228
+ }
229
+ targetNode.next = node;
230
+ if (targetNode === this.#last) {
231
+ this.#last = node;
232
+ }
233
+ this.#size++;
234
+ return node;
235
+ }
236
+
237
+ /**
238
+ * Inserts a new value after the target node.
239
+ * @param {T} value - Value to insert.
240
+ * @param {ListNode<T>} targetNode - Node to insert after.
241
+ * @returns {ListNode<T>} The new node.
242
+ */
243
+ insertAfter(value: T, targetNode: ListNode<T>): ListNode<T> {
244
+ const node = new ListNode<T>(value, targetNode, targetNode.next);
245
+ if (targetNode.next != null) {
246
+ targetNode.next.prev = node;
247
+ }
248
+ targetNode.next = node;
249
+ if (targetNode === this.#last) {
250
+ this.#last = node;
251
+ }
252
+ this.#size++;
253
+ return node;
254
+ }
255
+
256
+ /**
257
+ * Inserts an existing node before the target node.
258
+ * @param {ListNode<T>} node - Node to insert.
259
+ * @param {ListNode<T>} targetNode - Node to insert before.
260
+ * @returns {ListNode<T>} The inserted node.
261
+ */
262
+ insertNodeBefore(node: ListNode<T>, targetNode: ListNode<T>): ListNode<T> {
263
+ node.prev = targetNode.prev;
264
+ node.next = targetNode;
265
+ if (targetNode.prev != null) {
266
+ targetNode.prev.next = node;
267
+ }
268
+ targetNode.prev = node;
269
+ if (targetNode === this.#first) {
270
+ this.#first = node;
271
+ }
272
+ this.#size++;
273
+ return node;
274
+ }
275
+
276
+ /**
277
+ * Inserts a new value before the target node.
278
+ * @param {T} value - Value to insert.
279
+ * @param {ListNode<T>} targetNode - Node to insert before.
280
+ * @returns {ListNode<T>} The new node.
281
+ */
282
+ insertBefore(value: T, targetNode: ListNode<T>): ListNode<T> {
283
+ const node = new ListNode<T>(value, targetNode.prev, targetNode);
284
+ if (targetNode.prev != null) {
285
+ targetNode.prev.next = node;
286
+ }
287
+ targetNode.prev = node;
288
+ if (targetNode === this.#first) {
289
+ this.#first = node;
290
+ }
291
+ this.#size++;
292
+ return node;
293
+ }
294
+
295
+ /**
296
+ * Removes the given node from the list.
297
+ * @param {ListNode<T>} node - Node to remove.
298
+ * @returns {ListNode<T>} The removed node.
299
+ */
300
+ remove(node: ListNode<T>): ListNode<T> {
301
+ if (node.next != null) {
302
+ node.next.prev = node.prev;
303
+ }
304
+ if (node.prev != null) {
305
+ node.prev.next = node.next;
306
+ }
307
+ if (this.#first === node) {
308
+ this.#first = node.next;
309
+ }
310
+ if (this.#last === node) {
311
+ this.#last = node.prev;
312
+ }
313
+ this.#size--;
314
+ return node;
315
+ }
316
+
317
+ /**
318
+ * Clears the list.
319
+ * @returns {void}
320
+ */
321
+ clear(): void {
322
+ this.#first = this.#last = undefined;
323
+ this.#size = 0;
324
+ }
325
+
326
+ /**
327
+ * Rotates the list by the given amount.
328
+ * Positive values move nodes from first to last.
329
+ * Negative values move nodes from last to first.
330
+ * @param {number} amount - Number of positions to rotate.
331
+ * @returns {number} The absolute number of rotations performed.
332
+ */
333
+ rotate(amount: number): number {
334
+ if (this.#first == null || this.#last == null || this.#size === 0) { // empty or invalid
335
+ return 0;
336
+ } else if (this.#size === 1) {
337
+ return 1;
338
+ }
339
+ amount = amount % this.#size;
340
+ if (amount === 0) {
341
+ return 0;
342
+ }
343
+ // rotate via the shortest path
344
+ const absAmount = Math.abs(amount);
345
+ if (absAmount > this.#size / 2) {
346
+ amount = amount > 0 ? amount - this.#size : this.#size + amount;
347
+ }
348
+ // make circular
349
+ this.#first.prev = this.#last;
350
+ this.#last.next = this.#first;
351
+ // find the new start node
352
+ let it: ListNode<T> = this.#first;
353
+ if (amount > 0) {
354
+ while (amount-- > 0) it = it.next!;
355
+ } else {
356
+ while (amount++ < 0) it = it.prev!;
357
+ }
358
+ // reset the first and last nodes
359
+ this.#first = it;
360
+ this.#last = it.prev!;
361
+ // detach first and last nodes
362
+ this.#first.prev = undefined;
363
+ this.#last.next = undefined;
364
+ return absAmount;
365
+ }
366
+
367
+ /**
368
+ * Removes `amount` nodes from the start of the list and returns the last node
369
+ * of the detached segment (i.e., the node that was at the boundary of the detachment).
370
+ *
371
+ * If `amount` is greater than or equal to the list size, the entire list is cleared,
372
+ * and the original first node is returned.
373
+ *
374
+ * @param {number} amount - Number of nodes to remove from the start.
375
+ * @returns {ListNode<T> | undefined} The first node of the detached segment, or `undefined` if the list was empty or `amount <= 0`.
376
+ */
377
+ trimStart(amount: number): ListNode<T> | undefined {
378
+ if (this.#first == null || this.#last == null || amount <= 0) { // empty
379
+ return undefined;
380
+ }
381
+ let node = this.#first;
382
+ if (this.#first == this.#last) { // one element
383
+ this.#first = undefined;
384
+ this.#last = undefined;
385
+ this.#size = 0;
386
+ } else if (amount >= this.#size) { // trimming all elements
387
+ // clear
388
+ this.#first = this.#last = undefined;
389
+ this.#size = 0;
390
+ } else { // many elements
391
+ // iterate via the shortest path
392
+ const absAmount = Math.abs(amount);
393
+ if (absAmount > this.#size / 2) {
394
+ amount = amount > 0 ? amount - this.#size : this.#size + amount;
395
+ }
396
+ let it: ListNode<T>;
397
+ if (amount > 0) {
398
+ it = this.#first;
399
+ while (amount-- > 0) it = it.next!;
400
+ } else {
401
+ it = this.#last;
402
+ while (++amount < 0) it = it.prev!;
403
+ }
404
+ // detach end
405
+ node = it.prev!;
406
+ it.prev!.next = undefined;
407
+ it.prev = undefined;
408
+ this.#first = it;
409
+ this.#size -= absAmount;
410
+ }
411
+ return node;
412
+ }
413
+
414
+ /**
415
+ * Removes `amount` nodes from the end of the list and returns the first node
416
+ * of the detached segment (i.e., the node that was at the boundary of the detachment).
417
+ *
418
+ * If `amount` is greater than or equal to the list size, the entire list is cleared,
419
+ * and the original last node is returned.
420
+ *
421
+ * @param {number} amount - Number of nodes to remove from the end.
422
+ * @returns {ListNode<T> | undefined} The first node of the detached segment, or `undefined` if the list was empty or `amount <= 0`.
423
+ */
424
+ trimEnd(amount: number): ListNode<T> | undefined {
425
+ if (this.#first == null || this.#last == null || amount <= 0) { // empty
426
+ return undefined;
427
+ }
428
+ let node = this.#last;
429
+ if (this.#first == this.#last) { // one element
430
+ this.#first = undefined;
431
+ this.#last = undefined;
432
+ this.#size--;
433
+ } else if (amount >= this.#size) { // trimming all elements
434
+ // clear
435
+ this.#first = this.#last = undefined;
436
+ this.#size = 0;
437
+ } else { // many elements
438
+ // iterate via the shortest path
439
+ const absAmount = Math.abs(amount);
440
+ if (absAmount > this.#size / 2) {
441
+ amount = amount > 0 ? amount - this.#size : this.#size + amount;
442
+ }
443
+ let it: ListNode<T>;
444
+ if (amount > 0) {
445
+ it = this.#last;
446
+ while (amount-- > 0) it = it.prev!;
447
+ } else {
448
+ it = this.#first;
449
+ while (++amount < 0) it = it.next!;
450
+ }
451
+ // detach end
452
+ node = it.next!;
453
+ it.next!.prev = undefined;
454
+ it.next = undefined;
455
+ this.#last = it;
456
+ this.#size -= absAmount;
457
+ }
458
+ return node;
459
+ }
460
+ }
461
+
462
+ export default List;