@tstdl/base 0.93.138 → 0.93.140

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 (138) hide show
  1. package/README.md +166 -0
  2. package/ai/genkit/multi-region.plugin.js +5 -3
  3. package/ai/genkit/tests/multi-region.test.d.ts +1 -0
  4. package/ai/genkit/tests/multi-region.test.js +5 -2
  5. package/ai/parser/parser.js +2 -2
  6. package/ai/prompts/build.js +1 -0
  7. package/ai/prompts/instructions-formatter.d.ts +15 -2
  8. package/ai/prompts/instructions-formatter.js +36 -31
  9. package/ai/prompts/prompt-builder.js +5 -5
  10. package/ai/prompts/steering.d.ts +3 -2
  11. package/ai/prompts/steering.js +3 -1
  12. package/ai/tests/instructions-formatter.test.js +1 -0
  13. package/api/README.md +403 -0
  14. package/api/client/client.js +7 -13
  15. package/api/client/tests/api-client.test.js +10 -10
  16. package/api/default-error-handlers.js +1 -1
  17. package/api/response.d.ts +2 -2
  18. package/api/response.js +22 -33
  19. package/api/server/api-controller.d.ts +1 -1
  20. package/api/server/api-controller.js +3 -3
  21. package/api/server/api-request-token.provider.d.ts +1 -0
  22. package/api/server/api-request-token.provider.js +1 -0
  23. package/api/server/middlewares/allowed-methods.middleware.js +2 -1
  24. package/api/server/middlewares/content-type.middleware.js +2 -1
  25. package/api/types.d.ts +3 -2
  26. package/application/README.md +240 -0
  27. package/application/application.js +2 -2
  28. package/audit/README.md +267 -0
  29. package/authentication/README.md +288 -0
  30. package/authentication/client/authentication.service.d.ts +12 -11
  31. package/authentication/client/authentication.service.js +21 -21
  32. package/authentication/client/http-client.middleware.js +2 -2
  33. package/authentication/tests/authentication.client-error-handling.test.js +2 -1
  34. package/authentication/tests/authentication.client-service-refresh.test.js +5 -3
  35. package/browser/README.md +401 -0
  36. package/cancellation/README.md +156 -0
  37. package/cancellation/tests/coverage.test.d.ts +1 -0
  38. package/cancellation/tests/coverage.test.js +49 -0
  39. package/cancellation/tests/leak.test.d.ts +1 -0
  40. package/cancellation/tests/leak.test.js +35 -0
  41. package/cancellation/tests/token.test.d.ts +1 -0
  42. package/cancellation/tests/token.test.js +136 -0
  43. package/cancellation/token.d.ts +53 -177
  44. package/cancellation/token.js +132 -201
  45. package/context/README.md +174 -0
  46. package/cookie/README.md +161 -0
  47. package/css/README.md +157 -0
  48. package/data-structures/README.md +320 -0
  49. package/decorators/README.md +140 -0
  50. package/distributed-loop/README.md +231 -0
  51. package/distributed-loop/distributed-loop.js +1 -1
  52. package/document-management/README.md +403 -0
  53. package/document-management/server/services/document-management.service.js +9 -7
  54. package/document-management/tests/document-management-core.test.js +2 -7
  55. package/document-management/tests/document-management.api.test.js +6 -7
  56. package/document-management/tests/document-statistics.service.test.js +11 -12
  57. package/document-management/tests/document.service.test.js +3 -3
  58. package/document-management/tests/enum-helpers.test.js +2 -3
  59. package/dom/README.md +213 -0
  60. package/enumerable/README.md +259 -0
  61. package/enumeration/README.md +121 -0
  62. package/errors/README.md +267 -0
  63. package/file/README.md +191 -0
  64. package/formats/README.md +210 -0
  65. package/function/README.md +144 -0
  66. package/http/README.md +318 -0
  67. package/http/client/adapters/undici.adapter.js +1 -1
  68. package/http/client/http-client-request.d.ts +6 -5
  69. package/http/client/http-client-request.js +8 -9
  70. package/http/server/node/node-http-server.js +1 -2
  71. package/image-service/README.md +137 -0
  72. package/injector/README.md +491 -0
  73. package/injector/injector.d.ts +1 -0
  74. package/injector/injector.js +17 -5
  75. package/injector/tests/leak.test.d.ts +1 -0
  76. package/injector/tests/leak.test.js +45 -0
  77. package/intl/README.md +113 -0
  78. package/json-path/README.md +182 -0
  79. package/jsx/README.md +154 -0
  80. package/key-value-store/README.md +191 -0
  81. package/lock/README.md +249 -0
  82. package/lock/web/web-lock.js +119 -47
  83. package/logger/README.md +287 -0
  84. package/mail/README.md +256 -0
  85. package/memory/README.md +144 -0
  86. package/message-bus/README.md +244 -0
  87. package/message-bus/message-bus-base.js +1 -1
  88. package/module/README.md +182 -0
  89. package/module/module.d.ts +1 -1
  90. package/module/module.js +77 -17
  91. package/module/modules/web-server.module.js +1 -1
  92. package/notification/tests/notification-type.service.test.js +24 -15
  93. package/object-storage/README.md +300 -0
  94. package/openid-connect/README.md +274 -0
  95. package/orm/README.md +423 -0
  96. package/package.json +8 -6
  97. package/password/README.md +164 -0
  98. package/pdf/README.md +246 -0
  99. package/polyfills.js +1 -0
  100. package/pool/README.md +198 -0
  101. package/process/README.md +237 -0
  102. package/promise/README.md +252 -0
  103. package/promise/cancelable-promise.js +1 -1
  104. package/random/README.md +193 -0
  105. package/reflection/README.md +305 -0
  106. package/rpc/README.md +386 -0
  107. package/rxjs-utils/README.md +262 -0
  108. package/schema/README.md +342 -0
  109. package/serializer/README.md +342 -0
  110. package/signals/implementation/README.md +134 -0
  111. package/sse/README.md +278 -0
  112. package/task-queue/README.md +300 -0
  113. package/task-queue/postgres/task-queue.d.ts +2 -1
  114. package/task-queue/postgres/task-queue.js +32 -2
  115. package/task-queue/task-context.js +1 -1
  116. package/task-queue/task-queue.d.ts +17 -0
  117. package/task-queue/task-queue.js +103 -44
  118. package/task-queue/tests/complex.test.js +4 -4
  119. package/task-queue/tests/dependencies.test.js +4 -2
  120. package/task-queue/tests/queue.test.js +111 -0
  121. package/task-queue/tests/worker.test.js +21 -13
  122. package/templates/README.md +287 -0
  123. package/testing/README.md +157 -0
  124. package/text/README.md +346 -0
  125. package/threading/README.md +238 -0
  126. package/types/README.md +311 -0
  127. package/utils/README.md +322 -0
  128. package/utils/async-iterable-helpers/observable-iterable.d.ts +1 -1
  129. package/utils/async-iterable-helpers/observable-iterable.js +4 -8
  130. package/utils/async-iterable-helpers/take-until.js +4 -4
  131. package/utils/backoff.js +89 -30
  132. package/utils/retry-with-backoff.js +1 -1
  133. package/utils/timer.d.ts +1 -1
  134. package/utils/timer.js +5 -7
  135. package/utils/timing.d.ts +1 -1
  136. package/utils/timing.js +2 -4
  137. package/utils/z-base32.d.ts +1 -0
  138. package/utils/z-base32.js +1 -0
@@ -0,0 +1,161 @@
1
+ # @tstdl/base/cookie
2
+
3
+ A lightweight, type-safe utility module for handling HTTP cookies. It provides functions to parse `Cookie` header strings into usable maps and to format `Set-Cookie` header strings with support for modern attributes like `SameSite`, `Partitioned`, and `Priority`.
4
+
5
+ ## Table of Contents
6
+
7
+ - [✨ Features](#-features)
8
+ - [Core Concepts](#core-concepts)
9
+ - [🚀 Basic Usage](#-basic-usage)
10
+ - [Parsing Cookies](#parsing-cookies)
11
+ - [Formatting Set-Cookie](#formatting-set-cookie)
12
+ - [🔧 Advanced Topics](#-advanced-topics)
13
+ - [Modern Cookie Attributes](#modern-cookie-attributes)
14
+ - [Expiration and Max-Age](#expiration-and-max-age)
15
+ - [Deleting Cookies](#deleting-cookies)
16
+ - [📚 API](#-api)
17
+
18
+ ## ✨ Features
19
+
20
+ - **Robust Parsing**: Converts raw `Cookie` header strings into a standard JavaScript `Map`. Supports quoted values and automatic decoding.
21
+ - **Comprehensive Formatting**: Generates `Set-Cookie` strings supporting standard and modern attributes.
22
+ - **Automatic Encoding**: Handles URL encoding and decoding of cookie values automatically.
23
+ - **Modern Standards**: Supports `Partitioned` (CHIPS), `Priority`, and `SameSite` attributes.
24
+ - **Type Safety**: Fully typed options for compile-time safety.
25
+
26
+ ## Core Concepts
27
+
28
+ HTTP Cookies are small pieces of data stored on the user's device. They are exchanged between the client and server via HTTP headers.
29
+
30
+ 1. **Parsing (`Cookie` Header)**: When a browser sends a request, it includes cookies in a single string (e.g., `name=value; name2=value2`). This module parses that string into a key-value map for easy access.
31
+ 2. **Formatting (`Set-Cookie` Header)**: To store a cookie on the client, the server sends a `Set-Cookie` header. This string includes the name, value, and various directives (attributes) that control the cookie's scope, security, and lifetime.
32
+
33
+ ## 🚀 Basic Usage
34
+
35
+ ### Parsing Cookies
36
+
37
+ Use `parseCookieString` to convert a raw cookie header string (typically found in `req.headers.cookie`) into a `Map`.
38
+
39
+ ```ts
40
+ import { parseCookieString } from '@tstdl/base/cookie';
41
+
42
+ // Simulating a raw header string received from a browser
43
+ const rawCookieHeader = 'session_id=abc-123; theme=dark; user_preferences="%7B%22notifications%22%3Atrue%7D"';
44
+
45
+ const cookies = parseCookieString(rawCookieHeader);
46
+
47
+ // Access values
48
+ const sessionId = cookies.get('session_id'); // 'abc-123'
49
+ const theme = cookies.get('theme'); // 'dark'
50
+
51
+ // Values are automatically URL-decoded and quotes are stripped
52
+ const userPrefs = cookies.get('user_preferences'); // '{"notifications":true}'
53
+
54
+ if (cookies.has('session_id')) {
55
+ console.log('Session active:', sessionId);
56
+ }
57
+ ```
58
+
59
+ ### Formatting Set-Cookie
60
+
61
+ Use `formatSetCookie` to generate the string value for a `Set-Cookie` HTTP response header.
62
+
63
+ ```ts
64
+ import { formatSetCookie } from '@tstdl/base/cookie';
65
+
66
+ // Create a secure, HTTP-only session cookie
67
+ const setCookieHeader = formatSetCookie('session_id', 'xyz-secret-token', {
68
+ path: '/',
69
+ httpOnly: true,
70
+ secure: true,
71
+ sameSite: 'strict',
72
+ });
73
+
74
+ console.log(setCookieHeader);
75
+ // Output: session_id=xyz-secret-token; Path=/; HttpOnly; SameSite=Strict; Secure
76
+ ```
77
+
78
+ ## 🔧 Advanced Topics
79
+
80
+ ### Modern Cookie Attributes
81
+
82
+ The module supports modern attributes required for specific browser behaviors, such as `Partitioned` (for CHIPS) and `Priority`.
83
+
84
+ ```ts
85
+ import { formatSetCookie } from '@tstdl/base/cookie';
86
+
87
+ const crossSiteCookie = formatSetCookie('widget_session', '123', {
88
+ path: '/',
89
+ secure: true,
90
+ // Required for cookies sent in cross-site contexts (e.g., iframes)
91
+ sameSite: 'none',
92
+ // Cookies Having Independent Partitioned State (CHIPS)
93
+ partitioned: true,
94
+ // Hint to the browser about the cookie's importance
95
+ priority: 'high',
96
+ });
97
+
98
+ console.log(crossSiteCookie);
99
+ // Output: widget_session=123; Path=/; SameSite=None; Priority=High; Secure; Partitioned
100
+ ```
101
+
102
+ ### Expiration and Max-Age
103
+
104
+ You can define the lifetime of a cookie using either `expires` (absolute date) or `maxAge` (relative seconds).
105
+
106
+ ```ts
107
+ import { formatSetCookie } from '@tstdl/base/cookie';
108
+
109
+ // Using Max-Age (in seconds)
110
+ const oneHourCookie = formatSetCookie('temp_data', 'foo', {
111
+ maxAge: 3600, // 1 hour
112
+ });
113
+
114
+ // Using Expires (Date object or timestamp in milliseconds)
115
+ const nextWeek = new Date();
116
+ nextWeek.setDate(nextWeek.getDate() + 7);
117
+
118
+ const persistentCookie = formatSetCookie('permanent_data', 'bar', {
119
+ expires: nextWeek,
120
+ });
121
+ ```
122
+
123
+ ### Deleting Cookies
124
+
125
+ To delete a cookie, you should set its expiration to the past or its `maxAge` to 0.
126
+
127
+ ```ts
128
+ import { formatSetCookie } from '@tstdl/base/cookie';
129
+
130
+ // Option 1: Set maxAge to 0
131
+ const deleteCookie1 = formatSetCookie('session_id', '', {
132
+ maxAge: 0,
133
+ });
134
+
135
+ // Option 2: Set expires to a date in the past
136
+ const deleteCookie2 = formatSetCookie('session_id', '', {
137
+ expires: new Date(0),
138
+ });
139
+ ```
140
+
141
+ ## 📚 API
142
+
143
+ | Name | Type | Description |
144
+ | :------------------ | :-------------------------------------------------------------------- | :------------------------------------------------------------------------------------- |
145
+ | `formatSetCookie` | `(name: string, value: string, options?: SetCookieOptions) => string` | Formats a cookie name, value, and options into a `Set-Cookie` header string. |
146
+ | `parseCookieString` | `(cookieString: string) => Map<string, string>` | Parses a `Cookie` header string into a Map of key-value pairs. Values are URL-decoded. |
147
+ | `SetCookieOptions` | `Type` | Configuration object for cookie attributes. |
148
+
149
+ ### SetCookieOptions
150
+
151
+ | Property | Type | Description |
152
+ | :------------ | :---------------------------- | :---------------------------------------------------------------------------------------------- |
153
+ | `domain` | `string` | Specifies the domain for which the cookie is valid. |
154
+ | `expires` | `Date \| number` | Date or timestamp (in milliseconds) when the cookie expires. |
155
+ | `httpOnly` | `boolean` | If true, the cookie is inaccessible to the JavaScript `Document.cookie` API. |
156
+ | `maxAge` | `number` | Number of seconds until the cookie expires. |
157
+ | `partitioned` | `boolean` | If true, sets the `Partitioned` attribute (CHIPS). Requires `secure` to be true. |
158
+ | `path` | `string` | Specifies the path for which the cookie is valid. |
159
+ | `sameSite` | `'strict' \| 'lax' \| 'none'` | Controls whether the cookie is sent with cross-site requests. |
160
+ | `priority` | `'low' \| 'medium' \| 'high'` | Hints at the priority of the cookie for browser retention. |
161
+ | `secure` | `boolean` | If true, the cookie is only sent to the server when a request is made with the `https:` scheme. |
package/css/README.md ADDED
@@ -0,0 +1,157 @@
1
+ # CSS
2
+
3
+ A utility module for programmatically managing CSS variables (custom properties) using the modern Constructable Stylesheets API. It provides a type-safe, disposable interface for dynamic theming and runtime style manipulation without the overhead of managing `<style>` tags or inline styles.
4
+
5
+ ## Table of Contents
6
+
7
+ - [✨ Features](#-features)
8
+ - [Core Concepts](#core-concepts)
9
+ - [🚀 Basic Usage](#-basic-usage)
10
+ - [🔧 Advanced Topics](#-advanced-topics)
11
+ - [Scoped Selectors](#scoped-selectors)
12
+ - [Namespacing with Prefixes](#namespacing-with-prefixes)
13
+ - [Batch Operations & Cleanup](#batch-operations--cleanup)
14
+ - [Lifecycle Management (Disposal)](#lifecycle-management-disposal)
15
+ - [📚 API](#-api)
16
+
17
+ ## ✨ Features
18
+
19
+ - **Constructable Stylesheets**: Leverages `document.adoptedStyleSheets` for performant style application.
20
+ - **Scoped Variables**: Apply variables globally (`:root`) or target specific CSS selectors.
21
+ - **Automatic Prefixing**: Automatically handles the `--` syntax for custom properties.
22
+ - **Batch Updates**: Set multiple variables simultaneously.
23
+ - **Disposable**: Implements the `Disposable` interface for automatic cleanup of stylesheets.
24
+ - **Type Safe**: Written in TypeScript for robust development.
25
+
26
+ ## Core Concepts
27
+
28
+ This module abstracts the **CSS Object Model (CSSOM)** to simplify the management of CSS Custom Properties.
29
+
30
+ Instead of appending `<style>` elements to the DOM or manipulating the `style` attribute of individual elements, this module creates a `CSSStyleSheet` in memory and adopts it into the document. This approach is generally more performant for global or shared styles (like themes) and keeps the DOM clean.
31
+
32
+ The `CssVariables` class manages a single CSS rule within a dedicated stylesheet. You can define the **selector** (where the variables apply) and an optional **prefix** (to namespace your variables).
33
+
34
+ ## 🚀 Basic Usage
35
+
36
+ The most common use case is setting global theme variables on the `:root` selector.
37
+
38
+ ```ts
39
+ import { cssVariables } from '@tstdl/base/css';
40
+
41
+ // Create a manager for :root variables
42
+ const theme = cssVariables();
43
+
44
+ // Set a variable (automatically adds '--' if missing)
45
+ theme.set('primary-color', '#3498db');
46
+ theme.set('font-size', '16px');
47
+
48
+ // Read a value
49
+ const color = theme.get('primary-color');
50
+ console.log(color); // " #3498db" (note: browser may add whitespace)
51
+
52
+ // The styles are now active in the document
53
+ ```
54
+
55
+ ## 🔧 Advanced Topics
56
+
57
+ ### Scoped Selectors
58
+
59
+ You can restrict the CSS variables to a specific selector, such as a class name or an ID. This is useful for component-specific theming.
60
+
61
+ ```ts
62
+ import { cssVariables } from '@tstdl/base/css';
63
+
64
+ // Apply variables only to elements with the class .dark-mode-container
65
+ const darkTheme = cssVariables('.dark-mode-container');
66
+
67
+ darkTheme.set('background', '#000000');
68
+ darkTheme.set('text', '#ffffff');
69
+ ```
70
+
71
+ ### Namespacing with Prefixes
72
+
73
+ To avoid collisions or group related variables, you can provide a prefix. The module handles the double hyphen syntax automatically.
74
+
75
+ ```ts
76
+ import { cssVariables } from '@tstdl/base/css';
77
+
78
+ // Variables will be prefixed with '--my-app-'
79
+ const appSettings = cssVariables(':root', 'my-app-');
80
+
81
+ // Sets '--my-app-spacing'
82
+ appSettings.set('spacing', '1rem');
83
+
84
+ // Sets '--my-app-header-height'
85
+ appSettings.set('header-height', '64px');
86
+ ```
87
+
88
+ ### Batch Operations & Cleanup
89
+
90
+ Use `setMany` to apply multiple variables at once using an object or an array of entries. You can also delete specific variables or clear the entire rule.
91
+
92
+ ```ts
93
+ import { cssVariables } from '@tstdl/base/css';
94
+
95
+ const theme = cssVariables();
96
+
97
+ // Batch update
98
+ theme.setMany({
99
+ 'color-primary': 'blue',
100
+ 'color-secondary': 'green',
101
+ 'border-radius': '4px',
102
+ });
103
+
104
+ // Delete a single variable
105
+ theme.delete('color-secondary');
106
+
107
+ // Clear all variables in this manager
108
+ theme.clear();
109
+ ```
110
+
111
+ ### Lifecycle Management (Disposal)
112
+
113
+ The `CssVariables` class implements the `Disposable` interface (`Symbol.dispose`). When the object is disposed, the underlying stylesheet is removed from `document.adoptedStyleSheets`, effectively reverting the changes.
114
+
115
+ This is particularly useful with the TypeScript `using` keyword (or manual `dispose` calls) for temporary styles.
116
+
117
+ ```ts
118
+ import { cssVariables } from '@tstdl/base/css';
119
+
120
+ function applyTemporaryTheme() {
121
+ // 'using' ensures the stylesheet is removed when the scope exits
122
+ using tempTheme = cssVariables();
123
+
124
+ tempTheme.set('overlay-color', 'rgba(0,0,0,0.5)');
125
+
126
+ // ... perform operations with the theme active ...
127
+ } // tempTheme is disposed here, removing the CSS variables from the document
128
+ ```
129
+
130
+ ## 📚 API
131
+
132
+ ### Functions
133
+
134
+ | Function | Description |
135
+ | :--------------------------------- | :------------------------------------------------------------------------------------------------------- |
136
+ | `cssVariables(selector?, prefix?)` | Factory function to create a new `CssVariables` instance. Defaults to `:root` selector and empty prefix. |
137
+
138
+ ### Classes
139
+
140
+ #### `CssVariables`
141
+
142
+ Implements `Disposable`.
143
+
144
+ | Method | Signature | Description |
145
+ | :----------------- | :------------------------------------------------------------------------------------ | :-------------------------------------------------------------------------------- |
146
+ | `constructor` | `(selector: string \| null, prefix?: string)` | Creates a new stylesheet adopted by the document. `selector` defaults to `:root`. |
147
+ | `set` | `(name: string, value: string): void` | Sets a CSS variable. Automatically handles the `--` prefix. |
148
+ | `setMany` | `(variables: Record<string, string> \| readonly (readonly [string, string])[]): void` | Sets multiple variables at once. |
149
+ | `get` | `(name: string): string \| null` | Retrieves the value of a CSS variable. Returns `null` if not set. |
150
+ | `delete` | `(name: string): void` | Removes a CSS variable from the rule. |
151
+ | `clear` | `(): void` | Clears all properties from the rule. |
152
+ | `[Symbol.dispose]` | `(): void` | Removes the stylesheet from the document. |
153
+
154
+ | Property | Type | Description |
155
+ | :--------- | :------- | :------------------------------------------ |
156
+ | `selector` | `string` | The CSS selector targeted by this instance. |
157
+ | `prefix` | `string` | The prefix applied to variable names. |
@@ -0,0 +1,320 @@
1
+ # @tstdl/base/data-structures
2
+
3
+ A comprehensive library of advanced, observable, and strongly-typed data structures for TypeScript, providing powerful alternatives to native collections with reactive capabilities.
4
+
5
+ ## Table of Contents
6
+
7
+ - [✨ Features](#-features)
8
+ - [Core Concepts](#core-concepts)
9
+ - [Collection Hierarchy](#collection-hierarchy)
10
+ - [Observability](#observability)
11
+ - [🚀 Basic Usage](#-basic-usage)
12
+ - [ArrayList](#arraylist)
13
+ - [MapDictionary](#mapdictionary)
14
+ - [SetCollection](#setcollection)
15
+ - [🔧 Advanced Topics](#-advanced-topics)
16
+ - [CircularBuffer](#circularbuffer)
17
+ - [SortedArrayList](#sortedarraylist)
18
+ - [Multi-Key Collections](#multi-key-collections)
19
+ - [Weak Reference Maps](#weak-reference-maps)
20
+ - [ContextDataMap](#contextdatamap)
21
+ - [Native Adapters](#native-adapters)
22
+ - [📚 API](#-api)
23
+
24
+ ## ✨ Features
25
+
26
+ - **Observable State**: Track changes, size, and emptiness via RxJS Observables (`size$`, `change$`) and Signals (`$size`, `$observe`).
27
+ - **Rich Collection Set**: Includes Lists (Array, Sorted, Linked), Dictionaries, Sets, Circular Buffers, and LRU Caches.
28
+ - **Specialized Maps**: Advanced implementations like `MultiKeyMap` (nested keys), `IterableWeakMap` (iterable weak keys), and `WeakRefMap` (weak values).
29
+ - **Native Compatibility**: Seamlessly adapt custom structures to standard `Map` and `Set` interfaces using `asMap()` and `asSet()`.
30
+ - **Type Safety**: Built with rigorous TypeScript generics to ensure type safety across all operations.
31
+
32
+ ## Core Concepts
33
+
34
+ ### Collection Hierarchy
35
+
36
+ The module is built on a robust hierarchy of abstract base classes:
37
+
38
+ - **`Collection<T>`**: The root of the hierarchy. Provides observability (`size$`, `change$`, `$size`, `$observe`) and standard methods like `add`, `clear`, and `items()`.
39
+ - **`List<T>`**: Extends `Collection` for ordered, indexed data. Adds `at(index)`, `indexOf(item)`, `removeAt(index)`, and `set(index, item)`.
40
+ - **`Dictionary<K, V>`**: Extends `Collection` for key-value pairs. Adds `get(key)`, `set(key, value)`, `has(key)`, and `delete(key)`.
41
+ - **`DistinctCollection<T>`**: Extends `Collection` for unique values (Sets). Adds `has(value)` and `delete(value)`.
42
+
43
+ ### Observability
44
+
45
+ All data structures in this library are reactive. You can subscribe to changes or use signals for efficient UI updates or side effects.
46
+
47
+ ```typescript
48
+ import { ArrayList } from '@tstdl/base/data-structures';
49
+
50
+ const list = new ArrayList<string>();
51
+
52
+ // RxJS Observable
53
+ list.size$.subscribe((size) => console.log(`Size: ${size}`));
54
+
55
+ // Signal (if using a signal-compatible environment)
56
+ console.log(list.$isEmpty());
57
+
58
+ list.add('Hello'); // Triggers updates
59
+ ```
60
+
61
+ ## 🚀 Basic Usage
62
+
63
+ ### ArrayList
64
+
65
+ A general-purpose, resizeable array implementation of `List`.
66
+
67
+ ```typescript
68
+ import { ArrayList } from '@tstdl/base/data-structures';
69
+
70
+ const list = new ArrayList<string>(['alpha', 'beta']);
71
+
72
+ list.add('gamma');
73
+ list.prepend('omega');
74
+
75
+ console.log(list.at(0)); // 'omega'
76
+ console.log(list.toArray()); // ['omega', 'alpha', 'beta', 'gamma']
77
+
78
+ list.remove('alpha');
79
+ ```
80
+
81
+ ### MapDictionary
82
+
83
+ A `Dictionary` backed by the native `Map`, offering O(1) access times.
84
+
85
+ ```typescript
86
+ import { MapDictionary } from '@tstdl/base/data-structures';
87
+
88
+ const dict = new MapDictionary<number, string>();
89
+
90
+ dict.set(1, 'One');
91
+ dict.set(2, 'Two');
92
+
93
+ if (dict.has(1)) {
94
+ console.log(dict.get(1)); // 'One'
95
+ }
96
+
97
+ for (const [key, value] of dict) {
98
+ console.log(`${key}: ${value}`);
99
+ }
100
+ ```
101
+
102
+ ### SetCollection
103
+
104
+ A `DistinctCollection` backed by the native `Set`, ensuring unique values.
105
+
106
+ ```typescript
107
+ import { SetCollection } from '@tstdl/base/data-structures';
108
+
109
+ const set = new SetCollection<number>();
110
+
111
+ set.add(1);
112
+ set.add(1); // Duplicate ignored
113
+ set.add(2);
114
+
115
+ console.log(set.size); // 2
116
+ ```
117
+
118
+ ## 🔧 Advanced Topics
119
+
120
+ ### CircularBuffer
121
+
122
+ A fixed-size buffer that overwrites the oldest elements when full. Useful for logs, history, or streaming data. It exposes specific observables for overflow events.
123
+
124
+ ```typescript
125
+ import { CircularBuffer } from '@tstdl/base/data-structures';
126
+
127
+ const buffer = new CircularBuffer<string>(3);
128
+
129
+ // React to overflows
130
+ buffer.overflow$.subscribe((dropped) => {
131
+ console.warn(`Buffer full! Dropped: ${dropped}`);
132
+ });
133
+
134
+ buffer.add('A');
135
+ buffer.add('B');
136
+ buffer.add('C');
137
+ buffer.add('D'); // Triggers overflow$, 'A' is dropped
138
+
139
+ console.log(buffer.toArray()); // ['B', 'C', 'D']
140
+ ```
141
+
142
+ ### LinkedList
143
+
144
+ A doubly linked list that provides O(1) insertions and removals when holding a reference to a node.
145
+
146
+ ```typescript
147
+ import { LinkedList } from '@tstdl/base/data-structures';
148
+
149
+ const list = new LinkedList<string>();
150
+
151
+ const nodeA = list.add('A');
152
+ const nodeB = list.add('B');
153
+
154
+ // O(1) insertion at specific position
155
+ list.addAfterNode(nodeA, 'new item');
156
+
157
+ // Access nodes directly
158
+ console.log(list.firstNode?.item); // 'A'
159
+ console.log(nodeB.previous?.item); // 'new item'
160
+
161
+ console.log(list.toArray()); // ['A', 'new item', 'B']
162
+ ```
163
+
164
+ ### SortedArrayList
165
+
166
+ A list that maintains its elements in sorted order using a comparator. Binary search is used for insertions and lookups.
167
+
168
+ ```typescript
169
+ import { SortedArrayList } from '@tstdl/base/data-structures';
170
+
171
+ const scores = new SortedArrayList<number>([], (a, b) => a - b);
172
+
173
+ scores.add(10);
174
+ scores.add(5);
175
+ scores.add(20);
176
+
177
+ console.log(scores.toArray()); // [5, 10, 20]
178
+
179
+ // Fast lookup using binary search
180
+ const index = scores.fastIndexOf(10); // 1
181
+ ```
182
+
183
+ ### Multi-Key Collections
184
+
185
+ `MultiKeyMap` and `MultiKeySet` allow using arrays of values as keys. This is useful for coordinate systems, composite keys, or hierarchical data.
186
+
187
+ #### MultiKeyMap
188
+
189
+ ```typescript
190
+ import { MultiKeyMap } from '@tstdl/base/data-structures';
191
+
192
+ const grid = new MultiKeyMap<[number, number], string>();
193
+
194
+ grid.set([0, 0], 'Origin');
195
+ grid.set([10, 5], 'Target');
196
+
197
+ console.log(grid.get([0, 0])); // 'Origin'
198
+ console.log(grid.has([1, 1])); // false
199
+
200
+ // Flat access API (alternative syntax)
201
+ grid.setFlat(2, 2, 'Waypoint');
202
+ console.log(grid.getFlat(2, 2)); // 'Waypoint'
203
+ ```
204
+
205
+ #### MultiKeySet
206
+
207
+ ```typescript
208
+ import { MultiKeySet } from '@tstdl/base/data-structures';
209
+
210
+ const matrix = new MultiKeySet<[number, number, number]>();
211
+
212
+ matrix.add([1, 2, 3]);
213
+ matrix.add([1, 2, 3]); // Duplicate ignored
214
+
215
+ console.log(matrix.size); // 1
216
+ console.log(matrix.has([1, 2, 3])); // true
217
+
218
+ // Flat access
219
+ matrix.addFlat(4, 5, 6);
220
+ ```
221
+
222
+ ### Cache
223
+
224
+ A simple LRU (Least Recently Used) cache with configurable capacity. It automatically evicts the least recently accessed items when the limit is reached.
225
+
226
+ ```typescript
227
+ import { Cache } from '@tstdl/base/data-structures';
228
+
229
+ const cache = new Cache<string, object>(100); // Capacity: 100 items
230
+
231
+ cache.set('user:1', { name: 'Alice' });
232
+
233
+ // Accessing an item marks it as recently used
234
+ const user = cache.get('user:1');
235
+
236
+ // Adjusting capacity at runtime evicts items if necessary
237
+ cache.capacity = 50;
238
+
239
+ cache.delete('user:1');
240
+ ```
241
+
242
+ ### Weak Reference Maps
243
+
244
+ - **`IterableWeakMap`**: A `WeakMap` that allows iteration. It uses `WeakRef` and `FinalizationRegistry` to track keys and clean up internal references when keys are garbage collected.
245
+ - **`WeakRefMap`**: A map where _values_ are held weakly. Useful for caching large objects that can be reconstructed if memory is tight.
246
+
247
+ ```typescript
248
+ import { IterableWeakMap } from '@tstdl/base/data-structures';
249
+
250
+ let key: object | null = { id: 1 };
251
+ const map = new IterableWeakMap<object, string>();
252
+
253
+ map.set(key, 'Metadata');
254
+
255
+ // Unlike native WeakMap, we can iterate
256
+ for (const [k, v] of map) {
257
+ console.log(v); // 'Metadata'
258
+ }
259
+
260
+ key = null; // Key is now eligible for GC. Map will eventually be empty.
261
+ ```
262
+
263
+ ### ContextDataMap
264
+
265
+ A utility map for storing arbitrary context data, often used in request processing or dependency injection scopes. Supports merging data.
266
+
267
+ ```typescript
268
+ import { ContextDataMap } from '@tstdl/base/data-structures';
269
+
270
+ const context = new ContextDataMap();
271
+
272
+ context.set('user', { id: 1, name: 'Alice' });
273
+ context.set('config', { theme: 'dark' });
274
+
275
+ // Merge data into existing key
276
+ context.set('config', { lang: 'en' }, true);
277
+
278
+ console.log(context.get('config')); // { theme: 'dark', lang: 'en' }
279
+ ```
280
+
281
+ ### Native Adapters
282
+
283
+ If you need to pass a `Dictionary` to a function expecting a `Map`, or a `DistinctCollection` to a function expecting a `Set`, use the adapter methods. These create lightweight wrappers without copying data.
284
+
285
+ ```typescript
286
+ import { MapDictionary } from '@tstdl/base/data-structures';
287
+
288
+ const dict = new MapDictionary<string, number>();
289
+ const nativeMap: Map<string, number> = dict.asMap();
290
+
291
+ nativeMap.set('foo', 123); // Updates the underlying Dictionary
292
+ ```
293
+
294
+ ## 📚 API
295
+
296
+ | Class | Type | Description |
297
+ | :---------------------- | :----------------- | :---------------------------------------------------------- |
298
+ | `ArrayList<T>` | List | Dynamic array implementation backed by native Array. |
299
+ | `SortedArrayList<T>` | List | Auto-sorted list using a comparator and binary search. |
300
+ | `LinkedList<T>` | List | Doubly linked list implementation. |
301
+ | `CircularBuffer<T>` | Collection | Fixed-size buffer that overwrites oldest items on overflow. |
302
+ | `MapDictionary<K, V>` | Dictionary | Key-value collection backed by native `Map`. |
303
+ | `ArrayDictionary<K, V>` | Dictionary | Key-value collection backed by parallel arrays. |
304
+ | `MultiKeyMap<K[], V>` | Dictionary | Map using arrays as composite keys. |
305
+ | `IterableWeakMap<K, V>` | Dictionary | `WeakMap` that supports iteration and size tracking. |
306
+ | `WeakRefMap<K, V>` | Dictionary | Map where values are held via `WeakRef`. |
307
+ | `SetCollection<T>` | DistinctCollection | Unique value collection backed by native `Set`. |
308
+ | `MultiKeySet<T[]>` | DistinctCollection | Set using arrays as unique composite values. |
309
+ | `Cache<K, V>` | Class | Simple LRU (Least Recently Used) cache. |
310
+ | `ContextDataMap` | Class | Map for storing and merging arbitrary context data. |
311
+ | `IndexOutOfBoundsError` | Error | Thrown when accessing invalid list indices. |
312
+
313
+ ### Abstract Base Classes
314
+
315
+ | Class | Description |
316
+ | :---------------------- | :---------------------------------------------------------- |
317
+ | `Collection<T>` | Base class for all data structures. Provides observability. |
318
+ | `List<T>` | Base for ordered, indexed collections. |
319
+ | `Dictionary<K, V>` | Base for key-value collections. |
320
+ | `DistinctCollection<T>` | Base for unique value collections (Sets). |