@blamejs/blamejs-shop 0.0.75 → 0.0.76

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.
Files changed (2) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/package.json +1 -1
package/CHANGELOG.md CHANGED
@@ -8,6 +8,8 @@ upgrading across more than a few patches at a time.
8
8
 
9
9
  ## v0.0.x
10
10
 
11
+ - v0.0.76 (2026-05-23) — **Edge-render path for storefront read routes — `/`, `/search`, `/products/:slug` served from the Worker without a container hop + vendor refresh to blamejs v0.12.5.** The storefront read-side render now runs at the edge. `/`, `/search`, and `/products/:slug` are rendered by the Cloudflare Worker reading D1 directly through the bound binding, then returning HTML — no container hop, no Durable Object handoff. Public visitors see TTFB drop from ~3.4s (container wake-up) to ~50ms. Gated by the `EDGE_RENDER` env var so operators can roll back per-deploy without a re-push. Write-side routes (POST /cart/lines, /checkout, /admin, webhooks) continue to land on the container. Bundles the vendored blamejs refresh from v0.12.4 to v0.12.5 and three CI-tight 50ms `waitUntil` timeouts bumped to 5s for runner-contention resilience. **Added:** *Worker edge-render — `/` home, `/search`, and `/products/:slug` rendered without a container hop* — New Worker-side modules under `worker/render/` (`_lib.js`, `home.js`, `product.js`, `search.js`, `cart.js`) and `worker/data/catalog.js` carry the storefront templates + D1 read-side queries. When `env.EDGE_RENDER` is `"on"`, the Worker queries D1 directly via the bound `env.DB` binding and returns HTML inline. The container's storefront mount continues to own the same routes when the flag is off, so the toggle is operator-controlled and reversible. Cart-count display in the header is fixed at zero on edge-rendered pages until the sealed-session decrypt path lands in a follow-up — visitors landing on `/cart` still see the live count from the container path. · *`EDGE_RENDER` and `SHOP_NAME` wrangler vars* — `wrangler.toml` gains two new `[vars]` entries: `EDGE_RENDER` (default `"off"` — flip to `"on"` to enable the edge-render path) and `SHOP_NAME` (default `"blamejs.shop"` — surfaces in the rendered `<title>` and OpenGraph metadata). **Changed:** *Vendored blamejs refreshed from v0.12.4 to v0.12.5* — `bash scripts/vendor-update.sh blamejs v0.12.5` ran cleanly; `lib/vendor/blamejs/MANIFEST.json` updated. See `lib/vendor/blamejs/CHANGELOG.md` for the upstream surface changes between v0.12.4 and v0.12.5. **Fixed:** *Three 50ms `waitUntil` timeouts bumped to 5s — `live-chat`, `fraud-screen`, `support-tickets` tests* — Nine call sites across `test/layer-1-state/live-chat.test.js`, `test/layer-1-state/fraud-screen.test.js`, and `test/layer-1-state/support-tickets.test.js` were polling for `Date.now()` to advance past a captured timestamp on a 50ms budget. Under CI runner contention that budget sometimes exhausts before the monotonic-clock tick lands. Same fix the v0.0.69 ship applied to `return-labels.test.js`; same rule §11 root cause.
12
+
11
13
  - v0.0.75 (2026-05-22) — **Sixteen new primitives across operator tooling, vendor / inventory ops, marketing automation, and storefront content.** Sixteen primitives ship together. Operator + admin: customerImpersonation, carrierAccounts, operatorApprovals, customerMerge, operatorHelpCenter, eventLog. Vendor + inventory: vendorInvoices, inventoryAudits, smartRestocking, taxRemittance. Marketing + retention: winbackCampaigns, wishlistDigest. Storefront: blogArticles, categoryNavigation, productCompare, lineGiftWrap. **Added:** *`customerImpersonation` primitive — operator login-as-customer with audit* — 32-byte plaintext token returned once; namespaceHash at rest. 60-min default TTL. Capability gate via operatorRoles.hasPermission. notifyCustomer fan-out via injected notifications. actionsRecord builds the audit trail. Migration `0190`. · *`carrierAccounts` primitive — per-operator carrier API account management* — Carrier enum: ups / fedex / usps / dhl / canada_post / royal_mail / australia_post. All secrets hashed via namespaceHash under per-field namespaces. rotateCredentials with 24h grace. verifyCredentials timing-safe. Migration `0191`. · *`operatorApprovals` primitive — multi-step approval workflows* — Defines workflows with required_approvers + required_capability + escalation_after_hours. castVote dedup via UNIQUE(request_id, approver_id). Status FSM pending / approved / rejected / executed / cancelled / escalated. Migration `0192`. · *`vendorInvoices` primitive — vendor-issued invoices with PO reconciliation* — FSM received → approved → paid with disputed + voided side branches. Partial-pay first-class. UNIQUE(vendor_slug, invoice_number) for dedup. reconcileAgainstPOs returns variance summary. agingReport bucketing. Migration `0193`. · *`customerMerge` primitive — operator merge of duplicate customer accounts* — Reparents orders + subscriptions + loyalty + reviews + addresses + paymentMethods atomically (pre-flight all, then write all). 7-day rollback window. Jaro-Winkler-scored findDuplicateCandidates. customer_merge_redirects table for forwarding. Migration `0194`. · *`productCompare` primitive — storefront 2-4 product comparison* — Cap of 4 per session. compareTable returns per-attribute rows for the table render. Default attributes: price / sku / brand / vendor / weight / dimensions / inventory_status. defineCompareAttribute adds custom rows. popularCompares for analytics. Migration `0195`. · *`winbackCampaigns` primitive — multi-step re-engagement for lapsed customers* — Operator defines lapse_days_min + lapse_days_max + steps (delay + template + optional coupon). scanForLapsedCustomers finds candidates; enrollCustomer schedules; dispatchTick advances. markRecovered halts further steps. metricsForCampaign returns recovery rate + avg time-to-purchase. Migration `0196`. · *`inventoryAudits` primitive — periodic full-inventory audits* — Kinds: full / quarterly / spot. Scopes: all / category / vendor / location. recordScanLine + markRecount + finalizeAudit. Variance write-through composes inventoryLocations.adjustStock with `inventory-audit:<slug>` reason. compareToPriorAudit returns per-(sku, location) deltas. Migration `0197`. · *`wishlistDigest` primitive — scheduled weekly / monthly wishlist email digests* — Per-customer enrollment + cadence. next_dispatch_at computed via Intl.DateTimeFormat with two-pass DST-fold refinement. composeDigest returns HTML + text. Suppressed customers keep cadence ETA on rails but no email fires. Migration `0198`. · *`eventLog` primitive — universal append-only application event stream* — Drop-silent on bad input. Severity: debug / info / warning / critical. query with HMAC cursor. tail + topKinds + metricsForKind + purgeOlderThan (exclude_critical opt-in). Distinct from analytics (customer events) and operatorAuditLog (operator mutations). Migration `0199`. · *`operatorHelpCenter` primitive — in-admin operator help articles* — audience_roles closed allow-list against operatorRoles.PERMISSIONS. searchSuggest title 3 / section 2 / body 1 weighted ranker. recordHelpfulVote dedup at UNIQUE(slug, operator_id). Migration `0200`. · *`categoryNavigation` primitive — hierarchical storefront category tree* — self-FK parent_slug + CHECK(slug != parent_slug). tree returns nested shape. breadcrumbsFor returns ancestor chain. move walks ancestor chain to refuse cycles (bounded MAX_TREE_DEPTH=16). reorderSiblings requires the complete member set. Migration `0201`. · *`lineGiftWrap` primitive — per-line gift wrap selection* — Distinct from giftOptions (one wrap for the whole order). UNIQUE(order_id, line_id) UPSERT. gift_message ≤ 500 chars + control-byte refusal; recipient_name ≤ 120. feeForOrder sums per-line wrap fees via injected giftOptions. renderPackingSlipLines HTML-escapes every operator field. Migration `0202`. · *`smartRestocking` primitive — EOQ + safety-stock recommendations* — Composes demandForecast + reorderThresholds + costLayers + vendors. recommendOrderQty returns EOQ formula `sqrt(2DS/H)` + service-level safety-stock + reorder point + cost estimate. Service levels: 0.90 / 0.95 / 0.99. definePolicy + applyPolicy assigns SKUs to policies. Migration `0203`. · *`taxRemittance` primitive — per-jurisdiction tax payment tracking* — Records remittances with payment_method enum (bank_transfer / credit_card / ach / wire / check). reconcileWithFiling returns variance. lateRemittances threshold + recordPenalty + metricsForJurisdiction on-time rate. Migration `0204`. · *`blogArticles` primitive — operator-published blog posts* — Author + tags + featured_product_ids + SEO meta + publish FSM (draft → published → archived → draft). Markdown render through b.template.escapeHtml + b.safeUrl. relatedArticles tag-overlap ranking. byAuthor + popularArticles + recordView. Migration `0189`.
12
14
 
13
15
  - v0.0.74 (2026-05-22) — **`emailEngagementScore` primitive + republish 0.0.73.** 0.0.73 source landed on `main` but the npm publish workflow stopped on a smoke check — the email-engagement-score test was committed without its lib counterpart. 0.0.74 adds the missing `emailEngagementScore` primitive and republishes the full v0.0.73 surface so `npm install @blamejs/blamejs-shop@0.0.74` pulls every primitive cleanly. **Added:** *`emailEngagementScore` primitive — per-customer 0-100 email engagement grade* — `bShop.emailEngagementScore.create({ query?, emailCampaigns?, emailSuppressions? })` returns `{ recordEngagementEvent, getScore, recompute, recomputeAll, unengagedCustomers, metricsForBand, historyForCustomer }`. Six event types with calibrated weights (opened +5, clicked +15, unsubscribed -50, spam_reported -75, bounced -10, not_opened_in_window -3). Score starts at 50 baseline, clamped to [0, 100]. Four bands: unengaged (0-19) / lapsed (20-49) / engaged (50-74) / highly_engaged (75-100). Click implies open in the open_rate denominator (compensates for image-blocking clients). Monotonic per-customer `_resolveOccurredAt` to break same-millisecond ties. Migration `0187_email_engagement_score.sql`. **Fixed:** *Republish to npm — 0.0.73 source on `main` reached operators via `git clone` but not via `npm install`* — `npm install @blamejs/blamejs-shop@0.0.73` resolves to a missing version because the publish workflow exited early when the CI smoke gate couldn't find `lib/email-engagement-score.js` (its test file was committed alongside v0.0.73 but the lib file itself was untracked at commit time). 0.0.74 ships the full surface so operators upgrading by version number get every primitive.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@blamejs/blamejs-shop",
3
- "version": "0.0.75",
3
+ "version": "0.0.76",
4
4
  "description": "Open-source framework built on blamejs. Vendored stack, zero npm runtime deps, PQC-first crypto, security-on by default.",
5
5
  "main": "lib/index.js",
6
6
  "scripts": {