@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.
- package/CHANGELOG.core.md +1747 -0
- package/CHANGELOG.md +267 -0
- package/LICENSE.md +73 -0
- package/MIGRATION.md +271 -0
- package/README.md +62 -0
- package/dist/browser/callimacus-runtime.min.js +22 -0
- package/dist/browser/callimacus-runtime.min.js.map +1 -0
- package/dist/esm/index.js +9 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/types/index.d.ts +201 -0
- package/package.json +48 -0
|
@@ -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
|
+
}
|