@picked/client 0.0.101-next.1 → 0.0.101-next.3

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 (147) hide show
  1. package/README.md +34 -158
  2. package/dist/{api-DThEBKPu.cjs → api-9o_emCM5.cjs} +1 -1
  3. package/dist/{api-DcXndm41.js → api-BbQt8aW3.js} +1 -1
  4. package/dist/cjs/index.js +2 -2
  5. package/dist/cjs/plugins/dynamic-experiences/index.js +1 -1
  6. package/dist/cjs/server/index.js +1 -1
  7. package/dist/esm/index.js +2 -2
  8. package/dist/esm/plugins/dynamic-experiences/index.js +2 -2
  9. package/dist/esm/server/index.js +2 -2
  10. package/dist/{plugin-DA34qpbe.cjs → plugin-I8_6ncy_.cjs} +1 -1
  11. package/dist/{plugin-BZPx7WhX.js → plugin-uZJ45vK6.js} +2 -2
  12. package/dist/{preview-unavailable-sDBBJFrE.cjs → preview-unavailable-BUNxTYLe.cjs} +1 -1
  13. package/dist/{preview-unavailable-Bg8UuQeR.js → preview-unavailable-BYFD2a58.js} +1 -1
  14. package/dist/{provider-BkN7A93w.cjs → provider-Bzi_Kb-n.cjs} +1 -1
  15. package/dist/{provider-DRNHPacW.js → provider-CQKp0iUJ.js} +1 -1
  16. package/package.json +5 -5
  17. package/dist/docs/_root.css +0 -101
  18. package/dist/docs/explanation/conditions-and-the-logic-engine.md +0 -94
  19. package/dist/docs/explanation/content-references.md +0 -99
  20. package/dist/docs/explanation/feature-flag-allocation.md +0 -218
  21. package/dist/docs/explanation/how-picked-works.md +0 -124
  22. package/dist/docs/explanation/how-pickedql-works.md +0 -76
  23. package/dist/docs/explanation/pages-and-flows.md +0 -64
  24. package/dist/docs/explanation/the-content-model.md +0 -87
  25. package/dist/docs/explanation/the-two-apis.md +0 -68
  26. package/dist/docs/explanation/why-server-side-rendering.md +0 -76
  27. package/dist/docs/explanation/workspaces-and-versions.md +0 -71
  28. package/dist/docs/how-to/add-a-step-field-or-action.md +0 -43
  29. package/dist/docs/how-to/analytics/index.md +0 -316
  30. package/dist/docs/how-to/archive-or-delete-a-workspace.md +0 -46
  31. package/dist/docs/how-to/authenticate-the-cli.md +0 -101
  32. package/dist/docs/how-to/authenticate-with-a-magic-link.md +0 -47
  33. package/dist/docs/how-to/authenticate-with-a-password.md +0 -59
  34. package/dist/docs/how-to/authenticate-with-an-api-key.md +0 -51
  35. package/dist/docs/how-to/authenticate-with-oauth.md +0 -40
  36. package/dist/docs/how-to/build-a-flow.md +0 -93
  37. package/dist/docs/how-to/call-an-external-api-from-a-workflow.md +0 -102
  38. package/dist/docs/how-to/connect-the-mcp-server.md +0 -46
  39. package/dist/docs/how-to/create-a-content-entry.md +0 -48
  40. package/dist/docs/how-to/create-a-project.md +0 -29
  41. package/dist/docs/how-to/create-an-experience.md +0 -42
  42. package/dist/docs/how-to/create-and-revoke-an-api-key.md +0 -42
  43. package/dist/docs/how-to/debug-with-the-chrome-extension.md +0 -57
  44. package/dist/docs/how-to/define-a-page-layout.md +0 -46
  45. package/dist/docs/how-to/fill-and-publish-a-page.md +0 -66
  46. package/dist/docs/how-to/install-the-gtm-template.md +0 -84
  47. package/dist/docs/how-to/install-the-sdk.md +0 -93
  48. package/dist/docs/how-to/install-the-vite-plugin.md +0 -69
  49. package/dist/docs/how-to/invite-and-remove-members.md +0 -35
  50. package/dist/docs/how-to/point-one-entry-at-another.md +0 -61
  51. package/dist/docs/how-to/preview-a-workspace.md +0 -28
  52. package/dist/docs/how-to/publish-a-workspace.md +0 -30
  53. package/dist/docs/how-to/read-a-feature-flag.md +0 -113
  54. package/dist/docs/how-to/read-a-referenced-entry.md +0 -109
  55. package/dist/docs/how-to/register-a-component.md +0 -55
  56. package/dist/docs/how-to/register-an-action-handler.md +0 -85
  57. package/dist/docs/how-to/register-an-api-that-uses-oauth2.md +0 -107
  58. package/dist/docs/how-to/render-a-step-form.md +0 -131
  59. package/dist/docs/how-to/render-an-unpublished-preview.md +0 -41
  60. package/dist/docs/how-to/retry-a-failed-call-with-a-loop.md +0 -81
  61. package/dist/docs/how-to/reuse-a-section.md +0 -53
  62. package/dist/docs/how-to/reuse-a-step-field-or-action.md +0 -28
  63. package/dist/docs/how-to/roll-back-a-published-version.md +0 -26
  64. package/dist/docs/how-to/run-an-ab-test.md +0 -49
  65. package/dist/docs/how-to/run-code-on-a-form-submission.md +0 -125
  66. package/dist/docs/how-to/server-render-a-page.md +0 -81
  67. package/dist/docs/how-to/set-a-content-security-policy.md +0 -32
  68. package/dist/docs/how-to/set-up-mfa.md +0 -113
  69. package/dist/docs/how-to/switch-workspaces.md +0 -122
  70. package/dist/docs/how-to/upload-and-use-an-asset.mdx +0 -73
  71. package/dist/docs/how-to/validate-a-field.md +0 -52
  72. package/dist/docs/how-to/wait-for-an-action-response.md +0 -182
  73. package/dist/docs/how-to/write-a-condition.md +0 -45
  74. package/dist/docs/how-to/write-a-predicate.md +0 -60
  75. package/dist/docs/index.md +0 -59
  76. package/dist/docs/reference/dashboard/actions.mdx +0 -56
  77. package/dist/docs/reference/dashboard/api-keys.mdx +0 -38
  78. package/dist/docs/reference/dashboard/conditions.mdx +0 -42
  79. package/dist/docs/reference/dashboard/content/asset-library.mdx +0 -63
  80. package/dist/docs/reference/dashboard/content/blocks.mdx +0 -57
  81. package/dist/docs/reference/dashboard/content/content-entries.mdx +0 -95
  82. package/dist/docs/reference/dashboard/content/models.mdx +0 -108
  83. package/dist/docs/reference/dashboard/content/pages.mdx +0 -61
  84. package/dist/docs/reference/dashboard/experiences.mdx +0 -51
  85. package/dist/docs/reference/dashboard/external-apis.md +0 -169
  86. package/dist/docs/reference/dashboard/features.mdx +0 -154
  87. package/dist/docs/reference/dashboard/fields.mdx +0 -106
  88. package/dist/docs/reference/dashboard/flow-builder/canvas.mdx +0 -58
  89. package/dist/docs/reference/dashboard/flow-builder/condition-builder.md +0 -57
  90. package/dist/docs/reference/dashboard/flow-builder/keyboard-shortcuts.md +0 -72
  91. package/dist/docs/reference/dashboard/flow-builder/nodes.md +0 -63
  92. package/dist/docs/reference/dashboard/labels.md +0 -321
  93. package/dist/docs/reference/dashboard/lead-search.md +0 -224
  94. package/dist/docs/reference/dashboard/projects.mdx +0 -44
  95. package/dist/docs/reference/dashboard/reports.mdx +0 -43
  96. package/dist/docs/reference/dashboard/steps.mdx +0 -37
  97. package/dist/docs/reference/dashboard/team-management.md +0 -29
  98. package/dist/docs/reference/dashboard/workflow-runs.md +0 -142
  99. package/dist/docs/reference/dashboard/workflow-templates.md +0 -182
  100. package/dist/docs/reference/dashboard/workflow-test-runs.md +0 -77
  101. package/dist/docs/reference/dashboard/workspace-versioning.mdx +0 -30
  102. package/dist/docs/reference/dashboard/workspaces.mdx +0 -76
  103. package/dist/docs/reference/delivery-api/experience-content.md +0 -152
  104. package/dist/docs/reference/delivery-api/index.md +0 -45
  105. package/dist/docs/reference/delivery-api/preview-caching-crawling.md +0 -79
  106. package/dist/docs/reference/delivery-api/project-config.md +0 -65
  107. package/dist/docs/reference/delivery-api/workspace-schema.md +0 -107
  108. package/dist/docs/reference/glossary.md +0 -201
  109. package/dist/docs/reference/management-api/authentication.md +0 -87
  110. package/dist/docs/reference/management-api/authorization-and-scopes.md +0 -291
  111. package/dist/docs/reference/management-api/error-handling.md +0 -232
  112. package/dist/docs/reference/management-api/pagination.md +0 -192
  113. package/dist/docs/reference/pickedql/data-sources.md +0 -174
  114. package/dist/docs/reference/pickedql/dimensions.md +0 -103
  115. package/dist/docs/reference/pickedql/filtering.md +0 -64
  116. package/dist/docs/reference/pickedql/index.md +0 -18
  117. package/dist/docs/reference/pickedql/schema.md +0 -172
  118. package/dist/docs/reference/pickedql/virtual-functions.md +0 -248
  119. package/dist/docs/reference/sdk/actions.md +0 -154
  120. package/dist/docs/reference/sdk/analytics-events.md +0 -453
  121. package/dist/docs/reference/sdk/conditions.md +0 -147
  122. package/dist/docs/reference/sdk/content-security-policy.md +0 -21
  123. package/dist/docs/reference/sdk/content.md +0 -253
  124. package/dist/docs/reference/sdk/experiences.md +0 -51
  125. package/dist/docs/reference/sdk/features.md +0 -256
  126. package/dist/docs/reference/sdk/fields.md +0 -255
  127. package/dist/docs/reference/sdk/index.md +0 -68
  128. package/dist/docs/reference/sdk/plugins/create-experience.md +0 -123
  129. package/dist/docs/reference/sdk/plugins/dynamic-experiences.md +0 -74
  130. package/dist/docs/reference/sdk/plugins/index.md +0 -29
  131. package/dist/docs/reference/sdk/plugins/window-object.md +0 -25
  132. package/dist/docs/reference/sdk/predicates.md +0 -43
  133. package/dist/docs/reference/sdk/ssr/index.md +0 -33
  134. package/dist/docs/reference/sdk/ssr/rendering-and-hydration.md +0 -103
  135. package/dist/docs/reference/sdk/ssr/serialize.md +0 -80
  136. package/dist/docs/reference/sdk/ssr/slots-and-placements.md +0 -113
  137. package/dist/docs/reference/sdk/steps.md +0 -86
  138. package/dist/docs/reference/sdk/type-generation.md +0 -265
  139. package/dist/docs/reference/tools/chrome-extension.md +0 -16
  140. package/dist/docs/reference/tools/cli.md +0 -292
  141. package/dist/docs/reference/tools/image-optimisation-service.md +0 -104
  142. package/dist/docs/reference/tools/mcp.md +0 -136
  143. package/dist/docs/reference/tools/vite-plugin.md +0 -163
  144. package/dist/docs/tutorials/first-api-call.md +0 -235
  145. package/dist/docs/tutorials/first-experience-in-the-dashboard.mdx +0 -143
  146. package/dist/docs/tutorials/first-experience.mdx +0 -254
  147. package/dist/docs/tutorials/first-server-rendered-page.mdx +0 -186
@@ -1,172 +0,0 @@
1
- ---
2
- type: reference
3
- layout: docs
4
- ---
5
-
6
- # Schema
7
-
8
- Column reference for each PickedQL data source.
9
-
10
- ## `metrics`
11
-
12
- Pre-aggregated daily data. One row per unique combination of dimensions per day.
13
-
14
- | Column | Type | Description |
15
- |---|---|---|
16
- | `project_id` | `String` | Project identifier (required in `WHERE`) |
17
- | `project_local_date` | `Date` | Date in project timezone |
18
- | `experience_id` | `String` | Experience identifier |
19
- | `step_id` | `String` | Step identifier |
20
- | `event_type` | `String` | Event type (for example `page_view`, `click`) |
21
- | `interaction_type` | `String` | Interaction type (for example `Button Click`) |
22
- | `variant_type` | `String` | `Control`, `Variant`, or `Unknown` |
23
- | `device_category` | `String` | Device category (for example `Desktop`, `Mobile`) |
24
- | `country_code` | `String` | ISO country code |
25
- | `utm_source` | `String` | UTM source |
26
- | `utm_medium` | `String` | UTM medium |
27
- | `product_name` | `String` | Product name |
28
- | `product_category` | `String` | Product category |
29
- | `landing_page_url` | `String` | Landing page URL |
30
-
31
- :::note
32
- Aggregate columns (`users`, `sessions`, `events`, and so on) are not queried directly — use [virtual functions](/reference/pickedql/virtual-functions) instead.
33
- :::
34
-
35
- ## `events`
36
-
37
- User-level event data. One row per event per user. Dimension columns are joined automatically when referenced.
38
-
39
- ### Native columns
40
-
41
- | Column | Type | Description |
42
- |---|---|---|
43
- | `project_id` | `String` | Project identifier (required in `WHERE`) |
44
- | `event_id` | `String` | Unique event identifier |
45
- | `user_canonical_id` | `String` | Canonical user identifier |
46
- | `session_id` | `String` | Session identifier |
47
- | `experience_id` | `String` | Experience identifier |
48
- | `step_id` | `String` | Step identifier |
49
- | `event_type` | `String` | Event type (for example `page_view`, `click`) |
50
- | `interaction_type` | `String` | Interaction type (for example `Button Click`) |
51
- | `client_local_date` | `Date` | Date in client timezone |
52
- | `is_purchase` | `UInt8` | `1` if checkout complete event |
53
- | `is_cart_add` | `UInt8` | `1` if cart add event |
54
- | `is_first_session` | `UInt8` | `1` if first session for this user |
55
- | `landing_page_url` | `String` | Landing page URL |
56
- | `features` | Map(String, String) | Feature flag assignments |
57
- | `feature_keys` | Map(String, String) | Feature key assignments |
58
- | `event_meta` | `String` | Event metadata |
59
-
60
- ### Dimension columns (auto-joined)
61
-
62
- These columns are joined automatically when referenced — no `JOIN` syntax needed.
63
-
64
- | Column | Source | Description |
65
- |---|---|---|
66
- | `variant_type` | `dim_variant` | `Control`, `Variant`, or `Unknown` |
67
- | `ab_feature_name` | `dim_variant` | A/B feature name |
68
- | `ab_feature_value` | `dim_variant` | A/B feature value |
69
- | `device_category` | `dim_device` | Device category |
70
- | `browser_name` | `dim_device` | Browser name |
71
- | `browser_version` | `dim_device` | Browser version |
72
- | `os_name` | `dim_device` | The name of the operating system |
73
- | `os_version` | `dim_device` | The version of the operating system |
74
- | `platform` | `dim_device` | Platform |
75
- | `country_code` | `dim_geo` | ISO country code |
76
- | `country_name` | `dim_geo` | Country name |
77
- | `region` | `dim_geo` | Region |
78
- | `city` | `dim_geo` | City |
79
- | `utm_source` | `dim_utm` | UTM source |
80
- | `utm_medium` | `dim_utm` | UTM medium |
81
- | `utm_campaign` | `dim_utm` | UTM campaign |
82
- | `utm_term` | `dim_utm` | UTM term |
83
- | `utm_content` | `dim_utm` | UTM content |
84
- | `product_name` | `dim_product` | Product name |
85
- | `product_category` | `dim_product` | Product category |
86
- | `product_page` | `dim_product` | Product page |
87
- | `step_title` | `steps` | Step title (joined on `project_id` + `experience_id` + `step_id`) |
88
- | `experience_title` | `experiences` | Experience title (joined on `project_id` + `experience_id`) |
89
- | `project_name` | `projects` | Project name |
90
- | `project_timezone` | `projects` | Project timezone |
91
-
92
- ## `steps`, `experiences`, `projects`
93
-
94
- These reference tables hold the configuration of your Picked project. PickedQL joins them
95
- onto `events` when you point at one of their analyst-facing columns. Each one needs
96
- its own tenant filter when you read it directly.
97
-
98
- | Source | Real columns | Analyst columns, when you point at them from `events` | Tenant filter, when you read the table directly |
99
- |---|---|---|---|
100
- | `steps` | `id`, `title`, `experience_id`, `project_id`, `organization_id` | `step_title` | `project_id = '…'` |
101
- | `experiences` | `id`, `title`, `project_id`, `organization_id` | `experience_title` | `project_id = '…'` |
102
- | `projects` | `id`, `name`, `timezone`, `organization_id` | `project_name`, `project_timezone` | `id = '<project_id>'` |
103
-
104
- When queried directly, use the real column names:
105
-
106
- ```sql
107
- -- List all experiences for a project
108
- SELECT id, title FROM experiences WHERE project_id = 'your-project-id'
109
- ```
110
-
111
- When referenced from `events`, use the prefixed analyst names — joins are injected automatically:
112
-
113
- ```sql
114
- SELECT experience_title, step_title, count(*)
115
- FROM events
116
- WHERE project_id = 'your-project-id'
117
- GROUP BY experience_title, step_title
118
- ```
119
-
120
- ## `features`
121
-
122
- The `features` table gives you
123
- [parameterized virtual functions](/reference/pickedql/virtual-functions#feature-functions-on-features-and-on-events).
124
- Use them to read which visitors each feature flag holds:
125
-
126
- | Function | Description |
127
- |---|---|
128
- | `feature_users('name', 'bucket' [, 'key'])` | Unique users in a feature bucket |
129
- | `feature_sessions('name', 'bucket' [, 'key'])` | Unique sessions in a feature bucket |
130
- | `feature_events('name', 'bucket' [, 'key'])` | Unique events in a feature bucket |
131
-
132
- ## `experience_journey`
133
-
134
- This table gives one edge for each step transition, and PickedQL aggregates them
135
- first. Use the edges in a sankey chart or a funnel chart. Give each parameter in the
136
- outer `WHERE` clause. PickedQL reads them and puts them into the query below.
137
-
138
- ### Columns
139
-
140
- | Column | Type | Description |
141
- |---|---|---|
142
- | `source` | `String` | Edge start, formatted as `NN. <step title>` (for example `001. Welcome screen`) |
143
- | `target` | `String` | Edge end, formatted as `NN. <step title>`.
144
- | `users` | `UInt64` | Distinct `user_canonical_id` count that traversed this edge. |
145
-
146
- ### Parameters, in the `WHERE` clause
147
-
148
- | Key | Type | Required | Purpose |
149
- |---|---|---|---|
150
- | `project_id` | `String` | ✓ | The tenant filter. |
151
- | `experience_id` | `String` | | Limits the rows to one `fact_events.experience_id`. |
152
- | `starting_step` | `String` | | Anchors each edge at the first time that a user reaches this `step_id`. The default is the first step of each user. |
153
- | `targeting_step` | `String` | | Trims the window of each user at the first time that the user reaches this `step_id`. A user who never reaches it still gives the journey up to that point. |
154
- | `num_nodes_after_start` | Integer | | The forward window from the start. It keeps a step where `seq_pos < start_seq + N`. |
155
- | `num_nodes_before_target` | Integer | | The backward window from the target. It keeps a step where `seq_pos >= target_seq - N`. It needs `targeting_step`. |
156
- | `top_n_path` | Integer | | Keeps the paths that the most users take, and drops the rest. The default is no limit. |
157
- | `user_cohort_event` | `String` | | Limits the rows to a user with at least one `fact_events` row of this `event_type`. PickedQL writes it as `user_canonical_id IN (SELECT DISTINCT user_canonical_id FROM fact_events WHERE event_type = '…')`. |
158
- | `client_local_date` | `Date` | | A filter on a range of dates. PickedQL puts it into the read below. It takes `=`, `<`, `<=`, `>`, `>=`, and `BETWEEN`. |
159
- | `event_timestamp` | `DateTime64` | | A filter on the timestamp from the server. It takes the same operators as `client_local_date`. |
160
-
161
- When you set both window parameters, both tests apply, and the result is their
162
- intersection. A date filter joins the other parameters with `AND`.
163
-
164
- See
165
- [data sources, `experience_journey`](/reference/pickedql/data-sources#experience_journey--step-transitions-for-a-sankey-chart)
166
- for examples.
167
-
168
- ## Related
169
-
170
- - [Data sources](/reference/pickedql/data-sources)
171
- - [Dimensions](/reference/pickedql/dimensions)
172
- - [About PickedQL](/explanation/how-pickedql-works)
@@ -1,248 +0,0 @@
1
- ---
2
- type: reference
3
- layout: docs
4
- ---
5
-
6
- # Virtual functions
7
-
8
- A virtual function is a short form of an aggregate expression. Each one is
9
- **table-aware**. The same function expands one way on `metrics`, where PickedQL
10
- aggregates the data first. It expands another way on `events`, where there is one row
11
- for each user.
12
-
13
- ## A/B test metrics
14
-
15
- | Function | Description |
16
- |---|---|
17
- | `control_users([condition])` | The different users in the Control group. A condition of your own can narrow them. |
18
- | `variant_users([condition])` | The different users in the Variant group. A condition of your own can narrow them. |
19
- | `all_users()` | Every different user |
20
- | `control_sessions([condition])` | The different sessions in the Control group. A condition of your own can narrow them. |
21
- | `variant_sessions([condition])` | The different sessions in the Variant group. A condition of your own can narrow them. |
22
- | `all_sessions()` | Every different session |
23
-
24
- ### Your own filters on `events`
25
-
26
- On the `events` table, each `control_*` function and each `variant_*` function takes
27
- **one optional filter argument**. The filter counts only a user or a session that
28
- matches your expression. It applies together with the `variant_type` filter that
29
- PickedQL adds. Give the argument in the first place, or by the name `filter=`.
30
-
31
- The filter uses the same `column=value` syntax as a conversion-rate condition. It
32
- takes the `AND` and `OR` operators, and parentheses can hold a set of terms.
33
-
34
- ```sql
35
- -- The default: every Control user.
36
- SELECT control_users() FROM events
37
-
38
- -- Your own filter, in the first place.
39
- SELECT control_users('event_type=app_initialize') FROM events
40
- SELECT variant_users('event_type=app_initialize AND step_id=xxx') FROM events
41
-
42
- -- The AND and OR operators, with parentheses.
43
- SELECT control_users('event_type=app_initialize OR event_type=app_load') FROM events
44
- SELECT control_users('event_type=form_submit AND (step_id=lead-capture OR step_id=xxx)') FROM events
45
-
46
- -- Sessions
47
- SELECT control_sessions('event_type=step_enter') FROM events
48
- SELECT variant_sessions('event_type=step_enter AND step_id=checkout') FROM events
49
-
50
- -- Named form
51
- SELECT control_users(filter='event_type=app_initialize AND step_id=xxx') FROM events
52
- ```
53
-
54
- :::note
55
- A filter of your own is **not supported on `metrics`**, because PickedQL aggregates
56
- that data first. On `metrics` these functions ignore every argument. They use the
57
- default Control filter and Variant filter only.
58
- :::
59
-
60
- ## Conversion metrics
61
-
62
- | Function | Description |
63
- |---|---|
64
- | `all_purchase_users()` | Users who completed a purchase |
65
- | `control_purchase_users()` | Control users who purchased (`metrics` only) |
66
- | `variant_purchase_users()` | Variant users who purchased (`metrics` only) |
67
- | `all_purchase_sessions()` | Sessions with a purchase (`metrics` only) |
68
- | `all_purchase_orders()` | Unique order count (`metrics` only) |
69
- | `all_cart_add_users()` | Users who added to cart |
70
-
71
- ## Conversion rates
72
-
73
- | Function | Description |
74
- |---|---|
75
- | `control_conversion_rate([numerator [, denominator]])` | The conversion rate of the Control group. By default it divides the users with a purchase by all users. |
76
- | `variant_conversion_rate([numerator [, denominator]])` | The conversion rate of the Variant group. It takes the same arguments. |
77
- | `conversion_rate_uplift([numerator [, denominator]])` | The gain of the Variant over the Control: `(variant CR - control CR) / control CR`. It takes the same arguments. |
78
-
79
- ### Your own conditions on `events`
80
-
81
- On the `events` table, each conversion-rate function takes up to **two optional
82
- arguments**. They set the numerator and the denominator. Each argument is either a
83
- **condition expression string** or a **nested virtual function call**. See below.
84
- Give the arguments in order, or by the names `numerator=` and `denominator=`.
85
-
86
- Each condition expression uses `column=value`, with the `AND` and `OR` operators.
87
- Parentheses can hold a set of terms.
88
-
89
- ```sql
90
- -- Default: purchase users / all users
91
- SELECT control_conversion_rate() FROM events
92
-
93
- -- Custom numerator, default denominator (all users)
94
- SELECT control_conversion_rate('event_type=form_submit_success') FROM events
95
-
96
- -- The AND and OR operators in a condition.
97
- SELECT control_conversion_rate('event_type=checkout_complete OR event_type=order_create') FROM events
98
- SELECT control_conversion_rate('step_id=lead-capture AND event_type=form_submit_success') FROM events
99
-
100
- -- Parentheses hold a set of terms.
101
- SELECT control_conversion_rate('event_type=form_submit AND (step_id=lead-capture OR step_id=xxx)') FROM events
102
-
103
- -- Custom numerator AND denominator (positional)
104
- SELECT control_conversion_rate('event_type=form_submit', 'step_id=lead-capture') FROM events
105
-
106
- -- Named arguments (explicit, any order)
107
- SELECT control_conversion_rate(numerator='event_type=form_submit', denominator='step_id=lead-capture') FROM events
108
-
109
- -- Named: denominator only (numerator defaults to purchase)
110
- SELECT control_conversion_rate(denominator='step_id=lead-capture') FROM events
111
-
112
- -- The uplift, with the arguments given by name.
113
- SELECT conversion_rate_uplift(numerator='event_type=form_submit', denominator='step_id=lead-capture') FROM events
114
- ```
115
-
116
- #### A nested virtual function as the numerator or the denominator
117
-
118
- You can pass a **virtual function call** as the numerator or the denominator, in
119
- place of a condition string. PickedQL puts the inner aggregate there directly. It
120
- adds no `variant_type` filter above it, because the nested function sets its own
121
- filter.
122
-
123
- This form is the most flexible one when the numerator and the denominator come from
124
- different segments. An example is the Control users who fired one event, over **all**
125
- users of every variant:
126
-
127
- ```sql
128
- -- The Control users who fired `app_initialize`, over all users.
129
- SELECT control_conversion_rate(
130
- control_users('event_type=app_initialize'),
131
- all_users()
132
- ) FROM events
133
-
134
- -- Mix string and nested forms
135
- SELECT control_conversion_rate(
136
- 'event_type=form_submit',
137
- all_users()
138
- ) FROM events
139
-
140
- -- The uplift, with a nested function in each place.
141
- SELECT conversion_rate_uplift(
142
- control_users('event_type=app_initialize'),
143
- all_users()
144
- ) FROM events
145
- ```
146
-
147
- :::note
148
- A condition of your own, and a nested virtual function, are both **not supported on
149
- `metrics`**, because PickedQL aggregates that data first. On `metrics` these
150
- functions always divide the users with a purchase by all users.
151
- :::
152
-
153
- ## Visitor segmentation (`metrics` only)
154
-
155
- | Function | Description |
156
- |---|---|
157
- | `new_users()` | First-time visitors |
158
- | `returning_users()` | Returning visitors |
159
- | `new_sessions()` | Sessions from new visitors |
160
- | `returning_sessions()` | Sessions from returning visitors |
161
-
162
- ## Funnel metrics (`events` only)
163
-
164
- :::note
165
- We add to the funnel metrics all the time. Read this page again for a new function.
166
- :::
167
-
168
- | Function | Description |
169
- |---|---|
170
- | `step_enter_users()` | Users who entered a funnel step |
171
- | `step_enter_sessions()` | Sessions that entered a funnel step |
172
-
173
- ## Cohort filters (`events` only)
174
-
175
- Each of these functions has the shape of a predicate. It writes a
176
- `user_canonical_id IN (SELECT … FROM events …)` subquery. Put one in a `WHERE` clause
177
- to limit any analysis to a user with at least one event that matches a condition of
178
- your own.
179
-
180
- | Function | Description |
181
- |---|---|
182
- | `user_cohort_filter('<condition>')` | Limits the query to a user with one or more `events` rows that match `<condition>` |
183
- | `user_cohort_filter(filter='<condition>')` | The same, with the argument given by name |
184
-
185
- `<condition>` uses the same short `column=value [AND\|OR …]` form as `control_users`
186
- and `variant_users`.
187
-
188
- ```sql
189
- -- Funnel scoped to users who eventually submitted lead capture
190
- SELECT all_users(), all_purchase_users()
191
- FROM events
192
- WHERE project_id = 'proj-abc'
193
- AND user_cohort_filter('event_type=lead_capture')
194
-
195
- -- Multi-condition cohort with OR-grouping
196
- SELECT all_sessions()
197
- FROM events
198
- WHERE project_id = 'proj-abc'
199
- AND user_cohort_filter('event_type=signup OR event_type=trial_start')
200
- ```
201
-
202
- The outer query MUST hold one `project_id` filter. The function puts that tenant into
203
- the inner subquery. The read of the cohort therefore covers your project, and not the
204
- whole warehouse.
205
-
206
- ## Feature functions, on `features` and on `events`
207
-
208
- Parameterized functions that accept the feature name, bucket, and an optional feature key:
209
-
210
- | Function | Description |
211
- |---|---|
212
- | `feature_users('name', 'bucket' [, 'key'])` | Unique users in a feature bucket |
213
- | `feature_sessions('name', 'bucket' [, 'key'])` | Unique sessions in a feature bucket |
214
- | `feature_events('name', 'bucket' [, 'key'])` | Unique events in a feature bucket |
215
-
216
- The bucket is what the SDK sent to the site of the visitor. A Boolean feature flag gives
217
- `'true'` or `'false'`. A Text feature flag gives the value of one variant, or `'false'` for
218
- the control group. The key is the version of the feature flag, such as `'v1'`.
219
-
220
- ```sql
221
- -- Compare the two buckets of a Boolean feature flag.
222
- SELECT
223
- feature_users('homepage_test', 'false') AS control,
224
- feature_users('homepage_test', 'true') AS variant
225
- FROM features
226
-
227
- -- Compare the variants of a Text feature flag.
228
- SELECT
229
- feature_users('hero', 'false') AS control,
230
- feature_users('hero', 'hero-a') AS hero_a,
231
- feature_users('hero', 'hero-b') AS hero_b
232
- FROM features
233
-
234
- -- Count one version of the feature flag alone.
235
- SELECT feature_users('homepage_test', 'false', 'v1') FROM features
236
- ```
237
-
238
- ## Other (`metrics` only)
239
-
240
- | Function | Description |
241
- |---|---|
242
- | `event_count()` | Total event count (from pre-aggregation) |
243
-
244
- ## Related
245
-
246
- - [Filters](/reference/pickedql/filtering) — the filter string a function takes.
247
- - [Analytics queries](/how-to/analytics)
248
- - [About PickedQL](/explanation/how-pickedql-works)
@@ -1,154 +0,0 @@
1
- ---
2
- type: reference
3
- layout: docs
4
- ---
5
-
6
- # Actions
7
-
8
- An action is a function that the SDK runs by its key. An action comes from one of two
9
- places:
10
-
11
- - **Your application** registers a handler in `createClient({ actions })`.
12
- - **Your project** publishes the action. Its handler sends the visitor's answers to Picked,
13
- and the workflow of the action runs there.
14
-
15
- A handler from your application replaces a published action that has the same key. The
16
- workflow then does not start.
17
-
18
- ## Response
19
-
20
- The value that a handler returns is the response of the action. A handler can return any
21
- value, or a promise of any value.
22
-
23
- The response of a published action is the payload of the **Action response** node in its
24
- workflow. A workflow that has no **Action response** node gives `undefined`.
25
-
26
- ## Outcome and branch
27
-
28
- | Handler outcome | Branch the flow takes |
29
- | --- | --- |
30
- | Throws, or its promise rejects | `onFail` |
31
- | Resolves to any value, and that includes `false` | `onSuccess` |
32
-
33
- An action node can also carry one plain connection, with no success or failure branch. The
34
- flow then continues through it on either outcome.
35
-
36
- An action does not interrupt your visitor. The current step stays on the screen while an
37
- async action runs. While the action runs, the flow ignores a request to go to the next step
38
- or to a specified step. The outcome of the action then chooses the branch. If your visitor
39
- goes back before the action completes, the flow stays on that step. The signal that the
40
- handler receives then stops.
41
-
42
- ## Published actions
43
-
44
- A published action waits for the response of its workflow. It stops after 30 seconds.
45
-
46
- | Cause | The action rejects with |
47
- | --- | --- |
48
- | Picked refuses the request | An `Error` that names the HTTP status |
49
- | Picked does not accept the request in 25 seconds | A `TimeoutError` |
50
- | Picked accepts the request, but gives no run to wait for | An `Error` that says that no run is available |
51
- | The workflow fails before it sends a response | `ActionRunFailedError` |
52
- | Picked refuses a request for the response with a `4xx` status | An `Error` that names the HTTP status |
53
- | No response in 30 seconds | `ActionResponseTimeoutError` |
54
- | Your code stops the wait with a signal | The reason of the signal |
55
-
56
- A request for the response can fail because of a network error, a timeout, a `5xx` status or
57
- a body that the SDK cannot read. The SDK then sends the request again. It waits 1 second after
58
- the first failure, and two times longer after each failure that follows. If the requests
59
- continue to fail, the 30-second limit stops the wait with `ActionResponseTimeoutError`.
60
-
61
- To identify `ActionRunFailedError` and `ActionResponseTimeoutError` with `instanceof`, import
62
- them from `@picked/client/plugins/dynamic-experiences`. The `name` of each error is the same
63
- as the name that you import.
64
-
65
- ## Run an action from code
66
-
67
- | API | Returns | Rejects |
68
- | --- | --- | --- |
69
- | `client.actions.run(key, options)` | A promise of the response | Yes, with the error of the action |
70
- | `useAction(key, options)` (React) | For an action that starts a workflow: `{ run, status, response, error }`. For other actions: the action as a function. | `run`: No. The function: it returns or throws what the action returns or throws. |
71
- | `getAction(key, options)` (Svelte) | A store of the same value | The same as `useAction` |
72
- | `useActionResult(key, options)` (React) | The last result of your own action | No |
73
- | `getActionResult(key, options)` (Svelte) | A store of the last result of your own action | No |
74
- | `client.actions.getActionBinding(key, options)` | A store of the value that `useAction` and `getAction` give | The same as `useAction` |
75
- | `client.actions.getActionResult(key, options)` | A store of the last result of your own action, which `useActionResult` and `getActionResult` read | No |
76
-
77
- Type generation names the actions that start a workflow (`WorkflowActionKeys`). Without generated
78
- types, `useAction` and `getAction` give the action as a function. For each key, the value also
79
- includes `run`, `status`, `response` and `error`.
80
-
81
- The handler receives the arguments of a call to the function in `args`. It also receives the
82
- arguments of `run(...args)` in `args`.
83
-
84
- `status` is `idle`, `running`, `succeeded` or `failed`, for the last run. When a run starts,
85
- `response` and `error` are `undefined`. `run(...args)` resolves to
86
- `{ status: 'succeeded', response }` or to `{ status: 'failed', error }`.
87
-
88
- The SDK keeps one run state for each key and experience. All the components that use the
89
- same key and the same experience share that run state, and they show the same last run. When
90
- one of them calls `run`, all of them show that run.
91
-
92
- `useActionResult` and `getActionResult` run your own action again when a response, a field or
93
- the handler of the action changes. They also run it when a component that reads the result
94
- starts. In React, the action runs when the component mounts, and when an `<Activity>` shows the
95
- component again. In Svelte, it runs each time a component calls `getActionResult`. A change that
96
- occurs outside Picked, for example a login, then shows in a component that starts after the
97
- change.
98
-
99
- The components that read the same key and the same experience share one result. The action
100
- runs one time for each change. It also runs one time for the components that React renders
101
- together. React can stop while it renders and continue later, for example in a transition. Then
102
- the components that React renders after it continues run the action again.
103
-
104
- The result is always from the run that started last. If that run throws, the result is
105
- `undefined`. For a published action they give `undefined` and do not send a request. The types
106
- refuse the key of an action that starts a workflow.
107
-
108
- A result for an experience follows the changes only while `client.experienceInstances`
109
- contains that experience. When `client.experienceInstances` adds the experience, the action
110
- runs if a response, a field or the handler changed after the last run.
111
-
112
- The options of `client.actions.run`:
113
-
114
- | Option | Type | Description |
115
- | --- | --- | --- |
116
- | `args` | `unknown[]` | The values that the handler receives in `args`. |
117
- | `experience` | `ExperienceInstance` | The experience that the handler receives as `context.experience`. |
118
- | `signal` | `AbortSignal` | Stops the wait. The handler receives a signal that stops too. |
119
- | `timeoutMs` | `number` | Stops the wait after this many milliseconds, with a `TimeoutError`. |
120
-
121
- `useAction` and `getAction` take `experience` only.
122
-
123
- ## Other methods of `client.actions`
124
-
125
- | Method | Description |
126
- | --- | --- |
127
- | `refreshActionResult(key, options)` | Runs your own action again for the result that `getActionResult` gives. It does nothing until a component or your code reads that result. The calls in one task start one run. |
128
- | `isPublished(key)` | Returns `true` when the handler of the key is a published action. |
129
- | `unregister(key)` | Removes the handler of the key. If the key has no handler, nothing changes. |
130
-
131
- `refreshActionResult` and `getActionResult` take `experience` only.
132
-
133
- ## Rule logic
134
-
135
- A rule reads the response of an action with `{ "invoke": [{ "var": "actions.<key>" }] }`. A
136
- response that is a string, a number, a Boolean, `null`, or an array or object of these
137
- reaches the rule. A different response reaches the rule as `undefined`.
138
-
139
- A rule runs the action each time the SDK evaluates the rule.
140
-
141
- A condition node can have a rule that runs an action. While the condition node waits for that
142
- rule, the flow ignores a request to go to the next step or to a specified step. The result of
143
- the rule then chooses the branch. If your visitor goes back before the rule has a result, the
144
- flow ignores the result.
145
-
146
- ## Related
147
-
148
- - [How to wait for the response of an action](/how-to/wait-for-an-action-response) — show
149
- the response in a component.
150
- - [How to register an action handler](/how-to/register-an-action-handler) — the handler,
151
- and when to throw.
152
- - [About how Picked works](/explanation/how-picked-works#how-an-action-decides-which-way-to-go)
153
- — why a returned `false` is a success.
154
- - [Actions](/reference/dashboard/actions) — the dashboard options.