@callimacus/thamyr-liquid

中文文档
4.23.5发布于 2026/11/09SEE LICENSE IN LICENSE.mdTypeScriptES Module近 30 天下载 5795

Headless Callimacus runtime for Shopify Liquid themes

原始使用文档
文档目录9 节
  1. Theme usage (no build step)
  2. Rounds without a message
  3. Suggestions
  4. Catalogue lookups without a round
  5. On-screen context
  6. One session across pages
  7. Seeing the SDK's warnings
  8. Bundler usage
  9. License

@callimacus/thamyr-liquid

Headless Callimacus runtime for Shopify Liquid themes (Online Store 2.0).

The runtime owns transport, round lifecycle, block dispatch, error containment, and the commerce plumbing (currency, URLs, native AJAX cart). The theme owns every element, every class name, all CSS, and all customer-facing copy. The runtime creates no DOM of its own and ships no CSS.

Theme usage (no build step)

Load the self-contained browser bundle — it auto-mounts every [data-callimacus] element and re-mounts on shopify:section:load:

<script src="https://cdn.jsdelivr.net/npm/@callimacus/thamyr-liquid@4/dist/browser/callimacus-runtime.min.js" defer></script>

The floating @4 picks up minor and patch releases automatically. If you prefer integrity over auto-updates, pin an exact version and add Subresource Integrity (integrity="sha384-…" crossorigin="anonymous") — jsdelivr shows the hash on the file listing. Or skip the CDN entirely: download the file into your theme as assets/callimacus-runtime.min.js and load it with {{ 'callimacus-runtime.min.js' | asset_url }} — first-party hosting, no external script at all (required for Theme Store-listed themes).

Register your renderers from your own file — one entry per block type:

window.callimacusRenderers = window.callimacusRenderers || [];
window.callimacusRenderers.push({
  type: 'custom:giftGuide',
  render(block, ctx) {
    const picks = ctx.picks(block);
    if (!picks.length) return null;
    const grid = document.createElement('ul');
    grid.className = 'gift-guide__grid'; // your class, your CSS
    for (const item of picks) grid.append(card(item, ctx));
    return grid;
  },
});

The full walkthrough — mount-point markup, section settings, renderer contract, and the ctx helpers — lives at docs.callimacus.ai.

Rounds without a message

Not everything a storefront sends is a typed question. The handle on the mount element (element.callimacus) carries the TypeScript SDK's calls, with the same names and options, built by the same helpers:

  • ask(text) — a typed question.
  • sendInteraction(id, {value, payload, block}) — one of the interactions the project declared in its configuration document: a click, a product viewed.
  • openLanding(value?) — the project's custom landing: a round with no message.

The mount supplies the page's language and the visitor's story; pass language or storyId to override them for one call. Every round runs alike — the same data-callimacus-state, the same events, one at a time.

A section opens with one round, declared in its markup:

<div data-callimacus data-client-id="…"
  data-interaction="productDetail"
  data-interaction-value="{{ product.title | escape }}"
  data-interaction-payload='{{ product_payload | json | escape }}'>

data-interaction (with optional data-interaction-value and a JSON object in data-interaction-payload) sends a declared interaction; data-landing opens the custom landing (data-landing="pdp" sends pdp as its value); data-prompt asks a question. Name several and the first in that order wins, with a warning.

Suggestions

element.callimacus.suggest(prefix) resolves with {suggestions}: the project's starter questions on an empty or short prefix, autocomplete while the visitor types — the TypeScript SDK's suggest. It opens no round and changes no state, so it can run beside one; it connects first when the mount has not yet. No connection, a timeout (timeoutMs, 4 s by default) or an error all resolve to no suggestions. Suggestions come back only when the project has them turned on (Thamyr › Configuration › Suggestions).

input.addEventListener('input', async () => {
  const {suggestions} = await root.callimacus.suggest(input.value);
  renderChips(suggestions); // yours
});

Catalogue lookups without a round

Some answers are plain catalogue lookups, not rounds: nothing to compose, nothing to generate. ctx.similar(item, {topK}) and ctx.related(item) — the TypeScript SDK's skesis.similar / skesis.related — read the catalogue directly, in a few hundred milliseconds, and hand items back shaped like ctx.picks, so the same card renderer draws them:

const others = await ctx.similar(item, {topK: 12});
const sameModel = others.filter(other => other.fields.title === item.fields.title);

ctx.related(item) resolves with {related, siblingColors, usedFallback}: what the item references, what references it, and its other colours when the catalogue links them. Both take an item or its id, and read the catalogue in the locale the storefront's route names (/it-it/ reads it-IT, /it/ reads it, the root the page's data-language); pass locale to choose another. They reject with a CallimacusError — lookup_unreachable when the request failed or ran out of time (timeoutMs, 10 s by default), server_<status> when Callimacus refused it.

On-screen context

data-ui-observer on the mount element makes every round carry what the visitor can see — the catalogue items and blocks in view — which the cognitive flow and on-screen conditions read. It is off by default.

Mark each product element with its item's full id, data-product-id="${item.id}" (shopify:product:gid://…, never the handle or a numeric Shopify id). While observing, the runtime marks each rendered block's root element with data-block-id — the block's own id — unless the renderer set one.

The observer reads every [data-product-id] on the page. If the theme's own markup already uses that attribute, give the observer a selector of its own: data-ui-observer="[data-callimacus-product]".

One session across pages

Every ask on a mount continues the same story, so follow-ups carry the conversation behind them. A storefront reloads on every navigation, though, and a fresh mount opens a fresh story — unless the theme names the one it kept:

  • data-story-id on the mount element is the story its first round continues. Empty means none. A story the server no longer has is replaced by a new one.
  • callimacus:story (bubbling, detail {storyId}) fires whenever the server opens a story. element.callimacus.storyId reads the current one.

Liquid cannot read browser storage, so a few lines of inline script carry it over. Place them after the mount element and before the deferred runtime runs:

<script>
  (function () {
    var key = 'callimacus:story';
    var kept;
    try { kept = sessionStorage.getItem(key); } catch (error) {}
    document.querySelectorAll('[data-callimacus]').forEach(function (element) {
      if (kept && !element.dataset.storyId) element.dataset.storyId = kept;
    });
    document.addEventListener('callimacus:story', function (event) {
      try { sessionStorage.setItem(key, event.detail.storyId); } catch (error) {}
    });
  })();
</script>

To start over — a "new conversation" button — call element.callimacus.resetStory() and forget the kept id (sessionStorage.removeItem('callimacus:story')): the next round opens a new story and announces it. The old story is left as it was.

sessionStorage scopes the conversation to the tab; localStorage would keep it across visits. Both can throw (private windows, blocked storage), hence the try: without them the experience still works, one story per page.

Seeing the SDK's warnings

The SDK's logger is off, so visitors' consoles stay quiet. Open a page with ?callimacus_debug in its URL, or run localStorage.setItem('callimacus:debug', '1') in the console and reload, and the browser bundle turns the logger on at warn when it starts. A block a round did not show because one of its contents failed then logs Block "saga" was not shown: its content "guide" failed (shortfall). The reason stays server-side: callimacus thamyr probe shows it. localStorage.removeItem('callimacus:debug') turns it off again. Nothing in the theme changes.

Bundler usage

The ESM entry exports the same runtime without the auto-mount side effect:

import {mountAll} from '@callimacus/thamyr-liquid';

mountAll(document);

It leaves the logger alone: call enableLoggerIfRequested() from @callimacus/thamyr-core before mountAll for the switch above.

License

Proprietary — licensed for use by Callimacus customers only. See LICENSE.md.

版本与发布记录

@callimacus/thamyr-liquid 共发布 39 个版本,首次发布于 2026/09/29;过去 12 个月发布了 39 个版本。

版本发布日期距今
4.23.5latest2026/11/09今天
4.23.42026/11/072 天前
4.23.32026/11/062 天前
4.23.22026/11/063 天前
4.23.12026/11/063 天前
4.23.02026/11/053 天前

关于 @callimacus/thamyr-liquid 的常见问题

@callimacus/thamyr-liquid 是什么?

Headless Callimacus runtime for Shopify Liquid themes

如何安装 @callimacus/thamyr-liquid?

在项目目录运行 npm install @callimacus/thamyr-liquid,或使用 pnpm add / yarn add / bun add。

@callimacus/thamyr-liquid 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@callimacus/thamyr-liquid 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@callimacus/thamyr-liquid 可以商用吗?

@callimacus/thamyr-liquid 使用 SEE LICENSE IN LICENSE.md 许可。许可条款写在包内的独立文件中,请阅读该文件确认可否商用。以上为概括,不构成法律意见,请以许可原文为准。

@callimacus/thamyr-liquid 的下载量有多少?

根据 npm 官方下载统计,@callimacus/thamyr-liquid 在 2026/10/09 – 2026/11/07 这 30 天内被下载 5,795 次,日均约 193 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@callimacus/thamyr-liquid 还在维护吗?

最新版本 4.23.5 发布于 2026/11/09(今天);至今共发布 39 个版本,其中过去 12 个月发布了 39 个;首次发布于 2026/09/29。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。