@multisystemsuite/timezone-engine-angular 1.0.0 → 2.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.
package/README.md ADDED
@@ -0,0 +1,86 @@
1
+ # @multisystemsuite/timezone-engine-angular
2
+
3
+ Angular services, pipes, and standalone components for enterprise timezone handling.
4
+
5
+ ## What it is used for
6
+
7
+ - Angular 17+ standalone apps and NgModule-based ERP/HRMS dashboards
8
+ - Injectable timezone engine via DI
9
+ - Template pipes for dates and relative time
10
+ - Live world clock widgets
11
+ - Global workforce scheduling views
12
+
13
+ ## Install
14
+
15
+ ```bash
16
+ npm install @multisystemsuite/timezone-engine-angular
17
+ ```
18
+
19
+ Peer dependencies: `@angular/core >= 17`, `@angular/common >= 17`
20
+
21
+ ## Usage
22
+
23
+ ```typescript
24
+ import { Component } from "@angular/core";
25
+ import {
26
+ TimezoneService,
27
+ TeFormatDatePipe,
28
+ TeRelativeTimePipe,
29
+ WorldClockComponent,
30
+ SchedulerComponent,
31
+ } from "@multisystemsuite/timezone-engine-angular";
32
+
33
+ @Component({
34
+ standalone: true,
35
+ imports: [TeFormatDatePipe, WorldClockComponent],
36
+ template: `
37
+ <te-world-clock [timezones]="['UTC', 'Europe/London', 'Asia/Kolkata']" />
38
+ <p>{{ now | teFormatDate: "FULL" : "UTC" }}</p>
39
+ <p>{{ createdAt | teRelativeTime }}</p>
40
+ `,
41
+ })
42
+ export class DashboardComponent {
43
+ now = new Date();
44
+ createdAt = new Date(Date.now() - 3600_000);
45
+
46
+ constructor(private tz: TimezoneService) {
47
+ console.log(this.tz.detectTimezone());
48
+ }
49
+ }
50
+ ```
51
+
52
+ ## Exports
53
+
54
+ | Export | Purpose |
55
+ | ------------------------- | ------------------------------------ |
56
+ | `TimezoneService` | Format, convert, detect, world clock |
57
+ | `WorldClockService` | RxJS live clock observable |
58
+ | `TeFormatDatePipe` | Locale-aware date pipe |
59
+ | `TeRelativeTimePipe` | "2 hours ago" pipe |
60
+ | `TeTimezonePipe` | Convert date to target timezone |
61
+ | `WorldClockComponent` | Standalone world clock |
62
+ | `LiveClockComponent` | Standalone live time |
63
+ | `SchedulerComponent` | Meeting participant scheduler |
64
+ | `TIMEZONE_ENGINE_IMPORTS` | Bundle all standalone imports |
65
+
66
+ ## Config injection
67
+
68
+ ```typescript
69
+ import { TIMEZONE_ENGINE_CONFIG } from "@multisystemsuite/timezone-engine-angular";
70
+
71
+ providers: [
72
+ {
73
+ provide: TIMEZONE_ENGINE_CONFIG,
74
+ useValue: { defaultTimezone: "Asia/Kolkata", defaultLocale: "en-IN" },
75
+ },
76
+ ];
77
+ ```
78
+
79
+ ## Related packages
80
+
81
+ - `@multisystemsuite/timezone-engine-core` — shared logic
82
+ - `@multisystemsuite/timezone-engine-scheduler` — backend scheduling
83
+
84
+ ## License
85
+
86
+ MIT
package/dist/index.cjs CHANGED
@@ -161,7 +161,7 @@ exports.WorldClockComponent = __decorateClass([
161
161
  `
162
162
  })
163
163
  ], exports.WorldClockComponent);
164
- exports.LiveClockComponent = class LiveClockComponent {
164
+ exports.RealtimeClockComponent = class LiveClockComponent {
165
165
  timezone;
166
166
  intervalMs = 1e3;
167
167
  display = "";
@@ -184,17 +184,17 @@ exports.LiveClockComponent = class LiveClockComponent {
184
184
  };
185
185
  __decorateClass([
186
186
  core.Input()
187
- ], exports.LiveClockComponent.prototype, "timezone", 2);
187
+ ], exports.RealtimeClockComponent.prototype, "timezone", 2);
188
188
  __decorateClass([
189
189
  core.Input()
190
- ], exports.LiveClockComponent.prototype, "intervalMs", 2);
191
- exports.LiveClockComponent = __decorateClass([
190
+ ], exports.RealtimeClockComponent.prototype, "intervalMs", 2);
191
+ exports.RealtimeClockComponent = __decorateClass([
192
192
  core.Component({
193
193
  selector: "te-live-clock",
194
194
  standalone: true,
195
195
  template: `<span class="te-live-clock">{{ display }}</span>`
196
196
  })
197
- ], exports.LiveClockComponent);
197
+ ], exports.RealtimeClockComponent);
198
198
  exports.SchedulerComponent = class SchedulerComponent {
199
199
  participants = [];
200
200
  durationMinutes = 60;
@@ -234,10 +234,12 @@ var TIMEZONE_ENGINE_IMPORTS = [
234
234
  exports.TeRelativeTimePipe,
235
235
  exports.TeTimezonePipe,
236
236
  exports.WorldClockComponent,
237
- exports.LiveClockComponent,
237
+ exports.RealtimeClockComponent,
238
238
  exports.SchedulerComponent
239
239
  ];
240
240
 
241
+ exports.DateFormatPipe = exports.TeFormatDatePipe;
242
+ exports.LiveClockComponent = exports.RealtimeClockComponent;
241
243
  exports.TIMEZONE_ENGINE_CONFIG = TIMEZONE_ENGINE_CONFIG;
242
244
  exports.TIMEZONE_ENGINE_IMPORTS = TIMEZONE_ENGINE_IMPORTS;
243
245
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/timezone.service.ts","../src/pipes.ts","../src/components.ts","../src/index.ts"],"names":["InjectionToken","TimezoneService","inject","createTimezoneEngine","BehaviorSubject","detectBrowserTimezone","getUserTimezone","formatDate","convertTimezone","compareTimezones","getWorldClock","getCountryTimezones","getCityTimezone","Injectable","WorldClockService","Observable","createLiveClockUpdater","TeFormatDatePipe","Pipe","TeRelativeTimePipe","formatRelativeTime","TeTimezonePipe","WorldClockComponent","Input","Component","CommonModule","LiveClockComponent","SchedulerComponent"],"mappings":"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","file":"index.cjs","sourcesContent":["import { Injectable, InjectionToken, inject } from \"@angular/core\";\nimport type {\n FormatDateOptions,\n TimezoneEngineConfig,\n WorldClockEntry,\n} from \"@multisystemsuite/timezone-engine-shared-types\";\nimport {\n createTimezoneEngine,\n detectBrowserTimezone,\n formatDate,\n convertTimezone,\n compareTimezones,\n getWorldClock,\n createLiveClockUpdater,\n getUserTimezone,\n type TimezoneEngine,\n} from \"@multisystemsuite/timezone-engine-core\";\nimport { getCountryTimezones, getCityTimezone } from \"@multisystemsuite/timezone-engine-world-data\";\nimport { BehaviorSubject, Observable } from \"rxjs\";\n\nexport const TIMEZONE_ENGINE_CONFIG = new InjectionToken<TimezoneEngineConfig>(\n \"TIMEZONE_ENGINE_CONFIG\",\n);\n\n/** Injectable timezone engine service for Angular */\n@Injectable({ providedIn: \"root\" })\nexport class TimezoneService {\n private config = inject(TIMEZONE_ENGINE_CONFIG, { optional: true }) ?? {};\n private engine: TimezoneEngine = createTimezoneEngine(this.config);\n private timezoneSubject = new BehaviorSubject<string>(\n this.config.defaultTimezone ?? detectBrowserTimezone().timezone,\n );\n\n readonly timezone$: Observable<string> = this.timezoneSubject.asObservable();\n\n get timezone(): string {\n return this.timezoneSubject.value;\n }\n\n setTimezone(tz: string): void {\n this.timezoneSubject.next(tz);\n this.engine.config.update({ defaultTimezone: tz });\n }\n\n detectTimezone(): string {\n return detectBrowserTimezone().timezone;\n }\n\n getUserTimezone(): string {\n return getUserTimezone();\n }\n\n formatDate(date: Date | string | number, options: FormatDateOptions = {}): string {\n return formatDate(date, { timezone: this.timezone, ...options });\n }\n\n convertTimezone(sourceTimezone: string, targetTimezone: string, date?: Date | string | number): Date {\n return convertTimezone({\n sourceTimezone,\n targetTimezone,\n ...(date !== undefined ? { date } : {}),\n });\n }\n\n compareTimezones(source: string, target: string, date?: Date | string | number) {\n return compareTimezones(source, target, date);\n }\n\n getWorldClock(timezones: string[]): WorldClockEntry[] {\n return getWorldClock(timezones);\n }\n\n getCountryTimezones(countryCode: string) {\n return getCountryTimezones(countryCode);\n }\n\n getCityTimezone(city: string) {\n return getCityTimezone(city);\n }\n\n getEngine(): TimezoneEngine {\n return this.engine;\n }\n}\n\n/** World clock observable stream */\n@Injectable({ providedIn: \"root\" })\nexport class WorldClockService {\n private timezoneService = inject(TimezoneService);\n\n createLiveClock(timezones: string[], intervalMs = 1000): Observable<WorldClockEntry[]> {\n return new Observable((subscriber) => {\n const updater = createLiveClockUpdater(\n timezones,\n (clocks) => {\n subscriber.next(clocks);\n },\n intervalMs,\n );\n updater.start();\n return () => {\n updater.stop();\n };\n });\n }\n}\n","import { Pipe, inject, type PipeTransform } from \"@angular/core\";\nimport type { FormatDateOptions } from \"@multisystemsuite/timezone-engine-shared-types\";\nimport { formatRelativeTime } from \"@multisystemsuite/timezone-engine-core\";\nimport { TimezoneService } from \"./timezone.service.js\";\n\n/** Angular pipe for locale-aware date formatting */\n@Pipe({ name: \"teFormatDate\", standalone: true, pure: false })\nexport class TeFormatDatePipe implements PipeTransform {\n private timezoneService = inject(TimezoneService);\n\n transform(\n value: Date | string | number | null | undefined,\n format: FormatDateOptions[\"format\"] = \"DATETIME\",\n timezone?: string,\n locale?: string,\n ): string {\n if (value == null) return \"\";\n const options: FormatDateOptions = { format };\n if (timezone !== undefined) options.timezone = timezone;\n if (locale !== undefined) options.locale = locale;\n return this.timezoneService.formatDate(value, options);\n }\n}\n\n/** Angular pipe for relative time formatting */\n@Pipe({ name: \"teRelativeTime\", standalone: true })\nexport class TeRelativeTimePipe implements PipeTransform {\n transform(value: Date | string | number | null | undefined): string {\n if (value == null) return \"\";\n return formatRelativeTime(value);\n }\n}\n\n/** Angular pipe for timezone conversion display */\n@Pipe({ name: \"teTimezone\", standalone: true })\nexport class TeTimezonePipe implements PipeTransform {\n private timezoneService = inject(TimezoneService);\n\n transform(\n value: Date | string | number | null | undefined,\n targetTimezone: string,\n sourceTimezone?: string,\n ): Date | null {\n if (value == null) return null;\n const source = sourceTimezone ?? this.timezoneService.timezone;\n return this.timezoneService.convertTimezone(source, targetTimezone, value);\n }\n}\n","import { Component, Input, inject, type OnInit, type OnDestroy } from \"@angular/core\";\nimport { CommonModule } from \"@angular/common\";\nimport type { WorldClockEntry } from \"@multisystemsuite/timezone-engine-shared-types\";\nimport { WorldClockService, TimezoneService } from \"./timezone.service.js\";\nimport type { Subscription } from \"rxjs\";\n\n/** Standalone world clock component for Angular */\n@Component({\n selector: \"te-world-clock\",\n standalone: true,\n imports: [CommonModule],\n template: `\n <div class=\"te-clock\" data-testid=\"world-clock\">\n @for (clock of clocks; track clock.timezone) {\n <div class=\"te-clock__entry\">\n <strong>{{ clock.label }}</strong>\n <span>{{ clock.formattedTime }}</span>\n <small>{{ clock.utcOffset }}</small>\n </div>\n }\n </div>\n `,\n})\nexport class WorldClockComponent implements OnInit, OnDestroy {\n @Input() timezones: string[] = [\"UTC\", \"America/New_York\", \"Europe/London\", \"Asia/Kolkata\"];\n @Input() intervalMs = 1000;\n\n clocks: WorldClockEntry[] = [];\n private worldClockService = inject(WorldClockService);\n private subscription?: Subscription;\n\n ngOnInit(): void {\n this.subscription = this.worldClockService\n .createLiveClock(this.timezones, this.intervalMs)\n .subscribe((clocks) => {\n this.clocks = clocks;\n });\n }\n\n ngOnDestroy(): void {\n this.subscription?.unsubscribe();\n }\n}\n\n/** Standalone live clock component */\n@Component({\n selector: \"te-live-clock\",\n standalone: true,\n template: `<span class=\"te-live-clock\">{{ display }}</span>`,\n})\nexport class LiveClockComponent implements OnInit, OnDestroy {\n @Input() timezone?: string;\n @Input() intervalMs = 1000;\n\n display = \"\";\n private timezoneService = inject(TimezoneService);\n private timerId?: ReturnType<typeof setInterval>;\n\n ngOnInit(): void {\n const tz = this.timezone ?? this.timezoneService.timezone;\n const update = () => {\n this.display = this.timezoneService.formatDate(new Date(), {\n format: \"TIME_ONLY\",\n timezone: tz,\n });\n };\n update();\n this.timerId = setInterval(update, this.intervalMs);\n }\n\n ngOnDestroy(): void {\n if (this.timerId !== undefined) clearInterval(this.timerId);\n }\n}\n\n/** Scheduler display component */\n@Component({\n selector: \"te-scheduler\",\n standalone: true,\n imports: [CommonModule, WorldClockComponent],\n template: `\n <div class=\"te-scheduler\">\n <h3 class=\"te-scheduler__title\">Meeting Scheduler</h3>\n <p>Duration: {{ durationMinutes }} minutes</p>\n <ul>\n @for (p of participants; track p.name) {\n <li>{{ p.name }} — {{ p.timezone }}</li>\n }\n </ul>\n <te-world-clock [timezones]=\"participantTimezones\" />\n </div>\n `,\n})\nexport class SchedulerComponent {\n @Input() participants: { name: string; timezone: string }[] = [];\n @Input() durationMinutes = 60;\n\n get participantTimezones(): string[] {\n return [...new Set(this.participants.map((p) => p.timezone))];\n }\n}\n","export {\n TimezoneService,\n WorldClockService,\n TIMEZONE_ENGINE_CONFIG,\n} from \"./timezone.service.js\";\n\nexport { TeFormatDatePipe, TeRelativeTimePipe, TeTimezonePipe } from \"./pipes.js\";\n\nexport {\n WorldClockComponent,\n LiveClockComponent,\n SchedulerComponent,\n} from \"./components.js\";\n\nimport { TeFormatDatePipe, TeRelativeTimePipe, TeTimezonePipe } from \"./pipes.js\";\nimport {\n WorldClockComponent,\n LiveClockComponent,\n SchedulerComponent,\n} from \"./components.js\";\n\n/** Standalone imports bundle for Angular 17+ */\nexport const TIMEZONE_ENGINE_IMPORTS = [\n TeFormatDatePipe,\n TeRelativeTimePipe,\n TeTimezonePipe,\n WorldClockComponent,\n LiveClockComponent,\n SchedulerComponent,\n] as const;\n"]}
1
+ {"version":3,"sources":["../src/timezone.service.ts","../src/pipes.ts","../src/components.ts","../src/index.ts"],"names":["InjectionToken","TimezoneService","inject","createTimezoneEngine","BehaviorSubject","detectBrowserTimezone","getUserTimezone","formatDate","convertTimezone","compareTimezones","getWorldClock","getCountryTimezones","getCityTimezone","Injectable","WorldClockService","Observable","createLiveClockUpdater","TeFormatDatePipe","Pipe","TeRelativeTimePipe","formatRelativeTime","TeTimezonePipe","WorldClockComponent","Input","Component","CommonModule","LiveClockComponent","SchedulerComponent"],"mappings":"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","file":"index.cjs","sourcesContent":["import { Injectable, InjectionToken, inject } from \"@angular/core\";\nimport type {\n FormatDateOptions,\n TimezoneEngineConfig,\n WorldClockEntry,\n} from \"@multisystemsuite/timezone-engine-shared-types\";\nimport {\n createTimezoneEngine,\n detectBrowserTimezone,\n formatDate,\n convertTimezone,\n compareTimezones,\n getWorldClock,\n createLiveClockUpdater,\n getUserTimezone,\n type TimezoneEngine,\n} from \"@multisystemsuite/timezone-engine-core\";\nimport { getCountryTimezones, getCityTimezone } from \"@multisystemsuite/timezone-engine-world-data\";\nimport { BehaviorSubject, Observable } from \"rxjs\";\n\nexport const TIMEZONE_ENGINE_CONFIG = new InjectionToken<TimezoneEngineConfig>(\n \"TIMEZONE_ENGINE_CONFIG\",\n);\n\n/** Injectable timezone engine service for Angular */\n@Injectable({ providedIn: \"root\" })\nexport class TimezoneService {\n private config = inject(TIMEZONE_ENGINE_CONFIG, { optional: true }) ?? {};\n private engine: TimezoneEngine = createTimezoneEngine(this.config);\n private timezoneSubject = new BehaviorSubject<string>(\n this.config.defaultTimezone ?? detectBrowserTimezone().timezone,\n );\n\n readonly timezone$: Observable<string> = this.timezoneSubject.asObservable();\n\n get timezone(): string {\n return this.timezoneSubject.value;\n }\n\n setTimezone(tz: string): void {\n this.timezoneSubject.next(tz);\n this.engine.config.update({ defaultTimezone: tz });\n }\n\n detectTimezone(): string {\n return detectBrowserTimezone().timezone;\n }\n\n getUserTimezone(): string {\n return getUserTimezone();\n }\n\n formatDate(date: Date | string | number, options: FormatDateOptions = {}): string {\n return formatDate(date, { timezone: this.timezone, ...options });\n }\n\n convertTimezone(\n sourceTimezone: string,\n targetTimezone: string,\n date?: Date | string | number,\n ): Date {\n return convertTimezone({\n sourceTimezone,\n targetTimezone,\n ...(date !== undefined ? { date } : {}),\n });\n }\n\n compareTimezones(source: string, target: string, date?: Date | string | number) {\n return compareTimezones(source, target, date);\n }\n\n getWorldClock(timezones: string[]): WorldClockEntry[] {\n return getWorldClock(timezones);\n }\n\n getCountryTimezones(countryCode: string) {\n return getCountryTimezones(countryCode);\n }\n\n getCityTimezone(city: string) {\n return getCityTimezone(city);\n }\n\n getEngine(): TimezoneEngine {\n return this.engine;\n }\n}\n\n/** World clock observable stream */\n@Injectable({ providedIn: \"root\" })\nexport class WorldClockService {\n private timezoneService = inject(TimezoneService);\n\n createLiveClock(timezones: string[], intervalMs = 1000): Observable<WorldClockEntry[]> {\n return new Observable((subscriber) => {\n const updater = createLiveClockUpdater(\n timezones,\n (clocks) => {\n subscriber.next(clocks);\n },\n intervalMs,\n );\n updater.start();\n return () => {\n updater.stop();\n };\n });\n }\n}\n","import { Pipe, inject, type PipeTransform } from \"@angular/core\";\nimport type { FormatDateOptions } from \"@multisystemsuite/timezone-engine-shared-types\";\nimport { formatRelativeTime } from \"@multisystemsuite/timezone-engine-core\";\nimport { TimezoneService } from \"./timezone.service.js\";\n\n/** Angular pipe for locale-aware date formatting */\n@Pipe({ name: \"teFormatDate\", standalone: true, pure: false })\nexport class TeFormatDatePipe implements PipeTransform {\n private timezoneService = inject(TimezoneService);\n\n transform(\n value: Date | string | number | null | undefined,\n format: FormatDateOptions[\"format\"] = \"DATETIME\",\n timezone?: string,\n locale?: string,\n ): string {\n if (value == null) return \"\";\n const options: FormatDateOptions = { format };\n if (timezone !== undefined) options.timezone = timezone;\n if (locale !== undefined) options.locale = locale;\n return this.timezoneService.formatDate(value, options);\n }\n}\n\n/** Angular pipe for relative time formatting */\n@Pipe({ name: \"teRelativeTime\", standalone: true })\nexport class TeRelativeTimePipe implements PipeTransform {\n transform(value: Date | string | number | null | undefined): string {\n if (value == null) return \"\";\n return formatRelativeTime(value);\n }\n}\n\n/** Angular pipe for timezone conversion display */\n@Pipe({ name: \"teTimezone\", standalone: true })\nexport class TeTimezonePipe implements PipeTransform {\n private timezoneService = inject(TimezoneService);\n\n transform(\n value: Date | string | number | null | undefined,\n targetTimezone: string,\n sourceTimezone?: string,\n ): Date | null {\n if (value == null) return null;\n const source = sourceTimezone ?? this.timezoneService.timezone;\n return this.timezoneService.convertTimezone(source, targetTimezone, value);\n }\n}\n","import { Component, Input, inject, type OnInit, type OnDestroy } from \"@angular/core\";\nimport { CommonModule } from \"@angular/common\";\nimport type { WorldClockEntry } from \"@multisystemsuite/timezone-engine-shared-types\";\nimport { WorldClockService, TimezoneService } from \"./timezone.service.js\";\nimport type { Subscription } from \"rxjs\";\n\n/** Standalone world clock component for Angular */\n@Component({\n selector: \"te-world-clock\",\n standalone: true,\n imports: [CommonModule],\n template: `\n <div class=\"te-clock\" data-testid=\"world-clock\">\n @for (clock of clocks; track clock.timezone) {\n <div class=\"te-clock__entry\">\n <strong>{{ clock.label }}</strong>\n <span>{{ clock.formattedTime }}</span>\n <small>{{ clock.utcOffset }}</small>\n </div>\n }\n </div>\n `,\n})\nexport class WorldClockComponent implements OnInit, OnDestroy {\n @Input() timezones: string[] = [\"UTC\", \"America/New_York\", \"Europe/London\", \"Asia/Kolkata\"];\n @Input() intervalMs = 1000;\n\n clocks: WorldClockEntry[] = [];\n private worldClockService = inject(WorldClockService);\n private subscription?: Subscription;\n\n ngOnInit(): void {\n this.subscription = this.worldClockService\n .createLiveClock(this.timezones, this.intervalMs)\n .subscribe((clocks) => {\n this.clocks = clocks;\n });\n }\n\n ngOnDestroy(): void {\n this.subscription?.unsubscribe();\n }\n}\n\n/** Standalone live clock component */\n@Component({\n selector: \"te-live-clock\",\n standalone: true,\n template: `<span class=\"te-live-clock\">{{ display }}</span>`,\n})\nexport class LiveClockComponent implements OnInit, OnDestroy {\n @Input() timezone?: string;\n @Input() intervalMs = 1000;\n\n display = \"\";\n private timezoneService = inject(TimezoneService);\n private timerId?: ReturnType<typeof setInterval>;\n\n ngOnInit(): void {\n const tz = this.timezone ?? this.timezoneService.timezone;\n const update = () => {\n this.display = this.timezoneService.formatDate(new Date(), {\n format: \"TIME_ONLY\",\n timezone: tz,\n });\n };\n update();\n this.timerId = setInterval(update, this.intervalMs);\n }\n\n ngOnDestroy(): void {\n if (this.timerId !== undefined) clearInterval(this.timerId);\n }\n}\n\n/** Scheduler display component */\n@Component({\n selector: \"te-scheduler\",\n standalone: true,\n imports: [CommonModule, WorldClockComponent],\n template: `\n <div class=\"te-scheduler\">\n <h3 class=\"te-scheduler__title\">Meeting Scheduler</h3>\n <p>Duration: {{ durationMinutes }} minutes</p>\n <ul>\n @for (p of participants; track p.name) {\n <li>{{ p.name }} — {{ p.timezone }}</li>\n }\n </ul>\n <te-world-clock [timezones]=\"participantTimezones\" />\n </div>\n `,\n})\nexport class SchedulerComponent {\n @Input() participants: { name: string; timezone: string }[] = [];\n @Input() durationMinutes = 60;\n\n get participantTimezones(): string[] {\n return [...new Set(this.participants.map((p) => p.timezone))];\n }\n}\n","export { TimezoneService, WorldClockService, TIMEZONE_ENGINE_CONFIG } from \"./timezone.service.js\";\n\nexport { TeFormatDatePipe, TeRelativeTimePipe, TeTimezonePipe } from \"./pipes.js\";\n\n/** Enterprise alias for TeFormatDatePipe */\nexport { TeFormatDatePipe as DateFormatPipe } from \"./pipes.js\";\n\nexport { WorldClockComponent, LiveClockComponent, SchedulerComponent } from \"./components.js\";\n\n/** Enterprise alias for LiveClockComponent */\nexport { LiveClockComponent as RealtimeClockComponent } from \"./components.js\";\n\nimport { TeFormatDatePipe, TeRelativeTimePipe, TeTimezonePipe } from \"./pipes.js\";\nimport { WorldClockComponent, LiveClockComponent, SchedulerComponent } from \"./components.js\";\n\n/** Standalone imports bundle for Angular 17+ */\nexport const TIMEZONE_ENGINE_IMPORTS = [\n TeFormatDatePipe,\n TeRelativeTimePipe,\n TeTimezonePipe,\n WorldClockComponent,\n LiveClockComponent,\n SchedulerComponent,\n] as const;\n"]}
package/dist/index.d.cts CHANGED
@@ -77,4 +77,4 @@ declare class SchedulerComponent {
77
77
  /** Standalone imports bundle for Angular 17+ */
78
78
  declare const TIMEZONE_ENGINE_IMPORTS: readonly [typeof TeFormatDatePipe, typeof TeRelativeTimePipe, typeof TeTimezonePipe, typeof WorldClockComponent, typeof LiveClockComponent, typeof SchedulerComponent];
79
79
 
80
- export { LiveClockComponent, SchedulerComponent, TIMEZONE_ENGINE_CONFIG, TIMEZONE_ENGINE_IMPORTS, TeFormatDatePipe, TeRelativeTimePipe, TeTimezonePipe, TimezoneService, WorldClockComponent, WorldClockService };
80
+ export { TeFormatDatePipe as DateFormatPipe, LiveClockComponent, LiveClockComponent as RealtimeClockComponent, SchedulerComponent, TIMEZONE_ENGINE_CONFIG, TIMEZONE_ENGINE_IMPORTS, TeFormatDatePipe, TeRelativeTimePipe, TeTimezonePipe, TimezoneService, WorldClockComponent, WorldClockService };
package/dist/index.d.ts CHANGED
@@ -77,4 +77,4 @@ declare class SchedulerComponent {
77
77
  /** Standalone imports bundle for Angular 17+ */
78
78
  declare const TIMEZONE_ENGINE_IMPORTS: readonly [typeof TeFormatDatePipe, typeof TeRelativeTimePipe, typeof TeTimezonePipe, typeof WorldClockComponent, typeof LiveClockComponent, typeof SchedulerComponent];
79
79
 
80
- export { LiveClockComponent, SchedulerComponent, TIMEZONE_ENGINE_CONFIG, TIMEZONE_ENGINE_IMPORTS, TeFormatDatePipe, TeRelativeTimePipe, TeTimezonePipe, TimezoneService, WorldClockComponent, WorldClockService };
80
+ export { TeFormatDatePipe as DateFormatPipe, LiveClockComponent, LiveClockComponent as RealtimeClockComponent, SchedulerComponent, TIMEZONE_ENGINE_CONFIG, TIMEZONE_ENGINE_IMPORTS, TeFormatDatePipe, TeRelativeTimePipe, TeTimezonePipe, TimezoneService, WorldClockComponent, WorldClockService };
package/dist/index.js CHANGED
@@ -236,6 +236,6 @@ var TIMEZONE_ENGINE_IMPORTS = [
236
236
  SchedulerComponent
237
237
  ];
238
238
 
239
- export { LiveClockComponent, SchedulerComponent, TIMEZONE_ENGINE_CONFIG, TIMEZONE_ENGINE_IMPORTS, TeFormatDatePipe, TeRelativeTimePipe, TeTimezonePipe, TimezoneService, WorldClockComponent, WorldClockService };
239
+ export { TeFormatDatePipe as DateFormatPipe, LiveClockComponent, LiveClockComponent as RealtimeClockComponent, SchedulerComponent, TIMEZONE_ENGINE_CONFIG, TIMEZONE_ENGINE_IMPORTS, TeFormatDatePipe, TeRelativeTimePipe, TeTimezonePipe, TimezoneService, WorldClockComponent, WorldClockService };
240
240
  //# sourceMappingURL=index.js.map
241
241
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/timezone.service.ts","../src/pipes.ts","../src/components.ts","../src/index.ts"],"names":["inject"],"mappings":"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","file":"index.js","sourcesContent":["import { Injectable, InjectionToken, inject } from \"@angular/core\";\nimport type {\n FormatDateOptions,\n TimezoneEngineConfig,\n WorldClockEntry,\n} from \"@multisystemsuite/timezone-engine-shared-types\";\nimport {\n createTimezoneEngine,\n detectBrowserTimezone,\n formatDate,\n convertTimezone,\n compareTimezones,\n getWorldClock,\n createLiveClockUpdater,\n getUserTimezone,\n type TimezoneEngine,\n} from \"@multisystemsuite/timezone-engine-core\";\nimport { getCountryTimezones, getCityTimezone } from \"@multisystemsuite/timezone-engine-world-data\";\nimport { BehaviorSubject, Observable } from \"rxjs\";\n\nexport const TIMEZONE_ENGINE_CONFIG = new InjectionToken<TimezoneEngineConfig>(\n \"TIMEZONE_ENGINE_CONFIG\",\n);\n\n/** Injectable timezone engine service for Angular */\n@Injectable({ providedIn: \"root\" })\nexport class TimezoneService {\n private config = inject(TIMEZONE_ENGINE_CONFIG, { optional: true }) ?? {};\n private engine: TimezoneEngine = createTimezoneEngine(this.config);\n private timezoneSubject = new BehaviorSubject<string>(\n this.config.defaultTimezone ?? detectBrowserTimezone().timezone,\n );\n\n readonly timezone$: Observable<string> = this.timezoneSubject.asObservable();\n\n get timezone(): string {\n return this.timezoneSubject.value;\n }\n\n setTimezone(tz: string): void {\n this.timezoneSubject.next(tz);\n this.engine.config.update({ defaultTimezone: tz });\n }\n\n detectTimezone(): string {\n return detectBrowserTimezone().timezone;\n }\n\n getUserTimezone(): string {\n return getUserTimezone();\n }\n\n formatDate(date: Date | string | number, options: FormatDateOptions = {}): string {\n return formatDate(date, { timezone: this.timezone, ...options });\n }\n\n convertTimezone(sourceTimezone: string, targetTimezone: string, date?: Date | string | number): Date {\n return convertTimezone({\n sourceTimezone,\n targetTimezone,\n ...(date !== undefined ? { date } : {}),\n });\n }\n\n compareTimezones(source: string, target: string, date?: Date | string | number) {\n return compareTimezones(source, target, date);\n }\n\n getWorldClock(timezones: string[]): WorldClockEntry[] {\n return getWorldClock(timezones);\n }\n\n getCountryTimezones(countryCode: string) {\n return getCountryTimezones(countryCode);\n }\n\n getCityTimezone(city: string) {\n return getCityTimezone(city);\n }\n\n getEngine(): TimezoneEngine {\n return this.engine;\n }\n}\n\n/** World clock observable stream */\n@Injectable({ providedIn: \"root\" })\nexport class WorldClockService {\n private timezoneService = inject(TimezoneService);\n\n createLiveClock(timezones: string[], intervalMs = 1000): Observable<WorldClockEntry[]> {\n return new Observable((subscriber) => {\n const updater = createLiveClockUpdater(\n timezones,\n (clocks) => {\n subscriber.next(clocks);\n },\n intervalMs,\n );\n updater.start();\n return () => {\n updater.stop();\n };\n });\n }\n}\n","import { Pipe, inject, type PipeTransform } from \"@angular/core\";\nimport type { FormatDateOptions } from \"@multisystemsuite/timezone-engine-shared-types\";\nimport { formatRelativeTime } from \"@multisystemsuite/timezone-engine-core\";\nimport { TimezoneService } from \"./timezone.service.js\";\n\n/** Angular pipe for locale-aware date formatting */\n@Pipe({ name: \"teFormatDate\", standalone: true, pure: false })\nexport class TeFormatDatePipe implements PipeTransform {\n private timezoneService = inject(TimezoneService);\n\n transform(\n value: Date | string | number | null | undefined,\n format: FormatDateOptions[\"format\"] = \"DATETIME\",\n timezone?: string,\n locale?: string,\n ): string {\n if (value == null) return \"\";\n const options: FormatDateOptions = { format };\n if (timezone !== undefined) options.timezone = timezone;\n if (locale !== undefined) options.locale = locale;\n return this.timezoneService.formatDate(value, options);\n }\n}\n\n/** Angular pipe for relative time formatting */\n@Pipe({ name: \"teRelativeTime\", standalone: true })\nexport class TeRelativeTimePipe implements PipeTransform {\n transform(value: Date | string | number | null | undefined): string {\n if (value == null) return \"\";\n return formatRelativeTime(value);\n }\n}\n\n/** Angular pipe for timezone conversion display */\n@Pipe({ name: \"teTimezone\", standalone: true })\nexport class TeTimezonePipe implements PipeTransform {\n private timezoneService = inject(TimezoneService);\n\n transform(\n value: Date | string | number | null | undefined,\n targetTimezone: string,\n sourceTimezone?: string,\n ): Date | null {\n if (value == null) return null;\n const source = sourceTimezone ?? this.timezoneService.timezone;\n return this.timezoneService.convertTimezone(source, targetTimezone, value);\n }\n}\n","import { Component, Input, inject, type OnInit, type OnDestroy } from \"@angular/core\";\nimport { CommonModule } from \"@angular/common\";\nimport type { WorldClockEntry } from \"@multisystemsuite/timezone-engine-shared-types\";\nimport { WorldClockService, TimezoneService } from \"./timezone.service.js\";\nimport type { Subscription } from \"rxjs\";\n\n/** Standalone world clock component for Angular */\n@Component({\n selector: \"te-world-clock\",\n standalone: true,\n imports: [CommonModule],\n template: `\n <div class=\"te-clock\" data-testid=\"world-clock\">\n @for (clock of clocks; track clock.timezone) {\n <div class=\"te-clock__entry\">\n <strong>{{ clock.label }}</strong>\n <span>{{ clock.formattedTime }}</span>\n <small>{{ clock.utcOffset }}</small>\n </div>\n }\n </div>\n `,\n})\nexport class WorldClockComponent implements OnInit, OnDestroy {\n @Input() timezones: string[] = [\"UTC\", \"America/New_York\", \"Europe/London\", \"Asia/Kolkata\"];\n @Input() intervalMs = 1000;\n\n clocks: WorldClockEntry[] = [];\n private worldClockService = inject(WorldClockService);\n private subscription?: Subscription;\n\n ngOnInit(): void {\n this.subscription = this.worldClockService\n .createLiveClock(this.timezones, this.intervalMs)\n .subscribe((clocks) => {\n this.clocks = clocks;\n });\n }\n\n ngOnDestroy(): void {\n this.subscription?.unsubscribe();\n }\n}\n\n/** Standalone live clock component */\n@Component({\n selector: \"te-live-clock\",\n standalone: true,\n template: `<span class=\"te-live-clock\">{{ display }}</span>`,\n})\nexport class LiveClockComponent implements OnInit, OnDestroy {\n @Input() timezone?: string;\n @Input() intervalMs = 1000;\n\n display = \"\";\n private timezoneService = inject(TimezoneService);\n private timerId?: ReturnType<typeof setInterval>;\n\n ngOnInit(): void {\n const tz = this.timezone ?? this.timezoneService.timezone;\n const update = () => {\n this.display = this.timezoneService.formatDate(new Date(), {\n format: \"TIME_ONLY\",\n timezone: tz,\n });\n };\n update();\n this.timerId = setInterval(update, this.intervalMs);\n }\n\n ngOnDestroy(): void {\n if (this.timerId !== undefined) clearInterval(this.timerId);\n }\n}\n\n/** Scheduler display component */\n@Component({\n selector: \"te-scheduler\",\n standalone: true,\n imports: [CommonModule, WorldClockComponent],\n template: `\n <div class=\"te-scheduler\">\n <h3 class=\"te-scheduler__title\">Meeting Scheduler</h3>\n <p>Duration: {{ durationMinutes }} minutes</p>\n <ul>\n @for (p of participants; track p.name) {\n <li>{{ p.name }} — {{ p.timezone }}</li>\n }\n </ul>\n <te-world-clock [timezones]=\"participantTimezones\" />\n </div>\n `,\n})\nexport class SchedulerComponent {\n @Input() participants: { name: string; timezone: string }[] = [];\n @Input() durationMinutes = 60;\n\n get participantTimezones(): string[] {\n return [...new Set(this.participants.map((p) => p.timezone))];\n }\n}\n","export {\n TimezoneService,\n WorldClockService,\n TIMEZONE_ENGINE_CONFIG,\n} from \"./timezone.service.js\";\n\nexport { TeFormatDatePipe, TeRelativeTimePipe, TeTimezonePipe } from \"./pipes.js\";\n\nexport {\n WorldClockComponent,\n LiveClockComponent,\n SchedulerComponent,\n} from \"./components.js\";\n\nimport { TeFormatDatePipe, TeRelativeTimePipe, TeTimezonePipe } from \"./pipes.js\";\nimport {\n WorldClockComponent,\n LiveClockComponent,\n SchedulerComponent,\n} from \"./components.js\";\n\n/** Standalone imports bundle for Angular 17+ */\nexport const TIMEZONE_ENGINE_IMPORTS = [\n TeFormatDatePipe,\n TeRelativeTimePipe,\n TeTimezonePipe,\n WorldClockComponent,\n LiveClockComponent,\n SchedulerComponent,\n] as const;\n"]}
1
+ {"version":3,"sources":["../src/timezone.service.ts","../src/pipes.ts","../src/components.ts","../src/index.ts"],"names":["inject"],"mappings":"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","file":"index.js","sourcesContent":["import { Injectable, InjectionToken, inject } from \"@angular/core\";\nimport type {\n FormatDateOptions,\n TimezoneEngineConfig,\n WorldClockEntry,\n} from \"@multisystemsuite/timezone-engine-shared-types\";\nimport {\n createTimezoneEngine,\n detectBrowserTimezone,\n formatDate,\n convertTimezone,\n compareTimezones,\n getWorldClock,\n createLiveClockUpdater,\n getUserTimezone,\n type TimezoneEngine,\n} from \"@multisystemsuite/timezone-engine-core\";\nimport { getCountryTimezones, getCityTimezone } from \"@multisystemsuite/timezone-engine-world-data\";\nimport { BehaviorSubject, Observable } from \"rxjs\";\n\nexport const TIMEZONE_ENGINE_CONFIG = new InjectionToken<TimezoneEngineConfig>(\n \"TIMEZONE_ENGINE_CONFIG\",\n);\n\n/** Injectable timezone engine service for Angular */\n@Injectable({ providedIn: \"root\" })\nexport class TimezoneService {\n private config = inject(TIMEZONE_ENGINE_CONFIG, { optional: true }) ?? {};\n private engine: TimezoneEngine = createTimezoneEngine(this.config);\n private timezoneSubject = new BehaviorSubject<string>(\n this.config.defaultTimezone ?? detectBrowserTimezone().timezone,\n );\n\n readonly timezone$: Observable<string> = this.timezoneSubject.asObservable();\n\n get timezone(): string {\n return this.timezoneSubject.value;\n }\n\n setTimezone(tz: string): void {\n this.timezoneSubject.next(tz);\n this.engine.config.update({ defaultTimezone: tz });\n }\n\n detectTimezone(): string {\n return detectBrowserTimezone().timezone;\n }\n\n getUserTimezone(): string {\n return getUserTimezone();\n }\n\n formatDate(date: Date | string | number, options: FormatDateOptions = {}): string {\n return formatDate(date, { timezone: this.timezone, ...options });\n }\n\n convertTimezone(\n sourceTimezone: string,\n targetTimezone: string,\n date?: Date | string | number,\n ): Date {\n return convertTimezone({\n sourceTimezone,\n targetTimezone,\n ...(date !== undefined ? { date } : {}),\n });\n }\n\n compareTimezones(source: string, target: string, date?: Date | string | number) {\n return compareTimezones(source, target, date);\n }\n\n getWorldClock(timezones: string[]): WorldClockEntry[] {\n return getWorldClock(timezones);\n }\n\n getCountryTimezones(countryCode: string) {\n return getCountryTimezones(countryCode);\n }\n\n getCityTimezone(city: string) {\n return getCityTimezone(city);\n }\n\n getEngine(): TimezoneEngine {\n return this.engine;\n }\n}\n\n/** World clock observable stream */\n@Injectable({ providedIn: \"root\" })\nexport class WorldClockService {\n private timezoneService = inject(TimezoneService);\n\n createLiveClock(timezones: string[], intervalMs = 1000): Observable<WorldClockEntry[]> {\n return new Observable((subscriber) => {\n const updater = createLiveClockUpdater(\n timezones,\n (clocks) => {\n subscriber.next(clocks);\n },\n intervalMs,\n );\n updater.start();\n return () => {\n updater.stop();\n };\n });\n }\n}\n","import { Pipe, inject, type PipeTransform } from \"@angular/core\";\nimport type { FormatDateOptions } from \"@multisystemsuite/timezone-engine-shared-types\";\nimport { formatRelativeTime } from \"@multisystemsuite/timezone-engine-core\";\nimport { TimezoneService } from \"./timezone.service.js\";\n\n/** Angular pipe for locale-aware date formatting */\n@Pipe({ name: \"teFormatDate\", standalone: true, pure: false })\nexport class TeFormatDatePipe implements PipeTransform {\n private timezoneService = inject(TimezoneService);\n\n transform(\n value: Date | string | number | null | undefined,\n format: FormatDateOptions[\"format\"] = \"DATETIME\",\n timezone?: string,\n locale?: string,\n ): string {\n if (value == null) return \"\";\n const options: FormatDateOptions = { format };\n if (timezone !== undefined) options.timezone = timezone;\n if (locale !== undefined) options.locale = locale;\n return this.timezoneService.formatDate(value, options);\n }\n}\n\n/** Angular pipe for relative time formatting */\n@Pipe({ name: \"teRelativeTime\", standalone: true })\nexport class TeRelativeTimePipe implements PipeTransform {\n transform(value: Date | string | number | null | undefined): string {\n if (value == null) return \"\";\n return formatRelativeTime(value);\n }\n}\n\n/** Angular pipe for timezone conversion display */\n@Pipe({ name: \"teTimezone\", standalone: true })\nexport class TeTimezonePipe implements PipeTransform {\n private timezoneService = inject(TimezoneService);\n\n transform(\n value: Date | string | number | null | undefined,\n targetTimezone: string,\n sourceTimezone?: string,\n ): Date | null {\n if (value == null) return null;\n const source = sourceTimezone ?? this.timezoneService.timezone;\n return this.timezoneService.convertTimezone(source, targetTimezone, value);\n }\n}\n","import { Component, Input, inject, type OnInit, type OnDestroy } from \"@angular/core\";\nimport { CommonModule } from \"@angular/common\";\nimport type { WorldClockEntry } from \"@multisystemsuite/timezone-engine-shared-types\";\nimport { WorldClockService, TimezoneService } from \"./timezone.service.js\";\nimport type { Subscription } from \"rxjs\";\n\n/** Standalone world clock component for Angular */\n@Component({\n selector: \"te-world-clock\",\n standalone: true,\n imports: [CommonModule],\n template: `\n <div class=\"te-clock\" data-testid=\"world-clock\">\n @for (clock of clocks; track clock.timezone) {\n <div class=\"te-clock__entry\">\n <strong>{{ clock.label }}</strong>\n <span>{{ clock.formattedTime }}</span>\n <small>{{ clock.utcOffset }}</small>\n </div>\n }\n </div>\n `,\n})\nexport class WorldClockComponent implements OnInit, OnDestroy {\n @Input() timezones: string[] = [\"UTC\", \"America/New_York\", \"Europe/London\", \"Asia/Kolkata\"];\n @Input() intervalMs = 1000;\n\n clocks: WorldClockEntry[] = [];\n private worldClockService = inject(WorldClockService);\n private subscription?: Subscription;\n\n ngOnInit(): void {\n this.subscription = this.worldClockService\n .createLiveClock(this.timezones, this.intervalMs)\n .subscribe((clocks) => {\n this.clocks = clocks;\n });\n }\n\n ngOnDestroy(): void {\n this.subscription?.unsubscribe();\n }\n}\n\n/** Standalone live clock component */\n@Component({\n selector: \"te-live-clock\",\n standalone: true,\n template: `<span class=\"te-live-clock\">{{ display }}</span>`,\n})\nexport class LiveClockComponent implements OnInit, OnDestroy {\n @Input() timezone?: string;\n @Input() intervalMs = 1000;\n\n display = \"\";\n private timezoneService = inject(TimezoneService);\n private timerId?: ReturnType<typeof setInterval>;\n\n ngOnInit(): void {\n const tz = this.timezone ?? this.timezoneService.timezone;\n const update = () => {\n this.display = this.timezoneService.formatDate(new Date(), {\n format: \"TIME_ONLY\",\n timezone: tz,\n });\n };\n update();\n this.timerId = setInterval(update, this.intervalMs);\n }\n\n ngOnDestroy(): void {\n if (this.timerId !== undefined) clearInterval(this.timerId);\n }\n}\n\n/** Scheduler display component */\n@Component({\n selector: \"te-scheduler\",\n standalone: true,\n imports: [CommonModule, WorldClockComponent],\n template: `\n <div class=\"te-scheduler\">\n <h3 class=\"te-scheduler__title\">Meeting Scheduler</h3>\n <p>Duration: {{ durationMinutes }} minutes</p>\n <ul>\n @for (p of participants; track p.name) {\n <li>{{ p.name }} — {{ p.timezone }}</li>\n }\n </ul>\n <te-world-clock [timezones]=\"participantTimezones\" />\n </div>\n `,\n})\nexport class SchedulerComponent {\n @Input() participants: { name: string; timezone: string }[] = [];\n @Input() durationMinutes = 60;\n\n get participantTimezones(): string[] {\n return [...new Set(this.participants.map((p) => p.timezone))];\n }\n}\n","export { TimezoneService, WorldClockService, TIMEZONE_ENGINE_CONFIG } from \"./timezone.service.js\";\n\nexport { TeFormatDatePipe, TeRelativeTimePipe, TeTimezonePipe } from \"./pipes.js\";\n\n/** Enterprise alias for TeFormatDatePipe */\nexport { TeFormatDatePipe as DateFormatPipe } from \"./pipes.js\";\n\nexport { WorldClockComponent, LiveClockComponent, SchedulerComponent } from \"./components.js\";\n\n/** Enterprise alias for LiveClockComponent */\nexport { LiveClockComponent as RealtimeClockComponent } from \"./components.js\";\n\nimport { TeFormatDatePipe, TeRelativeTimePipe, TeTimezonePipe } from \"./pipes.js\";\nimport { WorldClockComponent, LiveClockComponent, SchedulerComponent } from \"./components.js\";\n\n/** Standalone imports bundle for Angular 17+ */\nexport const TIMEZONE_ENGINE_IMPORTS = [\n TeFormatDatePipe,\n TeRelativeTimePipe,\n TeTimezonePipe,\n WorldClockComponent,\n LiveClockComponent,\n SchedulerComponent,\n] as const;\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@multisystemsuite/timezone-engine-angular",
3
- "version": "1.0.0",
3
+ "version": "2.0.0",
4
4
  "description": "Angular services, pipes, and components for @multisystemsuite/timezone-engine",
5
5
  "license": "MIT",
6
6
  "author": "MultiSystemSuite",
@@ -30,13 +30,14 @@
30
30
  },
31
31
  "sideEffects": false,
32
32
  "files": [
33
- "dist"
33
+ "dist",
34
+ "README.md"
34
35
  ],
35
36
  "dependencies": {
36
- "@multisystemsuite/timezone-engine-shared-types": "1.0.0",
37
- "@multisystemsuite/timezone-engine-world-data": "1.0.0",
38
- "@multisystemsuite/timezone-engine-scheduler": "1.0.0",
39
- "@multisystemsuite/timezone-engine-core": "1.0.0"
37
+ "@multisystemsuite/timezone-engine-core": "2.0.0",
38
+ "@multisystemsuite/timezone-engine-world-data": "2.0.0",
39
+ "@multisystemsuite/timezone-engine-scheduler": "2.0.0",
40
+ "@multisystemsuite/timezone-engine-shared-types": "2.0.0"
40
41
  },
41
42
  "peerDependencies": {
42
43
  "@angular/common": ">=17.0.0",