@picked/client 0.0.1-dev.1777856271317 → 0.0.1-dev.1777867216429
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/{api-DaHz97Mz.js → api-Xp22knXn.js} +1 -1
- package/dist/{api-dOWgI8zV.cjs → api-qBG8rsTJ.cjs} +1 -1
- package/dist/cjs/form/index.js +1 -1
- package/dist/cjs/index.js +2 -2
- package/dist/cjs/plugins/create-experience/index.js +1 -1
- package/dist/cjs/plugins/dynamic-experiences/index.js +1 -1
- package/dist/cjs/plugins/experience-browser-storage/index.js +1 -1
- package/dist/cjs/plugins/history-browser-storage/index.js +1 -1
- package/dist/cjs/plugins/responses-browser-storage/index.js +1 -1
- package/dist/cjs/server/index.js +1 -1
- package/dist/docs/api/authentication.md +376 -0
- package/dist/docs/api/authorization-and-scopes.md +262 -0
- package/dist/docs/api/error-handling.md +211 -0
- package/dist/docs/api/index.md +172 -11
- package/dist/docs/api/pagination.md +176 -0
- package/dist/docs/image-optimisation-service.md +72 -0
- package/dist/docs/sdk/plugins/dynamic-experiences.md +2 -2
- package/dist/docs/workspaces.mdx +60 -1
- package/dist/esm/form/index.js +40 -33
- package/dist/esm/index.js +295 -170
- package/dist/esm/plugins/create-experience/index.js +1 -1
- package/dist/esm/plugins/dynamic-experiences/index.js +1 -1
- package/dist/esm/plugins/experience-browser-storage/index.js +1 -1
- package/dist/esm/plugins/history-browser-storage/index.js +1 -1
- package/dist/esm/plugins/responses-browser-storage/index.js +1 -1
- package/dist/esm/server/index.js +1 -1
- package/dist/experience-instance-BWniatU5.cjs +1 -0
- package/dist/experience-instance-C4UJM092.js +506 -0
- package/dist/types/entities/experience-instance/experience-instance.d.ts.map +1 -1
- package/dist/types/entities/history/history.d.ts +9 -0
- package/dist/types/entities/history/history.d.ts.map +1 -1
- package/dist/types/form/create-form.d.ts +55 -0
- package/dist/types/form/create-form.d.ts.map +1 -1
- package/package.json +1 -11
- package/dist/cjs/plugins/dom-observer/index.js +0 -1
- package/dist/docs/reference/index.md +0 -11
- package/dist/docs/tooling/index.md +0 -19
- package/dist/esm/plugins/dom-observer/index.js +0 -107
- package/dist/experience-BhteyYBl.cjs +0 -1
- package/dist/experience-CoMdlvyn.js +0 -136
- package/dist/experience-instance-CZDcicPj.cjs +0 -1
- package/dist/experience-instance-IkIw31Cg.js +0 -387
- package/dist/nodes-ChVU1VZO.js +0 -101
- package/dist/nodes-DDDs-rC2.cjs +0 -1
- package/dist/types/plugins/dom-observer/index.d.ts +0 -3
- package/dist/types/plugins/dom-observer/index.d.ts.map +0 -1
- package/dist/types/plugins/dom-observer/plugin.d.ts +0 -51
- package/dist/types/plugins/dom-observer/plugin.d.ts.map +0 -1
- /package/dist/docs/{tooling/chrome-extension.md → chrome-extension.md} +0 -0
- /package/dist/docs/{tooling/gtm-template.md → gtm-template.md} +0 -0
- /package/dist/docs/{tooling/mcp.md → mcp.md} +0 -0
- /package/dist/docs/{tooling/vite-plugin.md → vite-plugin.md} +0 -0
- /package/dist/{id-Bbodazn8.cjs → id-Bv44ilEo.cjs} +0 -0
- /package/dist/{id-B-N2zNbS.js → id-CRqy981z.js} +0 -0
- /package/dist/{storage-hOHCCXvP.js → storage-6Xk0uAxB.js} +0 -0
- /package/dist/{storage-BXSlLTRa.cjs → storage-B6lQtc4-.cjs} +0 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: docs
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Pagination
|
|
6
|
+
|
|
7
|
+
The Picked API uses Relay-style cursor-based pagination for all list fields that may return large result sets. This guide explains the connection pattern and demonstrates how to paginate through results.
|
|
8
|
+
|
|
9
|
+
## Connection pattern
|
|
10
|
+
|
|
11
|
+
Paginated fields return a **connection** object with the following shape:
|
|
12
|
+
|
|
13
|
+
```graphql
|
|
14
|
+
type ExampleConnection {
|
|
15
|
+
edges: [ExampleEdge!]!
|
|
16
|
+
pageInfo: PageInfo!
|
|
17
|
+
totalCount: Int!
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
type ExampleEdge {
|
|
21
|
+
cursor: String!
|
|
22
|
+
node: Example!
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
type PageInfo {
|
|
26
|
+
hasNextPage: Boolean!
|
|
27
|
+
hasPreviousPage: Boolean!
|
|
28
|
+
startCursor: String
|
|
29
|
+
endCursor: String
|
|
30
|
+
}
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
| Field | Description |
|
|
34
|
+
|-------|-------------|
|
|
35
|
+
| `edges` | An ordered list of edges, each containing a `cursor` and a `node` (the actual data object) |
|
|
36
|
+
| `pageInfo.hasNextPage` | `true` if more results exist after the last edge |
|
|
37
|
+
| `pageInfo.hasPreviousPage` | `true` if results exist before the first edge |
|
|
38
|
+
| `pageInfo.startCursor` | Cursor of the first edge in the current page |
|
|
39
|
+
| `pageInfo.endCursor` | Cursor of the last edge in the current page |
|
|
40
|
+
| `totalCount` | Total number of items across all pages |
|
|
41
|
+
|
|
42
|
+
## Forward pagination with `first` and `after`
|
|
43
|
+
|
|
44
|
+
To paginate forward through results, use the `first` argument to specify the page size and the `after` argument to specify the cursor to start after.
|
|
45
|
+
|
|
46
|
+
### First page
|
|
47
|
+
|
|
48
|
+
Omit the `after` argument to fetch the first page:
|
|
49
|
+
|
|
50
|
+
```graphql
|
|
51
|
+
query {
|
|
52
|
+
organizations(input: { first: 10 }) {
|
|
53
|
+
edges {
|
|
54
|
+
cursor
|
|
55
|
+
node {
|
|
56
|
+
id
|
|
57
|
+
name
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
pageInfo {
|
|
61
|
+
hasNextPage
|
|
62
|
+
endCursor
|
|
63
|
+
}
|
|
64
|
+
totalCount
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
### Next page
|
|
70
|
+
|
|
71
|
+
Pass the `endCursor` from the previous response as the `after` argument:
|
|
72
|
+
|
|
73
|
+
```graphql
|
|
74
|
+
query {
|
|
75
|
+
organizations(input: { first: 10, after: "cursor_from_previous_page" }) {
|
|
76
|
+
edges {
|
|
77
|
+
cursor
|
|
78
|
+
node {
|
|
79
|
+
id
|
|
80
|
+
name
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
pageInfo {
|
|
84
|
+
hasNextPage
|
|
85
|
+
endCursor
|
|
86
|
+
}
|
|
87
|
+
totalCount
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
## Checking for more pages
|
|
93
|
+
|
|
94
|
+
Before requesting the next page, check the `hasNextPage` field:
|
|
95
|
+
|
|
96
|
+
- `hasNextPage: true` — more results are available; pass `endCursor` to the next request's `after` argument
|
|
97
|
+
- `hasNextPage: false` — all results have been fetched; stop paginating
|
|
98
|
+
|
|
99
|
+
## Full paginated query example
|
|
100
|
+
|
|
101
|
+
The following example fetches all members of an organization, page by page:
|
|
102
|
+
|
|
103
|
+
```graphql
|
|
104
|
+
# Page 1
|
|
105
|
+
query {
|
|
106
|
+
organization(input: { slug: "my-company" }) {
|
|
107
|
+
members(first: 20) {
|
|
108
|
+
edges {
|
|
109
|
+
cursor
|
|
110
|
+
node {
|
|
111
|
+
id
|
|
112
|
+
userEmail
|
|
113
|
+
role
|
|
114
|
+
joinedAt
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
pageInfo {
|
|
118
|
+
hasNextPage
|
|
119
|
+
endCursor
|
|
120
|
+
}
|
|
121
|
+
totalCount
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
If `pageInfo.hasNextPage` is `true`, fetch the next page:
|
|
128
|
+
|
|
129
|
+
```graphql
|
|
130
|
+
# Page 2
|
|
131
|
+
query {
|
|
132
|
+
organization(input: { slug: "my-company" }) {
|
|
133
|
+
members(first: 20, after: "cursor_from_page_1") {
|
|
134
|
+
edges {
|
|
135
|
+
cursor
|
|
136
|
+
node {
|
|
137
|
+
id
|
|
138
|
+
userEmail
|
|
139
|
+
role
|
|
140
|
+
joinedAt
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
pageInfo {
|
|
144
|
+
hasNextPage
|
|
145
|
+
endCursor
|
|
146
|
+
}
|
|
147
|
+
totalCount
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Continue until `hasNextPage` returns `false`.
|
|
154
|
+
|
|
155
|
+
## Paginated fields
|
|
156
|
+
|
|
157
|
+
The following fields in the schema return connection types and support `first`/`after` pagination:
|
|
158
|
+
|
|
159
|
+
| Parent Type | Field | Connection Type |
|
|
160
|
+
|------------|-------|----------------|
|
|
161
|
+
| `Query` | `organizations` | `OrganizationConnection` |
|
|
162
|
+
| `User` | `organizations` | `OrganizationConnection` |
|
|
163
|
+
| `User` | `invitations` | `ViewerInvitationConnection` |
|
|
164
|
+
| `Organization` | `members` | `OrganizationMemberConnection` |
|
|
165
|
+
| `Organization` | `invitations` | `OrganizationInvitationConnection` |
|
|
166
|
+
| `Organization` | `projects` | `ProjectConnection` |
|
|
167
|
+
| `Project` | `reports` | `ProjectReportConnection` |
|
|
168
|
+
|
|
169
|
+
All of these fields accept the same `first` and `after` arguments and return the standard `edges`, `pageInfo`, and `totalCount` structure.
|
|
170
|
+
|
|
171
|
+
## Tips
|
|
172
|
+
|
|
173
|
+
- **Default page size** — if `first` is omitted, the API applies a default limit. Explicitly setting `first` ensures predictable page sizes.
|
|
174
|
+
- **Cursors are opaque** — cursor strings should be treated as opaque tokens. Do not parse, construct, or modify them. Pass them exactly as received from the API.
|
|
175
|
+
- **Stable ordering** — results within a connection are returned in a stable order. The same cursor always refers to the same position in the result set.
|
|
176
|
+
- **Combine with other fields** — pagination arguments can be used alongside other query fields. For example, fetching an organization and its first page of members in a single request is common and efficient.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
---
|
|
2
|
+
layout: docs
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
# Image optimisation service
|
|
6
|
+
|
|
7
|
+
The Picked image optimisation service is a hosted endpoint at `https://img.picked.app`. It fetches images from allowed source domains, resizes them, re-encodes to modern formats (WebP or AVIF), and caches the result.
|
|
8
|
+
|
|
9
|
+
## Endpoint
|
|
10
|
+
|
|
11
|
+
```
|
|
12
|
+
GET https://img.picked.app/_next/image?url={source}&w={width}&q={quality}
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
| Parameter | Description |
|
|
16
|
+
|-----------|-------------|
|
|
17
|
+
| `url` | URL-encoded URL of the source image. Must point to an allowed source domain (see below). |
|
|
18
|
+
| `w` | Target width in pixels. Must match one of the supported widths. |
|
|
19
|
+
| `q` | Target quality (`25`, `50`, `75`, or `100`). |
|
|
20
|
+
|
|
21
|
+
The service performs content negotiation: if the requesting browser advertises `image/avif` or `image/webp` in its `Accept` header, the response uses that format. Otherwise the response uses the source format.
|
|
22
|
+
|
|
23
|
+
## Allowed source domains
|
|
24
|
+
|
|
25
|
+
The service only fetches from these hostnames:
|
|
26
|
+
|
|
27
|
+
- `**.picked.app`
|
|
28
|
+
|
|
29
|
+
A request whose `url` parameter resolves to any other hostname returns `400 Bad Request`.
|
|
30
|
+
|
|
31
|
+
## Supported widths
|
|
32
|
+
|
|
33
|
+
```
|
|
34
|
+
640, 750, 828, 1080, 1200, 1920, 2048, 3840
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Requests with any other width return `400 Bad Request`. Pick the smallest width that covers your target rendering size at the user's device pixel ratio.
|
|
38
|
+
|
|
39
|
+
## Supported qualities
|
|
40
|
+
|
|
41
|
+
```
|
|
42
|
+
25, 50, 75, 100
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Lower values reduce bandwidth significantly. `75` is a good default for most images; use `25` or `50` for thumbnails on slow networks.
|
|
46
|
+
|
|
47
|
+
## Responsive images
|
|
48
|
+
|
|
49
|
+
Combine the endpoint with the standard `srcset` attribute to let browsers pick the right width per viewport:
|
|
50
|
+
|
|
51
|
+
```html
|
|
52
|
+
<img
|
|
53
|
+
src="https://img.picked.app/_next/image?url=https%3A%2F%2Fcdn.picked.app%2Fhero.png&w=1080&q=75"
|
|
54
|
+
srcset="
|
|
55
|
+
https://img.picked.app/_next/image?url=https%3A%2F%2Fcdn.picked.app%2Fhero.png&w=640&q=75 640w,
|
|
56
|
+
https://img.picked.app/_next/image?url=https%3A%2F%2Fcdn.picked.app%2Fhero.png&w=1080&q=75 1080w,
|
|
57
|
+
https://img.picked.app/_next/image?url=https%3A%2F%2Fcdn.picked.app%2Fhero.png&w=1920&q=75 1920w
|
|
58
|
+
"
|
|
59
|
+
sizes="(max-width: 768px) 100vw, 720px"
|
|
60
|
+
alt="..."
|
|
61
|
+
/>
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Caching
|
|
65
|
+
|
|
66
|
+
Optimised responses are cached by the upstream CDN. The minimum cache TTL is 60 seconds; the actual lifetime depends on the CDN's eviction policy. If you change the source image at the same URL, expect the optimised variant to remain cached for at least that interval.
|
|
67
|
+
|
|
68
|
+
## Security
|
|
69
|
+
|
|
70
|
+
- SVG sources are not optimised. Requests for SVG return the original bytes if the source is allowed; the service never executes embedded scripts.
|
|
71
|
+
- Optimised responses carry a strict `Content-Security-Policy` (`default-src *; script-src 'none'; sandbox;`) so even a compromised source cannot run scripts in a viewing browser.
|
|
72
|
+
- The response uses `Content-Disposition: inline`, never `attachment`.
|
|
@@ -35,14 +35,14 @@ When the client starts, the plugin resolves your project configuration using a t
|
|
|
35
35
|
|
|
36
36
|
1. **Preview mode** — When you [enter preview mode from the dashboard](/workspaces#preview), the plugin fetches fresh config from the API. Feature decisions use session storage so they are not persisted beyond the current tab.
|
|
37
37
|
|
|
38
|
-
2. **Build-time config** — If `projectConfig` was passed as a plugin option, or the [Vite Plugin](/
|
|
38
|
+
2. **Build-time config** — If `projectConfig` was passed as a plugin option, or the [Vite Plugin](/vite-plugin) injected config at build time, the plugin uses that config with no network request.
|
|
39
39
|
|
|
40
40
|
3. **Runtime fetch** — Otherwise, the plugin fetches config from the API when the client starts.
|
|
41
41
|
|
|
42
42
|
Once resolved, the plugin registers all features, conditions, fields, steps, and experiences with the client. Experiences then initialize according to their [conditions](/sdk/conditions) and [target selectors](/sdk/experiences).
|
|
43
43
|
|
|
44
44
|
:::note
|
|
45
|
-
The [Vite Plugin](/
|
|
45
|
+
The [Vite Plugin](/vite-plugin) eliminates the runtime API request in production by embedding your project config at build time. This is the recommended setup for Vite-based applications.
|
|
46
46
|
:::
|
|
47
47
|
|
|
48
48
|
## Feature Allocation
|
package/dist/docs/workspaces.mdx
CHANGED
|
@@ -18,6 +18,12 @@ A workspace is a version of your project's configuration. Use workspaces to stag
|
|
|
18
18
|
|
|
19
19
|
Each project has a workspace that holds your experiences, features, and entity configurations. When you make changes in the dashboard — editing a flow, updating a feature, or modifying an entity — those changes exist in the workspace until you publish.
|
|
20
20
|
|
|
21
|
+
A workspace is in one of three states:
|
|
22
|
+
|
|
23
|
+
- **Live** — the workspace the SDK serves to visitors. There is exactly one live workspace per project.
|
|
24
|
+
- **Draft** — a workspace not currently serving traffic. You can edit, preview, and publish a draft to make it live.
|
|
25
|
+
- **Archived** — a draft you have set aside. Archived workspaces stay editable but are filtered out of the default workspaces list.
|
|
26
|
+
|
|
21
27
|
## Preview
|
|
22
28
|
|
|
23
29
|
Preview your workspace to see how changes look before publishing.
|
|
@@ -34,10 +40,63 @@ Your site opens in a new tab with the unpublished workspace applied. Preview use
|
|
|
34
40
|
Publishing creates an immutable snapshot of your workspace. Once published, the SDK serves the new configuration to visitors.
|
|
35
41
|
|
|
36
42
|
1. Click **Publish** in the workspace toolbar.
|
|
37
|
-
2.
|
|
43
|
+
2. Review the change preview in the publish modal.
|
|
44
|
+
3. Click **Publish** to confirm.
|
|
38
45
|
|
|
39
46
|
The publish button is only enabled when there are unpublished changes. A status badge in the toolbar shows whether the workspace has unpublished changes or is up to date.
|
|
40
47
|
|
|
48
|
+
## Change previews
|
|
49
|
+
|
|
50
|
+
The publish modal shows a side-by-side change preview comparing the current workspace against the last published snapshot. Use it to verify exactly what your visitors will see after publishing.
|
|
51
|
+
|
|
52
|
+
<Screenshot
|
|
53
|
+
route="/{orgSlug}/{projectId}/workspaces/{workspaceId}?action=publish"
|
|
54
|
+
alt="The publish modal showing a change preview with added experiences, steps, and conditions"
|
|
55
|
+
selector='[role="dialog"]'
|
|
56
|
+
wait='[role="dialog"]'
|
|
57
|
+
hide={['[data-testid="publish-diff-replaces-version"]']}
|
|
58
|
+
renderWidth={720}
|
|
59
|
+
renderHeight={579}
|
|
60
|
+
/>
|
|
61
|
+
|
|
62
|
+
The preview groups changes by entity type — experiences, features, steps, fields, actions, and conditions. Each row shows whether the entity was **added**, **removed**, or **modified**. For modifications, expand the row to see which properties changed.
|
|
63
|
+
|
|
64
|
+
When the change preview includes breaking changes — for example, removing a field that other steps still reference — a banner highlights the breaking entries above the diff so you can reconsider before publishing.
|
|
65
|
+
|
|
66
|
+
The first publish of a workspace has no previous snapshot to compare against, so the publish modal shows the workspace's contents as the initial publish without a diff.
|
|
67
|
+
|
|
41
68
|
## Unpublished changes
|
|
42
69
|
|
|
43
70
|
The workspace tracks whether any changes have been made since the last publish. If you create or update an experience, feature, or entity after the last publish, the toolbar shows a warning badge indicating unpublished changes.
|
|
71
|
+
|
|
72
|
+
## Workspace settings
|
|
73
|
+
|
|
74
|
+
The workspace settings page (**Settings** in the workspace nav) covers renaming, archiving, and deleting a workspace.
|
|
75
|
+
|
|
76
|
+
### Rename
|
|
77
|
+
|
|
78
|
+
Change the workspace name in the **Name** field and click **Save**. Names are unique within a project — duplicates are rejected with a validation error.
|
|
79
|
+
|
|
80
|
+
### Archive
|
|
81
|
+
|
|
82
|
+
Archiving moves a draft workspace out of the default workspaces list without deleting it. Use it for drafts you want to set aside for later without losing the work.
|
|
83
|
+
|
|
84
|
+
1. Open the workspace settings page.
|
|
85
|
+
2. Click **Archive** in the page header.
|
|
86
|
+
3. Confirm in the modal.
|
|
87
|
+
|
|
88
|
+
Live workspaces cannot be archived directly — make a different workspace live first, then archive the previous one.
|
|
89
|
+
|
|
90
|
+
### Unarchive
|
|
91
|
+
|
|
92
|
+
Restore an archived workspace to draft status from the same page. The settings page detects the archived state and switches the toolbar button to **Unarchive**.
|
|
93
|
+
|
|
94
|
+
### Delete
|
|
95
|
+
|
|
96
|
+
Deleting a workspace permanently removes it and its entities. This is destructive and cannot be undone — prefer archive when in doubt.
|
|
97
|
+
|
|
98
|
+
1. Open the workspace settings page.
|
|
99
|
+
2. In the **Danger zone** card at the bottom, click **Delete**.
|
|
100
|
+
3. Confirm in the modal.
|
|
101
|
+
|
|
102
|
+
Live workspaces cannot be deleted. Archive or publish a different workspace first to free the workspace for deletion.
|
package/dist/esm/form/index.js
CHANGED
|
@@ -389,7 +389,32 @@ function y(e) {
|
|
|
389
389
|
if (t instanceof HTMLInputElement) return t.type === "checkbox" ? t.checked : t.value;
|
|
390
390
|
if (t instanceof HTMLSelectElement || t instanceof HTMLTextAreaElement) return t.value;
|
|
391
391
|
}
|
|
392
|
-
function b(e, t,
|
|
392
|
+
function b(e, t, n) {
|
|
393
|
+
let r = e.currentTarget;
|
|
394
|
+
if (t.multiple) {
|
|
395
|
+
if (r instanceof HTMLInputElement && r.type === "checkbox") return x(e, r, n);
|
|
396
|
+
if (r instanceof HTMLSelectElement && r.multiple) return Array.from(r.selectedOptions, (e) => e.value);
|
|
397
|
+
}
|
|
398
|
+
return y(e);
|
|
399
|
+
}
|
|
400
|
+
function x(e, t, n) {
|
|
401
|
+
if (e.type === "input") return;
|
|
402
|
+
let r = Array.isArray(n) ? n.map(String) : [];
|
|
403
|
+
return e.type === "change" ? S(r, String(t.value)) : r;
|
|
404
|
+
}
|
|
405
|
+
function S(e, t) {
|
|
406
|
+
return e.includes(t) ? e.filter((e) => e !== t) : [...e, t];
|
|
407
|
+
}
|
|
408
|
+
function C(e, t, n) {
|
|
409
|
+
return (r) => {
|
|
410
|
+
let i = b(r, e, t);
|
|
411
|
+
i !== void 0 && n({
|
|
412
|
+
fieldKey: e.key,
|
|
413
|
+
value: i
|
|
414
|
+
});
|
|
415
|
+
};
|
|
416
|
+
}
|
|
417
|
+
function w(e, t, r, i) {
|
|
393
418
|
let { client: s, experienceInstance: c } = e, { currentStepStore: l, goToNextStep: u } = c, d = n(l, c, (e, t) => ({
|
|
394
419
|
stepId: e?.id,
|
|
395
420
|
experienceId: t.id
|
|
@@ -404,49 +429,31 @@ function b(e, t, r, i) {
|
|
|
404
429
|
},
|
|
405
430
|
target: f
|
|
406
431
|
});
|
|
407
|
-
let { fieldInputEvent: h, fieldChangeEvent: _, fieldBlurEvent:
|
|
432
|
+
let { fieldInputEvent: h, fieldChangeEvent: _, fieldBlurEvent: y, touchedStore: b, fieldErrorsStore: x, formErrorsStore: S } = g(s, p, f), w = n({
|
|
408
433
|
fields: p,
|
|
409
434
|
responses: s.responses.listStore,
|
|
410
435
|
staged: f,
|
|
411
|
-
fieldErrors:
|
|
412
|
-
touched:
|
|
436
|
+
fieldErrors: x,
|
|
437
|
+
touched: b,
|
|
413
438
|
experienceAndStepId: d
|
|
414
439
|
}, ({ fields: e, responses: t, staged: n, fieldErrors: r, touched: i, experienceAndStepId: a }) => e.map((e) => {
|
|
415
|
-
let o = (t) => {
|
|
416
|
-
let n = y(t);
|
|
417
|
-
n !== void 0 && h({
|
|
418
|
-
fieldKey: e.key,
|
|
419
|
-
value: n
|
|
420
|
-
});
|
|
421
|
-
}, s = (t) => {
|
|
422
|
-
let n = y(t);
|
|
423
|
-
n !== void 0 && _({
|
|
424
|
-
fieldKey: e.key,
|
|
425
|
-
value: n
|
|
426
|
-
});
|
|
427
|
-
}, c = (t) => {
|
|
428
|
-
let n = y(t);
|
|
429
|
-
n !== void 0 && b({
|
|
430
|
-
fieldKey: e.key,
|
|
431
|
-
value: n
|
|
432
|
-
});
|
|
433
|
-
}, l = n[e.key] ?? t.find((t) => t.fieldKey === e.key)?.value ?? e.defaultValue, u = r[e.key], d = e.type === "number" ? "number" : "text", f = e.type === "boolean" ? "checkbox" : d, { experienceId: p, stepId: m } = a, g = `${p}-${m ?? "step"}-${e.id}`;
|
|
440
|
+
let o = n[e.key] ?? t.find((t) => t.fieldKey === e.key)?.value ?? e.defaultValue, s = C(e, o, h), c = C(e, o, _), l = C(e, o, y), u = r[e.key], d = e.type === "number" ? "number" : "text", f = e.type === "boolean" ? "checkbox" : d, { experienceId: p, stepId: m } = a, g = `${p}-${m ?? "step"}-${e.id}`;
|
|
434
441
|
return {
|
|
435
442
|
...e,
|
|
436
|
-
value:
|
|
443
|
+
value: o,
|
|
437
444
|
error: u,
|
|
438
445
|
touched: i[e.key] ?? !1,
|
|
439
446
|
props: {
|
|
440
447
|
id: g,
|
|
441
448
|
name: e.key,
|
|
442
449
|
key: e.key,
|
|
443
|
-
value:
|
|
450
|
+
value: o,
|
|
444
451
|
type: f,
|
|
445
452
|
required: e.required,
|
|
446
453
|
placeholder: e.placeholder,
|
|
447
|
-
oninput:
|
|
448
|
-
onchange:
|
|
449
|
-
onblur:
|
|
454
|
+
oninput: s,
|
|
455
|
+
onchange: c,
|
|
456
|
+
onblur: l
|
|
450
457
|
}
|
|
451
458
|
};
|
|
452
459
|
})), { submitEvent: T, isFormSubmitting: E, onBeforeSubmit: D, onSuccess: O, onError: k, submitStarted: A, validationErrorsReceived: j } = v({
|
|
@@ -461,20 +468,20 @@ function b(e, t, r, i) {
|
|
|
461
468
|
return o({
|
|
462
469
|
clock: A,
|
|
463
470
|
fn: () => ({}),
|
|
464
|
-
target:
|
|
471
|
+
target: b
|
|
465
472
|
}), o({
|
|
466
473
|
clock: A,
|
|
467
474
|
fn: () => ({}),
|
|
468
|
-
target:
|
|
475
|
+
target: x
|
|
469
476
|
}), o({
|
|
470
477
|
clock: j,
|
|
471
478
|
source: p,
|
|
472
479
|
fn: (e, t) => Object.fromEntries(t.map((t) => [e.find((e) => e.key === t.fieldKey)?.key ?? t.fieldKey, t])),
|
|
473
|
-
target:
|
|
480
|
+
target: x
|
|
474
481
|
}), {
|
|
475
482
|
form: {
|
|
476
483
|
props: { onsubmit: T },
|
|
477
|
-
errors:
|
|
484
|
+
errors: S,
|
|
478
485
|
submitting: E,
|
|
479
486
|
onBeforeSubmit: D,
|
|
480
487
|
onSuccess: O,
|
|
@@ -484,4 +491,4 @@ function b(e, t, r, i) {
|
|
|
484
491
|
};
|
|
485
492
|
}
|
|
486
493
|
//#endregion
|
|
487
|
-
export { l as buildResponsesFromFormData, m as createFieldEvaluator, g as createFieldValidation,
|
|
494
|
+
export { l as buildResponsesFromFormData, m as createFieldEvaluator, g as createFieldValidation, w as createForm, v as createSubmitPipeline, y as getEventValue, p as getStepFields };
|