@openshop/svelte 0.7.0 → 0.9.0

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/index.d.ts CHANGED
@@ -29,6 +29,7 @@ interface CartStores {
29
29
  addDeliveryAddresses: CartStore["addDeliveryAddresses"];
30
30
  updateDeliveryAddresses: CartStore["updateDeliveryAddresses"];
31
31
  removeDeliveryAddresses: CartStore["removeDeliveryAddresses"];
32
+ setSelectedDeliveryOptions: CartStore["setSelectedDeliveryOptions"];
32
33
  refresh: CartStore["refresh"];
33
34
  };
34
35
  }
package/dist/index.js CHANGED
@@ -38,6 +38,7 @@ function createCartStores(cart) {
38
38
  addDeliveryAddresses: cart.addDeliveryAddresses.bind(cart),
39
39
  updateDeliveryAddresses: cart.updateDeliveryAddresses.bind(cart),
40
40
  removeDeliveryAddresses: cart.removeDeliveryAddresses.bind(cart),
41
+ setSelectedDeliveryOptions: cart.setSelectedDeliveryOptions.bind(cart),
41
42
  refresh: cart.refresh.bind(cart)
42
43
  }
43
44
  };
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/store.ts","../src/cart.ts","../src/product.ts","../src/search.ts","../src/i18n.ts"],"names":["writable"],"mappings":"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","file":"index.js","sourcesContent":["import { readable, type Readable } from \"svelte/store\";\nimport {\n refEquals,\n type EqualityFn,\n type ReadableStore,\n type Selector,\n} from \"@openshop/core\";\n\n/**\n * Adapt an OpenShop reactive store into a Svelte `Readable` of a selected\n * slice. The Svelte store contract (subscribe-with-immediate-value) maps\n * cleanly onto the core's `subscribeRaw` + selector model, and the underlying\n * subscription is released when the last Svelte subscriber leaves.\n */\nexport function selectStore<T, R>(\n store: ReadableStore<T>,\n selector: Selector<T, R>,\n equals: EqualityFn<R> = refEquals,\n): Readable<R> {\n return readable(selector(store.get()), (set) => {\n let current = selector(store.get());\n set(current);\n return store.subscribeRaw(() => {\n const next = selector(store.get());\n if (!equals(current, next)) {\n current = next;\n set(next);\n }\n });\n });\n}\n","import type { Readable } from \"svelte/store\";\nimport type { Cart, CartStatus, CartStore } from \"@openshop/core\";\nimport { selectStore } from \"./store.js\";\n\nexport interface CartStores {\n cart: Readable<Cart | null>;\n count: Readable<number>;\n status: Readable<CartStatus>;\n isUpdating: Readable<boolean>;\n error: Readable<string | null>;\n actions: {\n addLine: CartStore[\"addLine\"];\n addLines: CartStore[\"addLines\"];\n updateLine: CartStore[\"updateLine\"];\n removeLine: CartStore[\"removeLine\"];\n setDiscountCodes: CartStore[\"setDiscountCodes\"];\n setGiftCardCodes: CartStore[\"setGiftCardCodes\"];\n setBuyerIdentity: CartStore[\"setBuyerIdentity\"];\n setAttributes: CartStore[\"setAttributes\"];\n setNote: CartStore[\"setNote\"];\n addDeliveryAddresses: CartStore[\"addDeliveryAddresses\"];\n updateDeliveryAddresses: CartStore[\"updateDeliveryAddresses\"];\n removeDeliveryAddresses: CartStore[\"removeDeliveryAddresses\"];\n refresh: CartStore[\"refresh\"];\n };\n}\n\n/**\n * Derive a set of Svelte stores (plus bound actions) from a `CartStore`.\n * Each store updates only when its slice changes.\n *\n * ```svelte\n * <script>\n * import { createCartStores } from \"@openshop/svelte\";\n * const { count, actions } = createCartStores(cart);\n * </script>\n * <button on:click={() => actions.addLine({ merchandiseId })}>Cart {$count}</button>\n * ```\n */\nexport function createCartStores(cart: CartStore): CartStores {\n return {\n cart: selectStore(cart, (s) => s.cart),\n count: selectStore(cart, (s) => s.cart?.totalQuantity ?? 0),\n status: selectStore(cart, (s) => s.status),\n isUpdating: selectStore(cart, (s) => s.status === \"updating\"),\n error: selectStore(cart, (s) => s.error),\n actions: {\n addLine: cart.addLine.bind(cart),\n addLines: cart.addLines.bind(cart),\n updateLine: cart.updateLine.bind(cart),\n removeLine: cart.removeLine.bind(cart),\n setDiscountCodes: cart.setDiscountCodes.bind(cart),\n setGiftCardCodes: cart.setGiftCardCodes.bind(cart),\n setBuyerIdentity: cart.setBuyerIdentity.bind(cart),\n setAttributes: cart.setAttributes.bind(cart),\n setNote: cart.setNote.bind(cart),\n addDeliveryAddresses: cart.addDeliveryAddresses.bind(cart),\n updateDeliveryAddresses: cart.updateDeliveryAddresses.bind(cart),\n removeDeliveryAddresses: cart.removeDeliveryAddresses.bind(cart),\n refresh: cart.refresh.bind(cart),\n },\n };\n}\n","import { derived, writable, type Readable, type Writable } from \"svelte/store\";\nimport {\n findVariantBySelection,\n getInitialSelection,\n getOptionValueStates,\n type OptionSelection,\n type OptionValueState,\n type Product,\n type ProductVariant,\n} from \"@openshop/core\";\n\nexport interface VariantSelectionStores {\n selection: Writable<OptionSelection>;\n selectedVariant: Readable<ProductVariant | undefined>;\n options: Readable<{ name: string; values: OptionValueState[] }[]>;\n setOption: (optionName: string, value: string) => void;\n}\n\n/** Svelte stores driving variant selection for a product. */\nexport function createVariantSelection(\n product: Product,\n initial?: OptionSelection,\n): VariantSelectionStores {\n const selection = writable<OptionSelection>(\n initial ?? getInitialSelection(product),\n );\n\n const selectedVariant = derived(selection, ($selection) =>\n findVariantBySelection(product, $selection),\n );\n\n const options = derived(selection, ($selection) =>\n product.options.map((option) => ({\n name: option.name,\n values: getOptionValueStates(product, option.name, $selection),\n })),\n );\n\n function setOption(optionName: string, value: string): void {\n selection.update((prev) => ({ ...prev, [optionName]: value }));\n }\n\n return { selection, selectedVariant, options, setOption };\n}\n","import { writable, type Readable, type Writable } from \"svelte/store\";\nimport type { PredictiveSearchResult } from \"@openshop/core\";\n\nconst EMPTY: PredictiveSearchResult = {\n products: [],\n collections: [],\n pages: [],\n articles: [],\n queries: [],\n};\n\nexport interface PredictiveSearchOptions {\n debounceMs?: number;\n minLength?: number;\n}\n\nexport interface PredictiveSearchStores {\n term: Writable<string>;\n results: Readable<PredictiveSearchResult>;\n loading: Readable<boolean>;\n error: Readable<unknown>;\n clear: () => void;\n /** Stop watching `term`. Call when the component is destroyed. */\n destroy: () => void;\n}\n\n/**\n * Debounced predictive search as Svelte stores, with stale-response protection.\n * Bind an input to `term`; read `$results` / `$loading`.\n */\nexport function createPredictiveSearch(\n search: (term: string) => Promise<PredictiveSearchResult>,\n options: PredictiveSearchOptions = {},\n): PredictiveSearchStores {\n const { debounceMs = 200, minLength = 2 } = options;\n const term = writable(\"\");\n const results = writable<PredictiveSearchResult>(EMPTY);\n const loading = writable(false);\n const error = writable<unknown>(null);\n\n let requestId = 0;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const unsubscribe = term.subscribe((value) => {\n if (timer) clearTimeout(timer);\n const trimmed = value.trim();\n if (trimmed.length < minLength) {\n results.set(EMPTY);\n loading.set(false);\n return;\n }\n const id = ++requestId;\n loading.set(true);\n timer = setTimeout(async () => {\n try {\n const next = await search(trimmed);\n if (id === requestId) {\n results.set(next);\n error.set(null);\n }\n } catch (err) {\n if (id === requestId) error.set(err);\n } finally {\n if (id === requestId) loading.set(false);\n }\n }, debounceMs);\n });\n\n function clear(): void {\n requestId += 1;\n if (timer) clearTimeout(timer);\n term.set(\"\");\n results.set(EMPTY);\n loading.set(false);\n error.set(null);\n }\n\n function destroy(): void {\n if (timer) clearTimeout(timer);\n unsubscribe();\n }\n\n return { term, results, loading, error, clear, destroy };\n}\n","import type { I18n, Locale } from \"@openshop/core\";\n\nexport interface I18nHelpers {\n locale: Locale;\n locales: Locale[];\n localizePath: (path: string, locale?: Locale) => string;\n alternates: (path: string) => { locale: Locale; href: string }[];\n}\n\n/**\n * Build locale helpers bound to the active locale. Framework-neutral (no Svelte\n * context dependency) so it works in load functions and components alike; stash\n * the result in Svelte context yourself if you want app-wide access.\n */\nexport function createI18nHelpers(\n i18n: I18n,\n locale: Locale,\n origin?: string,\n): I18nHelpers {\n return {\n locale,\n locales: i18n.locales,\n localizePath: (path, target = locale) =>\n i18n.localizePath(path, target, origin),\n alternates: (path) => i18n.alternates(path, origin),\n };\n}\n"]}
1
+ {"version":3,"sources":["../src/store.ts","../src/cart.ts","../src/product.ts","../src/search.ts","../src/i18n.ts"],"names":["writable"],"mappings":"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","file":"index.js","sourcesContent":["import { readable, type Readable } from \"svelte/store\";\nimport {\n refEquals,\n type EqualityFn,\n type ReadableStore,\n type Selector,\n} from \"@openshop/core\";\n\n/**\n * Adapt an OpenShop reactive store into a Svelte `Readable` of a selected\n * slice. The Svelte store contract (subscribe-with-immediate-value) maps\n * cleanly onto the core's `subscribeRaw` + selector model, and the underlying\n * subscription is released when the last Svelte subscriber leaves.\n */\nexport function selectStore<T, R>(\n store: ReadableStore<T>,\n selector: Selector<T, R>,\n equals: EqualityFn<R> = refEquals,\n): Readable<R> {\n return readable(selector(store.get()), (set) => {\n let current = selector(store.get());\n set(current);\n return store.subscribeRaw(() => {\n const next = selector(store.get());\n if (!equals(current, next)) {\n current = next;\n set(next);\n }\n });\n });\n}\n","import type { Readable } from \"svelte/store\";\nimport type { Cart, CartStatus, CartStore } from \"@openshop/core\";\nimport { selectStore } from \"./store.js\";\n\nexport interface CartStores {\n cart: Readable<Cart | null>;\n count: Readable<number>;\n status: Readable<CartStatus>;\n isUpdating: Readable<boolean>;\n error: Readable<string | null>;\n actions: {\n addLine: CartStore[\"addLine\"];\n addLines: CartStore[\"addLines\"];\n updateLine: CartStore[\"updateLine\"];\n removeLine: CartStore[\"removeLine\"];\n setDiscountCodes: CartStore[\"setDiscountCodes\"];\n setGiftCardCodes: CartStore[\"setGiftCardCodes\"];\n setBuyerIdentity: CartStore[\"setBuyerIdentity\"];\n setAttributes: CartStore[\"setAttributes\"];\n setNote: CartStore[\"setNote\"];\n addDeliveryAddresses: CartStore[\"addDeliveryAddresses\"];\n updateDeliveryAddresses: CartStore[\"updateDeliveryAddresses\"];\n removeDeliveryAddresses: CartStore[\"removeDeliveryAddresses\"];\n setSelectedDeliveryOptions: CartStore[\"setSelectedDeliveryOptions\"];\n refresh: CartStore[\"refresh\"];\n };\n}\n\n/**\n * Derive a set of Svelte stores (plus bound actions) from a `CartStore`.\n * Each store updates only when its slice changes.\n *\n * ```svelte\n * <script>\n * import { createCartStores } from \"@openshop/svelte\";\n * const { count, actions } = createCartStores(cart);\n * </script>\n * <button on:click={() => actions.addLine({ merchandiseId })}>Cart {$count}</button>\n * ```\n */\nexport function createCartStores(cart: CartStore): CartStores {\n return {\n cart: selectStore(cart, (s) => s.cart),\n count: selectStore(cart, (s) => s.cart?.totalQuantity ?? 0),\n status: selectStore(cart, (s) => s.status),\n isUpdating: selectStore(cart, (s) => s.status === \"updating\"),\n error: selectStore(cart, (s) => s.error),\n actions: {\n addLine: cart.addLine.bind(cart),\n addLines: cart.addLines.bind(cart),\n updateLine: cart.updateLine.bind(cart),\n removeLine: cart.removeLine.bind(cart),\n setDiscountCodes: cart.setDiscountCodes.bind(cart),\n setGiftCardCodes: cart.setGiftCardCodes.bind(cart),\n setBuyerIdentity: cart.setBuyerIdentity.bind(cart),\n setAttributes: cart.setAttributes.bind(cart),\n setNote: cart.setNote.bind(cart),\n addDeliveryAddresses: cart.addDeliveryAddresses.bind(cart),\n updateDeliveryAddresses: cart.updateDeliveryAddresses.bind(cart),\n removeDeliveryAddresses: cart.removeDeliveryAddresses.bind(cart),\n setSelectedDeliveryOptions: cart.setSelectedDeliveryOptions.bind(cart),\n refresh: cart.refresh.bind(cart),\n },\n };\n}\n","import { derived, writable, type Readable, type Writable } from \"svelte/store\";\nimport {\n findVariantBySelection,\n getInitialSelection,\n getOptionValueStates,\n type OptionSelection,\n type OptionValueState,\n type Product,\n type ProductVariant,\n} from \"@openshop/core\";\n\nexport interface VariantSelectionStores {\n selection: Writable<OptionSelection>;\n selectedVariant: Readable<ProductVariant | undefined>;\n options: Readable<{ name: string; values: OptionValueState[] }[]>;\n setOption: (optionName: string, value: string) => void;\n}\n\n/** Svelte stores driving variant selection for a product. */\nexport function createVariantSelection(\n product: Product,\n initial?: OptionSelection,\n): VariantSelectionStores {\n const selection = writable<OptionSelection>(\n initial ?? getInitialSelection(product),\n );\n\n const selectedVariant = derived(selection, ($selection) =>\n findVariantBySelection(product, $selection),\n );\n\n const options = derived(selection, ($selection) =>\n product.options.map((option) => ({\n name: option.name,\n values: getOptionValueStates(product, option.name, $selection),\n })),\n );\n\n function setOption(optionName: string, value: string): void {\n selection.update((prev) => ({ ...prev, [optionName]: value }));\n }\n\n return { selection, selectedVariant, options, setOption };\n}\n","import { writable, type Readable, type Writable } from \"svelte/store\";\nimport type { PredictiveSearchResult } from \"@openshop/core\";\n\nconst EMPTY: PredictiveSearchResult = {\n products: [],\n collections: [],\n pages: [],\n articles: [],\n queries: [],\n};\n\nexport interface PredictiveSearchOptions {\n debounceMs?: number;\n minLength?: number;\n}\n\nexport interface PredictiveSearchStores {\n term: Writable<string>;\n results: Readable<PredictiveSearchResult>;\n loading: Readable<boolean>;\n error: Readable<unknown>;\n clear: () => void;\n /** Stop watching `term`. Call when the component is destroyed. */\n destroy: () => void;\n}\n\n/**\n * Debounced predictive search as Svelte stores, with stale-response protection.\n * Bind an input to `term`; read `$results` / `$loading`.\n */\nexport function createPredictiveSearch(\n search: (term: string) => Promise<PredictiveSearchResult>,\n options: PredictiveSearchOptions = {},\n): PredictiveSearchStores {\n const { debounceMs = 200, minLength = 2 } = options;\n const term = writable(\"\");\n const results = writable<PredictiveSearchResult>(EMPTY);\n const loading = writable(false);\n const error = writable<unknown>(null);\n\n let requestId = 0;\n let timer: ReturnType<typeof setTimeout> | undefined;\n\n const unsubscribe = term.subscribe((value) => {\n if (timer) clearTimeout(timer);\n const trimmed = value.trim();\n if (trimmed.length < minLength) {\n results.set(EMPTY);\n loading.set(false);\n return;\n }\n const id = ++requestId;\n loading.set(true);\n timer = setTimeout(async () => {\n try {\n const next = await search(trimmed);\n if (id === requestId) {\n results.set(next);\n error.set(null);\n }\n } catch (err) {\n if (id === requestId) error.set(err);\n } finally {\n if (id === requestId) loading.set(false);\n }\n }, debounceMs);\n });\n\n function clear(): void {\n requestId += 1;\n if (timer) clearTimeout(timer);\n term.set(\"\");\n results.set(EMPTY);\n loading.set(false);\n error.set(null);\n }\n\n function destroy(): void {\n if (timer) clearTimeout(timer);\n unsubscribe();\n }\n\n return { term, results, loading, error, clear, destroy };\n}\n","import type { I18n, Locale } from \"@openshop/core\";\n\nexport interface I18nHelpers {\n locale: Locale;\n locales: Locale[];\n localizePath: (path: string, locale?: Locale) => string;\n alternates: (path: string) => { locale: Locale; href: string }[];\n}\n\n/**\n * Build locale helpers bound to the active locale. Framework-neutral (no Svelte\n * context dependency) so it works in load functions and components alike; stash\n * the result in Svelte context yourself if you want app-wide access.\n */\nexport function createI18nHelpers(\n i18n: I18n,\n locale: Locale,\n origin?: string,\n): I18nHelpers {\n return {\n locale,\n locales: i18n.locales,\n localizePath: (path, target = locale) =>\n i18n.localizePath(path, target, origin),\n alternates: (path) => i18n.alternates(path, origin),\n };\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openshop/svelte",
3
- "version": "0.7.0",
3
+ "version": "0.9.0",
4
4
  "description": "Svelte stores for OpenShop's framework-agnostic commerce core.",
5
5
  "license": "MIT",
6
6
  "author": "Aquafr198",
@@ -39,7 +39,7 @@
39
39
  "svelte": ">=4.0.0"
40
40
  },
41
41
  "dependencies": {
42
- "@openshop/core": "0.7.0"
42
+ "@openshop/core": "0.9.0"
43
43
  },
44
44
  "devDependencies": {
45
45
  "svelte": "^5.15.0",