@picked/svelte 0.0.62-next.1 → 0.0.62-next.11
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/components/LazyImage.svelte +1 -1
- package/dist/hooks/content.d.ts +18 -0
- package/dist/hooks/content.js +1 -0
- package/dist/hooks/events.js +1 -1
- package/dist/hooks/index.d.ts +2 -1
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/step.d.ts +25 -2
- package/dist/hooks/step.js +1 -1
- package/dist/plugins/devtools/screens/project/ProjectScreen.svelte +0 -1
- package/dist/plugins/devtools/screens/responses/ResponseTableRow.svelte +11 -9
- package/dist/router/StepRouter.svelte +11 -45
- package/package.json +2 -2
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
if (isConvincelyDomain(url)) {
|
|
89
89
|
const encodedUrl = encodeURIComponent(url.toString())
|
|
90
90
|
const optimizedSize = findClosestSize(targetWidth)
|
|
91
|
-
return `https://img.
|
|
91
|
+
return `https://img.picked-content.com/_next/image?url=${encodedUrl}&w=${optimizedSize}&q=75`
|
|
92
92
|
}
|
|
93
93
|
|
|
94
94
|
// For other domains, return the original URL
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { Store } from 'effector';
|
|
2
|
+
import { Content } from '@picked/client';
|
|
3
|
+
/**
|
|
4
|
+
* Returns the registry store for a content id, mirroring `getField(key)`. Resolves
|
|
5
|
+
* the Picked client via `getPicked()` and returns `client.contents.getById(id)`.
|
|
6
|
+
*
|
|
7
|
+
* @param {string} id - The content record id to look up.
|
|
8
|
+
* @returns {Store<Content | null>} The registry store; `null` until content is registered.
|
|
9
|
+
* @example
|
|
10
|
+
* ```svelte
|
|
11
|
+
* <script>
|
|
12
|
+
* import { getContent } from '@picked/svelte'
|
|
13
|
+
* const banner = getContent('lc_banner')
|
|
14
|
+
* </script>
|
|
15
|
+
* <h1>{$banner?.data?.headline ?? ''}</h1>
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare function getContent(id: string): Store<Content | null>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{getPicked as e}from"./client.js";function t(t){return e().contents.getById(t)}export{t as getContent};
|
package/dist/hooks/events.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getExperience as e,getPicked as t}from"./client.js";import{attach as n}from"effector";import{trackRecommendationPresentEvent as r}from"@picked/analytics";var i=()=>{let{session:i,projectId:a
|
|
1
|
+
import{getExperience as e,getPicked as t}from"./client.js";import{attach as n}from"effector";import{trackRecommendationPresentEvent as r}from"@picked/analytics";var i=()=>{let{session:i,projectId:a}=t(),o=e();return n({source:{config:o.configStore,step:o.currentStepStore,sessionSnapshot:i.store},async effect({config:e,step:t,sessionSnapshot:n},i){if(!t)throw Error(`Cannot track recommendation present event: missing experience step.`);return r({projectId:a,experience:{id:o.experienceId,title:e.name},sessionId:n.id,identifiers:n.identifiers,isUser:n.isUser,step:t,productList:i})}})};export{i as getTrackRecommendationPresentEvent};
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -3,7 +3,8 @@ export { getPicked, getExperience } from './client';
|
|
|
3
3
|
export { getPredicate, getPredicateResult } from './predicate';
|
|
4
4
|
export { getFeature, getFeatureResult } from './feature';
|
|
5
5
|
export { getAction, getActionResult } from './action';
|
|
6
|
-
export { getStep, setStepContext } from './step';
|
|
6
|
+
export { getStep, setStepContext, getStepContent } from './step';
|
|
7
|
+
export { getContent } from './content';
|
|
7
8
|
export { useUnit, getContextScope, setContextScope } from './stores';
|
|
8
9
|
export { createSessionStorageStore, createLocalStorageStore } from './storage.js';
|
|
9
10
|
export { getTrackRecommendationPresentEvent } from './events';
|
package/dist/hooks/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getExperience as e,getPicked as t}from"./client.js";import{getPredicate as n,getPredicateResult as r}from"./predicate.js";import{getFeature as i,getFeatureResult as a}from"./feature.js";import{getAction as o,getActionResult as s}from"./action.js";import{getStep as c,setStepContext as
|
|
1
|
+
import{getExperience as e,getPicked as t}from"./client.js";import{getPredicate as n,getPredicateResult as r}from"./predicate.js";import{getFeature as i,getFeatureResult as a}from"./feature.js";import{getAction as o,getActionResult as s}from"./action.js";import{getStep as c,getStepContent as l,setStepContext as u}from"./step.js";import{getContent as d}from"./content.js";import{getContextScope as f,setContextScope as p,useUnit as m}from"./stores.js";import{createLocalStorageStore as h,createSessionStorageStore as g}from"./storage.js";import{getTrackRecommendationPresentEvent as _}from"./events.js";import{createQuery as v,queryCache as y,queryPresets as b}from"./create-query/index.js";export{h as createLocalStorageStore,v as createQuery,g as createSessionStorageStore,o as getAction,s as getActionResult,d as getContent,f as getContextScope,e as getExperience,i as getFeature,a as getFeatureResult,t as getPicked,n as getPredicate,r as getPredicateResult,c as getStep,l as getStepContent,_ as getTrackRecommendationPresentEvent,y as queryCache,b as queryPresets,p as setContextScope,u as setStepContext,m as useUnit};
|
package/dist/hooks/step.d.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { Store } from 'effector';
|
|
2
|
-
import { ExperienceStep } from '@picked/client';
|
|
2
|
+
import { Content, ExperienceStep } from '@picked/client';
|
|
3
3
|
import { FormInstance, FormField } from '../form/create-form.svelte';
|
|
4
4
|
export interface StepContext extends FormInstance {
|
|
5
5
|
step: Store<ExperienceStep>;
|
|
6
6
|
/** Directly accessible fields with current response values — usable without a form. */
|
|
7
7
|
fields: Store<FormField[]>;
|
|
8
|
+
/**
|
|
9
|
+
* Reactive store of the current step's CMS layout content. Resolves the step's
|
|
10
|
+
* `layoutContentId` against `client.contents` and stays reactive.
|
|
11
|
+
*/
|
|
12
|
+
layoutContentStore: Store<Content | null>;
|
|
8
13
|
isActive: Store<boolean>;
|
|
9
14
|
/** @deprecated Use `isActive` instead. */
|
|
10
15
|
isActiveStep: Store<boolean>;
|
|
@@ -12,13 +17,31 @@ export interface StepContext extends FormInstance {
|
|
|
12
17
|
/**
|
|
13
18
|
* Creates and sets step context in the Svelte context tree.
|
|
14
19
|
*
|
|
15
|
-
* @param stepKey - The step key.
|
|
20
|
+
* @param {string} stepKey - The step key.
|
|
21
|
+
* @returns {StepContext} The created step context.
|
|
16
22
|
* @example setStepContext('step-1')
|
|
17
23
|
*/
|
|
18
24
|
export declare function setStepContext(stepKey: string): StepContext;
|
|
19
25
|
/**
|
|
20
26
|
* Retrieves the step context from the Svelte context tree.
|
|
21
27
|
*
|
|
28
|
+
* @returns {StepContext} The current step context.
|
|
22
29
|
* @example getStep()
|
|
23
30
|
*/
|
|
24
31
|
export declare function getStep(): StepContext;
|
|
32
|
+
/**
|
|
33
|
+
* Returns a Svelte/Effector store that yields the current step's resolved CMS content
|
|
34
|
+
* data, or `null` when no content is registered for the step's `layoutContentId`.
|
|
35
|
+
* Subscribers automatically receive updates when content is registered or replaced.
|
|
36
|
+
*
|
|
37
|
+
* @returns {Store<Record<string, unknown> | null>} A store of the Content record's `data`.
|
|
38
|
+
* @example
|
|
39
|
+
* ```svelte
|
|
40
|
+
* <script>
|
|
41
|
+
* import { getStepContent } from '@picked/svelte'
|
|
42
|
+
* const content = getStepContent()
|
|
43
|
+
* </script>
|
|
44
|
+
* <h1>{$content?.headline ?? ''}</h1>
|
|
45
|
+
* ```
|
|
46
|
+
*/
|
|
47
|
+
export declare function getStepContent(): Store<Record<string, unknown> | null>;
|
package/dist/hooks/step.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{STEP_CONTEXT_KEY as e}from"../context.js";import{getPicked as t}from"./client.js";import{getStepRouter as n}from"../router/context.js";import{getContext as
|
|
1
|
+
import{STEP_CONTEXT_KEY as e}from"../context.js";import{getPicked as t}from"./client.js";import{getStepRouter as n}from"../router/context.js";import{combine as r}from"effector";import{getContext as i,setContext as a}from"svelte";import{createForm as o}from"../form/create-form.svelte";function s(i){let s=t(),{activeStep:c}=n(),l=c.map(e=>e?.key===i),u=s.steps.listStore.map(e=>e.find(e=>e.key===i)??{id:i,key:i,name:``,fieldKeys:[]}),d=o(i,u.map(e=>e.name),u.map(e=>e.fieldKeys));return a(e,{step:u,layoutContentStore:r(u,s.contents.indexStore,(e,t)=>e.layoutContentId?t[e.layoutContentId]??null:null,{skipVoid:!1}),isActive:l,isActiveStep:l,...d})}function c(){return i(e)}function l(){let{layoutContentStore:e}=c();return e.map(e=>e?.data??null,{skipVoid:!1})}export{c as getStep,l as getStepContent,s as setStepContext};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
/** @file Editable table row for a single field response in the devtools responses screen. */
|
|
3
|
-
import type { ResponseListItem,
|
|
3
|
+
import type { ResponseListItem, Field, FieldValue, JsonValue } from '@picked/client'
|
|
4
4
|
import { getPicked } from '../../../../hooks'
|
|
5
5
|
import { Button, Text, CodeBlock, Banner, Stack } from '../../ui'
|
|
6
6
|
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
let editValue = ''
|
|
14
14
|
let editError = ''
|
|
15
15
|
// eslint-disable-next-line svelte/prefer-svelte-reactivity -- Set is reassigned for Svelte reactivity via `selectedOptions = selectedOptions`
|
|
16
|
-
let selectedOptions: Set<
|
|
16
|
+
let selectedOptions: Set<JsonValue> = new Set()
|
|
17
17
|
|
|
18
18
|
$: hasOptions = Array.isArray(field?.options) && field.options.length > 0
|
|
19
19
|
$: staticOptions = Array.isArray(field?.options) ? field.options : null
|
|
@@ -22,7 +22,8 @@
|
|
|
22
22
|
/**
|
|
23
23
|
* Formats a response value for display, handling arrays, objects, and primitives.
|
|
24
24
|
*
|
|
25
|
-
* @param value - The response value to format.
|
|
25
|
+
* @param {unknown} value - The response value to format.
|
|
26
|
+
* @returns {string} The display string for the value.
|
|
26
27
|
* @example
|
|
27
28
|
* ```typescript
|
|
28
29
|
* formatValue(['a', 'b']) // 'a, b'
|
|
@@ -87,13 +88,13 @@
|
|
|
87
88
|
/**
|
|
88
89
|
* Toggles selection of a field option, supporting both single and multi-select modes.
|
|
89
90
|
*
|
|
90
|
-
* @param optionValue - The option value to toggle.
|
|
91
|
+
* @param {JsonValue} optionValue - The option value to toggle.
|
|
91
92
|
* @example
|
|
92
93
|
* ```typescript
|
|
93
94
|
* toggleOption('red') // selects or deselects the 'red' option
|
|
94
95
|
* ```
|
|
95
96
|
*/
|
|
96
|
-
function toggleOption(optionValue:
|
|
97
|
+
function toggleOption(optionValue: JsonValue) {
|
|
97
98
|
if (field?.multiple) {
|
|
98
99
|
if (selectedOptions.has(optionValue)) {
|
|
99
100
|
selectedOptions.delete(optionValue)
|
|
@@ -110,14 +111,15 @@
|
|
|
110
111
|
/**
|
|
111
112
|
* Parses a string input into a typed value based on the field's type.
|
|
112
113
|
*
|
|
113
|
-
* @param input - The raw string input to parse.
|
|
114
|
+
* @param {string} input - The raw string input to parse.
|
|
115
|
+
* @returns {FieldValue} The parsed value (null, number, boolean, JSON, or string).
|
|
114
116
|
* @example
|
|
115
117
|
* ```typescript
|
|
116
118
|
* parseValue('42') // 42 (when field.type is 'number')
|
|
117
119
|
* parseValue('true') // true (when field.type is 'boolean')
|
|
118
120
|
* ```
|
|
119
121
|
*/
|
|
120
|
-
function parseValue(input: string):
|
|
122
|
+
function parseValue(input: string): FieldValue {
|
|
121
123
|
const trimmed = input.trim()
|
|
122
124
|
|
|
123
125
|
if (trimmed === '' || trimmed === '-') {
|
|
@@ -173,7 +175,7 @@
|
|
|
173
175
|
newValue = parseValue(editValue)
|
|
174
176
|
}
|
|
175
177
|
|
|
176
|
-
const result = await client.responses.commit({ [field.
|
|
178
|
+
const result = await client.responses.commit({ [field.key]: newValue })
|
|
177
179
|
|
|
178
180
|
if (result.errors.length > 0) {
|
|
179
181
|
editError = result.errors[0].userMessage
|
|
@@ -197,7 +199,7 @@
|
|
|
197
199
|
* ```
|
|
198
200
|
*/
|
|
199
201
|
function handleClear() {
|
|
200
|
-
client.responses.clear(field.
|
|
202
|
+
client.responses.clear(field.key)
|
|
201
203
|
}
|
|
202
204
|
</script>
|
|
203
205
|
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
/** @file Root router component that manages step registration and active step detection via Effector. */
|
|
3
|
-
import { createEvent, createStore
|
|
4
|
-
import { supportsWindow } from '@picked/client'
|
|
3
|
+
import { combine, createEvent, createStore } from 'effector'
|
|
5
4
|
import { getExperience } from '../hooks'
|
|
6
5
|
import { setStepRouter, type Step } from './context'
|
|
7
6
|
|
|
@@ -9,57 +8,24 @@
|
|
|
9
8
|
|
|
10
9
|
const { currentStepStore } = experience
|
|
11
10
|
|
|
12
|
-
const activeStepStore = createStore<Step | null>(null)
|
|
13
|
-
let hasActiveStep = false
|
|
14
11
|
const stepsStore = createStore<Step[]>([])
|
|
15
12
|
|
|
16
|
-
const
|
|
17
|
-
const
|
|
18
|
-
const setActiveStepEvent = createEvent<Step | null>()
|
|
13
|
+
const registerStep = createEvent<Step>()
|
|
14
|
+
const unregisterStep = createEvent<Step>()
|
|
19
15
|
|
|
20
|
-
stepsStore
|
|
21
|
-
|
|
16
|
+
stepsStore
|
|
17
|
+
.on(registerStep, (state, step) => [...state, step])
|
|
18
|
+
.on(unregisterStep, (state, step) => state.filter((s) => s !== step))
|
|
22
19
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
})
|
|
28
|
-
|
|
29
|
-
const registerStep = (step: Step) => {
|
|
30
|
-
// todo: getIsSSR context
|
|
31
|
-
|
|
32
|
-
if (!supportsWindow()) {
|
|
33
|
-
// In SSR we should set the activeStep immediately if it is a match.
|
|
34
|
-
// If there are more Routes being registered after a match is found,
|
|
35
|
-
// we just skip them.
|
|
36
|
-
if (hasActiveStep) return
|
|
37
|
-
|
|
38
|
-
const isMatchingStep = step.key === currentStepStore.getState()?.key
|
|
39
|
-
|
|
40
|
-
if (isMatchingStep) {
|
|
41
|
-
setActiveStepEvent(step)
|
|
42
|
-
hasActiveStep = true
|
|
43
|
-
}
|
|
44
|
-
} else {
|
|
45
|
-
registerStepEvent(step)
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
const unregisterStep = (step: Step) => {
|
|
50
|
-
unregisterStepEvent(step)
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
sample({
|
|
54
|
-
source: { steps: stepsStore, currentStep: currentStepStore },
|
|
55
|
-
fn: ({ steps, currentStep }) => steps.find((s) => s.key === currentStep?.key) || null,
|
|
56
|
-
target: setActiveStepEvent,
|
|
57
|
-
})
|
|
20
|
+
const activeStepStore = combine(
|
|
21
|
+
{ steps: stepsStore, currentStep: currentStepStore },
|
|
22
|
+
({ steps, currentStep }) => steps.find((s) => s.key === currentStep?.key) ?? null,
|
|
23
|
+
)
|
|
58
24
|
|
|
59
25
|
setStepRouter({
|
|
60
26
|
registerStep,
|
|
61
27
|
unregisterStep,
|
|
62
|
-
activeStep: activeStepStore
|
|
28
|
+
activeStep: activeStepStore,
|
|
63
29
|
})
|
|
64
30
|
</script>
|
|
65
31
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@picked/svelte",
|
|
3
|
-
"version": "0.0.62-next.
|
|
3
|
+
"version": "0.0.62-next.11",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"d3": "^7.9.0"
|
|
6
6
|
},
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
},
|
|
89
89
|
"module": "./dist/index.js",
|
|
90
90
|
"peerDependencies": {
|
|
91
|
-
"@picked/client": "0.0.62-next.
|
|
91
|
+
"@picked/client": "0.0.62-next.11",
|
|
92
92
|
"effector": "^23.3.0",
|
|
93
93
|
"svelte": "^5.46.4"
|
|
94
94
|
},
|