@callimacus/thamyr-liquid 4.3.4

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.
@@ -0,0 +1,201 @@
1
+ /*!
2
+ * Copyright © 2025–2026 Solomei AI SRL. All rights reserved.
3
+ *
4
+ * Proprietary software, licensed for use by Callimacus customers only.
5
+ * See LICENSE.md for the full terms.
6
+ *
7
+ */
8
+ import { CallimacusService } from '@callimacus/thamyr-core';
9
+
10
+ /**
11
+ Headless Callimacus runtime for Shopify Liquid themes.
12
+
13
+ Mounts on `[data-callimacus]` elements, owns transport and round lifecycle,
14
+ and dispatches server blocks to theme-owned renderers registered on
15
+ `window.callimacusRenderers`. Creates no DOM of its own and ships no CSS.
16
+ On the mount element it maintains `data-callimacus-state` (see
17
+ {@link MountState}), `aria-busy`, a `data-callimacus-ready` marker, and the
18
+ {@link CallimacusHandle} at `element.callimacus`; after a successful round it
19
+ replaces the contents of `[data-callimacus-output]` — or, when that element
20
+ is missing, of the mount element itself (warned at mount time). The theme's
21
+ server-rendered markup survives every failure path.
22
+
23
+ @packageDocumentation
24
+ */
25
+
26
+ /**
27
+ The values the runtime writes to `data-callimacus-state`. Themes key their
28
+ state CSS and copy off this attribute.
29
+ */
30
+ type MountState = 'loading' | 'ready' | 'empty' | 'error' | 'design-mode';
31
+ /**
32
+ The machine-readable grammar of {@link CallimacusError.code}: `timeout` and
33
+ `send_failed` from the round lifecycle, `cart_rejected` and
34
+ `cart_unreachable` from `ctx.addToCart`, `server_<code>` for errors relayed
35
+ from Callimacus.
36
+ */
37
+ type CallimacusErrorCode = 'timeout' | 'send_failed' | 'cart_rejected' | 'cart_unreachable' | `server_${string}`;
38
+ /**
39
+ Error surfaced by the runtime, both to `callimacus:error` listeners and from
40
+ `ctx.addToCart`. The original failure, when there is one, rides on `cause`.
41
+ */
42
+ declare class CallimacusError extends Error {
43
+ readonly code: CallimacusErrorCode;
44
+ constructor(code: CallimacusErrorCode, message: string, options?: ErrorOptions);
45
+ }
46
+ /**
47
+ A Skesis price object; `amount` is in major units (313.6 is $313.60).
48
+ */
49
+ type Price = {
50
+ amount?: number;
51
+ currency?: string;
52
+ };
53
+ type CatalogVariant = {
54
+ id?: string | number;
55
+ orderable?: boolean;
56
+ } & Record<string, unknown>;
57
+ /**
58
+ A catalogue hit as Skesis returns it for a Shopify-connected project.
59
+ */
60
+ type CatalogItem = {
61
+ fields?: {
62
+ title?: string;
63
+ 'shopify-handle'?: string;
64
+ price?: Price | number;
65
+ images?: Array<{
66
+ url?: string;
67
+ alt?: string;
68
+ }>;
69
+ variantTree?: {
70
+ variants?: CatalogVariant[];
71
+ };
72
+ } & Record<string, unknown>;
73
+ } & Record<string, unknown>;
74
+ /**
75
+ The slice of a server block a renderer works with. Custom blocks arrive with
76
+ their type prefixed on the wire: a block saved as `giftGuide` is
77
+ `custom:giftGuide` here — register renderers with the prefixed name.
78
+ */
79
+ type RenderableBlock = {
80
+ id: string;
81
+ type: string;
82
+ priority?: number;
83
+ data: unknown;
84
+ };
85
+ /**
86
+ The helpers handed to every renderer. Emits no markup — these package the
87
+ commerce plumbing that is easy to get wrong on Shopify. The object is frozen:
88
+ all renderers of a mount share it across rounds.
89
+ */
90
+ type RendererContext = {
91
+ locale: string;
92
+ currency?: string;
93
+ /**
94
+ The parsed `[data-callimacus-settings]` JSON, `{}` when absent or invalid.
95
+ */
96
+ settings: Record<string, unknown>;
97
+ /**
98
+ Catalogue items in a block, whatever data key they arrived under. Every
99
+ returned item carries a non-empty `shopify-handle` — exactly what
100
+ `productUrl` needs.
101
+ */
102
+ picks(block: RenderableBlock): CatalogItem[];
103
+ /**
104
+ First non-empty string in a block's data, direct or under a `text` key —
105
+ Demosthenes/LLM copy.
106
+ */
107
+ text(block: RenderableBlock): string | undefined;
108
+ /**
109
+ Currency formatting for a Skesis price object or number. A price's own
110
+ `currency` wins over the storefront's presentment currency (the amount is
111
+ not converted, so the label must follow the data); returns `''` when
112
+ there is no numeric amount.
113
+ */
114
+ money(price: Price | number | undefined): string;
115
+ /**
116
+ Locale-correct storefront URL. Never build this by hand.
117
+ */
118
+ productUrl(item: CatalogItem): string | undefined;
119
+ /**
120
+ Shopify CDN transform. Returns a URL string, not an element.
121
+ */
122
+ imageUrl(item: CatalogItem, options?: {
123
+ width?: number;
124
+ index?: number;
125
+ }): string | undefined;
126
+ /**
127
+ Numeric id of the first orderable variant, for the AJAX cart — falling
128
+ back to the first variant when none is marked orderable.
129
+ */
130
+ variantId(item: CatalogItem): string | undefined;
131
+ /**
132
+ Native AJAX cart, executed inside the theme so the cart cookie and the
133
+ theme's own cart object stay authoritative. Resolves with the cart;
134
+ rejects with a {@link CallimacusError} — `cart_rejected` carrying
135
+ Shopify's own message, or `cart_unreachable` when the request itself
136
+ failed at the network level.
137
+ */
138
+ addToCart(variantId: string | number, quantity?: number): Promise<unknown>;
139
+ };
140
+ /**
141
+ One renderer: owns the markup for one block type. Return a Node, or
142
+ null/undefined to render nothing — a block whose renderer returns nothing is
143
+ simply absent from the page.
144
+ */
145
+ type CallimacusRenderer = {
146
+ type: string;
147
+ render(block: RenderableBlock, context: RendererContext): Node | null | undefined;
148
+ };
149
+ /**
150
+ The handle placed on the mount element and emitted as the
151
+ `callimacus:mounted` event detail.
152
+ */
153
+ type CallimacusHandle = {
154
+ ask(value: string): Promise<void>;
155
+ readonly ctx: RendererContext;
156
+ readonly state: string | undefined;
157
+ };
158
+ /**
159
+ A mount element once the runtime has taken it over.
160
+ */
161
+ type CallimacusHostElement = HTMLElement & {
162
+ callimacus?: CallimacusHandle;
163
+ };
164
+ /**
165
+ The transport surface the runtime needs — {@link CallimacusService}
166
+ satisfies it. Injectable so tests can drive rounds without a socket.
167
+ */
168
+ type RoundTransport = Pick<CallimacusService, 'connect' | 'sendUserInteraction' | 'onServerResponse' | 'onError'>;
169
+ type MountOptions = {
170
+ transport?: RoundTransport;
171
+ roundTimeoutMs?: number;
172
+ };
173
+ type MountConfig = {
174
+ clientId?: string;
175
+ endpoint: string;
176
+ language: string;
177
+ currency?: string;
178
+ rootUrl: string;
179
+ cartAddUrl: string;
180
+ settings: Record<string, unknown>;
181
+ };
182
+ /**
183
+ Builds the {@link RendererContext} for one mount. Exported for tests; hosts
184
+ receive it ready-made via `callimacus:mounted` and `root.callimacus.ctx`.
185
+ */
186
+ declare function makeCtx(config: MountConfig): RendererContext;
187
+ /**
188
+ Takes over one `[data-callimacus]` element. Idempotent: a root that is
189
+ already mounted is left alone, so calling it again after
190
+ `shopify:section:load` re-mounts only the reloaded section's fresh element.
191
+ A mount that fails degrades like every other failure — error state, event,
192
+ prefixed log — and never takes sibling mounts with it.
193
+ */
194
+ declare function mount(root: CallimacusHostElement, options?: MountOptions): void;
195
+ /**
196
+ Mounts every `[data-callimacus]` element in scope not already mounted.
197
+ */
198
+ declare function mountAll(scope: ParentNode, options?: MountOptions): void;
199
+
200
+ export { CallimacusError, makeCtx, mount, mountAll };
201
+ export type { CallimacusErrorCode, CallimacusHandle, CallimacusHostElement, CallimacusRenderer, CatalogItem, CatalogVariant, MountOptions, MountState, Price, RenderableBlock, RendererContext, RoundTransport };
package/package.json ADDED
@@ -0,0 +1,48 @@
1
+ {
2
+ "name": "@callimacus/thamyr-liquid",
3
+ "version": "4.3.4",
4
+ "private": false,
5
+ "description": "Headless Callimacus runtime for Shopify Liquid themes",
6
+ "license": "SEE LICENSE IN LICENSE.md",
7
+ "homepage": "https://docs.callimacus.ai/thamyr-sdk/shopify-liquid",
8
+ "main": "dist/esm/index.js",
9
+ "module": "dist/esm/index.js",
10
+ "types": "dist/types/index.d.ts",
11
+ "jsdelivr": "dist/browser/callimacus-runtime.min.js",
12
+ "unpkg": "dist/browser/callimacus-runtime.min.js",
13
+ "exports": {
14
+ ".": {
15
+ "import": "./dist/esm/index.js",
16
+ "types": "./dist/types/index.d.ts"
17
+ },
18
+ "./browser": "./dist/browser/callimacus-runtime.min.js"
19
+ },
20
+ "files": [
21
+ "dist",
22
+ "CHANGELOG.md",
23
+ "CHANGELOG.core.md",
24
+ "MIGRATION.md"
25
+ ],
26
+ "type": "module",
27
+ "publishConfig": {
28
+ "access": "public",
29
+ "registry": "https://registry.npmjs.org",
30
+ "@callimacus:registry": "https://registry.npmjs.org"
31
+ },
32
+ "scripts": {
33
+ "prepack": "cp ../../MIGRATION.md ./MIGRATION.md && cp ../core/CHANGELOG.md ./CHANGELOG.core.md",
34
+ "build": "rollup -c --failAfterWarnings",
35
+ "dev": "rollup -c -w",
36
+ "clean": "rm -rf dist",
37
+ "test": "vitest run",
38
+ "lint": "eslint src"
39
+ },
40
+ "dependencies": {
41
+ "@callimacus/thamyr-core": "^4.3.4"
42
+ },
43
+ "devDependencies": {
44
+ "eslint-config-xo": "^4.0.1",
45
+ "jsdom": "^30.1.1",
46
+ "vitest": "^5.0.2"
47
+ }
48
+ }