@picked/svelte 0.0.1-dev.1767922288295 → 0.0.1-dev.1767924764002
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/dist/form/form.svelte.d.ts +169 -10
- package/dist/form/form.svelte.ts +126 -54
- package/dist/hooks/action.d.ts +2 -0
- package/dist/hooks/action.js +1 -0
- package/dist/hooks/feature.d.ts +5 -0
- package/dist/hooks/feature.js +1 -0
- package/dist/hooks/index.d.ts +4 -0
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/predicate.d.ts +3 -0
- package/dist/hooks/predicate.js +1 -0
- package/dist/hooks/step.d.ts +3 -21
- package/dist/hooks/step.js +1 -1
- package/package.json +2 -2
|
@@ -1,26 +1,185 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FieldValue, ValidationError } from '@picked/client';
|
|
2
2
|
import { EventCallable, Store } from 'effector';
|
|
3
|
-
|
|
4
|
-
interface GetFormOptions {
|
|
3
|
+
type ExtractFieldIds<TFieldIds extends readonly string[]> = TFieldIds[number];
|
|
4
|
+
interface GetFormOptions<TFieldIds extends readonly string[]> {
|
|
5
5
|
id: string;
|
|
6
6
|
title: string;
|
|
7
|
-
|
|
7
|
+
fieldIds: TFieldIds;
|
|
8
8
|
}
|
|
9
|
-
type SuccessCallback = (options: {
|
|
10
|
-
data:
|
|
9
|
+
type SuccessCallback<TFieldIds extends string = string> = (options: {
|
|
10
|
+
data: Record<TFieldIds, FieldValue>;
|
|
11
11
|
stopNavigation: EventCallable<void>;
|
|
12
12
|
}) => void | Promise<void>;
|
|
13
13
|
type ErrorCallback = (errors: ValidationError[]) => void | Promise<void>;
|
|
14
|
-
type SubmitCallback = (data:
|
|
14
|
+
type SubmitCallback<TFieldIds extends string = string> = (data: Record<TFieldIds, FieldValue>) => Record<TFieldIds, FieldValue> | void | Promise<Record<TFieldIds, FieldValue> | void>;
|
|
15
15
|
type SubmitEventWithCurrentTarget = SubmitEvent & {
|
|
16
16
|
currentTarget: EventTarget & HTMLFormElement;
|
|
17
17
|
};
|
|
18
|
-
export declare function getForm({ id: formId, title,
|
|
18
|
+
export declare function getForm<const TFieldIds extends readonly string[]>({ id: formId, title, fieldIds, }: GetFormOptions<TFieldIds>): {
|
|
19
19
|
form: {
|
|
20
20
|
onsubmit: EventCallable<SubmitEventWithCurrentTarget>;
|
|
21
21
|
};
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
fields: Store<({
|
|
23
|
+
value: FieldValue | undefined;
|
|
24
|
+
type: "text";
|
|
25
|
+
multiple: false;
|
|
26
|
+
defaultValue?: string;
|
|
27
|
+
options?: {
|
|
28
|
+
id: string;
|
|
29
|
+
label: string;
|
|
30
|
+
description?: string;
|
|
31
|
+
value: string;
|
|
32
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
33
|
+
}[] | null;
|
|
34
|
+
id: string;
|
|
35
|
+
name: string;
|
|
36
|
+
label: string;
|
|
37
|
+
required: boolean;
|
|
38
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
39
|
+
placeholder?: string;
|
|
40
|
+
description?: string;
|
|
41
|
+
helpText?: string;
|
|
42
|
+
validation?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
43
|
+
policies?: {
|
|
44
|
+
doNotTrackValue?: boolean;
|
|
45
|
+
doNotStoreValue?: boolean;
|
|
46
|
+
};
|
|
47
|
+
} | {
|
|
48
|
+
value: FieldValue | undefined;
|
|
49
|
+
type: "text";
|
|
50
|
+
multiple: true;
|
|
51
|
+
defaultValue?: string[];
|
|
52
|
+
options?: {
|
|
53
|
+
id: string;
|
|
54
|
+
label: string;
|
|
55
|
+
description?: string;
|
|
56
|
+
value: string;
|
|
57
|
+
condition
|
|
58
|
+
/**
|
|
59
|
+
* Factory function to create a callback observer with automatic cleanup
|
|
60
|
+
* Reduces duplication across success/error/submit callback patterns
|
|
61
|
+
*/
|
|
62
|
+
? /**
|
|
63
|
+
* Factory function to create a callback observer with automatic cleanup
|
|
64
|
+
* Reduces duplication across success/error/submit callback patterns
|
|
65
|
+
*/: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
66
|
+
}[] | null;
|
|
67
|
+
id: string;
|
|
68
|
+
name: string;
|
|
69
|
+
label: string;
|
|
70
|
+
required: boolean;
|
|
71
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
72
|
+
placeholder?: string;
|
|
73
|
+
description?: string;
|
|
74
|
+
helpText?: string;
|
|
75
|
+
validation?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
76
|
+
policies?: {
|
|
77
|
+
doNotTrackValue?: boolean;
|
|
78
|
+
doNotStoreValue?: boolean;
|
|
79
|
+
};
|
|
80
|
+
} | {
|
|
81
|
+
value: FieldValue | undefined;
|
|
82
|
+
type: "number";
|
|
83
|
+
multiple: false;
|
|
84
|
+
defaultValue?: number;
|
|
85
|
+
options?: {
|
|
86
|
+
id: string;
|
|
87
|
+
label: string;
|
|
88
|
+
description?: string;
|
|
89
|
+
value: number;
|
|
90
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
91
|
+
}[] | null;
|
|
92
|
+
id: string;
|
|
93
|
+
name: string;
|
|
94
|
+
label: string;
|
|
95
|
+
required: boolean;
|
|
96
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
97
|
+
placeholder?: string;
|
|
98
|
+
description?: string;
|
|
99
|
+
helpText?: string;
|
|
100
|
+
validation?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
101
|
+
policies?: {
|
|
102
|
+
doNotTrackValue?: boolean;
|
|
103
|
+
doNotStoreValue?: boolean;
|
|
104
|
+
};
|
|
105
|
+
} | {
|
|
106
|
+
value: FieldValue | undefined;
|
|
107
|
+
type: "number";
|
|
108
|
+
multiple: true;
|
|
109
|
+
defaultValue?: number[];
|
|
110
|
+
options?: {
|
|
111
|
+
id: string;
|
|
112
|
+
label: string;
|
|
113
|
+
description?: string;
|
|
114
|
+
value: number;
|
|
115
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
116
|
+
}[] | null;
|
|
117
|
+
id: string;
|
|
118
|
+
name: string;
|
|
119
|
+
label: string;
|
|
120
|
+
required: boolean;
|
|
121
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
122
|
+
placeholder?: string;
|
|
123
|
+
description?: string;
|
|
124
|
+
helpText?: string;
|
|
125
|
+
validation?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
126
|
+
policies?: {
|
|
127
|
+
doNotTrackValue?: boolean;
|
|
128
|
+
doNotStoreValue?: boolean;
|
|
129
|
+
};
|
|
130
|
+
} | {
|
|
131
|
+
value: FieldValue | undefined;
|
|
132
|
+
type: "boolean";
|
|
133
|
+
multiple: false;
|
|
134
|
+
defaultValue?: boolean;
|
|
135
|
+
options?: {
|
|
136
|
+
id: string;
|
|
137
|
+
label: string;
|
|
138
|
+
description?: string;
|
|
139
|
+
value: boolean;
|
|
140
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
141
|
+
}[] | null;
|
|
142
|
+
id: string;
|
|
143
|
+
name: string;
|
|
144
|
+
label: string;
|
|
145
|
+
required: boolean;
|
|
146
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
147
|
+
placeholder?: string;
|
|
148
|
+
description?: string;
|
|
149
|
+
helpText?: string;
|
|
150
|
+
validation?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
151
|
+
policies?: {
|
|
152
|
+
doNotTrackValue?: boolean;
|
|
153
|
+
doNotStoreValue?: boolean;
|
|
154
|
+
};
|
|
155
|
+
} | {
|
|
156
|
+
value: FieldValue | undefined;
|
|
157
|
+
type: "boolean";
|
|
158
|
+
multiple: true;
|
|
159
|
+
defaultValue?: boolean[];
|
|
160
|
+
options?: {
|
|
161
|
+
id: string;
|
|
162
|
+
label: string;
|
|
163
|
+
description?: string;
|
|
164
|
+
value: boolean;
|
|
165
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
166
|
+
}[] | null;
|
|
167
|
+
id: string;
|
|
168
|
+
name: string;
|
|
169
|
+
label: string;
|
|
170
|
+
required: boolean;
|
|
171
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
172
|
+
placeholder?: string;
|
|
173
|
+
description?: string;
|
|
174
|
+
helpText?: string;
|
|
175
|
+
validation?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
176
|
+
policies?: {
|
|
177
|
+
doNotTrackValue?: boolean;
|
|
178
|
+
doNotStoreValue?: boolean;
|
|
179
|
+
};
|
|
180
|
+
})[]>;
|
|
181
|
+
onFormSubmit: (callback: SubmitCallback<ExtractFieldIds<TFieldIds>>) => void;
|
|
182
|
+
onFormSuccess: (callback: SuccessCallback<ExtractFieldIds<TFieldIds>>) => void;
|
|
24
183
|
onFormError: (callback: ErrorCallback) => void;
|
|
25
184
|
isFormSubmitting: import('effector').StoreWritable<boolean>;
|
|
26
185
|
};
|
package/dist/form/form.svelte.ts
CHANGED
|
@@ -6,6 +6,7 @@ import type {
|
|
|
6
6
|
ValidationError,
|
|
7
7
|
ExperienceInstance,
|
|
8
8
|
} from '@picked/client'
|
|
9
|
+
import { getStepFields } from '@picked/client'
|
|
9
10
|
import {
|
|
10
11
|
attach,
|
|
11
12
|
createEffect,
|
|
@@ -15,6 +16,7 @@ import {
|
|
|
15
16
|
split,
|
|
16
17
|
type EventCallable,
|
|
17
18
|
type Store,
|
|
19
|
+
combine,
|
|
18
20
|
} from 'effector'
|
|
19
21
|
import { getPicked, getExperience, type FieldWithValue } from '../hooks'
|
|
20
22
|
|
|
@@ -23,25 +25,30 @@ interface Response {
|
|
|
23
25
|
value: FieldValue
|
|
24
26
|
}
|
|
25
27
|
|
|
26
|
-
|
|
28
|
+
// Extract field IDs from a readonly string array
|
|
29
|
+
type ExtractFieldIds<TFieldIds extends readonly string[]> = TFieldIds[number]
|
|
30
|
+
|
|
31
|
+
interface GetFormOptions<TFieldIds extends readonly string[]> {
|
|
27
32
|
id: string
|
|
28
33
|
title: string
|
|
29
|
-
|
|
34
|
+
fieldIds: TFieldIds
|
|
30
35
|
}
|
|
31
36
|
|
|
32
|
-
interface CommitResult {
|
|
33
|
-
data:
|
|
37
|
+
interface CommitResult<TFieldIds extends string = string> {
|
|
38
|
+
data: Record<TFieldIds, FieldValue>
|
|
34
39
|
errors: ValidationError[]
|
|
35
40
|
}
|
|
36
41
|
|
|
37
|
-
type SuccessCallback = (options: {
|
|
38
|
-
data:
|
|
42
|
+
type SuccessCallback<TFieldIds extends string = string> = (options: {
|
|
43
|
+
data: Record<TFieldIds, FieldValue>
|
|
39
44
|
stopNavigation: EventCallable<void>
|
|
40
45
|
}) => void | Promise<void>
|
|
46
|
+
|
|
41
47
|
type ErrorCallback = (errors: ValidationError[]) => void | Promise<void>
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
48
|
+
|
|
49
|
+
type SubmitCallback<TFieldIds extends string = string> = (
|
|
50
|
+
data: Record<TFieldIds, FieldValue>,
|
|
51
|
+
) => Record<TFieldIds, FieldValue> | void | Promise<Record<TFieldIds, FieldValue> | void>
|
|
45
52
|
|
|
46
53
|
type SubmitEventWithCurrentTarget = SubmitEvent & { currentTarget: EventTarget & HTMLFormElement }
|
|
47
54
|
|
|
@@ -70,13 +77,67 @@ function createObserver<TCallback extends (...args: any[]) => any, TReturn = voi
|
|
|
70
77
|
return { executeFx, register }
|
|
71
78
|
}
|
|
72
79
|
|
|
73
|
-
export function getForm
|
|
80
|
+
export function getForm<const TFieldIds extends readonly string[]>({
|
|
81
|
+
id: formId,
|
|
82
|
+
title,
|
|
83
|
+
fieldIds,
|
|
84
|
+
}: GetFormOptions<TFieldIds>) {
|
|
85
|
+
type FieldId = ExtractFieldIds<TFieldIds>
|
|
74
86
|
const client = getPicked()
|
|
75
|
-
|
|
76
|
-
|
|
87
|
+
|
|
88
|
+
// Make experience and router context optional
|
|
89
|
+
let experienceInstance: ExperienceInstance | null = null
|
|
90
|
+
let stepStore: Store<ExperienceStep | null>
|
|
91
|
+
let goToNextStep: EventCallable<void> | null = null
|
|
92
|
+
|
|
93
|
+
try {
|
|
94
|
+
experienceInstance = getExperience()
|
|
95
|
+
stepStore = experienceInstance.currentStepStore
|
|
96
|
+
goToNextStep = experienceInstance.goToNextStep
|
|
97
|
+
} catch {
|
|
98
|
+
// Not in experience context - create null store for standalone forms
|
|
99
|
+
stepStore = createStore<ExperienceStep | null>(null)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Create internal fields store
|
|
103
|
+
const fieldsStore = createStore<Field[]>([])
|
|
104
|
+
|
|
105
|
+
// Create fields with values store for UI
|
|
106
|
+
const fieldsWithValues = combine(
|
|
107
|
+
{
|
|
108
|
+
fields: fieldsStore,
|
|
109
|
+
responses: client.responses.listStore,
|
|
110
|
+
},
|
|
111
|
+
({ fields, responses }) => {
|
|
112
|
+
return fields.map((field) => {
|
|
113
|
+
const value = responses.find((r) => r.fieldId === field.id)?.value
|
|
114
|
+
return { ...field, value }
|
|
115
|
+
})
|
|
116
|
+
},
|
|
117
|
+
)
|
|
118
|
+
|
|
119
|
+
// Filter and evaluate fields based on fieldIds
|
|
120
|
+
const evaluateFieldsFx = attach({
|
|
121
|
+
source: client.fields.listStore,
|
|
122
|
+
effect: createEffect(async (allFields: Field[]) => {
|
|
123
|
+
const filteredFields = allFields.filter((field) =>
|
|
124
|
+
(fieldIds as readonly string[]).includes(field.id)
|
|
125
|
+
)
|
|
126
|
+
return await getStepFields(client, filteredFields)
|
|
127
|
+
}),
|
|
128
|
+
})
|
|
129
|
+
|
|
130
|
+
// Populate fields store when fields are evaluated
|
|
131
|
+
sample({
|
|
132
|
+
clock: evaluateFieldsFx.doneData,
|
|
133
|
+
target: fieldsStore,
|
|
134
|
+
})
|
|
135
|
+
|
|
136
|
+
// Auto-trigger field evaluation on form creation
|
|
137
|
+
evaluateFieldsFx()
|
|
77
138
|
|
|
78
139
|
const submitEvent = createEvent<SubmitEventWithCurrentTarget>()
|
|
79
|
-
const formSuccessEvent = createEvent<
|
|
140
|
+
const formSuccessEvent = createEvent<Record<FieldId, FieldValue>>()
|
|
80
141
|
const formErrorEvent = createEvent<ValidationError[]>()
|
|
81
142
|
const stopNavigationEvent = createEvent<void>()
|
|
82
143
|
const allCallbacksCompleteEvent = createEvent<void>()
|
|
@@ -88,7 +149,7 @@ export function getForm({ id: formId, title, fields }: GetFormOptions) {
|
|
|
88
149
|
.on(submitEvent, () => false) // Reset to false on new submit
|
|
89
150
|
|
|
90
151
|
// Create observers for each callback type
|
|
91
|
-
const successObserver = createObserver<SuccessCallback
|
|
152
|
+
const successObserver = createObserver<SuccessCallback<FieldId>>(async (callbacks, options) => {
|
|
92
153
|
await Promise.all(callbacks.map((callback) => Promise.resolve(callback(options))))
|
|
93
154
|
})
|
|
94
155
|
|
|
@@ -96,7 +157,7 @@ export function getForm({ id: formId, title, fields }: GetFormOptions) {
|
|
|
96
157
|
await Promise.all(callbacks.map((callback) => Promise.resolve(callback(errors))))
|
|
97
158
|
})
|
|
98
159
|
|
|
99
|
-
const submitObserver = createObserver<SubmitCallback,
|
|
160
|
+
const submitObserver = createObserver<SubmitCallback<FieldId>, Record<FieldId, FieldValue>>(
|
|
100
161
|
async (callbacks, data) => {
|
|
101
162
|
let transformedData = data
|
|
102
163
|
|
|
@@ -113,7 +174,7 @@ export function getForm({ id: formId, title, fields }: GetFormOptions) {
|
|
|
113
174
|
},
|
|
114
175
|
)
|
|
115
176
|
|
|
116
|
-
const commitFx = createEffect(async (responses:
|
|
177
|
+
const commitFx = createEffect(async (responses: Record<FieldId, FieldValue>) => {
|
|
117
178
|
const result = await client.responses.commit(responses)
|
|
118
179
|
// Merge submitted data with validation result
|
|
119
180
|
return {
|
|
@@ -124,18 +185,21 @@ export function getForm({ id: formId, title, fields }: GetFormOptions) {
|
|
|
124
185
|
|
|
125
186
|
const onSuccessFx = attach({
|
|
126
187
|
source: { step: stepStore },
|
|
127
|
-
mapParams: (commitResult: CommitResult
|
|
188
|
+
mapParams: (commitResult: CommitResult<FieldId>, source) => ({
|
|
128
189
|
step: source.step,
|
|
129
190
|
data: commitResult.data,
|
|
130
191
|
}),
|
|
131
192
|
effect: createEffect(
|
|
132
|
-
async ({ step, data }: { step: ExperienceStep | null; data:
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
193
|
+
async ({ step, data }: { step: ExperienceStep | null; data: Record<FieldId, FieldValue> }) => {
|
|
194
|
+
// Only fire events if in experience context
|
|
195
|
+
if (experienceInstance) {
|
|
196
|
+
client.eventBus({
|
|
197
|
+
type: 'form_submit_success',
|
|
198
|
+
form: { id: formId, title },
|
|
199
|
+
experience: experienceInstance,
|
|
200
|
+
step: step ?? undefined,
|
|
201
|
+
})
|
|
202
|
+
}
|
|
139
203
|
return data
|
|
140
204
|
},
|
|
141
205
|
),
|
|
@@ -143,28 +207,31 @@ export function getForm({ id: formId, title, fields }: GetFormOptions) {
|
|
|
143
207
|
|
|
144
208
|
const onErrorFx = attach({
|
|
145
209
|
source: { step: stepStore },
|
|
146
|
-
mapParams: (commitResult: CommitResult
|
|
210
|
+
mapParams: (commitResult: CommitResult<FieldId>, source) => ({
|
|
147
211
|
step: source.step,
|
|
148
212
|
errors: commitResult.errors,
|
|
149
213
|
}),
|
|
150
214
|
effect: createEffect(
|
|
151
215
|
async ({ step, errors }: { step: ExperienceStep | null; errors: ValidationError[] }) => {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
form: { id: formId, title },
|
|
155
|
-
exception: { reason: errors },
|
|
156
|
-
experience: experienceInstance,
|
|
157
|
-
step: step ?? undefined,
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
errors.forEach((exception) => {
|
|
216
|
+
// Only fire events if in experience context
|
|
217
|
+
if (experienceInstance) {
|
|
161
218
|
client.eventBus({
|
|
162
|
-
type: '
|
|
163
|
-
|
|
219
|
+
type: 'form_submit_error',
|
|
220
|
+
form: { id: formId, title },
|
|
221
|
+
exception: { reason: errors },
|
|
164
222
|
experience: experienceInstance,
|
|
165
223
|
step: step ?? undefined,
|
|
166
224
|
})
|
|
167
|
-
|
|
225
|
+
|
|
226
|
+
errors.forEach((exception) => {
|
|
227
|
+
client.eventBus({
|
|
228
|
+
type: 'field_validation_error',
|
|
229
|
+
exception: { reason: [exception] },
|
|
230
|
+
experience: experienceInstance!,
|
|
231
|
+
step: step ?? undefined,
|
|
232
|
+
})
|
|
233
|
+
})
|
|
234
|
+
}
|
|
168
235
|
|
|
169
236
|
return errors
|
|
170
237
|
},
|
|
@@ -192,12 +259,15 @@ export function getForm({ id: formId, title, fields }: GetFormOptions) {
|
|
|
192
259
|
title: string
|
|
193
260
|
step: ExperienceStep | null
|
|
194
261
|
}) => {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
262
|
+
// Only fire events if in experience context
|
|
263
|
+
if (experienceInstance) {
|
|
264
|
+
client.eventBus({
|
|
265
|
+
type: 'form_submit',
|
|
266
|
+
form: { id: formIdParam, title: titleParam },
|
|
267
|
+
experience: experienceInstance,
|
|
268
|
+
step: step ?? undefined,
|
|
269
|
+
})
|
|
270
|
+
}
|
|
201
271
|
},
|
|
202
272
|
),
|
|
203
273
|
})
|
|
@@ -205,8 +275,7 @@ export function getForm({ id: formId, title, fields }: GetFormOptions) {
|
|
|
205
275
|
sample({
|
|
206
276
|
clock: submitEvent,
|
|
207
277
|
source: {
|
|
208
|
-
|
|
209
|
-
stepFields: fields,
|
|
278
|
+
stepFields: fieldsStore,
|
|
210
279
|
},
|
|
211
280
|
fn: ({ stepFields }, event) => {
|
|
212
281
|
event.preventDefault()
|
|
@@ -244,7 +313,7 @@ export function getForm({ id: formId, title, fields }: GetFormOptions) {
|
|
|
244
313
|
},
|
|
245
314
|
}
|
|
246
315
|
|
|
247
|
-
stepFields.forEach((field) => {
|
|
316
|
+
stepFields.forEach((field: Field) => {
|
|
248
317
|
let fieldEntries = formDataEntries.filter(([key]) => key === field.id)
|
|
249
318
|
|
|
250
319
|
if (fieldEntries.length === 0) {
|
|
@@ -300,7 +369,7 @@ export function getForm({ id: formId, title, fields }: GetFormOptions) {
|
|
|
300
369
|
})
|
|
301
370
|
})
|
|
302
371
|
|
|
303
|
-
return responses.data
|
|
372
|
+
return responses.data as Record<FieldId, FieldValue>
|
|
304
373
|
},
|
|
305
374
|
target: submitObserver.executeFx,
|
|
306
375
|
})
|
|
@@ -341,13 +410,15 @@ export function getForm({ id: formId, title, fields }: GetFormOptions) {
|
|
|
341
410
|
target: allCallbacksCompleteEvent,
|
|
342
411
|
})
|
|
343
412
|
|
|
344
|
-
// Check navigation after all callbacks complete
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
413
|
+
// Check navigation after all callbacks complete (only if in router context)
|
|
414
|
+
if (goToNextStep) {
|
|
415
|
+
sample({
|
|
416
|
+
clock: allCallbacksCompleteEvent,
|
|
417
|
+
source: stopNavigationStore,
|
|
418
|
+
filter: (stop) => !stop,
|
|
419
|
+
target: goToNextStep,
|
|
420
|
+
})
|
|
421
|
+
}
|
|
351
422
|
|
|
352
423
|
// Declarative event wiring for error flow
|
|
353
424
|
sample({
|
|
@@ -371,6 +442,7 @@ export function getForm({ id: formId, title, fields }: GetFormOptions) {
|
|
|
371
442
|
form: {
|
|
372
443
|
onsubmit: submitEvent,
|
|
373
444
|
},
|
|
445
|
+
fields: fieldsWithValues,
|
|
374
446
|
onFormSubmit: submitObserver.register,
|
|
375
447
|
onFormSuccess: successObserver.register,
|
|
376
448
|
onFormError: errorObserver.register,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createStore as s,createEvent as f,attach as l,createEffect as u,sample as a}from"effector";import{getPicked as m}from"./client.js";function g(t){return m().actions.getEvokableAction(t)}function v(t){const c=g(t),o=s(void 0,{skipVoid:!1}),n=f(),r=l({source:c,mapParams:(e,i)=>i,effect:u(async e=>{if(e)return e()})});return a({clock:n,target:r}),a({clock:r.doneData,target:o}),n(),o}export{g as getAction,v as getActionResult};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function getFeature(featureName: string): import('effector').Store<() => Promise<boolean | string | undefined>>;
|
|
2
|
+
export declare function getFeatureResult(featureName: string): import('effector').StoreWritable<{
|
|
3
|
+
id: string;
|
|
4
|
+
bucket: string | boolean;
|
|
5
|
+
} | undefined>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createStore as i,createEvent as s,attach as f,createEffect as l,sample as o}from"effector";import{getPicked as v}from"./client.js";function d(t){return v().features.getEvokableFeature(t)}function m(t){const r=d(t),c=i(void 0,{skipVoid:!1}),a=s(),n=f({source:r,mapParams:(e,u)=>u,effect:l(async e=>await e())});return o({clock:a,target:n}),o({clock:n.doneData,fn:e=>{if(e!==void 0)return{id:t,bucket:e}},target:c}),a(),o({clock:r,target:a}),c}export{d as getFeature,m as getFeatureResult};
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export { getPicked, getExperience } from './client';
|
|
2
2
|
export { getStep, setStepContext, type FieldWithValue } from './step';
|
|
3
3
|
export { getField } from './field';
|
|
4
|
+
export { getForm } from '../form';
|
|
5
|
+
export { getAction, getActionResult } from './action';
|
|
6
|
+
export { getFeature, getFeatureResult } from './feature';
|
|
7
|
+
export { getPredicate, getPredicateResult } from './predicate';
|
|
4
8
|
export { useUnit, getContextScope, setContextScope } from './stores';
|
|
5
9
|
export { createSessionStorageStore, createLocalStorageStore } from './storage.js';
|
|
6
10
|
export { getTrackRecommendationPresentEvent } from './events';
|
package/dist/hooks/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getExperience as r,getPicked as o}from"./client.js";import{getStep as c,setStepContext as
|
|
1
|
+
import{getExperience as r,getPicked as o}from"./client.js";import{getStep as c,setStepContext as g}from"./step.js";import{getField as m}from"./field.js";import{getForm as n}from"../form/form.svelte";import{getAction as s,getActionResult as i}from"./action.js";import{getFeature as S,getFeatureResult as d}from"./feature.js";import{getPredicate as P,getPredicateResult as C}from"./predicate.js";import{getContextScope as R,setContextScope as y,useUnit as k}from"./stores.js";import{createLocalStorageStore as A,createSessionStorageStore as E}from"./storage.js";import{getTrackRecommendationPresentEvent as v}from"./events.js";import{createQuery as Q,queryCache as T,queryPresets as U}from"./create-query/index.js";export{A as createLocalStorageStore,Q as createQuery,E as createSessionStorageStore,s as getAction,i as getActionResult,R as getContextScope,r as getExperience,S as getFeature,d as getFeatureResult,m as getField,n as getForm,o as getPicked,P as getPredicate,C as getPredicateResult,c as getStep,v as getTrackRecommendationPresentEvent,T as queryCache,U as queryPresets,y as setContextScope,g as setStepContext,k as useUnit};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { Predicate } from '@picked/client';
|
|
2
|
+
export declare function getPredicate(predicateName: string): import('effector').Store<() => ReturnType<Predicate>>;
|
|
3
|
+
export declare function getPredicateResult(predicateName: string): import('effector').StoreWritable<string | boolean | string[] | undefined>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"@picked/client";import{createStore as s,createEvent as d,attach as l,createEffect as f,sample as a}from"effector";import{getPicked as u}from"./client.js";function m(e){return u().predicates.getEvokablePredicate(e)}function v(e){const t=m(e),o=s(void 0,{skipVoid:!1}),r=d(),i=l({source:t,mapParams:(c,n)=>n,effect:f(async c=>{if(c)return await c()})});return a({clock:r,target:i}),a({clock:i.doneData,target:o}),r(),a({clock:t,target:r}),o}export{m as getPredicate,v as getPredicateResult};
|
package/dist/hooks/step.d.ts
CHANGED
|
@@ -1,30 +1,12 @@
|
|
|
1
1
|
import { Store } from 'effector';
|
|
2
|
-
import { ExperienceStep,
|
|
2
|
+
import { ExperienceStep, Response, Field } from '@picked/client';
|
|
3
3
|
import { getForm } from '../form';
|
|
4
4
|
export type FieldWithValue = Field & {
|
|
5
5
|
value: Response | undefined;
|
|
6
6
|
};
|
|
7
|
-
export interface StepContext {
|
|
7
|
+
export interface StepContext extends ReturnType<typeof getForm> {
|
|
8
8
|
step: Store<ExperienceStep>;
|
|
9
|
-
fields: Store<FieldWithValue[]>;
|
|
10
9
|
isActiveStep: Store<boolean>;
|
|
11
|
-
form: ReturnType<typeof getForm>;
|
|
12
10
|
}
|
|
13
|
-
export declare function getStep():
|
|
14
|
-
form: {
|
|
15
|
-
onsubmit: import('effector').EventCallable<SubmitEvent & {
|
|
16
|
-
currentTarget: EventTarget & HTMLFormElement;
|
|
17
|
-
}>;
|
|
18
|
-
};
|
|
19
|
-
onFormSubmit: (callback: (data: import('@picked/client').CommitResponses) => import('@picked/client').CommitResponses | void | Promise<import('@picked/client').CommitResponses | void>) => void;
|
|
20
|
-
onFormSuccess: (callback: (options: {
|
|
21
|
-
data: import('@picked/client').CommitResponses;
|
|
22
|
-
stopNavigation: import('effector').EventCallable<void>;
|
|
23
|
-
}) => void | Promise<void>) => void;
|
|
24
|
-
onFormError: (callback: (errors: import('@picked/client').ValidationError[]) => void | Promise<void>) => void;
|
|
25
|
-
isFormSubmitting: import('effector').StoreWritable<boolean>;
|
|
26
|
-
step: Store<ExperienceStep>;
|
|
27
|
-
fields: Store<FieldWithValue[]>;
|
|
28
|
-
isActiveStep: Store<boolean>;
|
|
29
|
-
};
|
|
11
|
+
export declare function getStep(): StepContext;
|
|
30
12
|
export declare function setStepContext(stepId: string): StepContext;
|
package/dist/hooks/step.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getContext as
|
|
1
|
+
import{getContext as x,setContext as u}from"svelte";import{STEP_CONTEXT_KEY as n}from"../context.js";import{getStepRouter as a}from"../router/context.js";import{getForm as g}from"../form/form.svelte";import{getExperience as E}from"./client.js";function w(){return x(n)}function T(t){const i=E(),{activeStep:c}=a(),m=c.map(e=>(e==null?void 0:e.id)===t),o=i.treeStore.map(e=>{const r=e.steps.find(s=>s.id===t);if(!r)throw new Error(`Step with id "${t}" not found in the experience tree.`);return r}),{label:p,fieldIds:f}=o.getState(),S=g({id:`${t}`,title:p||t,fieldIds:f});return u(n,{step:o,isActiveStep:m,...S})}export{w as getStep,T as setStepContext};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@picked/svelte",
|
|
3
|
-
"version": "0.0.1-dev.
|
|
3
|
+
"version": "0.0.1-dev.1767924764002",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"d3": "^7.9.0"
|
|
6
6
|
},
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
],
|
|
76
76
|
"module": "./dist/index.js",
|
|
77
77
|
"peerDependencies": {
|
|
78
|
-
"@picked/client": "0.0.1-dev.
|
|
78
|
+
"@picked/client": "0.0.1-dev.1767924764002",
|
|
79
79
|
"effector": "^23.3.0",
|
|
80
80
|
"svelte": "^5.34.3"
|
|
81
81
|
},
|