@molecule/app-angular 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 (110) hide show
  1. package/LICENSE +115 -0
  2. package/dist/i18n-reactive.d.ts +41 -0
  3. package/dist/i18n-reactive.d.ts.map +1 -0
  4. package/dist/i18n-reactive.js +46 -0
  5. package/dist/i18n-reactive.js.map +1 -0
  6. package/dist/index.d.ts +84 -0
  7. package/dist/index.d.ts.map +1 -0
  8. package/dist/index.js +84 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/providers.d.ts +96 -0
  11. package/dist/providers.d.ts.map +1 -0
  12. package/dist/providers.js +144 -0
  13. package/dist/providers.js.map +1 -0
  14. package/dist/services/async-state.service.d.ts +50 -0
  15. package/dist/services/async-state.service.d.ts.map +1 -0
  16. package/dist/services/async-state.service.js +109 -0
  17. package/dist/services/async-state.service.js.map +1 -0
  18. package/dist/services/auth.service.d.ts +105 -0
  19. package/dist/services/auth.service.d.ts.map +1 -0
  20. package/dist/services/auth.service.js +124 -0
  21. package/dist/services/auth.service.js.map +1 -0
  22. package/dist/services/capacitor-app.service.d.ts +46 -0
  23. package/dist/services/capacitor-app.service.d.ts.map +1 -0
  24. package/dist/services/capacitor-app.service.js +53 -0
  25. package/dist/services/capacitor-app.service.js.map +1 -0
  26. package/dist/services/change-password.service.d.ts +37 -0
  27. package/dist/services/change-password.service.d.ts.map +1 -0
  28. package/dist/services/change-password.service.js +34 -0
  29. package/dist/services/change-password.service.js.map +1 -0
  30. package/dist/services/device.service.d.ts +35 -0
  31. package/dist/services/device.service.d.ts.map +1 -0
  32. package/dist/services/device.service.js +29 -0
  33. package/dist/services/device.service.js.map +1 -0
  34. package/dist/services/forms.service.d.ts +237 -0
  35. package/dist/services/forms.service.d.ts.map +1 -0
  36. package/dist/services/forms.service.js +280 -0
  37. package/dist/services/forms.service.js.map +1 -0
  38. package/dist/services/http.service.d.ts +118 -0
  39. package/dist/services/http.service.d.ts.map +1 -0
  40. package/dist/services/http.service.js +171 -0
  41. package/dist/services/http.service.js.map +1 -0
  42. package/dist/services/i18n.service.d.ts +111 -0
  43. package/dist/services/i18n.service.d.ts.map +1 -0
  44. package/dist/services/i18n.service.js +135 -0
  45. package/dist/services/i18n.service.js.map +1 -0
  46. package/dist/services/index.d.ts +27 -0
  47. package/dist/services/index.d.ts.map +1 -0
  48. package/dist/services/index.js +27 -0
  49. package/dist/services/index.js.map +1 -0
  50. package/dist/services/logger.service.d.ts +79 -0
  51. package/dist/services/logger.service.d.ts.map +1 -0
  52. package/dist/services/logger.service.js +110 -0
  53. package/dist/services/logger.service.js.map +1 -0
  54. package/dist/services/login.service.d.ts +37 -0
  55. package/dist/services/login.service.d.ts.map +1 -0
  56. package/dist/services/login.service.js +34 -0
  57. package/dist/services/login.service.js.map +1 -0
  58. package/dist/services/oauth.service.d.ts +110 -0
  59. package/dist/services/oauth.service.d.ts.map +1 -0
  60. package/dist/services/oauth.service.js +214 -0
  61. package/dist/services/oauth.service.js.map +1 -0
  62. package/dist/services/password-reset.service.d.ts +41 -0
  63. package/dist/services/password-reset.service.d.ts.map +1 -0
  64. package/dist/services/password-reset.service.js +45 -0
  65. package/dist/services/password-reset.service.js.map +1 -0
  66. package/dist/services/platform.service.d.ts +39 -0
  67. package/dist/services/platform.service.d.ts.map +1 -0
  68. package/dist/services/platform.service.js +33 -0
  69. package/dist/services/platform.service.js.map +1 -0
  70. package/dist/services/promise.service.d.ts +40 -0
  71. package/dist/services/promise.service.d.ts.map +1 -0
  72. package/dist/services/promise.service.js +85 -0
  73. package/dist/services/promise.service.js.map +1 -0
  74. package/dist/services/push.service.d.ts +45 -0
  75. package/dist/services/push.service.d.ts.map +1 -0
  76. package/dist/services/push.service.js +64 -0
  77. package/dist/services/push.service.js.map +1 -0
  78. package/dist/services/router.service.d.ts +114 -0
  79. package/dist/services/router.service.d.ts.map +1 -0
  80. package/dist/services/router.service.js +142 -0
  81. package/dist/services/router.service.js.map +1 -0
  82. package/dist/services/signup.service.d.ts +37 -0
  83. package/dist/services/signup.service.d.ts.map +1 -0
  84. package/dist/services/signup.service.js +34 -0
  85. package/dist/services/signup.service.js.map +1 -0
  86. package/dist/services/state.service.d.ts +82 -0
  87. package/dist/services/state.service.d.ts.map +1 -0
  88. package/dist/services/state.service.js +122 -0
  89. package/dist/services/state.service.js.map +1 -0
  90. package/dist/services/storage.service.d.ts +111 -0
  91. package/dist/services/storage.service.d.ts.map +1 -0
  92. package/dist/services/storage.service.js +167 -0
  93. package/dist/services/storage.service.js.map +1 -0
  94. package/dist/services/theme.service.d.ts +89 -0
  95. package/dist/services/theme.service.d.ts.map +1 -0
  96. package/dist/services/theme.service.js +116 -0
  97. package/dist/services/theme.service.js.map +1 -0
  98. package/dist/services/version.service.d.ts +44 -0
  99. package/dist/services/version.service.d.ts.map +1 -0
  100. package/dist/services/version.service.js +63 -0
  101. package/dist/services/version.service.js.map +1 -0
  102. package/dist/tokens.d.ts +47 -0
  103. package/dist/tokens.d.ts.map +1 -0
  104. package/dist/tokens.js +39 -0
  105. package/dist/tokens.js.map +1 -0
  106. package/dist/types.d.ts +42 -0
  107. package/dist/types.d.ts.map +1 -0
  108. package/dist/types.js +7 -0
  109. package/dist/types.js.map +1 -0
  110. package/package.json +61 -0
@@ -0,0 +1,237 @@
1
+ /**
2
+ * Angular service for form handling.
3
+ *
4
+ * @module
5
+ */
6
+ import { type OnDestroy } from '@angular/core';
7
+ import { type Observable } from 'rxjs';
8
+ import type { FieldRegistration, FormController, FormOptions, FormProvider, FormState, RegisterOptions } from '@molecule/app-forms';
9
+ import * as i0 from "@angular/core";
10
+ /**
11
+ * Wrapper around a FormController that provides RxJS observables and
12
+ * synchronous accessors for use in Angular components.
13
+ *
14
+ * @example
15
+ * ```typescript
16
+ * @Component({
17
+ * selector: 'app-login-form',
18
+ * template: `
19
+ * <form (ngSubmit)="onSubmit()">
20
+ * <input [value]="emailValue" (input)="emailReg.onChange($event)" (blur)="emailReg.onBlur()">
21
+ * <span *ngIf="errors$ | async as errors">{{ errors['email'] }}</span>
22
+ * <button type="submit" [disabled]="isSubmitting$ | async">Submit</button>
23
+ * </form>
24
+ * `
25
+ * })
26
+ * export class LoginFormComponent implements OnInit, OnDestroy {
27
+ * private form!: MoleculeFormInstance<{ email: string; password: string }>
28
+ * emailReg!: FieldRegistration
29
+ *
30
+ * errors$ = new Observable<Partial<Record<string, string>>>()
31
+ * isSubmitting$ = new Observable<boolean>()
32
+ *
33
+ * constructor(private formsService: MoleculeFormsService) {}
34
+ *
35
+ * ngOnInit() {
36
+ * this.form = this.formsService.createForm(myProvider, {
37
+ * defaultValues: { email: '', password: '' },
38
+ * mode: 'onBlur',
39
+ * })
40
+ * this.emailReg = this.form.register('email', { required: true, email: true })
41
+ * this.errors$ = this.form.errors$
42
+ * this.isSubmitting$ = this.form.isSubmitting$
43
+ * }
44
+ *
45
+ * onSubmit() {
46
+ * const handler = this.form.handleSubmit(async (values) => {
47
+ * await login(values)
48
+ * })
49
+ * handler()
50
+ * }
51
+ *
52
+ * ngOnDestroy() {
53
+ * this.form.destroy()
54
+ * }
55
+ * }
56
+ * ```
57
+ */
58
+ export declare class MoleculeFormInstance<T extends Record<string, unknown>> {
59
+ private controller;
60
+ private stateSubject;
61
+ private unsubscribe;
62
+ /**
63
+ * Observable of the full form state.
64
+ */
65
+ state$: Observable<FormState<T>>;
66
+ /**
67
+ * Observable of form validity.
68
+ */
69
+ isValid$: Observable<boolean>;
70
+ /**
71
+ * Observable of form dirty state.
72
+ */
73
+ isDirty$: Observable<boolean>;
74
+ /**
75
+ * Observable of form submitting state.
76
+ */
77
+ isSubmitting$: Observable<boolean>;
78
+ /**
79
+ * Observable of field errors.
80
+ */
81
+ errors$: Observable<Partial<Record<keyof T, string>>>;
82
+ constructor(controller: FormController<T>);
83
+ /**
84
+ * Get the current form state snapshot.
85
+ * @returns The current form state including values, errors, validity, and submission status.
86
+ */
87
+ get state(): FormState<T>;
88
+ /**
89
+ * Get the current form validity snapshot.
90
+ * @returns `true` if all fields pass validation, `false` otherwise.
91
+ */
92
+ get isValid(): boolean;
93
+ /**
94
+ * Get the current form dirty state snapshot.
95
+ * @returns `true` if any field has been modified from its default value, `false` otherwise.
96
+ */
97
+ get isDirty(): boolean;
98
+ /**
99
+ * Get the current form submitting state snapshot.
100
+ * @returns `true` if the form is currently being submitted, `false` otherwise.
101
+ */
102
+ get isSubmitting(): boolean;
103
+ /**
104
+ * Register a field for form management.
105
+ *
106
+ * @param name - The field name corresponding to a key in the form values type.
107
+ * @param options - Registration options including validation rules and default value.
108
+ * @returns The field registration with value, onChange, onBlur, and ref bindings.
109
+ */
110
+ register(name: keyof T, options?: Omit<RegisterOptions, 'name'>): FieldRegistration;
111
+ /**
112
+ * Get the value of a specific field.
113
+ *
114
+ * @param name - The field name corresponding to a key in the form values type.
115
+ * @returns The current value of the specified field.
116
+ */
117
+ getValue<K extends keyof T>(name: K): T[K];
118
+ /**
119
+ * Set the value of a specific field.
120
+ *
121
+ * @param name - The field name corresponding to a key in the form values type.
122
+ * @param value - The new value to set for the field.
123
+ */
124
+ setValue<K extends keyof T>(name: K, value: T[K]): void;
125
+ /**
126
+ * Get the error for a specific field.
127
+ *
128
+ * @param name - The field name to retrieve the error for.
129
+ * @returns The error message for the field, or `undefined` if the field has no error.
130
+ */
131
+ getError(name: keyof T): string | undefined;
132
+ /**
133
+ * Set the error for a specific field.
134
+ *
135
+ * @param name - The field name to set or clear the error for.
136
+ * @param error - The error message to set, or `undefined` to clear the error.
137
+ */
138
+ setError(name: keyof T, error: string | undefined): void;
139
+ /**
140
+ * Clear all field errors.
141
+ */
142
+ clearErrors(): void;
143
+ /**
144
+ * Create a submit handler function.
145
+ *
146
+ * @param onSubmit - Callback invoked with validated form values on successful submission.
147
+ * @param onError - Optional callback invoked with field errors when validation fails.
148
+ * @returns A submit handler function that can be called from form submit events.
149
+ */
150
+ handleSubmit(onSubmit: (values: T) => void | Promise<void>, onError?: (errors: Partial<Record<keyof T, string>>) => void): (event?: {
151
+ preventDefault?: () => void;
152
+ }) => Promise<void>;
153
+ /**
154
+ * Reset the form to initial values.
155
+ *
156
+ * @param values - Optional partial values to use as the new initial state.
157
+ */
158
+ reset(values?: Partial<T>): void;
159
+ /**
160
+ * Validate all fields.
161
+ *
162
+ * @returns A promise that resolves to `true` if all fields are valid, `false` otherwise.
163
+ */
164
+ validate(): Promise<boolean>;
165
+ /**
166
+ * Destroy the form instance and clean up subscriptions.
167
+ */
168
+ destroy(): void;
169
+ }
170
+ /**
171
+ * Angular service for form handling.
172
+ *
173
+ * Wraps molecule form providers and creates form instances that expose
174
+ * state as RxJS observables.
175
+ *
176
+ * @example
177
+ * ```typescript
178
+ * @Component({
179
+ * selector: 'app-registration',
180
+ * template: `
181
+ * <form (ngSubmit)="submit()">
182
+ * <div *ngIf="form">
183
+ * <input
184
+ * [value]="(form.state$ | async)?.values?.['username']"
185
+ * (input)="usernameReg.onChange($event)"
186
+ * (blur)="usernameReg.onBlur()"
187
+ * />
188
+ * <span *ngIf="(form.errors$ | async)?.['username'] as error">{{ error }}</span>
189
+ * <button type="submit" [disabled]="form.isSubmitting$ | async">Register</button>
190
+ * </div>
191
+ * </form>
192
+ * `
193
+ * })
194
+ * export class RegistrationComponent implements OnInit, OnDestroy {
195
+ * form!: MoleculeFormInstance<{ username: string; email: string }>
196
+ * usernameReg!: FieldRegistration
197
+ *
198
+ * constructor(private formsService: MoleculeFormsService) {}
199
+ *
200
+ * ngOnInit() {
201
+ * this.form = this.formsService.createForm(myFormProvider, {
202
+ * defaultValues: { username: '', email: '' },
203
+ * })
204
+ * this.usernameReg = this.form.register('username', { required: true })
205
+ * }
206
+ *
207
+ * submit() {
208
+ * const handler = this.form.handleSubmit(async (values) => {
209
+ * await registerUser(values)
210
+ * })
211
+ * handler()
212
+ * }
213
+ *
214
+ * ngOnDestroy() {
215
+ * this.form.destroy()
216
+ * }
217
+ * }
218
+ * ```
219
+ */
220
+ export declare class MoleculeFormsService implements OnDestroy {
221
+ private instances;
222
+ /**
223
+ * Create a form instance from a provider.
224
+ *
225
+ * @param provider - The form provider that creates form controllers.
226
+ * @param options - Form configuration including default values and validation mode.
227
+ * @returns A new form instance with RxJS observables for reactive state tracking.
228
+ */
229
+ createForm<T extends Record<string, unknown>>(provider: FormProvider, options: FormOptions<T>): MoleculeFormInstance<T>;
230
+ /**
231
+ * Destroy all managed form instances on service destruction.
232
+ */
233
+ ngOnDestroy(): void;
234
+ static ɵfac: i0.ɵɵFactoryDeclaration<MoleculeFormsService, never>;
235
+ static ɵprov: i0.ɵɵInjectableDeclaration<MoleculeFormsService>;
236
+ }
237
+ //# sourceMappingURL=forms.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forms.service.d.ts","sourceRoot":"","sources":["../../src/services/forms.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,280 @@
1
+ /**
2
+ * Angular service for form handling.
3
+ *
4
+ * @module
5
+ */
6
+ import { Injectable } from '@angular/core';
7
+ import { BehaviorSubject, distinctUntilChanged, map } from 'rxjs';
8
+ import * as i0 from "@angular/core";
9
+ /**
10
+ * Wrapper around a FormController that provides RxJS observables and
11
+ * synchronous accessors for use in Angular components.
12
+ *
13
+ * @example
14
+ * ```typescript
15
+ * @Component({
16
+ * selector: 'app-login-form',
17
+ * template: `
18
+ * <form (ngSubmit)="onSubmit()">
19
+ * <input [value]="emailValue" (input)="emailReg.onChange($event)" (blur)="emailReg.onBlur()">
20
+ * <span *ngIf="errors$ | async as errors">{{ errors['email'] }}</span>
21
+ * <button type="submit" [disabled]="isSubmitting$ | async">Submit</button>
22
+ * </form>
23
+ * `
24
+ * })
25
+ * export class LoginFormComponent implements OnInit, OnDestroy {
26
+ * private form!: MoleculeFormInstance<{ email: string; password: string }>
27
+ * emailReg!: FieldRegistration
28
+ *
29
+ * errors$ = new Observable<Partial<Record<string, string>>>()
30
+ * isSubmitting$ = new Observable<boolean>()
31
+ *
32
+ * constructor(private formsService: MoleculeFormsService) {}
33
+ *
34
+ * ngOnInit() {
35
+ * this.form = this.formsService.createForm(myProvider, {
36
+ * defaultValues: { email: '', password: '' },
37
+ * mode: 'onBlur',
38
+ * })
39
+ * this.emailReg = this.form.register('email', { required: true, email: true })
40
+ * this.errors$ = this.form.errors$
41
+ * this.isSubmitting$ = this.form.isSubmitting$
42
+ * }
43
+ *
44
+ * onSubmit() {
45
+ * const handler = this.form.handleSubmit(async (values) => {
46
+ * await login(values)
47
+ * })
48
+ * handler()
49
+ * }
50
+ *
51
+ * ngOnDestroy() {
52
+ * this.form.destroy()
53
+ * }
54
+ * }
55
+ * ```
56
+ */
57
+ export class MoleculeFormInstance {
58
+ constructor(controller) {
59
+ this.controller = controller;
60
+ this.unsubscribe = null;
61
+ this.stateSubject = new BehaviorSubject(controller.getState());
62
+ this.unsubscribe = controller.subscribe((state) => {
63
+ this.stateSubject.next(state);
64
+ });
65
+ this.state$ = this.stateSubject.asObservable();
66
+ this.isValid$ = this.state$.pipe(map((state) => state.isValid), distinctUntilChanged());
67
+ this.isDirty$ = this.state$.pipe(map((state) => state.isDirty), distinctUntilChanged());
68
+ this.isSubmitting$ = this.state$.pipe(map((state) => state.isSubmitting), distinctUntilChanged());
69
+ this.errors$ = this.state$.pipe(map((state) => state.errors), distinctUntilChanged());
70
+ }
71
+ /**
72
+ * Get the current form state snapshot.
73
+ * @returns The current form state including values, errors, validity, and submission status.
74
+ */
75
+ get state() {
76
+ return this.controller.getState();
77
+ }
78
+ /**
79
+ * Get the current form validity snapshot.
80
+ * @returns `true` if all fields pass validation, `false` otherwise.
81
+ */
82
+ get isValid() {
83
+ return this.controller.getState().isValid;
84
+ }
85
+ /**
86
+ * Get the current form dirty state snapshot.
87
+ * @returns `true` if any field has been modified from its default value, `false` otherwise.
88
+ */
89
+ get isDirty() {
90
+ return this.controller.getState().isDirty;
91
+ }
92
+ /**
93
+ * Get the current form submitting state snapshot.
94
+ * @returns `true` if the form is currently being submitted, `false` otherwise.
95
+ */
96
+ get isSubmitting() {
97
+ return this.controller.getState().isSubmitting;
98
+ }
99
+ /**
100
+ * Register a field for form management.
101
+ *
102
+ * @param name - The field name corresponding to a key in the form values type.
103
+ * @param options - Registration options including validation rules and default value.
104
+ * @returns The field registration with value, onChange, onBlur, and ref bindings.
105
+ */
106
+ register(name, options) {
107
+ return this.controller.register({ ...options, name: name });
108
+ }
109
+ /**
110
+ * Get the value of a specific field.
111
+ *
112
+ * @param name - The field name corresponding to a key in the form values type.
113
+ * @returns The current value of the specified field.
114
+ */
115
+ getValue(name) {
116
+ return this.controller.getValue(name);
117
+ }
118
+ /**
119
+ * Set the value of a specific field.
120
+ *
121
+ * @param name - The field name corresponding to a key in the form values type.
122
+ * @param value - The new value to set for the field.
123
+ */
124
+ setValue(name, value) {
125
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
126
+ this.controller.setValue(name, value);
127
+ }
128
+ /**
129
+ * Get the error for a specific field.
130
+ *
131
+ * @param name - The field name to retrieve the error for.
132
+ * @returns The error message for the field, or `undefined` if the field has no error.
133
+ */
134
+ getError(name) {
135
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
136
+ return this.controller.getError(name);
137
+ }
138
+ /**
139
+ * Set the error for a specific field.
140
+ *
141
+ * @param name - The field name to set or clear the error for.
142
+ * @param error - The error message to set, or `undefined` to clear the error.
143
+ */
144
+ setError(name, error) {
145
+ if (error !== undefined) {
146
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
147
+ this.controller.setError(name, error);
148
+ }
149
+ else {
150
+ this.controller.clearError(name);
151
+ }
152
+ }
153
+ /**
154
+ * Clear all field errors.
155
+ */
156
+ clearErrors() {
157
+ this.controller.clearErrors();
158
+ }
159
+ /**
160
+ * Create a submit handler function.
161
+ *
162
+ * @param onSubmit - Callback invoked with validated form values on successful submission.
163
+ * @param onError - Optional callback invoked with field errors when validation fails.
164
+ * @returns A submit handler function that can be called from form submit events.
165
+ */
166
+ handleSubmit(onSubmit, onError) {
167
+ return this.controller.handleSubmit(onSubmit, onError);
168
+ }
169
+ /**
170
+ * Reset the form to initial values.
171
+ *
172
+ * @param values - Optional partial values to use as the new initial state.
173
+ */
174
+ reset(values) {
175
+ this.controller.reset(values);
176
+ }
177
+ /**
178
+ * Validate all fields.
179
+ *
180
+ * @returns A promise that resolves to `true` if all fields are valid, `false` otherwise.
181
+ */
182
+ validate() {
183
+ return this.controller.validate();
184
+ }
185
+ /**
186
+ * Destroy the form instance and clean up subscriptions.
187
+ */
188
+ destroy() {
189
+ this.unsubscribe?.();
190
+ this.unsubscribe = null;
191
+ this.stateSubject.complete();
192
+ this.controller.destroy();
193
+ }
194
+ }
195
+ /**
196
+ * Angular service for form handling.
197
+ *
198
+ * Wraps molecule form providers and creates form instances that expose
199
+ * state as RxJS observables.
200
+ *
201
+ * @example
202
+ * ```typescript
203
+ * @Component({
204
+ * selector: 'app-registration',
205
+ * template: `
206
+ * <form (ngSubmit)="submit()">
207
+ * <div *ngIf="form">
208
+ * <input
209
+ * [value]="(form.state$ | async)?.values?.['username']"
210
+ * (input)="usernameReg.onChange($event)"
211
+ * (blur)="usernameReg.onBlur()"
212
+ * />
213
+ * <span *ngIf="(form.errors$ | async)?.['username'] as error">{{ error }}</span>
214
+ * <button type="submit" [disabled]="form.isSubmitting$ | async">Register</button>
215
+ * </div>
216
+ * </form>
217
+ * `
218
+ * })
219
+ * export class RegistrationComponent implements OnInit, OnDestroy {
220
+ * form!: MoleculeFormInstance<{ username: string; email: string }>
221
+ * usernameReg!: FieldRegistration
222
+ *
223
+ * constructor(private formsService: MoleculeFormsService) {}
224
+ *
225
+ * ngOnInit() {
226
+ * this.form = this.formsService.createForm(myFormProvider, {
227
+ * defaultValues: { username: '', email: '' },
228
+ * })
229
+ * this.usernameReg = this.form.register('username', { required: true })
230
+ * }
231
+ *
232
+ * submit() {
233
+ * const handler = this.form.handleSubmit(async (values) => {
234
+ * await registerUser(values)
235
+ * })
236
+ * handler()
237
+ * }
238
+ *
239
+ * ngOnDestroy() {
240
+ * this.form.destroy()
241
+ * }
242
+ * }
243
+ * ```
244
+ */
245
+ export class MoleculeFormsService {
246
+ constructor() {
247
+ this.instances = [];
248
+ }
249
+ /**
250
+ * Create a form instance from a provider.
251
+ *
252
+ * @param provider - The form provider that creates form controllers.
253
+ * @param options - Form configuration including default values and validation mode.
254
+ * @returns A new form instance with RxJS observables for reactive state tracking.
255
+ */
256
+ createForm(provider, options) {
257
+ const controller = provider.createForm(options);
258
+ const instance = new MoleculeFormInstance(controller);
259
+ this.instances.push(instance);
260
+ return instance;
261
+ }
262
+ /**
263
+ * Destroy all managed form instances on service destruction.
264
+ */
265
+ ngOnDestroy() {
266
+ for (const instance of this.instances) {
267
+ instance.destroy();
268
+ }
269
+ this.instances = [];
270
+ }
271
+ static { this.ɵfac = function MoleculeFormsService_Factory(__ngFactoryType__) { return new (__ngFactoryType__ || MoleculeFormsService)(); }; }
272
+ static { this.ɵprov = /*@__PURE__*/ i0.ɵɵdefineInjectable({ token: MoleculeFormsService, factory: MoleculeFormsService.ɵfac, providedIn: 'root' }); }
273
+ }
274
+ (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(MoleculeFormsService, [{
275
+ type: Injectable,
276
+ args: [{
277
+ providedIn: 'root',
278
+ }]
279
+ }], null, null); })();
280
+ //# sourceMappingURL=forms.service.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"forms.service.js","sourceRoot":"","sources":["../../src/services/forms.service.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,118 @@
1
+ import { BehaviorSubject, type Observable } from 'rxjs';
2
+ import type { HttpClient, HttpResponse, RequestConfig } from '@molecule/app-http';
3
+ import * as i0 from "@angular/core";
4
+ /**
5
+ * State for HTTP requests.
6
+ */
7
+ export interface HttpState<T> {
8
+ data: T | null;
9
+ loading: boolean;
10
+ error: Error | null;
11
+ }
12
+ /**
13
+ * Angular service for HTTP requests.
14
+ *
15
+ * Wraps molecule HTTP client and returns RxJS observables.
16
+ *
17
+ * @example
18
+ * ```typescript
19
+ * @Component({
20
+ * selector: 'app-users',
21
+ * template: `
22
+ * <div *ngIf="loading$ | async">Loading...</div>
23
+ * <div *ngIf="error$ | async as error">Error: {{ error.message }}</div>
24
+ * <ul *ngIf="users$ | async as users">
25
+ * <li *ngFor="let user of users">{{ user.name }}</li>
26
+ * </ul>
27
+ * `
28
+ * })
29
+ * export class UsersComponent implements OnInit {
30
+ * users$ = this.httpService.get<User[]>('/api/users')
31
+ *
32
+ * // Or with state management:
33
+ * private state = this.httpService.createState<User[]>()
34
+ * loading$ = this.state.pipe(map(s => s.loading))
35
+ * error$ = this.state.pipe(map(s => s.error))
36
+ * users$ = this.state.pipe(map(s => s.data))
37
+ *
38
+ * constructor(private httpService: MoleculeHttpService) {}
39
+ *
40
+ * ngOnInit() {
41
+ * this.httpService.getWithState('/api/users', this.state)
42
+ * }
43
+ * }
44
+ * ```
45
+ */
46
+ export declare class MoleculeHttpService {
47
+ private client;
48
+ constructor(client: HttpClient);
49
+ /**
50
+ * Make a GET request.
51
+ *
52
+ * @param url - Request URL
53
+ * @param config - Request configuration
54
+ * @returns Observable of response data
55
+ */
56
+ get<T>(url: string, config?: RequestConfig): Observable<T>;
57
+ /**
58
+ * Make a POST request.
59
+ *
60
+ * @param url - Request URL
61
+ * @param data - Request body
62
+ * @param config - Request configuration
63
+ * @returns Observable of response data
64
+ */
65
+ post<T>(url: string, data?: unknown, config?: RequestConfig): Observable<T>;
66
+ /**
67
+ * Make a PUT request.
68
+ *
69
+ * @param url - Request URL
70
+ * @param data - Request body
71
+ * @param config - Request configuration
72
+ * @returns Observable of response data
73
+ */
74
+ put<T>(url: string, data?: unknown, config?: RequestConfig): Observable<T>;
75
+ /**
76
+ * Make a PATCH request.
77
+ *
78
+ * @param url - Request URL
79
+ * @param data - Request body
80
+ * @param config - Request configuration
81
+ * @returns Observable of response data
82
+ */
83
+ patch<T>(url: string, data?: unknown, config?: RequestConfig): Observable<T>;
84
+ /**
85
+ * Make a DELETE request.
86
+ *
87
+ * @param url - Request URL
88
+ * @param config - Request configuration
89
+ * @returns Observable of response data
90
+ */
91
+ delete<T>(url: string, config?: RequestConfig): Observable<T>;
92
+ /**
93
+ * Get the full response (including headers, status, etc.).
94
+ *
95
+ * @param method - HTTP method
96
+ * @param url - Request URL
97
+ * @param config - Request configuration
98
+ * @returns Observable of full response
99
+ */
100
+ request<T>(method: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE', url: string, config?: RequestConfig): Observable<HttpResponse<T>>;
101
+ /**
102
+ * Create a state subject for managing request state.
103
+ *
104
+ * @returns The created instance.
105
+ */
106
+ createState<T>(): BehaviorSubject<HttpState<T>>;
107
+ /**
108
+ * Make a GET request with state management.
109
+ *
110
+ * @param url - Request URL
111
+ * @param state - State subject to update
112
+ * @param config - Request configuration
113
+ */
114
+ getWithState<T>(url: string, state: BehaviorSubject<HttpState<T>>, config?: RequestConfig): void;
115
+ static ɵfac: i0.ɵɵFactoryDeclaration<MoleculeHttpService, never>;
116
+ static ɵprov: i0.ɵɵInjectableDeclaration<MoleculeHttpService>;
117
+ }
118
+ //# sourceMappingURL=http.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.service.d.ts","sourceRoot":"","sources":["../../src/services/http.service.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,eAAe,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAA;AAG7D,OAAO,KAAK,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAA;;AAIjF;;GAEG;AACH,MAAM,WAAW,SAAS,CAAC,CAAC;IAC1B,IAAI,EAAE,CAAC,GAAG,IAAI,CAAA;IACd,OAAO,EAAE,OAAO,CAAA;IAChB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,qBAMa,mBAAmB;IACG,OAAO,CAAC,MAAM;gBAAN,MAAM,EAAE,UAAU;IAE3D;;;;;;OAMG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC;IAI1D;;;;;;;OAOG;IACH,IAAI,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC;IAI3E;;;;;;;OAOG;IACH,GAAG,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC;IAI1E;;;;;;;OAOG;IACH,KAAK,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC;IAI5E;;;;;;OAMG;IACH,MAAM,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,UAAU,CAAC,CAAC,CAAC;IAI7D;;;;;;;OAOG;IACH,OAAO,CAAC,CAAC,EACP,MAAM,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,OAAO,GAAG,QAAQ,EACnD,GAAG,EAAE,MAAM,EACX,MAAM,CAAC,EAAE,aAAa,GACrB,UAAU,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IA+B9B;;;;OAIG;IACH,WAAW,CAAC,CAAC,KAAK,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;IAQ/C;;;;;;OAMG;IACH,YAAY,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,eAAe,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,EAAE,aAAa,GAAG,IAAI;yCA5HrF,mBAAmB;6CAAnB,mBAAmB;CAyI/B"}