@relax.js/core 1.0.0

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 (194) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +188 -0
  3. package/dist/DataLoader.d.ts +51 -0
  4. package/dist/DependencyInjection.d.ts +271 -0
  5. package/dist/DependencyInjectionOld.d.ts +35 -0
  6. package/dist/Metadata.d.ts +8 -0
  7. package/dist/SequentialId.d.ts +47 -0
  8. package/dist/_alt/src/MustardEngine.d.ts +30 -0
  9. package/dist/_alt/src/MustardParser.d.ts +63 -0
  10. package/dist/_alt/src/MustardParser2.d.ts +35 -0
  11. package/dist/_alt/src/pipes.d.ts +93 -0
  12. package/dist/_alt/src/template.d.ts +166 -0
  13. package/dist/_alt/src/tools.d.ts +4 -0
  14. package/dist/_alt/tests/pipes.tests.d.ts +1 -0
  15. package/dist/_alt/tests/template.tests.d.ts +1 -0
  16. package/dist/_alt/vitest.config.d.ts +2 -0
  17. package/dist/collections/Index.d.ts +1 -0
  18. package/dist/collections/LinkedList.d.ts +75 -0
  19. package/dist/collections/Pager.d.ts +15 -0
  20. package/dist/collections/index.js +2 -0
  21. package/dist/collections/index.js.map +7 -0
  22. package/dist/collections/index.mjs +2 -0
  23. package/dist/collections/index.mjs.map +7 -0
  24. package/dist/components/Table.d.ts +13 -0
  25. package/dist/components/index.d.ts +4 -0
  26. package/dist/components/index.js +128 -0
  27. package/dist/components/index.js.map +7 -0
  28. package/dist/components/index.mjs +128 -0
  29. package/dist/components/index.mjs.map +7 -0
  30. package/dist/components/lists/Table.d.ts +59 -0
  31. package/dist/components/lists/TreeView.d.ts +67 -0
  32. package/dist/components/lists/index.d.ts +2 -0
  33. package/dist/components/loader.d.ts +60 -0
  34. package/dist/components/menus/MenuItem.d.ts +30 -0
  35. package/dist/components/menus/TopMenu.d.ts +16 -0
  36. package/dist/components/menus/index.d.ts +2 -0
  37. package/dist/components/panels/tabs.d.ts +15 -0
  38. package/dist/di/index.d.ts +1 -0
  39. package/dist/di/index.js +2 -0
  40. package/dist/di/index.js.map +7 -0
  41. package/dist/di/index.mjs +2 -0
  42. package/dist/di/index.mjs.map +7 -0
  43. package/dist/elements/CopyAttributes.d.ts +2 -0
  44. package/dist/elements/dom.d.ts +18 -0
  45. package/dist/elements/index.d.ts +2 -0
  46. package/dist/elements/index.js +2 -0
  47. package/dist/elements/index.js.map +7 -0
  48. package/dist/elements/index.mjs +2 -0
  49. package/dist/elements/index.mjs.map +7 -0
  50. package/dist/errors.d.ts +71 -0
  51. package/dist/forms/FormReader.d.ts +182 -0
  52. package/dist/forms/FormValidator.d.ts +114 -0
  53. package/dist/forms/ValidationRules.d.ts +103 -0
  54. package/dist/forms/index.d.ts +4 -0
  55. package/dist/forms/index.js +2 -0
  56. package/dist/forms/index.js.map +7 -0
  57. package/dist/forms/index.mjs +2 -0
  58. package/dist/forms/index.mjs.map +7 -0
  59. package/dist/forms/setFormData.d.ts +49 -0
  60. package/dist/getParentComponent.d.ts +43 -0
  61. package/dist/html/TableRenderer.d.ts +44 -0
  62. package/dist/html/TreeBinder.d.ts +9 -0
  63. package/dist/html/html.d.ts +55 -0
  64. package/dist/html/index.d.ts +5 -0
  65. package/dist/html/index.js +2 -0
  66. package/dist/html/index.js.map +7 -0
  67. package/dist/html/index.mjs +2 -0
  68. package/dist/html/index.mjs.map +7 -0
  69. package/dist/html/template.d.ts +167 -0
  70. package/dist/http/ServerSentEvents.d.ts +116 -0
  71. package/dist/http/SimpleWebSocket.d.ts +153 -0
  72. package/dist/http/http.d.ts +177 -0
  73. package/dist/http/index.d.ts +3 -0
  74. package/dist/http/index.js +2 -0
  75. package/dist/http/index.js.map +7 -0
  76. package/dist/http/index.mjs +2 -0
  77. package/dist/http/index.mjs.map +7 -0
  78. package/dist/i18n/i18n.d.ts +105 -0
  79. package/dist/i18n/icu.d.ts +64 -0
  80. package/dist/i18n/index.d.ts +2 -0
  81. package/dist/i18n/index.js +2 -0
  82. package/dist/i18n/index.js.map +7 -0
  83. package/dist/i18n/index.mjs +2 -0
  84. package/dist/i18n/index.mjs.map +7 -0
  85. package/dist/index.d.ts +16 -0
  86. package/dist/index.js +5 -0
  87. package/dist/index.js.map +7 -0
  88. package/dist/index.mjs +5 -0
  89. package/dist/index.mjs.map +7 -0
  90. package/dist/lib/DataLoader.d.ts +51 -0
  91. package/dist/lib/DependencyInjection.d.ts +271 -0
  92. package/dist/lib/InvokeParent.d.ts +10 -0
  93. package/dist/lib/Pipes.d.ts +236 -0
  94. package/dist/lib/SequentialId.d.ts +47 -0
  95. package/dist/lib/collections/Index.d.ts +1 -0
  96. package/dist/lib/collections/LinkedList.d.ts +75 -0
  97. package/dist/lib/collections/Pager.d.ts +15 -0
  98. package/dist/lib/collections/TableRenderer.d.ts +44 -0
  99. package/dist/lib/di/index.d.ts +1 -0
  100. package/dist/lib/elements/CopyAttributes.d.ts +2 -0
  101. package/dist/lib/elements/dom.d.ts +18 -0
  102. package/dist/lib/elements/index.d.ts +2 -0
  103. package/dist/lib/errors.d.ts +71 -0
  104. package/dist/lib/forms/FormReader.d.ts +182 -0
  105. package/dist/lib/forms/FormValidator.d.ts +114 -0
  106. package/dist/lib/forms/ValidationRules.d.ts +103 -0
  107. package/dist/lib/forms/index.d.ts +4 -0
  108. package/dist/lib/forms/setFormData.d.ts +49 -0
  109. package/dist/lib/getParentComponent.d.ts +43 -0
  110. package/dist/lib/html/TableRenderer.d.ts +44 -0
  111. package/dist/lib/html/TreeBinder.d.ts +9 -0
  112. package/dist/lib/html/html.d.ts +55 -0
  113. package/dist/lib/html/html2.d.ts +55 -0
  114. package/dist/lib/html/index.d.ts +5 -0
  115. package/dist/lib/html/m.d.ts +167 -0
  116. package/dist/lib/html/m2.d.ts +8 -0
  117. package/dist/lib/html/m3.d.ts +0 -0
  118. package/dist/lib/html/template.d.ts +167 -0
  119. package/dist/lib/http/HttpClient.d.ts +153 -0
  120. package/dist/lib/http/ServerSentEvents.d.ts +116 -0
  121. package/dist/lib/http/SimpleWebSocket.d.ts +153 -0
  122. package/dist/lib/http/http.d.ts +177 -0
  123. package/dist/lib/http/index.d.ts +3 -0
  124. package/dist/lib/i18n/i18n.d.ts +105 -0
  125. package/dist/lib/i18n/icu.d.ts +64 -0
  126. package/dist/lib/i18n/index.d.ts +2 -0
  127. package/dist/lib/index.d.ts +16 -0
  128. package/dist/lib/routing/NavigateRouteEvent.d.ts +52 -0
  129. package/dist/lib/routing/RouteLink.d.ts +7 -0
  130. package/dist/lib/routing/Routing.d.ts +270 -0
  131. package/dist/lib/routing/RoutingTarget.d.ts +22 -0
  132. package/dist/lib/routing/index.d.ts +7 -0
  133. package/dist/lib/routing/navigation.d.ts +70 -0
  134. package/dist/lib/routing/routeMatching.d.ts +21 -0
  135. package/dist/lib/routing/routeTargetRegistry.d.ts +23 -0
  136. package/dist/lib/routing/types.d.ts +130 -0
  137. package/dist/lib/templates/NodeTemplate.d.ts +38 -0
  138. package/dist/lib/templates/accessorParser.d.ts +87 -0
  139. package/dist/lib/templates/parseTemplate.d.ts +6 -0
  140. package/dist/lib/templates/tokenizer.d.ts +76 -0
  141. package/dist/lib/tools.d.ts +30 -0
  142. package/dist/lib/utils/index.d.ts +4 -0
  143. package/dist/pipes.d.ts +236 -0
  144. package/dist/routing/NavigateRouteEvent.d.ts +52 -0
  145. package/dist/routing/RouteLink.d.ts +7 -0
  146. package/dist/routing/RoutingTarget.d.ts +22 -0
  147. package/dist/routing/index.d.ts +7 -0
  148. package/dist/routing/index.js +5 -0
  149. package/dist/routing/index.js.map +7 -0
  150. package/dist/routing/index.mjs +5 -0
  151. package/dist/routing/index.mjs.map +7 -0
  152. package/dist/routing/navigation.d.ts +70 -0
  153. package/dist/routing/routeMatching.d.ts +21 -0
  154. package/dist/routing/routeTargetRegistry.d.ts +23 -0
  155. package/dist/routing/types.d.ts +130 -0
  156. package/dist/templates/NodeTemplate.d.ts +38 -0
  157. package/dist/templates/accessorParser.d.ts +87 -0
  158. package/dist/templates/parseTemplate.d.ts +6 -0
  159. package/dist/templates/tokenizer.d.ts +76 -0
  160. package/dist/tools.d.ts +30 -0
  161. package/dist/utils/index.d.ts +4 -0
  162. package/dist/utils/index.js +2 -0
  163. package/dist/utils/index.js.map +7 -0
  164. package/dist/utils/index.mjs +2 -0
  165. package/dist/utils/index.mjs.map +7 -0
  166. package/docs/Architecture.md +333 -0
  167. package/docs/DependencyInjection.md +237 -0
  168. package/docs/Errors.md +87 -0
  169. package/docs/GettingStarted.md +231 -0
  170. package/docs/Pipes.md +211 -0
  171. package/docs/Translations.md +312 -0
  172. package/docs/WhyRelaxjs.md +336 -0
  173. package/docs/elements/dom.md +102 -0
  174. package/docs/forms/creating-form-components.md +924 -0
  175. package/docs/forms/form-api.md +94 -0
  176. package/docs/forms/forms.md +99 -0
  177. package/docs/forms/patterns.md +311 -0
  178. package/docs/forms/reading-writing.md +365 -0
  179. package/docs/forms/validation.md +351 -0
  180. package/docs/html/TableRenderer.md +292 -0
  181. package/docs/html/html.md +175 -0
  182. package/docs/html/index.md +54 -0
  183. package/docs/html/template.md +422 -0
  184. package/docs/http/HttpClient.md +459 -0
  185. package/docs/http/ServerSentEvents.md +184 -0
  186. package/docs/http/index.md +109 -0
  187. package/docs/i18n/i18n.md +309 -0
  188. package/docs/i18n/intl-standard.md +178 -0
  189. package/docs/routing/RouteLink.md +98 -0
  190. package/docs/routing/Routing.md +332 -0
  191. package/docs/routing/RoutingTarget.md +136 -0
  192. package/docs/routing/layouts.md +207 -0
  193. package/docs/utilities.md +143 -0
  194. package/package.json +93 -0
@@ -0,0 +1,51 @@
1
+ /**
2
+ * Interface for loading paginated data from a data source.
3
+ * Implement this interface to provide data to table or list components
4
+ * that support pagination and sorting.
5
+ *
6
+ * Used by components like `r-table` to fetch data on demand as users
7
+ * navigate through pages or change sort order.
8
+ *
9
+ * @example
10
+ * // Implement for an API-backed data source
11
+ * class UserDataLoader implements DataLoader {
12
+ * async load(options) {
13
+ * const params = new URLSearchParams({
14
+ * page: options.page.toString(),
15
+ * pageSize: options.pageSize.toString(),
16
+ * sort: JSON.stringify(options.sort)
17
+ * });
18
+ *
19
+ * const response = await fetch(`/api/users?${params}`);
20
+ * return response.json();
21
+ * }
22
+ * }
23
+ *
24
+ * @example
25
+ * // Use with a table component
26
+ * const loader: DataLoader = new UserDataLoader();
27
+ * const result = await loader.load({ page: 1, pageSize: 25, sort: [] });
28
+ * table.render(result.rows);
29
+ */
30
+ export interface DataLoader {
31
+ /**
32
+ * Loads a page of data with optional sorting.
33
+ *
34
+ * @param options - The loading options
35
+ * @param options.page - The 1-based page number to load
36
+ * @param options.pageSize - Number of rows per page
37
+ * @param options.sort - Array of sort specifications
38
+ * @returns Promise resolving to rows and total count for pagination
39
+ */
40
+ load(options: {
41
+ page: number;
42
+ pageSize: number;
43
+ sort: {
44
+ column: string;
45
+ direction: 'asc' | 'desc';
46
+ }[];
47
+ }): Promise<{
48
+ rows: Record<string, any>[];
49
+ totalCount: number;
50
+ }>;
51
+ }
@@ -0,0 +1,271 @@
1
+ /**
2
+ * Generic constructor type used for dependency registration and injection.
3
+ * Represents any class constructor that can be used with the DI container.
4
+ *
5
+ * @template T - The type of object the constructor creates
6
+ *
7
+ * @example
8
+ * // Use with service registration
9
+ * class UserService {}
10
+ * const ctor: Constructor<UserService> = UserService;
11
+ * serviceCollection.registerByType(ctor, { inject: [] });
12
+ */
13
+ export type Constructor<T extends object = object> = new (...args: any[]) => T;
14
+ /**
15
+ * Controls how service instances are shared across the container hierarchy.
16
+ * Used when registering services to define their lifetime behavior.
17
+ *
18
+ * - `global`: Single instance shared everywhere (singleton pattern)
19
+ * - `closest`: New instance per container scope (scoped lifetime)
20
+ *
21
+ * @example
22
+ * // Singleton service - same instance everywhere
23
+ * serviceCollection.register(LoggerService, { scope: 'global', inject: [] });
24
+ *
25
+ * // Scoped service - new instance per scope
26
+ * serviceCollection.register(RequestContext, { scope: 'closest', inject: [] });
27
+ */
28
+ export type ServiceScope = 'global' | 'closest';
29
+ /**
30
+ * Configuration options for registering a service in the DI container.
31
+ * Controls identification, lifetime, and dependency resolution.
32
+ *
33
+ * @example
34
+ * // Register with constructor injection
35
+ * const options: RegistrationOptions = {
36
+ * scope: 'global',
37
+ * inject: [DatabaseConnection, ConfigService]
38
+ * };
39
+ * serviceCollection.register(UserRepository, options);
40
+ *
41
+ * @example
42
+ * // Register with property injection
43
+ * const options: RegistrationOptions = {
44
+ * inject: [],
45
+ * properties: { logger: Logger, config: 'appConfig' }
46
+ * };
47
+ *
48
+ * @example
49
+ * // Register with a pre-created instance
50
+ * const options: RegistrationOptions = {
51
+ * inject: [],
52
+ * instance: existingService
53
+ * };
54
+ */
55
+ export interface RegistrationOptions {
56
+ /** Service lifetime - 'global' for singleton, 'closest' for scoped */
57
+ scope?: ServiceScope;
58
+ /** Optional string key for resolving by name instead of type */
59
+ key?: string;
60
+ /** Pre-existing instance to use instead of creating new one */
61
+ instance?: unknown;
62
+ /** Types or keys for constructor parameters, in order */
63
+ inject: (string | Constructor)[];
64
+ /** Map of property names to their injection types/keys */
65
+ properties?: Record<string, string | Constructor>;
66
+ }
67
+ /**
68
+ * Field decorator that collects property injection configuration.
69
+ * Updates or creates the properties mapping in registration options.
70
+ *
71
+ * @example
72
+ * @ContainerService({
73
+ * inject: [Database],
74
+ * properties: {
75
+ * logger: Logger, // Inject by type
76
+ * audit: 'auditLogger' // Inject by key
77
+ * }
78
+ * })
79
+ * class UserService {
80
+ * @Inject(Logger)
81
+ * private logger!: Logger;
82
+ *
83
+ * @Inject('auditLogger')
84
+ * private audit!: Logger;
85
+ *
86
+ * constructor(db: Database) {}
87
+ * }
88
+ */
89
+ export declare function Inject<T extends object>(typeOrKey: Constructor<T> | string): (_: undefined, context: ClassFieldDecoratorContext) => (this: any) => T;
90
+ /**
91
+ * Class decorator that automatically registers a service in the global DI container.
92
+ * Use this to declaratively register services without manual registration calls.
93
+ *
94
+ * Services are registered at module load time, so ensure this file is imported
95
+ * before attempting to resolve the decorated service.
96
+ *
97
+ * @param options - Registration configuration including scope and dependencies
98
+ *
99
+ * @example
100
+ * // Simple service with constructor injection
101
+ * @ContainerService({ inject: [DatabaseConnection] })
102
+ * class UserRepository {
103
+ * constructor(private db: DatabaseConnection) {}
104
+ * }
105
+ *
106
+ * @example
107
+ * // Service with custom key for named resolution
108
+ * @ContainerService({ key: 'primaryCache', scope: 'global', inject: [] })
109
+ * class CacheService {}
110
+ *
111
+ * // Later resolve by key
112
+ * const cache = container.resolve('primaryCache');
113
+ */
114
+ export declare function ContainerService<T extends object>(options?: RegistrationOptions): (target: Constructor<T>) => void;
115
+ /**
116
+ * Internal class representing a registered service's metadata.
117
+ * Holds all information needed to create and configure service instances.
118
+ *
119
+ * @internal This is an implementation detail and should not be used directly.
120
+ */
121
+ declare class Registration {
122
+ classConstructor: Constructor;
123
+ scope: ServiceScope;
124
+ inject: (string | Constructor)[];
125
+ properties: Record<string, string | Constructor>;
126
+ key?: string;
127
+ instance?: unknown;
128
+ /**
129
+ * Creates a new registration record.
130
+ *
131
+ * @param classConstructor - The class constructor function
132
+ * @param scope - Instance sharing behavior
133
+ * @param inject - Constructor parameter dependencies
134
+ * @param properties - Property injection mappings
135
+ * @param key - Optional string identifier
136
+ * @param instance - Optional pre-created instance
137
+ */
138
+ constructor(classConstructor: Constructor, scope: ServiceScope, inject: (string | Constructor)[], properties?: Record<string, string | Constructor>, key?: string, instance?: unknown);
139
+ }
140
+ /**
141
+ * Registry that stores service registration metadata.
142
+ * Use this to register services before they can be resolved by a ServiceContainer.
143
+ *
144
+ * Typically you'll use the global `serviceCollection` instance rather than creating your own.
145
+ *
146
+ * @example
147
+ * // Register a service by type
148
+ * serviceCollection.registerByType(LoggerService, { inject: [] });
149
+ *
150
+ * // Register with a string key
151
+ * serviceCollection.register(CacheService, { key: 'cache', inject: [] });
152
+ *
153
+ * // Check if service is registered
154
+ * const reg = serviceCollection.tryGet(LoggerService);
155
+ * if (reg) {
156
+ * console.log('Logger is registered');
157
+ * }
158
+ */
159
+ export declare class ServiceCollection {
160
+ private servicesByKey;
161
+ private servicesByClassName;
162
+ /**
163
+ * Registers a service with full configuration options.
164
+ * The service will be resolvable by both its class name and optional key.
165
+ *
166
+ * @param constructor - The service class constructor
167
+ * @param options - Registration configuration
168
+ */
169
+ register<T extends object>(constructor: Constructor<T>, options: RegistrationOptions): void;
170
+ /**
171
+ * Registers a service by its class type.
172
+ * The service will be resolvable by its class constructor.
173
+ *
174
+ * @param constructor - The service class constructor
175
+ * @param options - Optional registration configuration
176
+ */
177
+ registerByType<T extends object>(constructor: Constructor<T>, options?: RegistrationOptions): void;
178
+ private checkNameCollision;
179
+ private validateRegistration;
180
+ /**
181
+ * Attempts to retrieve a service registration.
182
+ * Returns undefined if the service is not registered.
183
+ *
184
+ * @param key - Either a string key or class constructor
185
+ * @returns The registration or undefined
186
+ */
187
+ tryGet<T extends object>(key: string | Constructor<T>): Registration | undefined;
188
+ /**
189
+ * Retrieves a service registration or throws if not found.
190
+ *
191
+ * @param key - Either a string key or class constructor
192
+ * @returns The registration
193
+ * @throws Error if the service is not registered
194
+ */
195
+ get<T extends object>(key: string | Constructor<T>): Registration;
196
+ }
197
+ /**
198
+ * IoC container that resolves and manages service instances.
199
+ * Creates instances based on registrations in a ServiceCollection,
200
+ * handling constructor injection, property injection, and lifetime management.
201
+ *
202
+ * Typically you'll use the global `container` instance rather than creating your own.
203
+ *
204
+ * @example
205
+ * // Resolve a service by class
206
+ * const logger = container.resolve(LoggerService);
207
+ *
208
+ * // Resolve by string key
209
+ * const cache = container.resolve<CacheService>('primaryCache');
210
+ *
211
+ * @example
212
+ * // Full setup workflow
213
+ * serviceCollection.register(UserService, {
214
+ * inject: [DatabaseConnection],
215
+ * scope: 'global'
216
+ * });
217
+ *
218
+ * const userService = container.resolve(UserService);
219
+ */
220
+ export declare class ServiceContainer {
221
+ private serviceCollection;
222
+ private instances;
223
+ /**
224
+ * Creates a new container backed by the given service collection.
225
+ *
226
+ * @param serviceCollection - The registry containing service registrations
227
+ */
228
+ constructor(serviceCollection: ServiceCollection);
229
+ /**
230
+ * Resolves a service instance by class type or string key.
231
+ * Creates the instance if not already cached (for global scope).
232
+ * Handles constructor and property injection automatically.
233
+ *
234
+ * @param keyOrType - Either a string key or class constructor
235
+ * @returns The resolved service instance
236
+ * @throws Error if the service is not registered
237
+ *
238
+ * @example
239
+ * const service = container.resolve(MyService);
240
+ */
241
+ resolve<T extends object>(keyOrType: string | Constructor<T>): T;
242
+ /**
243
+ * Creates a new instance of a service, resolving all constructor dependencies.
244
+ */
245
+ private createInstance;
246
+ /**
247
+ * Injects dependencies into instance properties based on registration config.
248
+ */
249
+ private injectFields;
250
+ }
251
+ /**
252
+ * Global service collection instance for registering services.
253
+ * Use this to register services that can later be resolved by the container.
254
+ *
255
+ * @example
256
+ * import { serviceCollection } from 'relaxjs';
257
+ *
258
+ * serviceCollection.register(MyService, { inject: [Dependency] });
259
+ */
260
+ export declare const serviceCollection: ServiceCollection;
261
+ /**
262
+ * Global service container instance for resolving dependencies.
263
+ * Use this to obtain service instances with all dependencies injected.
264
+ *
265
+ * @example
266
+ * import { container } from 'relaxjs';
267
+ *
268
+ * const service = container.resolve(MyService);
269
+ */
270
+ export declare const container: ServiceContainer;
271
+ export {};
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Finds the closest parent of a specific type by traversing up the DOM tree.
3
+ *
4
+ * @param node - The starting node to search from.
5
+ * @param constructor - The constructor of the desired element type (e.g., MyParentComponent).
6
+ * @returns The matching element or null if not found.
7
+ */
8
+ export declare function getParentComponent<T extends HTMLElement>(node: Node, constructor: {
9
+ new (...args: any[]): T;
10
+ }): T | null;
@@ -0,0 +1,236 @@
1
+ /**
2
+ * @module pipes
3
+ * Data transformation functions (pipes) for use in template expressions.
4
+ * Pipes transform values for display, like formatting dates, currencies, or text.
5
+ *
6
+ * Locale-aware pipes (currency, date, daysAgo, pieces) use the i18n system
7
+ * for formatting and translations. Call `setLocale()` before using these pipes.
8
+ *
9
+ * Pipes can be chained in templates: `{{value | uppercase | shorten:20}}`
10
+ *
11
+ * @example
12
+ * // In templates
13
+ * <span>{{user.name | uppercase}}</span>
14
+ * <span>{{price | currency}}</span>
15
+ * <span>{{createdAt | daysAgo}}</span>
16
+ *
17
+ * @example
18
+ * // Programmatic usage
19
+ * import { applyPipes, defaultPipes } from 'relaxjs';
20
+ * const result = applyPipes('hello world', ['uppercase', 'shorten:8']);
21
+ * // Returns: 'HELLO...'
22
+ */
23
+ /**
24
+ * Type definition for pipe transformation functions.
25
+ * Pipes take a value and optional arguments, returning a transformed value.
26
+ *
27
+ * @example
28
+ * // Define a custom pipe
29
+ * const reversePipe: PipeFunction = (value: string) => {
30
+ * return value.split('').reverse().join('');
31
+ * };
32
+ */
33
+ export type PipeFunction = (value: any, ...args: any[]) => any;
34
+ /**
35
+ * Converts a string to uppercase
36
+ * @param value The string to convert
37
+ * @returns The uppercase string
38
+ */
39
+ export declare function uppercasePipe(value: string): string;
40
+ /**
41
+ * Converts a string to uppercase
42
+ * @param value The string to convert
43
+ * @returns The uppercase string
44
+ */
45
+ export declare function trimPipe(value: string): string;
46
+ /**
47
+ * Converts a string to lowercase
48
+ * @param value The string to convert
49
+ * @returns The lowercase string
50
+ */
51
+ export declare function lowercasePipe(value: string): string;
52
+ /**
53
+ * Capitalizes the first character of a string
54
+ * @param value The string to capitalize
55
+ * @returns The capitalized string
56
+ */
57
+ export declare function capitalizePipe(value: string): string;
58
+ /**
59
+ * Shortens a string to a specified length and adds ellipsis.
60
+ * @param value The string to shorten
61
+ * @param length Maximum length including ellipsis
62
+ * @returns The shortened string with ellipsis if needed
63
+ */
64
+ export declare function shortenPipe(value: string, length: string): string;
65
+ /**
66
+ * Formats a number as currency using the current locale.
67
+ * Uses the i18n system's current locale for formatting.
68
+ *
69
+ * @param value The number to format
70
+ * @param currency Currency code (defaults to USD)
71
+ * @returns Formatted currency string
72
+ *
73
+ * @example
74
+ * // In template: {{price | currency}} or {{price | currency:EUR}}
75
+ * currencyPipe(1234.56); // "$1,234.56" (en) or "1 234,56 $" (sv)
76
+ * currencyPipe(1234.56, 'SEK'); // "SEK 1,234.56" (en) or "1 234,56 kr" (sv)
77
+ */
78
+ export declare function currencyPipe(value: number, currency?: string): string;
79
+ /**
80
+ * Formats a date value according to the specified format.
81
+ * Uses the i18n system's current locale for formatting.
82
+ *
83
+ * @param value Date value (string, number, or Date object)
84
+ * @param format Format type: 'short', 'long', or default (ISO)
85
+ * @returns Formatted date string
86
+ *
87
+ * @example
88
+ * // In template: {{date | date:short}} or {{date | date:long}}
89
+ * datePipe(new Date(), 'short'); // "1/15/2024" (en) or "2024-01-15" (sv)
90
+ * datePipe(new Date(), 'long'); // "Monday, January 15, 2024" (en) or "måndag 15 januari 2024" (sv)
91
+ */
92
+ export declare function datePipe(value: string | number | Date, format?: string): string;
93
+ /**
94
+ * Prints today, yesterday or X days ago.
95
+ * Uses the i18n system for translations (requires pipes namespace loaded).
96
+ *
97
+ * @param value Date value (string, number, or Date object)
98
+ * @returns Formatted relative date string
99
+ *
100
+ * @example
101
+ * // In template: {{createdAt | daysAgo}}
102
+ * // English: "today", "yesterday", "3 days ago"
103
+ * // Swedish: "idag", "igår", "3 dagar sedan"
104
+ */
105
+ export declare function daysAgoPipe(value: string | number | Date): string;
106
+ /**
107
+ * Formats a count as pieces/items.
108
+ * Uses the i18n system for translations (requires pipes namespace loaded).
109
+ *
110
+ * @param value Count value
111
+ * @returns Formatted piece count string
112
+ *
113
+ * @example
114
+ * // In template: {{quantity | pieces}}
115
+ * // English: "none", "one", "3 pcs"
116
+ * // Swedish: "inga", "en", "3 st"
117
+ */
118
+ export declare function piecesPipe(value: string | number): string;
119
+ /**
120
+ * Joins array elements with the specified separator
121
+ * @param value Array to join
122
+ * @param separator Character(s) to use between elements (defaults to comma)
123
+ * @returns Joined string or original value if not an array
124
+ */
125
+ export declare function joinPipe(value: any[], separator?: string): string | any;
126
+ /**
127
+ * Returns the first element of an array
128
+ * @param value Array to extract from
129
+ * @returns First element or empty string if array is empty/invalid
130
+ */
131
+ export declare function firstPipe(value: any[]): any;
132
+ /**
133
+ * Returns the last element of an array
134
+ * @param value Array to extract from
135
+ * @returns Last element or empty string if array is empty/invalid
136
+ */
137
+ export declare function lastPipe(value: any[]): any;
138
+ /**
139
+ * Returns the keys of an object
140
+ * @param value Object to extract keys from
141
+ * @returns Array of object keys or empty array if not an object
142
+ */
143
+ export declare function keysPipe(value: object): string[];
144
+ /**
145
+ * Returns a default value if the input is falsy
146
+ * @param value Input value to check
147
+ * @param defaultValue Value to return if input is falsy
148
+ * @returns Original value or default value
149
+ */
150
+ export declare function defaultPipe(value: any, defaultValue: string): any;
151
+ /**
152
+ * Implements ternary operator as a pipe
153
+ * @param value Condition to evaluate
154
+ * @param trueValue Value to return if condition is truthy
155
+ * @param falseValue Value to return if condition is falsy
156
+ * @returns Selected value based on condition
157
+ */
158
+ export declare function ternaryPipe(value: any, trueValue: string, falseValue: string): string;
159
+ /**
160
+ * Interface for a collection of pipe functions.
161
+ * Use this to look up pipes by name for template processing.
162
+ *
163
+ * @example
164
+ * // Check if a pipe exists before using
165
+ * if (registry.has('currency')) {
166
+ * const formatted = registry.get('currency')(price);
167
+ * }
168
+ */
169
+ export interface PipeRegistry {
170
+ /**
171
+ * Looks up a pipe by name, returning null if not found.
172
+ */
173
+ lookup(name: string): PipeFunction | null;
174
+ /**
175
+ * Gets a pipe by name, throwing if not found.
176
+ */
177
+ get(name: string): PipeFunction;
178
+ /**
179
+ * Checks if a pipe with the given name exists.
180
+ */
181
+ has(name: string): boolean;
182
+ }
183
+ /**
184
+ * Creates a new pipe registry with all built-in pipes registered.
185
+ * Built-in pipes include:
186
+ *
187
+ * **Text:** uppercase, lowercase, capitalize, trim, shorten
188
+ * **Formatting:** currency, date, daysAgo, pieces
189
+ * **Arrays:** join, first, last
190
+ * **Objects:** keys
191
+ * **Conditionals:** default, ternary
192
+ *
193
+ * @returns A new pipe registry instance
194
+ *
195
+ * @example
196
+ * const registry = createPipeRegistry();
197
+ * const upperPipe = registry.get('uppercase');
198
+ * console.log(upperPipe('hello')); // 'HELLO'
199
+ */
200
+ export declare function createPipeRegistry(): PipeRegistry;
201
+ /**
202
+ * Default pipe registry instance with all built-in pipes.
203
+ * Used by template engines unless a custom registry is provided.
204
+ *
205
+ * @example
206
+ * import { defaultPipes } from 'relaxjs';
207
+ *
208
+ * if (defaultPipes.has('uppercase')) {
209
+ * const result = defaultPipes.get('uppercase')('hello');
210
+ * }
211
+ */
212
+ export declare const defaultPipes: PipeRegistry;
213
+ /**
214
+ * Applies a series of pipes to a value sequentially.
215
+ * Each pipe transforms the output of the previous pipe.
216
+ *
217
+ * Pipe arguments are specified after a colon: `shorten:20`
218
+ *
219
+ * @param value - Initial value to transform
220
+ * @param pipes - Array of pipe strings (name and optional arguments separated by ':')
221
+ * @param registry - Optional custom pipe registry (uses defaultPipes if not provided)
222
+ * @returns The transformed value after applying all pipes
223
+ *
224
+ * @example
225
+ * // Apply single pipe
226
+ * applyPipes('hello', ['uppercase']); // 'HELLO'
227
+ *
228
+ * @example
229
+ * // Chain multiple pipes
230
+ * applyPipes('hello world', ['uppercase', 'shorten:8']); // 'HELLO...'
231
+ *
232
+ * @example
233
+ * // With pipe arguments
234
+ * applyPipes(1234.56, ['currency']); // '$1,234.56'
235
+ */
236
+ export declare function applyPipes(value: any, pipes: string[], registry?: PipeRegistry): any;
@@ -0,0 +1,47 @@
1
+ /**
2
+ * @module SequentialId
3
+ * Generates compact, time-ordered unique identifiers suitable for distributed systems.
4
+ *
5
+ * IDs are structured to be:
6
+ * - Unique across multiple clients (via baseId)
7
+ * - Time-sortable (timestamp is the most significant bits)
8
+ * - Compact (Base36 encoding produces short strings)
9
+ *
10
+ * Bit allocation (58 bits total):
11
+ * - 30 bits for timestamp (seconds since January 1, 2025)
12
+ * - 8 bits for per-second counter (supports 256 IDs/second)
13
+ * - 20 bits for client/endpoint identifier (supports ~1M unique sources)
14
+ */
15
+ /**
16
+ * Generates a unique, time-ordered sequential ID.
17
+ *
18
+ * The ID combines a timestamp, per-second counter, and client identifier
19
+ * into a compact Base36 string. IDs generated later will sort after earlier IDs,
20
+ * making them suitable for ordered collections.
21
+ *
22
+ * @param baseId - Unique identifier for the client/endpoint (0 to 1,048,575).
23
+ * Use different baseIds for different servers or processes to
24
+ * avoid collisions.
25
+ * @returns Base36 encoded string representing the unique ID
26
+ * @throws Error if baseId is out of valid range
27
+ * @throws Error if more than 256 IDs are generated in a single second
28
+ * @throws Error if timestamp exceeds range (after year 2045)
29
+ *
30
+ * @example
31
+ * // Generate ID for server instance 1
32
+ * const id1 = generateSequentialId(1);
33
+ * // Returns something like: 'k2j8m3n5p'
34
+ *
35
+ * @example
36
+ * // Different servers use different baseIds
37
+ * const SERVER_ID = parseInt(process.env.SERVER_ID || '0');
38
+ * const orderId = generateSequentialId(SERVER_ID);
39
+ *
40
+ * @example
41
+ * // IDs are time-sortable
42
+ * const id1 = generateSequentialId(0);
43
+ * await delay(1000);
44
+ * const id2 = generateSequentialId(0);
45
+ * console.log(id1 < id2); // true (lexicographic comparison works)
46
+ */
47
+ export declare function generateSequentialId(baseId: number): string;
@@ -0,0 +1 @@
1
+ export { LinkedList, Node } from "./LinkedList";
@@ -0,0 +1,75 @@
1
+ /**
2
+ * A node in the @see LinkedList.
3
+ */
4
+ export declare class Node<T> {
5
+ value: T;
6
+ private removeCallback;
7
+ /**
8
+ * Next node unless last one.
9
+ */
10
+ next: Node<T> | null;
11
+ /**
12
+ * Previous node unless first one.
13
+ */
14
+ prev: Node<T> | null;
15
+ /**
16
+ * Constructor.
17
+ * @param value Value contained in the node.
18
+ */
19
+ constructor(value: T, removeCallback: () => void);
20
+ /**
21
+ * Remove this node.
22
+ * Will notify the list of the update to ensure correct element count.
23
+ */
24
+ remove(): void;
25
+ }
26
+ /**
27
+ * A trivial linked list implementation.
28
+ */
29
+ export declare class LinkedList<T> {
30
+ private _first?;
31
+ private _last?;
32
+ private _length;
33
+ /**
34
+ * Add a value to the beginning of the list.
35
+ * @param value Value that should be contained in the node.
36
+ */
37
+ addFirst(value: T): void;
38
+ /**
39
+ * Add a value to the end of the list.
40
+ * @param value Value that should be contained in a node.
41
+ */
42
+ addLast(value: T): void;
43
+ /**
44
+ * Remove a node from the beginning of the list.
45
+ * @returns Value contained in the first node.
46
+ */
47
+ removeFirst(): T;
48
+ /**
49
+ * Remove a node from the end of the list.
50
+ * @returns Value contained in the last node.
51
+ */
52
+ removeLast(): T;
53
+ /**
54
+ * Number of nodes in the list.
55
+ *
56
+ * The count works as long as you do not manually remove nodes (by assigning next/prev to the neighbors).
57
+ */
58
+ get length(): number;
59
+ /**
60
+ * First ndoe.
61
+ */
62
+ get first(): Node<T> | undefined;
63
+ /**
64
+ * Contained value of the first node.
65
+ */
66
+ get firstValue(): T | undefined;
67
+ /**
68
+ * Last node.
69
+ */
70
+ get last(): Node<T> | undefined;
71
+ /**
72
+ * Contained value of the last node.
73
+ */
74
+ get lastValue(): T | undefined;
75
+ }