@telperion/ng-pack 1.5.0 → 1.6.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.
package/README.md
CHANGED
|
@@ -200,7 +200,8 @@ Angular utility functions and plugins for enhanced development experience.
|
|
|
200
200
|
- 🎯 Event modifier syntax for templates (`.pd`, `.sp`)
|
|
201
201
|
- 🔗 Directive-as-service provider utility
|
|
202
202
|
- 🌐 Promise-based HTTP client with tuple error handling
|
|
203
|
-
-
|
|
203
|
+
- � Unified `toSignal` — convert values, Promises, or Observables to Signals
|
|
204
|
+
- �📦 Tree-shakeable and type-safe
|
|
204
205
|
- ⚡ Zero dependencies
|
|
205
206
|
|
|
206
207
|
#### Quick Start
|
|
@@ -4,7 +4,9 @@ import { DOCUMENT } from '@angular/common';
|
|
|
4
4
|
import { EventManagerPlugin, EVENT_MANAGER_PLUGINS } from '@angular/platform-browser';
|
|
5
5
|
import { HttpClient } from '@angular/common/http';
|
|
6
6
|
import { tryCatch } from '@telperion/js-utils/promise/try-catch';
|
|
7
|
-
import { firstValueFrom } from 'rxjs';
|
|
7
|
+
import { firstValueFrom, Observable, from } from 'rxjs';
|
|
8
|
+
import { toSignal as toSignal$1 } from '@angular/core/rxjs-interop';
|
|
9
|
+
import { promisify } from '@telperion/js-utils/promise/promisify';
|
|
8
10
|
|
|
9
11
|
/**
|
|
10
12
|
* Utility function to create a provider for a directive/component that can be injected as a service.
|
|
@@ -161,9 +163,37 @@ function constructFetcher() {
|
|
|
161
163
|
});
|
|
162
164
|
}
|
|
163
165
|
|
|
166
|
+
/**
|
|
167
|
+
* Converts a value, Promise, or Observable into an Angular Signal.
|
|
168
|
+
* Accepts any of the three source types and normalises them through
|
|
169
|
+
* `@angular/core/rxjs-interop`'s `toSignal` under the hood.
|
|
170
|
+
*
|
|
171
|
+
* @param source - A plain value, Promise, or Observable to convert
|
|
172
|
+
* @param options - Optional configuration forwarded to Angular's `toSignal`
|
|
173
|
+
* @returns A read-only Signal that emits the resolved value (or `undefined` until it resolves)
|
|
174
|
+
*
|
|
175
|
+
* @example
|
|
176
|
+
* ```typescript
|
|
177
|
+
* // From a plain value
|
|
178
|
+
* const sig = toSignal(42);
|
|
179
|
+
*
|
|
180
|
+
* // From a Promise
|
|
181
|
+
* const sig = toSignal(fetch('/api/data').then(r => r.json()));
|
|
182
|
+
*
|
|
183
|
+
* // From an Observable
|
|
184
|
+
* const sig = toSignal(myService.data$);
|
|
185
|
+
* ```
|
|
186
|
+
*/
|
|
187
|
+
function toSignal(source, options = {}) {
|
|
188
|
+
if (!(source instanceof Observable)) {
|
|
189
|
+
source = promisify(source);
|
|
190
|
+
}
|
|
191
|
+
return toSignal$1(from(source), options);
|
|
192
|
+
}
|
|
193
|
+
|
|
164
194
|
/**
|
|
165
195
|
* Generated bundle index. Do not edit.
|
|
166
196
|
*/
|
|
167
197
|
|
|
168
|
-
export { constructFetcher, provideEventModifiersPlugin, provideServiceDirective };
|
|
198
|
+
export { constructFetcher, provideEventModifiersPlugin, provideServiceDirective, toSignal };
|
|
169
199
|
//# sourceMappingURL=telperion-ng-pack-utils.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telperion-ng-pack-utils.mjs","sources":["../../utils/src/provide-service-directive.ts","../../utils/src/event-modifiers.plugin.ts","../../utils/src/construct-fetcher.ts","../../utils/src/telperion-ng-pack-utils.ts"],"sourcesContent":["import { forwardRef, InjectionToken, Provider, Type } from \"@angular/core\";\r\n\r\n/**\r\n * Utility function to create a provider for a directive/component that can be injected as a service.\r\n * This is useful for cases where you want to inject a directive/component instance into another directive/component.\r\n *\r\n * Example usage:\r\n *\r\n * files:\r\n * - parent.directive.ts\r\n * - child.directive.ts\r\n * - parent.service.ts\r\n *\r\n * parent.service.ts:\r\n * ```\r\n * import { InjectionToken } from \"@angular/core\";\r\n * import type { ParentDirective } from \"./parent.directive\";\r\n *\r\n * export const ParentService = new InjectionToken<ParentDirective>(\"ParentService\");\r\n * ```\r\n *\r\n * parent.directive.ts:\r\n * ```\r\n * @Directive({\r\n * selector: 'parent',\r\n * providers: [provideServiceDirective(ParentService, ParentDirective)],\r\n * })\r\n * export class ParentDirective {...}\r\n * ```\r\n * child.directive.ts:\r\n * ```\r\n * @Directive({\r\n * selector: 'child',\r\n * })\r\n * export class ChildDirective {\r\n * #parent = inject(ParentService);\r\n * }\r\n * ```\r\n *\r\n * @param token - The injection token to provide.\r\n * @param directive - The directive/component class that will be provided.\r\n * @returns A provider object that can be used in the providers array of an Angular module or component.\r\n */\r\nexport function provideServiceDirective<T>(\r\n token: InjectionToken<T>,\r\n directive: Type<NoInfer<T>>\r\n): Provider {\r\n return {\r\n provide: token,\r\n useExisting: forwardRef(() => directive)\r\n }\r\n}\r\n","/**\r\n * Angular Event Manager Plugin that enables event modifier syntax in templates.\r\n *\r\n * @example\r\n * ```html\r\n * <form (submit.pd)=\"onSubmit()\">...</form>\r\n * <div (click.sp)=\"handleClick()\">...</div>\r\n * <button (click.pd.sp)=\"handleButtonClick()\">Click me</button>\r\n * ```\r\n */\r\n\r\nimport { DOCUMENT } from '@angular/common';\r\nimport { Inject, Injectable, Provider } from '@angular/core';\r\nimport { EVENT_MANAGER_PLUGINS, EventManagerPlugin } from '@angular/platform-browser';\r\n\r\n/**\r\n * Event Manager Plugin that adds support for event modifiers.\r\n * @internal\r\n */\r\n@Injectable()\r\nexport class EventModifiersPlugin extends EventManagerPlugin {\r\n /**\r\n * Supported modifiers: `pd` (preventDefault), `sp` (stopPropagation)\r\n */\r\n private static modifierMap: { [key: string]: (e: Event) => void } = {\r\n 'pd': (e: Event) => e.preventDefault(),\r\n 'sp': (e: Event) => e.stopPropagation(),\r\n };\r\n\r\n constructor(@Inject(DOCUMENT) doc: Document) {\r\n super(doc);\r\n }\r\n\r\n supports(eventName: string): boolean {\r\n return eventName.includes('.') &&\r\n eventName.split('.').some(part => part in EventModifiersPlugin.modifierMap);\r\n }\r\n\r\n addEventListener(element: HTMLElement, eventName: string, handler: (event: Event) => void): () => void {\r\n const parts = eventName.split('.');\r\n const domEventName = parts[0];\r\n const modifiers = parts.slice(1).filter(m => m in EventModifiersPlugin.modifierMap);\r\n\r\n const wrappedHandler = (event: Event) => {\r\n modifiers.forEach(mod => EventModifiersPlugin.modifierMap[mod](event));\r\n\r\n return handler(event);\r\n };\r\n\r\n element.addEventListener(domEventName, wrappedHandler);\r\n\r\n return () => element.removeEventListener(domEventName, wrappedHandler);\r\n }\r\n}\r\n\r\n/**\r\n * Provides the Event Modifiers Plugin.\r\n *\r\n * @example\r\n * ```typescript\r\n * bootstrapApplication(AppComponent, {\r\n * providers: [provideEventModifiersPlugin()]\r\n * });\r\n * ```\r\n */\r\nexport function provideEventModifiersPlugin(): Provider {\r\n return {\r\n provide: EVENT_MANAGER_PLUGINS,\r\n useClass: EventModifiersPlugin,\r\n multi: true\r\n };\r\n}\r\n","import { HttpClient } from \"@angular/common/http\";\nimport { inject } from \"@angular/core\";\nimport { AnyFunction } from '@telperion/extra-ts-types';\nimport { tryCatch } from \"@telperion/js-utils/promise/try-catch\";\nimport { firstValueFrom, Observable } from 'rxjs';\n\nexport type Fetcher = {\n [P in keyof HttpClient]: HttpClient[P] extends (...args: infer A) => Observable<unknown> ? <T>(...args: A) => Promise<[unknown, T]> : never;\n}\n\n/**\n * Constructs a Fetcher that proxies HttpClient methods and returns a tuple of [error, response].\n * If the HttpClient method throws an error, it will be caught and returned as the first element of the tuple.\n * If the HttpClient method succeeds, the response will be returned as the second element of the tuple.\n * Example usage:\n * ```\n * @Component({\n * selector: 'app-example',\n * template: `<button (click)=\"fetchData()\">Fetch Data</button>`,\n * })\n * export class ExampleComponent {\n * private fetcher = constructFetcher();\n *\n * async fetchData() {\n * const [error, response] = await this.fetcher.get('/api/data');\n *\n* if (error) {\n* console.error('Error fetching data:', error);\n* } else {\n* console.log('Fetched data:', response);\n* }\n * }\n * }\n * ```\n */\nexport function constructFetcher() {\n const client = inject(HttpClient);\n\n return new Proxy({} as Fetcher, {\n get(target, prop) {\n if (prop in client) {\n return (...args: any[]) => {\n const method = (client as any)[prop] as AnyFunction;\n\n return tryCatch(firstValueFrom(method.apply(client, args)));\n }\n }\n\n throw new Error(`HttpClient does not have method ${String(prop)}`);\n }\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"telperion-ng-pack-utils.mjs","sources":["../../utils/src/provide-service-directive.ts","../../utils/src/event-modifiers.plugin.ts","../../utils/src/construct-fetcher.ts","../../utils/src/to-signal.ts","../../utils/src/telperion-ng-pack-utils.ts"],"sourcesContent":["import { forwardRef, InjectionToken, Provider, Type } from \"@angular/core\";\r\n\r\n/**\r\n * Utility function to create a provider for a directive/component that can be injected as a service.\r\n * This is useful for cases where you want to inject a directive/component instance into another directive/component.\r\n *\r\n * Example usage:\r\n *\r\n * files:\r\n * - parent.directive.ts\r\n * - child.directive.ts\r\n * - parent.service.ts\r\n *\r\n * parent.service.ts:\r\n * ```\r\n * import { InjectionToken } from \"@angular/core\";\r\n * import type { ParentDirective } from \"./parent.directive\";\r\n *\r\n * export const ParentService = new InjectionToken<ParentDirective>(\"ParentService\");\r\n * ```\r\n *\r\n * parent.directive.ts:\r\n * ```\r\n * @Directive({\r\n * selector: 'parent',\r\n * providers: [provideServiceDirective(ParentService, ParentDirective)],\r\n * })\r\n * export class ParentDirective {...}\r\n * ```\r\n * child.directive.ts:\r\n * ```\r\n * @Directive({\r\n * selector: 'child',\r\n * })\r\n * export class ChildDirective {\r\n * #parent = inject(ParentService);\r\n * }\r\n * ```\r\n *\r\n * @param token - The injection token to provide.\r\n * @param directive - The directive/component class that will be provided.\r\n * @returns A provider object that can be used in the providers array of an Angular module or component.\r\n */\r\nexport function provideServiceDirective<T>(\r\n token: InjectionToken<T>,\r\n directive: Type<NoInfer<T>>\r\n): Provider {\r\n return {\r\n provide: token,\r\n useExisting: forwardRef(() => directive)\r\n }\r\n}\r\n","/**\r\n * Angular Event Manager Plugin that enables event modifier syntax in templates.\r\n *\r\n * @example\r\n * ```html\r\n * <form (submit.pd)=\"onSubmit()\">...</form>\r\n * <div (click.sp)=\"handleClick()\">...</div>\r\n * <button (click.pd.sp)=\"handleButtonClick()\">Click me</button>\r\n * ```\r\n */\r\n\r\nimport { DOCUMENT } from '@angular/common';\r\nimport { Inject, Injectable, Provider } from '@angular/core';\r\nimport { EVENT_MANAGER_PLUGINS, EventManagerPlugin } from '@angular/platform-browser';\r\n\r\n/**\r\n * Event Manager Plugin that adds support for event modifiers.\r\n * @internal\r\n */\r\n@Injectable()\r\nexport class EventModifiersPlugin extends EventManagerPlugin {\r\n /**\r\n * Supported modifiers: `pd` (preventDefault), `sp` (stopPropagation)\r\n */\r\n private static modifierMap: { [key: string]: (e: Event) => void } = {\r\n 'pd': (e: Event) => e.preventDefault(),\r\n 'sp': (e: Event) => e.stopPropagation(),\r\n };\r\n\r\n constructor(@Inject(DOCUMENT) doc: Document) {\r\n super(doc);\r\n }\r\n\r\n supports(eventName: string): boolean {\r\n return eventName.includes('.') &&\r\n eventName.split('.').some(part => part in EventModifiersPlugin.modifierMap);\r\n }\r\n\r\n addEventListener(element: HTMLElement, eventName: string, handler: (event: Event) => void): () => void {\r\n const parts = eventName.split('.');\r\n const domEventName = parts[0];\r\n const modifiers = parts.slice(1).filter(m => m in EventModifiersPlugin.modifierMap);\r\n\r\n const wrappedHandler = (event: Event) => {\r\n modifiers.forEach(mod => EventModifiersPlugin.modifierMap[mod](event));\r\n\r\n return handler(event);\r\n };\r\n\r\n element.addEventListener(domEventName, wrappedHandler);\r\n\r\n return () => element.removeEventListener(domEventName, wrappedHandler);\r\n }\r\n}\r\n\r\n/**\r\n * Provides the Event Modifiers Plugin.\r\n *\r\n * @example\r\n * ```typescript\r\n * bootstrapApplication(AppComponent, {\r\n * providers: [provideEventModifiersPlugin()]\r\n * });\r\n * ```\r\n */\r\nexport function provideEventModifiersPlugin(): Provider {\r\n return {\r\n provide: EVENT_MANAGER_PLUGINS,\r\n useClass: EventModifiersPlugin,\r\n multi: true\r\n };\r\n}\r\n","import { HttpClient } from \"@angular/common/http\";\nimport { inject } from \"@angular/core\";\nimport { AnyFunction } from '@telperion/extra-ts-types';\nimport { tryCatch } from \"@telperion/js-utils/promise/try-catch\";\nimport { firstValueFrom, Observable } from 'rxjs';\n\nexport type Fetcher = {\n [P in keyof HttpClient]: HttpClient[P] extends (...args: infer A) => Observable<unknown> ? <T>(...args: A) => Promise<[unknown, T]> : never;\n}\n\n/**\n * Constructs a Fetcher that proxies HttpClient methods and returns a tuple of [error, response].\n * If the HttpClient method throws an error, it will be caught and returned as the first element of the tuple.\n * If the HttpClient method succeeds, the response will be returned as the second element of the tuple.\n * Example usage:\n * ```\n * @Component({\n * selector: 'app-example',\n * template: `<button (click)=\"fetchData()\">Fetch Data</button>`,\n * })\n * export class ExampleComponent {\n * private fetcher = constructFetcher();\n *\n * async fetchData() {\n * const [error, response] = await this.fetcher.get('/api/data');\n *\n* if (error) {\n* console.error('Error fetching data:', error);\n* } else {\n* console.log('Fetched data:', response);\n* }\n * }\n * }\n * ```\n */\nexport function constructFetcher() {\n const client = inject(HttpClient);\n\n return new Proxy({} as Fetcher, {\n get(target, prop) {\n if (prop in client) {\n return (...args: any[]) => {\n const method = (client as any)[prop] as AnyFunction;\n\n return tryCatch(firstValueFrom(method.apply(client, args)));\n }\n }\n\n throw new Error(`HttpClient does not have method ${String(prop)}`);\n }\n });\n}\n","import { Signal } from \"@angular/core\";\r\nimport { toSignal as ngToSignal } from \"@angular/core/rxjs-interop\";\r\nimport { from, Observable } from \"rxjs\";\r\nimport { promisify } from '@telperion/js-utils/promise/promisify';\r\n\r\n/**\r\n * Converts a value, Promise, or Observable into an Angular Signal.\r\n * Accepts any of the three source types and normalises them through\r\n * `@angular/core/rxjs-interop`'s `toSignal` under the hood.\r\n *\r\n * @param source - A plain value, Promise, or Observable to convert\r\n * @param options - Optional configuration forwarded to Angular's `toSignal`\r\n * @returns A read-only Signal that emits the resolved value (or `undefined` until it resolves)\r\n *\r\n * @example\r\n * ```typescript\r\n * // From a plain value\r\n * const sig = toSignal(42);\r\n *\r\n * // From a Promise\r\n * const sig = toSignal(fetch('/api/data').then(r => r.json()));\r\n *\r\n * // From an Observable\r\n * const sig = toSignal(myService.data$);\r\n * ```\r\n */\r\nexport function toSignal<T>(\r\n source: T | Promise<T> | Observable<T>,\r\n options: Partial<Parameters<typeof ngToSignal<T>>[1]> = {}\r\n): Signal<T | undefined> {\r\n if (!(source instanceof Observable)) {\r\n source = promisify(source);\r\n }\r\n\r\n return ngToSignal(from(source), options as Parameters<typeof ngToSignal<T>>[1]);\r\n}\r\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["ngToSignal"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@telperion/ng-pack",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Collection of Angular utilities and libraries organized as secondary entry points. Includes signal-based storage (localStorage/sessionStorage/cookieStorage), SSE client with HttpClient-inspired interceptors, event modifier plugins, and more. Built with TypeScript, RxJS, and Angular Signals for modern Angular applications.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"angular",
|
|
@@ -23,7 +23,9 @@
|
|
|
23
23
|
"httpclient",
|
|
24
24
|
"secondary-entrypoint",
|
|
25
25
|
"angular-utilities",
|
|
26
|
-
"event-manager"
|
|
26
|
+
"event-manager",
|
|
27
|
+
"promise",
|
|
28
|
+
"toSignal"
|
|
27
29
|
],
|
|
28
30
|
"peerDependencies": {
|
|
29
31
|
"@angular/common": "^21.0.0",
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { InjectionToken, Type, Provider } from '@angular/core';
|
|
1
|
+
import { InjectionToken, Type, Provider, Signal } from '@angular/core';
|
|
2
2
|
import { HttpClient } from '@angular/common/http';
|
|
3
3
|
import { Observable } from 'rxjs';
|
|
4
|
+
import { toSignal as toSignal$1 } from '@angular/core/rxjs-interop';
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* Utility function to create a provider for a directive/component that can be injected as a service.
|
|
@@ -87,4 +88,27 @@ type Fetcher = {
|
|
|
87
88
|
*/
|
|
88
89
|
declare function constructFetcher(): Fetcher;
|
|
89
90
|
|
|
90
|
-
|
|
91
|
+
/**
|
|
92
|
+
* Converts a value, Promise, or Observable into an Angular Signal.
|
|
93
|
+
* Accepts any of the three source types and normalises them through
|
|
94
|
+
* `@angular/core/rxjs-interop`'s `toSignal` under the hood.
|
|
95
|
+
*
|
|
96
|
+
* @param source - A plain value, Promise, or Observable to convert
|
|
97
|
+
* @param options - Optional configuration forwarded to Angular's `toSignal`
|
|
98
|
+
* @returns A read-only Signal that emits the resolved value (or `undefined` until it resolves)
|
|
99
|
+
*
|
|
100
|
+
* @example
|
|
101
|
+
* ```typescript
|
|
102
|
+
* // From a plain value
|
|
103
|
+
* const sig = toSignal(42);
|
|
104
|
+
*
|
|
105
|
+
* // From a Promise
|
|
106
|
+
* const sig = toSignal(fetch('/api/data').then(r => r.json()));
|
|
107
|
+
*
|
|
108
|
+
* // From an Observable
|
|
109
|
+
* const sig = toSignal(myService.data$);
|
|
110
|
+
* ```
|
|
111
|
+
*/
|
|
112
|
+
declare function toSignal<T>(source: T | Promise<T> | Observable<T>, options?: Partial<Parameters<typeof toSignal$1<T>>[1]>): Signal<T | undefined>;
|
|
113
|
+
|
|
114
|
+
export { constructFetcher, provideEventModifiersPlugin, provideServiceDirective, toSignal };
|
package/utils/README.md
CHANGED
|
@@ -242,6 +242,36 @@ All methods return a Promise that resolves to a tuple:
|
|
|
242
242
|
4. **DI integration**: Works seamlessly with Angular's dependency injection
|
|
243
243
|
5. **Clean code**: Reduces boilerplate and improves readability
|
|
244
244
|
|
|
245
|
+
### toSignal
|
|
246
|
+
|
|
247
|
+
A unified helper that converts a plain value, a Promise, or an Observable into an Angular `Signal`. It normalises the input through `@angular/core/rxjs-interop`'s `toSignal`, so you can use a single call regardless of the source type.
|
|
248
|
+
|
|
249
|
+
#### Usage
|
|
250
|
+
|
|
251
|
+
```typescript
|
|
252
|
+
import { toSignal } from '@telperion/ng-pack/utils';
|
|
253
|
+
|
|
254
|
+
// From a plain value
|
|
255
|
+
const count = toSignal(42);
|
|
256
|
+
|
|
257
|
+
// From a Promise
|
|
258
|
+
const user = toSignal(fetch('/api/me').then(r => r.json()));
|
|
259
|
+
|
|
260
|
+
// From an Observable
|
|
261
|
+
const messages = toSignal(this.messageService.messages$);
|
|
262
|
+
|
|
263
|
+
// With options (forwarded to Angular's toSignal)
|
|
264
|
+
const data = toSignal(this.dataService.data$, { initialValue: [] });
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
#### API
|
|
268
|
+
|
|
269
|
+
`toSignal<T>(source: T | Promise<T> | Observable<T>, options?): Signal<T | undefined>`
|
|
270
|
+
|
|
271
|
+
- `source` - A plain value, Promise, or Observable
|
|
272
|
+
- `options` (optional) - Configuration forwarded to Angular's `toSignal` (e.g., `{ initialValue }` )
|
|
273
|
+
- Returns a read-only `Signal<T | undefined>`
|
|
274
|
+
|
|
245
275
|
## License
|
|
246
276
|
|
|
247
277
|
MIT
|