@picked/client 0.0.1-dev.1788925875333 → 0.0.1-next.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +8 -0
- package/dist/cjs/index.js +1 -4
- package/dist/cjs/plugins/create-experience/index.js +1 -1
- package/dist/cjs/plugins/experience-browserstorage-plugin/index.js +1 -0
- package/dist/cjs/plugins/history-browserstorage-plugin/index.js +1 -0
- package/dist/cjs/plugins/responses-browserstorage-plugin/index.js +1 -0
- package/dist/cjs/plugins/responses-indexeddb-plugin/index.js +1 -0
- package/dist/cjs/plugins/shopify/index.js +1 -0
- package/dist/cjs/plugins/single-page-app/index.js +1 -1
- package/dist/cjs/plugins/window-object/index.js +1 -1
- package/dist/cjs/server/index.js +1 -1
- package/dist/esm/index.js +733 -1814
- package/dist/esm/plugins/create-experience/index.js +398 -490
- package/dist/esm/plugins/experience-browserstorage-plugin/index.js +38 -0
- package/dist/esm/plugins/history-browserstorage-plugin/index.js +26 -0
- package/dist/esm/plugins/responses-browserstorage-plugin/index.js +36 -0
- package/dist/esm/plugins/responses-indexeddb-plugin/index.js +101 -0
- package/dist/esm/plugins/shopify/index.js +59 -0
- package/dist/esm/plugins/single-page-app/index.js +35 -31
- package/dist/esm/plugins/window-object/index.js +9 -9
- package/dist/esm/server/index.js +89 -141
- package/dist/experience-instance-6ZKZS7dF.cjs +1 -0
- package/dist/experience-instance-BA0EXYg5.js +712 -0
- package/dist/id-BKIWbSTy.cjs +1 -0
- package/dist/id-BW-g3y32.js +6 -0
- package/dist/logger-BsmHUUw1.cjs +1 -0
- package/dist/logger-C9a75KZn.js +5 -0
- package/dist/object-BbFTsGh3.cjs +1 -0
- package/dist/object-JwZ58NOH.js +28 -0
- package/dist/storage-BPJwmlva.cjs +1 -0
- package/dist/storage-D87xFySf.js +85 -0
- package/dist/supports-BvrzQAVk.js +79 -0
- package/dist/supports-C0y3-V5V.cjs +1 -0
- package/dist/types/client.d.ts +23 -119
- package/dist/types/client.d.ts.map +1 -1
- package/dist/types/entities/component/component.d.ts +6 -45
- package/dist/types/entities/component/component.d.ts.map +1 -1
- package/dist/types/entities/experience/experience.d.ts +99 -152
- package/dist/types/entities/experience/experience.d.ts.map +1 -1
- package/dist/types/entities/experience-instance/experience-instance.d.ts +113 -83
- package/dist/types/entities/experience-instance/experience-instance.d.ts.map +1 -1
- package/dist/types/entities/feature/feature.d.ts +8 -118
- package/dist/types/entities/feature/feature.d.ts.map +1 -1
- package/dist/types/entities/field/field.d.ts +64 -96
- package/dist/types/entities/field/field.d.ts.map +1 -1
- package/dist/types/entities/framework/framework.d.ts +7 -32
- package/dist/types/entities/framework/framework.d.ts.map +1 -1
- package/dist/types/entities/history/history.d.ts +6 -6
- package/dist/types/entities/history/history.d.ts.map +1 -1
- package/dist/types/entities/plugin/plugin.d.ts +2 -41
- package/dist/types/entities/plugin/plugin.d.ts.map +1 -1
- package/dist/types/entities/predicate/predicate.d.ts +7 -30
- package/dist/types/entities/predicate/predicate.d.ts.map +1 -1
- package/dist/types/entities/project/project.d.ts +9 -0
- package/dist/types/entities/project/project.d.ts.map +1 -0
- package/dist/types/entities/response/response.d.ts +21 -57
- package/dist/types/entities/response/response.d.ts.map +1 -1
- package/dist/types/exports.d.ts +4 -22
- package/dist/types/exports.d.ts.map +1 -1
- package/dist/types/index.d.ts +3 -12
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/logic-engine.d.ts +11 -13
- package/dist/types/logic-engine.d.ts.map +1 -1
- package/dist/types/picked.d.ts +184 -381
- package/dist/types/picked.d.ts.map +1 -1
- package/dist/types/ping.d.ts +10 -0
- package/dist/types/ping.d.ts.map +1 -0
- package/dist/types/plugins/create-experience/create-experience.d.ts +44 -119
- package/dist/types/plugins/create-experience/create-experience.d.ts.map +1 -1
- package/dist/types/plugins/create-experience/index.d.ts +2 -2
- package/dist/types/plugins/create-experience/index.d.ts.map +1 -1
- package/dist/types/plugins/create-experience/plugin.d.ts +2 -3
- package/dist/types/plugins/create-experience/plugin.d.ts.map +1 -1
- package/dist/types/plugins/create-experience/serialization.d.ts.map +1 -1
- package/dist/types/plugins/experience-browserstorage-plugin/index.d.ts.map +1 -0
- package/dist/types/plugins/experience-browserstorage-plugin/plugin.d.ts +6 -0
- package/dist/types/plugins/experience-browserstorage-plugin/plugin.d.ts.map +1 -0
- package/dist/types/plugins/history-browserstorage-plugin/index.d.ts.map +1 -0
- package/dist/types/plugins/{history-browser-storage → history-browserstorage-plugin}/plugin.d.ts +1 -2
- package/dist/types/plugins/history-browserstorage-plugin/plugin.d.ts.map +1 -0
- package/dist/types/plugins/responses-browserstorage-plugin/index.d.ts.map +1 -0
- package/dist/types/plugins/responses-browserstorage-plugin/plugin.d.ts +6 -0
- package/dist/types/plugins/responses-browserstorage-plugin/plugin.d.ts.map +1 -0
- package/dist/types/plugins/responses-indexeddb-plugin/index.d.ts.map +1 -0
- package/dist/types/plugins/responses-indexeddb-plugin/plugin.d.ts +3 -0
- package/dist/types/plugins/responses-indexeddb-plugin/plugin.d.ts.map +1 -0
- package/dist/types/plugins/shopify/index.d.ts +2 -0
- package/dist/types/plugins/shopify/index.d.ts.map +1 -0
- package/dist/types/plugins/shopify/plugin.d.ts +3 -0
- package/dist/types/plugins/shopify/plugin.d.ts.map +1 -0
- package/dist/types/plugins/shopify/shopify.d.ts +28 -0
- package/dist/types/plugins/shopify/shopify.d.ts.map +1 -0
- package/dist/types/plugins/single-page-app/plugin.d.ts +2 -2
- package/dist/types/plugins/single-page-app/plugin.d.ts.map +1 -1
- package/dist/types/plugins/window-object/plugin.d.ts +2 -2
- package/dist/types/server/index.d.ts +3 -18
- package/dist/types/server/index.d.ts.map +1 -1
- package/dist/types/utils/dom.d.ts +6 -4
- package/dist/types/utils/dom.d.ts.map +1 -1
- package/dist/types/utils/events.d.ts +38 -83
- package/dist/types/utils/events.d.ts.map +1 -1
- package/dist/types/utils/global-obj.d.ts +2 -1
- package/dist/types/utils/global-obj.d.ts.map +1 -1
- package/dist/types/utils/id.d.ts.map +1 -1
- package/dist/types/utils/indexed-db.d.ts +1 -2
- package/dist/types/utils/indexed-db.d.ts.map +1 -1
- package/dist/types/utils/logger.d.ts +1 -2
- package/dist/types/utils/logger.d.ts.map +1 -1
- package/dist/types/utils/node-tree/get-next-node-from-conditional.d.ts +3 -0
- package/dist/types/utils/node-tree/get-next-node-from-conditional.d.ts.map +1 -0
- package/dist/types/utils/node-tree/get-next-node.d.ts +1 -1
- package/dist/types/utils/node-tree/get-next-node.d.ts.map +1 -1
- package/dist/types/utils/node-tree/get-origin-node.d.ts +1 -1
- package/dist/types/utils/node-tree/get-origin-node.d.ts.map +1 -1
- package/dist/types/utils/node-tree/min-max-steps-to-leaf.d.ts +1 -1
- package/dist/types/utils/node-tree/min-max-steps-to-leaf.d.ts.map +1 -1
- package/dist/types/utils/node-tree/min-max-steps-to-origin.d.ts +1 -1
- package/dist/types/utils/node-tree/min-max-steps-to-origin.d.ts.map +1 -1
- package/dist/types/utils/node-tree/next-reachable-step-nodes.d.ts +1 -1
- package/dist/types/utils/node-tree/next-reachable-step-nodes.d.ts.map +1 -1
- package/dist/types/utils/nodes.d.ts +2 -3
- package/dist/types/utils/nodes.d.ts.map +1 -1
- package/dist/types/utils/object.d.ts +8 -0
- package/dist/types/utils/object.d.ts.map +1 -1
- package/dist/types/utils/rules-logic.d.ts +3 -33
- package/dist/types/utils/rules-logic.d.ts.map +1 -1
- package/dist/types/utils/search-params.d.ts.map +1 -1
- package/dist/types/utils/state-snaphot.d.ts +16 -0
- package/dist/types/utils/state-snaphot.d.ts.map +1 -0
- package/dist/types/utils/storage.d.ts +11 -374
- package/dist/types/utils/storage.d.ts.map +1 -1
- package/dist/types/utils/supports.d.ts +0 -87
- package/dist/types/utils/supports.d.ts.map +1 -1
- package/package.json +49 -182
- package/dist/.tsbuildinfo +0 -1
- package/dist/api-DbMJli3H.js +0 -22
- package/dist/api-qiqq8lgz.cjs +0 -1
- package/dist/cjs/form/index.js +0 -1
- package/dist/cjs/plugins/dom-observer/index.js +0 -1
- package/dist/cjs/plugins/dynamic-experiences/index.js +0 -1
- package/dist/cjs/plugins/experience-browser-storage/index.js +0 -1
- package/dist/cjs/plugins/history-browser-storage/index.js +0 -1
- package/dist/cjs/plugins/responses-browser-storage/index.js +0 -1
- package/dist/cjs/plugins/responses-indexeddb/index.js +0 -1
- package/dist/cjs/plugins/telemetry/index.js +0 -1
- package/dist/cjs/plugins/web-components/index.js +0 -1
- package/dist/cjs/preview/index.js +0 -1
- package/dist/docs/_root.css +0 -101
- package/dist/docs/explanation/conditions-and-the-logic-engine.md +0 -94
- package/dist/docs/explanation/content-references.md +0 -99
- package/dist/docs/explanation/feature-flag-allocation.md +0 -218
- package/dist/docs/explanation/how-picked-works.md +0 -124
- package/dist/docs/explanation/how-pickedql-works.md +0 -76
- package/dist/docs/explanation/pages-and-flows.md +0 -64
- package/dist/docs/explanation/the-content-model.md +0 -87
- package/dist/docs/explanation/the-two-apis.md +0 -68
- package/dist/docs/explanation/why-server-side-rendering.md +0 -76
- package/dist/docs/explanation/workspaces-and-versions.md +0 -71
- package/dist/docs/how-to/add-a-step-field-or-action.md +0 -43
- package/dist/docs/how-to/analytics/index.md +0 -316
- package/dist/docs/how-to/archive-or-delete-a-workspace.md +0 -46
- package/dist/docs/how-to/authenticate-the-cli.md +0 -97
- package/dist/docs/how-to/authenticate-with-a-magic-link.md +0 -40
- package/dist/docs/how-to/authenticate-with-a-password.md +0 -51
- package/dist/docs/how-to/authenticate-with-an-api-key.md +0 -51
- package/dist/docs/how-to/authenticate-with-oauth.md +0 -40
- package/dist/docs/how-to/build-a-flow.md +0 -83
- package/dist/docs/how-to/connect-the-mcp-server.md +0 -38
- package/dist/docs/how-to/create-a-content-entry.md +0 -48
- package/dist/docs/how-to/create-a-project.md +0 -29
- package/dist/docs/how-to/create-an-experience.md +0 -42
- package/dist/docs/how-to/create-and-revoke-an-api-key.md +0 -42
- package/dist/docs/how-to/debug-with-the-chrome-extension.md +0 -57
- package/dist/docs/how-to/define-a-page-layout.md +0 -46
- package/dist/docs/how-to/fill-and-publish-a-page.md +0 -66
- package/dist/docs/how-to/install-the-gtm-template.md +0 -84
- package/dist/docs/how-to/install-the-sdk.md +0 -93
- package/dist/docs/how-to/install-the-vite-plugin.md +0 -69
- package/dist/docs/how-to/invite-and-remove-members.md +0 -34
- package/dist/docs/how-to/point-one-entry-at-another.md +0 -61
- package/dist/docs/how-to/preview-a-workspace.md +0 -28
- package/dist/docs/how-to/publish-a-workspace.md +0 -30
- package/dist/docs/how-to/read-a-feature-flag.md +0 -113
- package/dist/docs/how-to/read-a-referenced-entry.md +0 -109
- package/dist/docs/how-to/register-a-component.md +0 -55
- package/dist/docs/how-to/register-an-action-handler.md +0 -67
- package/dist/docs/how-to/render-a-step-form.md +0 -131
- package/dist/docs/how-to/render-an-unpublished-preview.md +0 -41
- package/dist/docs/how-to/reuse-a-section.md +0 -53
- package/dist/docs/how-to/reuse-a-step-field-or-action.md +0 -28
- package/dist/docs/how-to/roll-back-a-published-version.md +0 -26
- package/dist/docs/how-to/run-an-ab-test.md +0 -49
- package/dist/docs/how-to/run-code-on-a-form-submission.md +0 -125
- package/dist/docs/how-to/server-render-a-page.md +0 -81
- package/dist/docs/how-to/set-a-content-security-policy.md +0 -32
- package/dist/docs/how-to/set-up-mfa.md +0 -69
- package/dist/docs/how-to/switch-workspaces.md +0 -122
- package/dist/docs/how-to/upload-and-use-an-asset.mdx +0 -73
- package/dist/docs/how-to/validate-a-field.md +0 -52
- package/dist/docs/how-to/write-a-condition.md +0 -45
- package/dist/docs/how-to/write-a-predicate.md +0 -60
- package/dist/docs/index.md +0 -59
- package/dist/docs/reference/dashboard/actions.mdx +0 -53
- package/dist/docs/reference/dashboard/api-keys.mdx +0 -38
- package/dist/docs/reference/dashboard/conditions.mdx +0 -42
- package/dist/docs/reference/dashboard/content/asset-library.mdx +0 -63
- package/dist/docs/reference/dashboard/content/blocks.mdx +0 -57
- package/dist/docs/reference/dashboard/content/content-entries.mdx +0 -95
- package/dist/docs/reference/dashboard/content/models.mdx +0 -108
- package/dist/docs/reference/dashboard/content/pages.mdx +0 -61
- package/dist/docs/reference/dashboard/experiences.mdx +0 -51
- package/dist/docs/reference/dashboard/features.mdx +0 -154
- package/dist/docs/reference/dashboard/fields.mdx +0 -106
- package/dist/docs/reference/dashboard/flow-builder/canvas.mdx +0 -58
- package/dist/docs/reference/dashboard/flow-builder/condition-builder.md +0 -57
- package/dist/docs/reference/dashboard/flow-builder/keyboard-shortcuts.md +0 -72
- package/dist/docs/reference/dashboard/flow-builder/nodes.md +0 -63
- package/dist/docs/reference/dashboard/projects.mdx +0 -44
- package/dist/docs/reference/dashboard/reports.mdx +0 -43
- package/dist/docs/reference/dashboard/steps.mdx +0 -37
- package/dist/docs/reference/dashboard/team-management.md +0 -29
- package/dist/docs/reference/dashboard/workspace-versioning.mdx +0 -30
- package/dist/docs/reference/dashboard/workspaces.mdx +0 -76
- package/dist/docs/reference/delivery-api/experience-content.md +0 -152
- package/dist/docs/reference/delivery-api/index.md +0 -45
- package/dist/docs/reference/delivery-api/preview-caching-crawling.md +0 -79
- package/dist/docs/reference/delivery-api/project-config.md +0 -65
- package/dist/docs/reference/delivery-api/workspace-schema.md +0 -85
- package/dist/docs/reference/glossary.md +0 -181
- package/dist/docs/reference/management-api/authentication.md +0 -74
- package/dist/docs/reference/management-api/authorization-and-scopes.md +0 -285
- package/dist/docs/reference/management-api/error-handling.md +0 -233
- package/dist/docs/reference/management-api/pagination.md +0 -192
- package/dist/docs/reference/pickedql/data-sources.md +0 -174
- package/dist/docs/reference/pickedql/dimensions.md +0 -103
- package/dist/docs/reference/pickedql/filtering.md +0 -64
- package/dist/docs/reference/pickedql/index.md +0 -18
- package/dist/docs/reference/pickedql/schema.md +0 -172
- package/dist/docs/reference/pickedql/virtual-functions.md +0 -248
- package/dist/docs/reference/sdk/actions.md +0 -30
- package/dist/docs/reference/sdk/analytics-events.md +0 -445
- package/dist/docs/reference/sdk/conditions.md +0 -147
- package/dist/docs/reference/sdk/content-security-policy.md +0 -21
- package/dist/docs/reference/sdk/content.md +0 -213
- package/dist/docs/reference/sdk/experiences.md +0 -51
- package/dist/docs/reference/sdk/features.md +0 -256
- package/dist/docs/reference/sdk/fields.md +0 -255
- package/dist/docs/reference/sdk/index.md +0 -68
- package/dist/docs/reference/sdk/plugins/create-experience.md +0 -123
- package/dist/docs/reference/sdk/plugins/dynamic-experiences.md +0 -74
- package/dist/docs/reference/sdk/plugins/index.md +0 -29
- package/dist/docs/reference/sdk/plugins/window-object.md +0 -25
- package/dist/docs/reference/sdk/predicates.md +0 -43
- package/dist/docs/reference/sdk/ssr/index.md +0 -33
- package/dist/docs/reference/sdk/ssr/rendering-and-hydration.md +0 -103
- package/dist/docs/reference/sdk/ssr/serialize.md +0 -80
- package/dist/docs/reference/sdk/ssr/slots-and-placements.md +0 -59
- package/dist/docs/reference/sdk/steps.md +0 -86
- package/dist/docs/reference/sdk/type-generation.md +0 -196
- package/dist/docs/reference/tools/chrome-extension.md +0 -16
- package/dist/docs/reference/tools/cli.md +0 -146
- package/dist/docs/reference/tools/image-optimisation-service.md +0 -104
- package/dist/docs/reference/tools/mcp.md +0 -90
- package/dist/docs/reference/tools/vite-plugin.md +0 -163
- package/dist/docs/tutorials/first-api-call.md +0 -228
- package/dist/docs/tutorials/first-experience-in-the-dashboard.mdx +0 -143
- package/dist/docs/tutorials/first-experience.mdx +0 -254
- package/dist/docs/tutorials/first-server-rendered-page.mdx +0 -186
- package/dist/dom-BqcToNL0.js +0 -82
- package/dist/dom-DlLH3FxV.cjs +0 -1
- package/dist/emit-D-tLiWL1.cjs +0 -1
- package/dist/emit-Ds2EG7CB.js +0 -14
- package/dist/esm/form/index.js +0 -565
- package/dist/esm/plugins/dom-observer/index.js +0 -87
- package/dist/esm/plugins/dynamic-experiences/index.js +0 -5
- package/dist/esm/plugins/experience-browser-storage/index.js +0 -38
- package/dist/esm/plugins/history-browser-storage/index.js +0 -26
- package/dist/esm/plugins/responses-browser-storage/index.js +0 -71
- package/dist/esm/plugins/responses-indexeddb/index.js +0 -89
- package/dist/esm/plugins/telemetry/index.js +0 -100
- package/dist/esm/plugins/web-components/index.js +0 -19
- package/dist/esm/preview/index.js +0 -2
- package/dist/experience-instance-DGk11d8a.js +0 -563
- package/dist/experience-instance-Dej3P1sE.cjs +0 -1
- package/dist/id-Bo4RBeOs.js +0 -4
- package/dist/id-Js-62re-.cjs +0 -1
- package/dist/inert-script-report-B_bMPRzp.js +0 -18
- package/dist/inert-script-report-ijRHPtcY.cjs +0 -1
- package/dist/logger-CSTvAyyB.cjs +0 -1
- package/dist/logger-DMN6TxJJ.js +0 -4
- package/dist/object-BUDGxEqy.js +0 -25
- package/dist/object-CIkt7Fkr.cjs +0 -1
- package/dist/plugin-BcLaCLm1.cjs +0 -1
- package/dist/plugin-De_BJSwE.js +0 -194
- package/dist/preview-channel-CSr96XAo.js +0 -98
- package/dist/preview-channel-Cx0e6fye.cjs +0 -1
- package/dist/protocol-Bb_vpLKE.cjs +0 -1
- package/dist/protocol-C5KkkiZc.js +0 -84
- package/dist/provider-C_9u0yGJ.cjs +0 -1
- package/dist/provider-ovM-CBX_.js +0 -98
- package/dist/registry-C1t8l3t9.cjs +0 -1
- package/dist/registry-CXZv0uLg.js +0 -18
- package/dist/rules-logic-CGZIYgAI.cjs +0 -1
- package/dist/rules-logic-HesIUCu6.js +0 -13
- package/dist/storage-1MW3-_As.js +0 -103
- package/dist/storage-DUw9UJ2h.cjs +0 -1
- package/dist/supports-CO9bJGNl.js +0 -92
- package/dist/supports-DBzjGaWD.cjs +0 -1
- package/dist/types/data-source/api.d.ts +0 -60
- package/dist/types/data-source/api.d.ts.map +0 -1
- package/dist/types/data-source/provider.d.ts +0 -103
- package/dist/types/data-source/provider.d.ts.map +0 -1
- package/dist/types/data-source/registry.d.ts +0 -26
- package/dist/types/data-source/registry.d.ts.map +0 -1
- package/dist/types/data-source/request-observer.d.ts +0 -62
- package/dist/types/data-source/request-observer.d.ts.map +0 -1
- package/dist/types/data-source/virtual-data.d.ts +0 -19
- package/dist/types/data-source/virtual-data.d.ts.map +0 -1
- package/dist/types/entities/action/action.d.ts +0 -85
- package/dist/types/entities/action/action.d.ts.map +0 -1
- package/dist/types/entities/component/lazyComponent.d.ts +0 -11
- package/dist/types/entities/component/lazyComponent.d.ts.map +0 -1
- package/dist/types/entities/condition/condition.d.ts +0 -29
- package/dist/types/entities/condition/condition.d.ts.map +0 -1
- package/dist/types/entities/content/content.d.ts +0 -53
- package/dist/types/entities/content/content.d.ts.map +0 -1
- package/dist/types/entities/content/reference.d.ts +0 -101
- package/dist/types/entities/content/reference.d.ts.map +0 -1
- package/dist/types/entities/field/policies.d.ts +0 -35
- package/dist/types/entities/field/policies.d.ts.map +0 -1
- package/dist/types/entities/response/response-validation.d.ts +0 -75
- package/dist/types/entities/response/response-validation.d.ts.map +0 -1
- package/dist/types/entities/session/session.d.ts +0 -46
- package/dist/types/entities/session/session.d.ts.map +0 -1
- package/dist/types/entities/step/step.d.ts +0 -56
- package/dist/types/entities/step/step.d.ts.map +0 -1
- package/dist/types/form/build-responses.d.ts +0 -18
- package/dist/types/form/build-responses.d.ts.map +0 -1
- package/dist/types/form/create-field-evaluator.d.ts +0 -28
- package/dist/types/form/create-field-evaluator.d.ts.map +0 -1
- package/dist/types/form/create-field-validation.d.ts +0 -60
- package/dist/types/form/create-field-validation.d.ts.map +0 -1
- package/dist/types/form/create-form.d.ts +0 -153
- package/dist/types/form/create-form.d.ts.map +0 -1
- package/dist/types/form/create-submit-pipeline.d.ts +0 -116
- package/dist/types/form/create-submit-pipeline.d.ts.map +0 -1
- package/dist/types/form/get-step-fields.d.ts +0 -19
- package/dist/types/form/get-step-fields.d.ts.map +0 -1
- package/dist/types/form/index.d.ts +0 -11
- package/dist/types/form/index.d.ts.map +0 -1
- package/dist/types/lifecycle/condition-selection.d.ts +0 -146
- package/dist/types/lifecycle/condition-selection.d.ts.map +0 -1
- package/dist/types/lifecycle/lifecycle.d.ts +0 -48
- package/dist/types/lifecycle/lifecycle.d.ts.map +0 -1
- package/dist/types/lifecycle/rules-logic.d.ts +0 -25
- package/dist/types/lifecycle/rules-logic.d.ts.map +0 -1
- package/dist/types/lifecycle/state-snapshot.d.ts +0 -38
- package/dist/types/lifecycle/state-snapshot.d.ts.map +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 -50
- package/dist/types/plugins/dom-observer/plugin.d.ts.map +0 -1
- package/dist/types/plugins/dynamic-experiences/hash.d.ts +0 -105
- package/dist/types/plugins/dynamic-experiences/hash.d.ts.map +0 -1
- package/dist/types/plugins/dynamic-experiences/index.d.ts +0 -7
- package/dist/types/plugins/dynamic-experiences/index.d.ts.map +0 -1
- package/dist/types/plugins/dynamic-experiences/plugin.d.ts +0 -49
- package/dist/types/plugins/dynamic-experiences/plugin.d.ts.map +0 -1
- package/dist/types/plugins/dynamic-experiences/types.d.ts +0 -45
- package/dist/types/plugins/dynamic-experiences/types.d.ts.map +0 -1
- package/dist/types/plugins/experience-browser-storage/index.d.ts.map +0 -1
- package/dist/types/plugins/experience-browser-storage/plugin.d.ts +0 -7
- package/dist/types/plugins/experience-browser-storage/plugin.d.ts.map +0 -1
- package/dist/types/plugins/history-browser-storage/index.d.ts.map +0 -1
- package/dist/types/plugins/history-browser-storage/plugin.d.ts.map +0 -1
- package/dist/types/plugins/responses-browser-storage/index.d.ts.map +0 -1
- package/dist/types/plugins/responses-browser-storage/plugin.d.ts +0 -18
- package/dist/types/plugins/responses-browser-storage/plugin.d.ts.map +0 -1
- package/dist/types/plugins/responses-indexeddb/index.d.ts.map +0 -1
- package/dist/types/plugins/responses-indexeddb/plugin.d.ts +0 -3
- package/dist/types/plugins/responses-indexeddb/plugin.d.ts.map +0 -1
- package/dist/types/plugins/telemetry/emit.d.ts +0 -18
- package/dist/types/plugins/telemetry/emit.d.ts.map +0 -1
- package/dist/types/plugins/telemetry/index.d.ts +0 -4
- package/dist/types/plugins/telemetry/index.d.ts.map +0 -1
- package/dist/types/plugins/telemetry/plugin-summary.d.ts +0 -10
- package/dist/types/plugins/telemetry/plugin-summary.d.ts.map +0 -1
- package/dist/types/plugins/telemetry/plugin.d.ts +0 -45
- package/dist/types/plugins/telemetry/plugin.d.ts.map +0 -1
- package/dist/types/plugins/web-components/index.d.ts +0 -2
- package/dist/types/plugins/web-components/index.d.ts.map +0 -1
- package/dist/types/plugins/web-components/plugin.d.ts +0 -4
- package/dist/types/plugins/web-components/plugin.d.ts.map +0 -1
- package/dist/types/preview/index.d.ts +0 -18
- package/dist/types/preview/index.d.ts.map +0 -1
- package/dist/types/preview-bridge/index.d.ts +0 -14
- package/dist/types/preview-bridge/index.d.ts.map +0 -1
- package/dist/types/preview-channel.d.ts +0 -16
- package/dist/types/preview-channel.d.ts.map +0 -1
- package/dist/types/preview-receiver/apply-ops.d.ts +0 -32
- package/dist/types/preview-receiver/apply-ops.d.ts.map +0 -1
- package/dist/types/preview-receiver/index.d.ts +0 -32
- package/dist/types/preview-receiver/index.d.ts.map +0 -1
- package/dist/types/preview-receiver/protocol.d.ts +0 -69
- package/dist/types/preview-receiver/protocol.d.ts.map +0 -1
- package/dist/types/schema-registry.d.ts +0 -206
- package/dist/types/schema-registry.d.ts.map +0 -1
- package/dist/types/server/serialize.d.ts +0 -87
- package/dist/types/server/serialize.d.ts.map +0 -1
- package/dist/types/typed-content.d.ts +0 -17
- package/dist/types/typed-content.d.ts.map +0 -1
- package/dist/types/utils/client-telemetry.d.ts +0 -25
- package/dist/types/utils/client-telemetry.d.ts.map +0 -1
- package/dist/types/utils/content-path.d.ts +0 -37
- package/dist/types/utils/content-path.d.ts.map +0 -1
- package/dist/types/utils/html-asset-value.d.ts +0 -20
- package/dist/types/utils/html-asset-value.d.ts.map +0 -1
- package/dist/types/utils/inert-script-report.d.ts +0 -40
- package/dist/types/utils/inert-script-report.d.ts.map +0 -1
- package/dist/types/utils/node-tree/get-next-node-from-action.d.ts +0 -25
- package/dist/types/utils/node-tree/get-next-node-from-action.d.ts.map +0 -1
- package/dist/types/utils/node-tree/get-next-node-from-condition.d.ts +0 -17
- package/dist/types/utils/node-tree/get-next-node-from-condition.d.ts.map +0 -1
- package/dist/types/utils/picked-config.d.ts +0 -39
- package/dist/types/utils/picked-config.d.ts.map +0 -1
- package/dist/types/utils/preview-session.d.ts +0 -12
- package/dist/types/utils/preview-session.d.ts.map +0 -1
- package/dist/types/utils/rehydrate-scripts.d.ts +0 -50
- package/dist/types/utils/rehydrate-scripts.d.ts.map +0 -1
- package/dist/types/utils/render-string.d.ts +0 -24
- package/dist/types/utils/render-string.d.ts.map +0 -1
- package/dist/types/utils/user-timing.d.ts +0 -21
- package/dist/types/utils/user-timing.d.ts.map +0 -1
- package/dist/version-BvLZaTMC.cjs +0 -1
- package/dist/version-VvasRUfR.js +0 -256
- /package/dist/types/plugins/{experience-browser-storage → experience-browserstorage-plugin}/index.d.ts +0 -0
- /package/dist/types/plugins/{history-browser-storage → history-browserstorage-plugin}/index.d.ts +0 -0
- /package/dist/types/plugins/{responses-browser-storage → responses-browserstorage-plugin}/index.d.ts +0 -0
- /package/dist/types/plugins/{responses-indexeddb → responses-indexeddb-plugin}/index.d.ts +0 -0
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: reference
|
|
3
|
-
layout: docs
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Content
|
|
7
|
-
|
|
8
|
-
The client holds every content record in one index, keyed by the id. The hooks on this
|
|
9
|
-
page read that index.
|
|
10
|
-
|
|
11
|
-
## The content record
|
|
12
|
-
|
|
13
|
-
```ts
|
|
14
|
-
interface Content {
|
|
15
|
-
id: string
|
|
16
|
-
contentModelKey?: string | null
|
|
17
|
-
data: Record<string, unknown>
|
|
18
|
-
}
|
|
19
|
-
```
|
|
20
|
-
|
|
21
|
-
| Property | Type | Description |
|
|
22
|
-
| --- | --- | --- |
|
|
23
|
-
| `id` | `string` | The content entry id. |
|
|
24
|
-
| `contentModelKey` | `string \| null` | The Key of the [Model](/reference/dashboard/content/models) that the entry belongs to. |
|
|
25
|
-
| `data` | `Record<string, unknown>` | The field values, keyed by the field key from the schema. |
|
|
26
|
-
|
|
27
|
-
The client registers the `content` array and the `references` array of the
|
|
28
|
-
[experience content response](/reference/delivery-api/experience-content) into the same
|
|
29
|
-
index. Your code can therefore read a referenced entry by its own id.
|
|
30
|
-
|
|
31
|
-
## Read the content of a step
|
|
32
|
-
|
|
33
|
-
`useStepContent()` in React, and `getStepContent()` in Svelte, give the `data` of the
|
|
34
|
-
entry that the current step points at.
|
|
35
|
-
|
|
36
|
-
:::code-group
|
|
37
|
-
|
|
38
|
-
```tsx [React]
|
|
39
|
-
import { useStepContent } from '@picked/react/hooks'
|
|
40
|
-
|
|
41
|
-
export function Hero() {
|
|
42
|
-
const content = useStepContent()
|
|
43
|
-
|
|
44
|
-
return <h1>{String(content?.headline ?? '')}</h1>
|
|
45
|
-
}
|
|
46
|
-
```
|
|
47
|
-
|
|
48
|
-
```svelte [Svelte]
|
|
49
|
-
<script lang="ts">
|
|
50
|
-
import { getStepContent } from '@picked/svelte/hooks'
|
|
51
|
-
|
|
52
|
-
const content = getStepContent()
|
|
53
|
-
</script>
|
|
54
|
-
|
|
55
|
-
<h1>{$content?.headline ?? ''}</h1>
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
:::
|
|
59
|
-
|
|
60
|
-
`useStepContent()` returns the data, and React re-renders the component when the data
|
|
61
|
-
changes. `getStepContent()` returns a store, which you read with the `$` prefix.
|
|
62
|
-
|
|
63
|
-
## Read a record by id
|
|
64
|
-
|
|
65
|
-
`useContent(id)` and `getContent(id)` return a store of one record. The store holds
|
|
66
|
-
`null` until the client registers that record.
|
|
67
|
-
|
|
68
|
-
:::code-group
|
|
69
|
-
|
|
70
|
-
```tsx [React]
|
|
71
|
-
import { useContent, useStoreGlobal } from '@picked/react/hooks'
|
|
72
|
-
|
|
73
|
-
export function Banner() {
|
|
74
|
-
const banner = useStoreGlobal(useContent('entry_42'))
|
|
75
|
-
|
|
76
|
-
return <h1>{String(banner?.data.headline ?? '')}</h1>
|
|
77
|
-
}
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
```svelte [Svelte]
|
|
81
|
-
<script lang="ts">
|
|
82
|
-
import { getContent } from '@picked/svelte/hooks'
|
|
83
|
-
|
|
84
|
-
const banner = getContent('entry_42')
|
|
85
|
-
</script>
|
|
86
|
-
|
|
87
|
-
<h1>{$banner?.data.headline ?? ''}</h1>
|
|
88
|
-
```
|
|
89
|
-
|
|
90
|
-
:::
|
|
91
|
-
|
|
92
|
-
## Resolve a reference field
|
|
93
|
-
|
|
94
|
-
A [Reference field](/reference/dashboard/content/models#reference-fields) holds a pointer,
|
|
95
|
-
and not the record. `useReference()` and `getReference()` resolve the pointer against the
|
|
96
|
-
index.
|
|
97
|
-
|
|
98
|
-
:::code-group
|
|
99
|
-
|
|
100
|
-
```tsx [React]
|
|
101
|
-
import { useReference, useStepContent, useStoreGlobal } from '@picked/react/hooks'
|
|
102
|
-
|
|
103
|
-
export function ProductCategory() {
|
|
104
|
-
const content = useStepContent()
|
|
105
|
-
const category = useStoreGlobal(useReference(content?.category))
|
|
106
|
-
|
|
107
|
-
return <span>{String(category?.data.name ?? '')}</span>
|
|
108
|
-
}
|
|
109
|
-
```
|
|
110
|
-
|
|
111
|
-
```svelte [Svelte]
|
|
112
|
-
<script lang="ts">
|
|
113
|
-
import { getStepContent, getReference } from '@picked/svelte/hooks'
|
|
114
|
-
|
|
115
|
-
const content = getStepContent()
|
|
116
|
-
const category = getReference(content.map((c) => c?.category ?? null, { skipVoid: false }))
|
|
117
|
-
</script>
|
|
118
|
-
|
|
119
|
-
<span>{$category?.data.name ?? ''}</span>
|
|
120
|
-
```
|
|
121
|
-
|
|
122
|
-
:::
|
|
123
|
-
|
|
124
|
-
For a repeatable Reference field, use `useReferences()` and `getReferences()`. They give
|
|
125
|
-
a list in field order.
|
|
126
|
-
|
|
127
|
-
:::code-group
|
|
128
|
-
|
|
129
|
-
```tsx [React]
|
|
130
|
-
import { useReferences, useStepContent, useStoreGlobal } from '@picked/react/hooks'
|
|
131
|
-
|
|
132
|
-
export function ProductCategories() {
|
|
133
|
-
const content = useStepContent()
|
|
134
|
-
const categories = useStoreGlobal(useReferences(content?.categories))
|
|
135
|
-
|
|
136
|
-
return (
|
|
137
|
-
<ul>
|
|
138
|
-
{categories.map((category) => (
|
|
139
|
-
<li key={category.id}>{String(category.data.name ?? '')}</li>
|
|
140
|
-
))}
|
|
141
|
-
</ul>
|
|
142
|
-
)
|
|
143
|
-
}
|
|
144
|
-
```
|
|
145
|
-
|
|
146
|
-
```svelte [Svelte]
|
|
147
|
-
<script lang="ts">
|
|
148
|
-
import { getStepContent, getReferences } from '@picked/svelte/hooks'
|
|
149
|
-
|
|
150
|
-
const content = getStepContent()
|
|
151
|
-
const categories = getReferences(content.map((c) => c?.categories ?? null, { skipVoid: false }))
|
|
152
|
-
</script>
|
|
153
|
-
|
|
154
|
-
<ul>
|
|
155
|
-
{#each $categories as category (category.id)}
|
|
156
|
-
<li>{category.data.name ?? ''}</li>
|
|
157
|
-
{/each}
|
|
158
|
-
</ul>
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
:::
|
|
162
|
-
|
|
163
|
-
The list holds no empty places. A pointer that Picked cannot resolve is absent from the
|
|
164
|
-
list, so each item is a record.
|
|
165
|
-
|
|
166
|
-
:::note
|
|
167
|
-
The Svelte helpers accept a store, and the examples pass one. Content arrives after the
|
|
168
|
-
component starts. A plain value therefore holds the result at "not set".
|
|
169
|
-
:::
|
|
170
|
-
|
|
171
|
-
## Reference hooks
|
|
172
|
-
|
|
173
|
-
| Hook | Returns | When the target is absent |
|
|
174
|
-
| --- | --- | --- |
|
|
175
|
-
| `useReference(value)` | `Store<Content \| null>` | `null` |
|
|
176
|
-
| `useReferences(value)` | `Store<Content[]>` | The item is absent from the list. |
|
|
177
|
-
| `getReference(value)` | `Store<Content \| null>` | `null` |
|
|
178
|
-
| `getReferences(value)` | `Store<Content[]>` | The item is absent from the list. |
|
|
179
|
-
|
|
180
|
-
Each one accepts the raw field value, or a store of it. A single value that goes to
|
|
181
|
-
`useReferences()` or `getReferences()` gives a list of one.
|
|
182
|
-
|
|
183
|
-
A target is absent for three reasons. Somebody deleted the entry, the entry belongs to
|
|
184
|
-
another workspace, or the chain of references is deeper than the limit. See
|
|
185
|
-
[About content references](/explanation/content-references).
|
|
186
|
-
|
|
187
|
-
## Read a pointer directly
|
|
188
|
-
|
|
189
|
-
`@picked/client` gives you the readers behind the hooks, for the code that runs outside
|
|
190
|
-
React and Svelte.
|
|
191
|
-
|
|
192
|
-
| Export | Returns | Description |
|
|
193
|
-
| --- | --- | --- |
|
|
194
|
-
| `isContentReference(value)` | `boolean` | Whether the value is a pointer. |
|
|
195
|
-
| `readReferenceId(value)` | `string \| null` | The target id of a single pointer. |
|
|
196
|
-
| `readReferenceIds(value)` | `string[]` | Every target id, for a repeatable field. |
|
|
197
|
-
| `deriveReference(contents, value)` | `Store<Content \| null>` | The store behind `useReference` and `getReference`. |
|
|
198
|
-
| `deriveReferences(contents, value)` | `Store<Content[]>` | The store behind `useReferences` and `getReferences`. |
|
|
199
|
-
|
|
200
|
-
```ts
|
|
201
|
-
import { createClient, readReferenceIds } from 'picked'
|
|
202
|
-
|
|
203
|
-
const client = createClient({ projectId: 'proj_123' })
|
|
204
|
-
const content = client.contents.getById('entry_789').getState()
|
|
205
|
-
const categoryIds = readReferenceIds(content?.data.categories)
|
|
206
|
-
```
|
|
207
|
-
|
|
208
|
-
## Related
|
|
209
|
-
|
|
210
|
-
- [About content references](/explanation/content-references) — why a reference is a pointer.
|
|
211
|
-
- [How to read a referenced entry](/how-to/read-a-referenced-entry)
|
|
212
|
-
- [Experience content endpoint](/reference/delivery-api/experience-content) — the wire shape.
|
|
213
|
-
- [Server snapshot](/reference/sdk/ssr/serialize) — content on a server render.
|
|
@@ -1,51 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: reference
|
|
3
|
-
layout: docs
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Experiences
|
|
7
|
-
|
|
8
|
-
Define an experience in code with `createExperience()`. You can also load an
|
|
9
|
-
experience from the dashboard at runtime with the
|
|
10
|
-
[Dynamic Experiences Plugin](/reference/sdk/plugins/dynamic-experiences).
|
|
11
|
-
|
|
12
|
-
The flow below points at a DOM selector and renders into it. A Page experience
|
|
13
|
-
renders through a named slot instead. Point it at `.picked-slot-<name>` and render
|
|
14
|
-
`<ExperienceSlot name="<name>" />` on your server. Use the slot path for a Page that
|
|
15
|
-
the server renders and that search engines must read. Use the selector path for a
|
|
16
|
-
Flow that the browser renders. See [Server-Side Rendering](/reference/sdk/ssr) and
|
|
17
|
-
[Slots and Placements](/reference/sdk/ssr/slots-and-placements).
|
|
18
|
-
|
|
19
|
-
## Create an experience
|
|
20
|
-
|
|
21
|
-
```ts
|
|
22
|
-
import { createExperience } from '@picked/client/plugins/create-experience'
|
|
23
|
-
import { adaptSvelteComponent } from '@picked/svelte'
|
|
24
|
-
import appCss from '../app.css?inline'
|
|
25
|
-
|
|
26
|
-
export const productPageExperience = createExperience({
|
|
27
|
-
id: 'product-page-experience',
|
|
28
|
-
name: 'Product Page Experience',
|
|
29
|
-
condition: {
|
|
30
|
-
'==': [
|
|
31
|
-
{ var: 'location.pathname' },
|
|
32
|
-
'/product/',
|
|
33
|
-
],
|
|
34
|
-
},
|
|
35
|
-
targets: [{ selector: 'body', placement: 'after' }],
|
|
36
|
-
component: adaptSvelteComponent(
|
|
37
|
-
import('../ui/ProductPageExperience.svelte'),
|
|
38
|
-
{ css: [appCss] },
|
|
39
|
-
),
|
|
40
|
-
})
|
|
41
|
-
```
|
|
42
|
-
|
|
43
|
-
To register an experience that you define in code, use the
|
|
44
|
-
[Create Experience Plugin](/reference/sdk/plugins/create-experience). To read an experience from
|
|
45
|
-
the dashboard at runtime and control it there, use the
|
|
46
|
-
[Dynamic Experiences Plugin](/reference/sdk/plugins/dynamic-experiences).
|
|
47
|
-
|
|
48
|
-
## Related
|
|
49
|
-
|
|
50
|
-
- [About how Picked works](/explanation/how-picked-works) — the startup order.
|
|
51
|
-
- [How to register a component](/how-to/register-a-component)
|
|
@@ -1,256 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
type: reference
|
|
3
|
-
layout: docs
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# Feature flags
|
|
7
|
-
|
|
8
|
-
A feature flag lets you run an A/B test and roll a change out in stages. Control a
|
|
9
|
-
feature flag from the dashboard, or define it in SDK code when you need your own decision
|
|
10
|
-
rules.
|
|
11
|
-
|
|
12
|
-
## Where feature flags come from
|
|
13
|
-
|
|
14
|
-
You control most feature flags from the dashboard. The
|
|
15
|
-
[dynamic experiences plugin](/reference/sdk/plugins/dynamic-experiences) reads the options of
|
|
16
|
-
your project at runtime and registers every feature flag for you. You declare no feature flag in
|
|
17
|
-
code.
|
|
18
|
-
|
|
19
|
-
For a feature flag that you control from the dashboard, the SDK makes the definition:
|
|
20
|
-
|
|
21
|
-
| Field | Value |
|
|
22
|
-
| --- | --- |
|
|
23
|
-
| `id` | The dashboard key of the feature flag |
|
|
24
|
-
| `key` | `v{version}`, for example `v3` |
|
|
25
|
-
| `name` | The dashboard name of the feature flag |
|
|
26
|
-
| `enabled` | The dashboard **Enabled** toggle |
|
|
27
|
-
| `weight` | The dashboard **Weight**, 0 to 100 |
|
|
28
|
-
| `storage` | `local`, or `session` in [preview mode](/explanation/feature-flag-allocation#preview-mode) |
|
|
29
|
-
| `decide` | Made by the SDK. See the two routes below. |
|
|
30
|
-
|
|
31
|
-
The `decide` function that the SDK makes derives from the visitor ID and from the ID of
|
|
32
|
-
the feature flag. A feature flag that you control from the dashboard therefore cannot use
|
|
33
|
-
the data of your application. Define the feature flag in SDK code when you need that.
|
|
34
|
-
|
|
35
|
-
Which route `decide` takes depends on the type of the feature flag:
|
|
36
|
-
|
|
37
|
-
| Dashboard type | The bucket | How the SDK decides |
|
|
38
|
-
| --- | --- | --- |
|
|
39
|
-
| Boolean | `true` or `false` | It compares the stable value of the visitor against `weight`. |
|
|
40
|
-
| Text | The value of one variant, or `false` | It compares the stable value of the visitor against the range that Picked gives to each variant. |
|
|
41
|
-
|
|
42
|
-
The SDK sorts the variants by their key before it allocates, so the order of the payload
|
|
43
|
-
has no effect. See
|
|
44
|
-
[More than two groups](/explanation/feature-flag-allocation#more-than-two-groups).
|
|
45
|
-
|
|
46
|
-
## Define a feature flag in SDK code
|
|
47
|
-
|
|
48
|
-
Define your feature flags when you create the Picked client. Pass a `features` object. Use
|
|
49
|
-
this when a decision needs data that only your application holds. Each feature flag needs a
|
|
50
|
-
unique identifier, a version key, a name that a person can read, and a `decide`
|
|
51
|
-
function:
|
|
52
|
-
|
|
53
|
-
```ts
|
|
54
|
-
import { createClient } from 'picked'
|
|
55
|
-
|
|
56
|
-
const client = createClient({
|
|
57
|
-
projectId: 'your-project-id',
|
|
58
|
-
features: {
|
|
59
|
-
'summer-sale': {
|
|
60
|
-
key: 'summer-sale-v1', // The version key. Change it to invalidate the cache.
|
|
61
|
-
name: 'Summer Sale Experiment', // A name for analytics that a person can read.
|
|
62
|
-
decide: async () => {
|
|
63
|
-
// Put your decision rules here.
|
|
64
|
-
const isEligible = await checkUserEligibility()
|
|
65
|
-
return isEligible // Returns a boolean.
|
|
66
|
-
},
|
|
67
|
-
storage: 'local', // Optional: 'local' is the default, or 'session'.
|
|
68
|
-
},
|
|
69
|
-
'homepage-variant': {
|
|
70
|
-
key: 'homepage-test-v2',
|
|
71
|
-
name: 'Homepage A/B Test',
|
|
72
|
-
decide: async () => {
|
|
73
|
-
// Return a string for a test of more than two variants.
|
|
74
|
-
return Math.random() < 0.5 ? 'variant-a' : 'variant-b'
|
|
75
|
-
},
|
|
76
|
-
},
|
|
77
|
-
},
|
|
78
|
-
})
|
|
79
|
-
```
|
|
80
|
-
|
|
81
|
-
A feature flag can also be a factory function, which starts the feature flag only when it is
|
|
82
|
-
first needed:
|
|
83
|
-
|
|
84
|
-
```ts
|
|
85
|
-
features: {
|
|
86
|
-
'my-feature': () => ({
|
|
87
|
-
key: 'my-feature-v1',
|
|
88
|
-
name: 'My Feature',
|
|
89
|
-
decide: async () => true,
|
|
90
|
-
}),
|
|
91
|
-
}
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
## Overrides in the URL
|
|
95
|
-
|
|
96
|
-
You can override a feature flag decision from the URL search parameters, for a test:
|
|
97
|
-
|
|
98
|
-
```
|
|
99
|
-
https://example.com?picked-feature=my-feature:true
|
|
100
|
-
```
|
|
101
|
-
|
|
102
|
-
You can give more than one override value:
|
|
103
|
-
|
|
104
|
-
```
|
|
105
|
-
https://example.com?picked-feature=my-feature:true&picked-feature=homepage-variant:variant-a
|
|
106
|
-
```
|
|
107
|
-
|
|
108
|
-
The format is `?picked-feature=<feature-id>:<bucket-value>`. For a Text feature flag,
|
|
109
|
-
give the value that the variant serves.
|
|
110
|
-
|
|
111
|
-
A feature ID contains only lowercase letters, numbers, and hyphens. Therefore the SDK divides
|
|
112
|
-
the parameter at the first colon. The bucket value can contain more colons:
|
|
113
|
-
|
|
114
|
-
```
|
|
115
|
-
https://example.com?picked-feature=opening-hours:09:00-17:00
|
|
116
|
-
```
|
|
117
|
-
|
|
118
|
-
This is useful for QA, because you can test one bucket value and change no code. The
|
|
119
|
-
SDK keeps the override value in session storage. The browser clears it when you close
|
|
120
|
-
the tab.
|
|
121
|
-
|
|
122
|
-
When a URL parameter overrides a feature flag, the SDK registers that feature flag as
|
|
123
|
-
enabled. Therefore `useFeatureEnabled` and `getFeatureEnabled` give `true`. A URL
|
|
124
|
-
parameter can also override a feature flag that the dashboard **Enabled** toggle keeps
|
|
125
|
-
off.
|
|
126
|
-
|
|
127
|
-
## Use a feature flag in an experience condition
|
|
128
|
-
|
|
129
|
-
You can use a feature flag in an experience condition through JSON logic:
|
|
130
|
-
|
|
131
|
-
```ts
|
|
132
|
-
const myExperience = createExperience({
|
|
133
|
-
// The other options go here.
|
|
134
|
-
condition: {
|
|
135
|
-
and: [
|
|
136
|
-
{
|
|
137
|
-
'==': [
|
|
138
|
-
{
|
|
139
|
-
invoke: {
|
|
140
|
-
var: 'features.summer-sale', // Point at the feature flag by its ID.
|
|
141
|
-
},
|
|
142
|
-
},
|
|
143
|
-
true, // Check that the bucket equals true.
|
|
144
|
-
],
|
|
145
|
-
},
|
|
146
|
-
],
|
|
147
|
-
},
|
|
148
|
-
})
|
|
149
|
-
```
|
|
150
|
-
|
|
151
|
-
The ID in `features.<id>` is the **Key** of the feature flag from the dashboard. It is the
|
|
152
|
-
same value that the detail page of the feature flag shows.
|
|
153
|
-
|
|
154
|
-
An evaluation of a condition reads the bucket. Picked therefore allocates a visitor
|
|
155
|
-
to a feature flag when the condition that points at it runs.
|
|
156
|
-
|
|
157
|
-
## Watch for feature flag decisions
|
|
158
|
-
|
|
159
|
-
Subscribe to the `feature_decide` event to track when a feature flag resolves:
|
|
160
|
-
|
|
161
|
-
```ts
|
|
162
|
-
client.eventBus.watch((event) => {
|
|
163
|
-
if (event.type !== 'feature_decide') return
|
|
164
|
-
|
|
165
|
-
const { feature } = event
|
|
166
|
-
console.log(`Flag "${feature.id}" resolved to bucket:`, feature.bucket)
|
|
167
|
-
// Example output: the feature flag resolved to the bucket true.
|
|
168
|
-
|
|
169
|
-
// Send the decision to your analytics.
|
|
170
|
-
analytics.track('Feature Decision', {
|
|
171
|
-
featureId: feature.id,
|
|
172
|
-
bucket: feature.bucket,
|
|
173
|
-
})
|
|
174
|
-
})
|
|
175
|
-
```
|
|
176
|
-
|
|
177
|
-
A watch on `eventBus` reports only what happens after you subscribe.
|
|
178
|
-
|
|
179
|
-
## Read the events that already happened
|
|
180
|
-
|
|
181
|
-
`client.events` is a store of every event since the client started, in order. Each entry
|
|
182
|
-
holds an `id`, the time `at`, and the `payload` that went on the bus.
|
|
183
|
-
|
|
184
|
-
```ts
|
|
185
|
-
const alreadyAllocated = client.events
|
|
186
|
-
.getState()
|
|
187
|
-
.filter((entry) => entry.payload.type === 'feature_decide')
|
|
188
|
-
```
|
|
189
|
-
|
|
190
|
-
Use it when your code starts after Picked does, and a `feature_decide` that you needed
|
|
191
|
-
already happened before you subscribed.
|
|
192
|
-
|
|
193
|
-
## Versions and cache invalidation
|
|
194
|
-
|
|
195
|
-
The SDK caches a feature flag decision in browser storage. It uses `localStorage`, or
|
|
196
|
-
`sessionStorage` in a preview. The cache key derives from the feature flag ID and the version,
|
|
197
|
-
so a visitor keeps the same decision across page loads.
|
|
198
|
-
|
|
199
|
-
:::note
|
|
200
|
-
The SDK keeps a bucket value in storage as text. It reads `'true'` and `'false'` back as
|
|
201
|
-
booleans. A variant with the name `true` or `false` therefore comes back as a boolean.
|
|
202
|
-
Give each variant a different name.
|
|
203
|
-
:::
|
|
204
|
-
|
|
205
|
-
### How versions work
|
|
206
|
-
|
|
207
|
-
A feature flag that you create in the dashboard starts at version 1. The SDK uses the
|
|
208
|
-
version to build the cache key. A feature flag at version 3 caches under `v3`.
|
|
209
|
-
|
|
210
|
-
The version affects **the cache only**. It is not part of the allocation. For a feature flag
|
|
211
|
-
that you control from the dashboard, the allocation derives from the visitor ID and
|
|
212
|
-
the weight of the feature flag.
|
|
213
|
-
|
|
214
|
-
### What happens when you increment the version
|
|
215
|
-
|
|
216
|
-
When you increment the version of a feature flag in the dashboard:
|
|
217
|
-
|
|
218
|
-
1. **The cache key changes.** The old entry, `v3`, no longer matches the new key,
|
|
219
|
-
`v4`. The SDK therefore treats the feature flag as undecided.
|
|
220
|
-
2. **The `decide` function runs again.** On the next page load, the SDK calls
|
|
221
|
-
`decide()` again and caches the new result.
|
|
222
|
-
3. **Picked evaluates each visitor again and moves nobody.** For a feature flag that you
|
|
223
|
-
control from the dashboard the allocation is deterministic. The same visitor
|
|
224
|
-
against an unchanged weight gives the same bucket.
|
|
225
|
-
|
|
226
|
-
:::note
|
|
227
|
-
The new version clears the cached decisions and runs the allocation again. It moves
|
|
228
|
-
no visitor between groups. With an unchanged weight, everybody lands where they were.
|
|
229
|
-
Increment the version after you change a weight, so that Picked evaluates a visitor
|
|
230
|
-
with a cached decision against the new weight.
|
|
231
|
-
:::
|
|
232
|
-
|
|
233
|
-
### The SDK `key` and the dashboard version
|
|
234
|
-
|
|
235
|
-
For a feature flag that you define in SDK code, use the `key` field to set the version
|
|
236
|
-
yourself. This applies when you do not read the feature flag from the dashboard:
|
|
237
|
-
|
|
238
|
-
```ts
|
|
239
|
-
features: {
|
|
240
|
-
'summer-sale': {
|
|
241
|
-
key: 'summer-sale-v2', // Change this to invalidate the cache.
|
|
242
|
-
// The other options go here.
|
|
243
|
-
},
|
|
244
|
-
}
|
|
245
|
-
```
|
|
246
|
-
|
|
247
|
-
For a feature flag that you control from the dashboard, Picked sets the version for you. The
|
|
248
|
-
dashboard adds the version number to the end of the cache key that the SDK uses.
|
|
249
|
-
|
|
250
|
-
## Related
|
|
251
|
-
|
|
252
|
-
- [How to read a feature flag](/how-to/read-a-feature-flag) — the accessors in use.
|
|
253
|
-
- [About feature flag allocation](/explanation/feature-flag-allocation) — when a visitor
|
|
254
|
-
enters a test.
|
|
255
|
-
- [Feature flags](/reference/dashboard/features) — the dashboard controls.
|
|
256
|
-
|