@picked/svelte 0.0.1-dev.1780446300503 → 0.0.1-dev.1780464669265

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.
@@ -7,7 +7,7 @@
7
7
  * re-renders reactively.
8
8
  */
9
9
  import type { ExperienceStore, ExperienceTarget } from '@picked/client'
10
- import { evaluateConditionMemo, hashRule } from '@picked/client/server'
10
+ import { evaluateConditionMemo, hashRule, ruleReferencesAction } from '@picked/client/server'
11
11
  import { getPicked, useUnit } from '../hooks'
12
12
  import ExperienceHost from './ExperienceHost.svelte'
13
13
 
@@ -26,7 +26,7 @@
26
26
  const { name }: Props = $props()
27
27
 
28
28
  const client = getPicked()
29
- const selector = `.picked-slot-${name}`
29
+ const selector = $derived(`.picked-slot-${name}`)
30
30
 
31
31
  const PLACEMENT_ORDER: ExperienceTarget['placement'][] = ['before', 'prepend', 'append', 'after']
32
32
 
@@ -54,10 +54,11 @@
54
54
  }
55
55
 
56
56
  /**
57
- * Maps an experience to a slot candidate, or null when it does not target this slot.
57
+ * Maps an experience to a slot candidate, or null when it does not target this slot, uses the
58
+ * deferred `replace` placement, or carries an action-referencing condition.
58
59
  *
59
60
  * @param {ExperienceStore} experience - The experience to inspect.
60
- * @returns {Candidate | null} The candidate, or null when the experience does not target this slot.
61
+ * @returns {Candidate | null} The candidate, or null when the experience is not an eligible slot match.
61
62
  * @example
62
63
  * toCandidate(experienceStore)
63
64
  */
@@ -70,6 +71,20 @@
70
71
  return null
71
72
  }
72
73
 
74
+ // `replace` is deferred (first-wins semantics are not implemented yet), so skip it rather than
75
+ // letting it fall through and render appended-last.
76
+ if (target.placement === 'replace') {
77
+ return null
78
+ }
79
+
80
+ // Action-referencing conditions are never cached (their side effect must re-run), so they can
81
+ // never resolve through the synchronous `peek` the slot path relies on. Slots do not support
82
+ // action-gated conditions in v1; excluding them also stops the selection effect from re-firing
83
+ // the action on every render.
84
+ if (ruleReferencesAction(config.decisionLogic)) {
85
+ return null
86
+ }
87
+
73
88
  return {
74
89
  experience,
75
90
  placement: target.placement,
@@ -40,7 +40,10 @@
40
40
  // content arrives pre-registered via the snapshot.
41
41
  $effect(() => {
42
42
  if ($ready) {
43
- void experience.prepareExperienceContentFx()
43
+ // Content fetch failures (e.g. a 404 when the content endpoint is unavailable) are already
44
+ // swallowed inside the effect; the explicit catch guarantees no unhandled rejection even if
45
+ // that contract changes, so a missing/erroring content endpoint never breaks rendering.
46
+ experience.prepareExperienceContentFx().catch(() => undefined)
44
47
  }
45
48
  })
46
49
 
@@ -1,5 +1,29 @@
1
1
  import { AdaptedComponent, ExperienceInstance, Picked } from '@picked/client';
2
+ /**
3
+ * Builds the Svelte context map exposing the client and experience instance to a mounted component.
4
+ *
5
+ * @param {Picked} client - The Picked client.
6
+ * @param {ExperienceInstance} experience - The experience instance.
7
+ * @returns {Map<symbol, Picked | ExperienceInstance>} The context map keyed by the client and experience context symbols.
8
+ * @example
9
+ * createContext(client, experience)
10
+ */
2
11
  export declare function createContext(client: Picked, experience: ExperienceInstance): Map<symbol, Picked | ExperienceInstance>;
12
+ /**
13
+ * Renders an adapted Svelte component into a shadow root, injecting its stylesheets and inline CSS.
14
+ *
15
+ * @param {ShadowRoot} shadowRoot - The shadow root to render into.
16
+ * @param {AdaptedComponent<string, unknown>} component - The adapted component to render.
17
+ * @param {Picked} client - The Picked client.
18
+ * @param {ExperienceInstance} experience - The experience instance.
19
+ * @param {object} options - Stylesheets and inline CSS to inject into the shadow root.
20
+ * @param {string[]} [options.stylesheets] - Stylesheet URLs to inject as `<link>` elements.
21
+ * @param {string[]} [options.css] - Inline CSS blocks to inject as `<style>` elements.
22
+ * @returns {Promise<void>} A promise that resolves once the component is mounted.
23
+ * @throws {Error} When the component is not a valid adapted Svelte component.
24
+ * @example
25
+ * await renderSvelteComponent(shadowRoot, component, client, experience, {})
26
+ */
3
27
  export declare const renderSvelteComponent: (shadowRoot: ShadowRoot, component: AdaptedComponent<string, unknown>, client: Picked, experience: ExperienceInstance, options: {
4
28
  stylesheets?: string[];
5
29
  css?: string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@picked/svelte",
3
- "version": "0.0.1-dev.1780446300503",
3
+ "version": "0.0.1-dev.1780464669265",
4
4
  "dependencies": {
5
5
  "d3": "^7.9.0"
6
6
  },
@@ -14,7 +14,7 @@
14
14
  "@tsconfig/svelte": "^5.0.4",
15
15
  "@types/d3": "^7.4.3",
16
16
  "@types/node": "^22",
17
- "@vitest/coverage-v8": "^4.1.0",
17
+ "@vitest/coverage-v8": "^4.1.8",
18
18
  "effector": "^23.3.0",
19
19
  "fast-glob": "^3.3.3",
20
20
  "happy-dom": "^20.8.8",
@@ -25,7 +25,7 @@
25
25
  "typedoc-plugin-markdown": "^4.6.3",
26
26
  "vite": "^8.0.8",
27
27
  "vite-plugin-dts": "^4.5.4",
28
- "vitest": "^4.1.0"
28
+ "vitest": "^4.1.8"
29
29
  },
30
30
  "exports": {
31
31
  ".": {
@@ -106,7 +106,7 @@
106
106
  },
107
107
  "module": "./dist/index.js",
108
108
  "peerDependencies": {
109
- "@picked/client": "0.0.1-dev.1780446300503",
109
+ "@picked/client": "0.0.1-dev.1780464669265",
110
110
  "effector": "^23.3.0",
111
111
  "svelte": "^5.46.4"
112
112
  },