@qratilabs/qrati-connect 2.24.2 → 2.24.3

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/README.md CHANGED
@@ -1,174 +1,130 @@
1
- <p align="center">
2
- <img src="https://qrati.com/images/qrati-connect-banner.jpg" alt="Qrati Connect Banner" style="max-width:100%;height:auto;" />
3
- </p>
1
+ ![Qrati Connect Architecture](https://assets.qrati.com/images/tech-docs/qrati-connect-architecture-29-06-2026.webp)
4
2
 
5
- <p align="center">
6
- <a href="https://www.npmjs.com/package/@qratilabs/qrati-connect"><img src="https://img.shields.io/npm/v/@qratilabs/qrati-connect.svg" alt="npm version"></a>
7
- <a href="https://www.npmjs.com/package/@qratilabs/qrati-connect"><img src="https://img.shields.io/npm/dm/@qratilabs/qrati-connect.svg" alt="npm downloads"></a>
8
- <a href="https://github.com/qrati-labs/qrati-connect-ts/blob/main/LICENSE"><img src="https://img.shields.io/npm/l/@qratilabs/qrati-connect.svg" alt="license"></a>
9
- <img src="https://img.shields.io/badge/TypeScript-Ready-blue.svg" alt="TypeScript">
10
- </p>
3
+ ![Node.js](https://img.shields.io/badge/Node-24.12-339933?logo=node.js)
4
+ ![pnpm](https://img.shields.io/badge/pnpm-11-F69220?logo=pnpm)
5
+ ![Preact](https://img.shields.io/badge/Preact-10.29-673AB8?logo=preact)
6
+ ![Vite](https://img.shields.io/badge/Vite-8-646CFF?logo=vite)
7
+ ![TypeScript](https://img.shields.io/badge/TypeScript-6.0+-3178C6?logo=typescript)
8
+ ![Tailwind CSS](https://img.shields.io/badge/Tailwind%20CSS-v4-06B6D4?logo=tailwindcss)
9
+ ![Vitest](https://img.shields.io/badge/Tests-Vitest-6E9F18?logo=vitest)
10
+ ![Playwright](https://img.shields.io/badge/E2E-Playwright-2EAD33?logo=playwright)
11
+ ![Storybook](https://img.shields.io/badge/Storybook-10-FF4785?logo=storybook)
12
+ ![semantic-release](https://img.shields.io/badge/Release-semantic--release-CB3837?logo=semantic-release)
11
13
 
12
- ---
13
-
14
- # Qrati Connect — Embeddable Media & Engagement SDK
15
-
16
- **Qrati Connect** is a compact, production-grade SDK for embedding photo galleries, media uploads, curation, and engagement into any website. It is built with [Preact](https://preactjs.com/), strict TypeScript, and Shadow-DOM style isolation, then distributed as a Web Component, React wrapper, and zero-code embed script.
17
-
18
- ---
19
-
20
- ## Why Qrati Connect?
14
+ Qrati Connect is a drop-in, embeddable event/gallery widget. It ships as three friendly bundles:
21
15
 
22
- - **Framework-agnostic** — works in React, Vue, Angular, WordPress, or plain HTML.
23
- - **Style isolation** — Shadow DOM keeps SDK styles separate from the host page.
24
- - **Small initial payload** — Preact core plus strategic lazy-loading for heavy features (upload, HEIC conversion, maps).
25
- - **Themeable** — organization colors, fonts, radius, and shadows are fetched from the Qrati API and applied via CSS custom properties.
26
- - **TypeScript-first** — full typings for the public API.
16
+ - **`<qrati-connect>` Web Component** — shadow-DOM isolated, Preact-powered, ~3 KB.
17
+ - **React wrapper** — external React, lazy-loads the custom element.
18
+ - **Embed loader** — one `<script>` tag, no bundler needed.
27
19
 
28
- ---
29
-
30
- ## Highlights
31
-
32
- - Interactive media gallery with lightbox, blurhash placeholders, infinite scroll, and facial search.
33
- - Smart uploads: compression, chunked progress, video trimming, and HEIC → JPEG conversion on demand.
34
- - Reactions, curation workflow, leaderboards, and points-based engagement.
35
- - Public events page with folder navigation and optional map view (Google Maps, Mapbox, OpenStreetMap).
20
+ Styles self-inject at runtime, so hosts never import a stylesheet.
36
21
 
37
- ---
38
-
39
- ## Distribution Formats
40
22
 
41
- | Format | Output | Best for |
42
- |--------|--------|----------|
43
- | **React wrapper** | `dist/react/index.mjs` / `index.cjs` | React / Next.js apps |
44
- | **Web Component** | `dist/element/web.es.js` | Any framework or vanilla JS |
45
- | **Embed loader** | `dist/embed/embed.js` | Zero-code `<script>` integration |
23
+ ## Install
46
24
 
47
- The React wrapper and embed loader dynamically load the element build at runtime, so the same `web.es.js` bundle is always used.
25
+ ```bash
26
+ # contributors
27
+ pnpm install
48
28
 
49
- ---
29
+ # consumers
30
+ npm install @qratilabs/qrati-connect
31
+ ```
50
32
 
51
- ## Quick Install & Integration
33
+ > Requires **Node ≥24** and **pnpm ≥11**. See `.nvmrc` for the pinned Node version.
52
34
 
53
- ### React (client component)
35
+ ## Environment
54
36
 
55
37
  ```bash
56
- pnpm add @qratilabs/qrati-connect
57
- # or
58
- npm install @qratilabs/qrati-connect
38
+ cp .env.example .env.local
59
39
  ```
60
40
 
61
- ```tsx
62
- 'use client';
41
+ Set at least:
63
42
 
64
- import { QratiConnect } from '@qratilabs/qrati-connect';
43
+ - `VITE_BASE_URL` API base, e.g. `https://api.qrati.com`
44
+ - `VITE_APP_ENVIRONMENT` — e.g. `alpha`, `beta`, `prod`
65
45
 
66
- export default function Page() {
67
- return <QratiConnect organizationId='your-org-id' router='memory' />;
68
- }
69
- ```
46
+ ## Develop
70
47
 
71
- ### Web Component (framework-agnostic)
48
+ No separate dev server, but you have options:
72
49
 
73
- ```html
74
- <script type="module" src="https://cdn.jsdelivr.net/npm/@qratilabs/qrati-connect@2/element/web.es.js"></script>
50
+ ```bash
51
+ # Component workbench
52
+ pnpm storybook
75
53
 
76
- <qrati-connect organization-id="your-org-id" router="hash"></qrati-connect>
54
+ # Iterate on the standalone element
55
+ pnpm build:element:watch
56
+ pnpm serve:element # http://localhost:4599
77
57
  ```
78
58
 
79
- ### Embed script (zero-code)
59
+ ## Test
80
60
 
81
- ```html
82
- <script async
83
- src="https://cdn.jsdelivr.net/npm/@qratilabs/qrati-connect@2/embed/embed.js"
84
- data-organization-id="your-org-id"
85
- data-router="hash"></script>
61
+ ```bash
62
+ pnpm test:unit:run # Vitest + jsdom
63
+ pnpm test:production # Playwright against a live env
64
+ pnpm test:all # unit + production
86
65
  ```
87
66
 
88
- The embed script inserts a `<qrati-connect>` element next to the script tag (or into the element matched by `data-target`) and lazy-loads the element build.
67
+ ## Build
89
68
 
90
- ---
91
-
92
- ## Props & Attributes
93
-
94
- | Prop / Attribute | Type | Default | Description |
95
- |------------------|------|---------|-------------|
96
- | `organizationId` * | `string` | — | Qrati organization ID |
97
- | `router` | `'memory' \| 'hash'` | `'memory'` | Routing strategy |
98
- | `uid` | `string` | — | Pre-authenticated user ID |
99
- | `fname` | `string` | — | Pre-authenticated first name |
100
- | `lname` | `string` | — | Pre-authenticated last name |
101
- | `theme` | `'light' \| 'dark'` | `'light'` | Color scheme |
102
- | `onError` | `(error: Error) => void` | — | SDK error callback |
69
+ ```bash
70
+ pnpm build # all three bundles + post-build validation
71
+ pnpm build:element # dist/element/web.es.js
72
+ pnpm build:react # dist/react/index.{mjs,cjs,d.ts}
73
+ pnpm build:embed # dist/embed/embed.js
74
+ ```
103
75
 
104
- \* Required.
76
+ `build:react` automatically builds the element first because the React wrapper loads `../element/web.es.js` at runtime.
105
77
 
106
- Custom auth requires `uid` and `fname`; `lname` is optional.
78
+ ## Use it
107
79
 
108
- ---
80
+ ### React
109
81
 
110
- ## Events & Callbacks
82
+ ```tsx
83
+ import { QratiConnect } from '@qratilabs/qrati-connect';
111
84
 
112
- | Callback / Event | Payload | Description |
113
- |------------------|---------|-------------|
114
- | `onError` | `Error` | Called when an SDK error is caught |
115
- | `qrati-error` (custom event) | `{ error: Error }` | Dispatched on `window` and the custom element |
85
+ <QratiConnect
86
+ organizationId="your-org-id"
87
+ router="hash"
88
+ theme="light"
89
+ onError={(err) => console.error(err)}
90
+ />
91
+ ```
116
92
 
117
- React wrapper users should use the `onError` prop. Vanilla Web Component users can listen for `qrati-error`.
93
+ ### Script tag
118
94
 
119
- ---
95
+ ```html
96
+ <script
97
+ async
98
+ src="https://cdn.jsdelivr.net/npm/@qratilabs/qrati-connect/embed/embed.js"
99
+ data-organization-id="your-org-id"
100
+ data-router="hash"
101
+ data-theme="light"
102
+ ></script>
103
+ ```
120
104
 
121
- ## Performance & Bundling
105
+ Use a **classic** `<script>` tag — not `type="module"` — so the loader can read `document.currentScript`.
122
106
 
123
- Sizes are approximate and depend on the build output:
107
+ ### Web Component (programmatic)
124
108
 
125
- - React wrapper: ~1–2 KB gzipped (loads element build at runtime).
126
- - Initial element bundle: ~139 KB gzipped.
127
- - Upload feature: loaded on demand.
128
- - HEIC conversion (`heic2any`): loaded only when a `.heic` file is selected.
129
- - Maps and heavy UI libraries are split into lazy chunks.
109
+ ```ts
110
+ import { renderComponent } from '@qratilabs/qrati-connect/element';
130
111
 
131
- ---
132
-
133
- ## Development
112
+ renderComponent('#qrati-host', {
113
+ organizationId: 'your-org-id',
114
+ router: 'memory',
115
+ theme: 'dark'
116
+ });
117
+ ```
134
118
 
135
- This repository uses **pnpm** and **Node.js 24.x**.
119
+ ## Deploy
136
120
 
137
121
  ```bash
138
- pnpm install # install dependencies
139
- pnpm storybook # start Storybook on http://localhost:6006
140
- pnpm type-check # TypeScript check (no emit)
141
- pnpm lint # ESLint
142
- pnpm format # Prettier
143
- pnpm build # build all distribution targets
144
- pnpm test:unit # Vitest unit tests (watch)
145
- pnpm test:unit:run # Vitest unit tests (once)
146
- pnpm test:all # unit tests + Playwright production regression
122
+ pnpm deploy:beta # merge main into release/beta and push
123
+ pnpm deploy:prod # merge main into release/prod and push
147
124
  ```
148
125
 
149
- See [`docs/DEVELOPMENT.md`](docs/DEVELOPMENT.md) for the full setup guide and [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) for design details.
150
-
151
- ---
152
-
153
- ## Documentation
154
-
155
- - [`docs/INDEX.md`](docs/INDEX.md) — documentation map
156
- - [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) — architecture, build system, routing, styling, i18n
157
- - [`docs/DEVELOPMENT.md`](docs/DEVELOPMENT.md) — environment setup, workflow, testing, Storybook
158
- - [`docs/API.md`](docs/API.md) — backend API communication
159
- - [`docs/REFERENCE.md`](docs/REFERENCE.md) — components, hooks, pages, utilities, router API
160
- - [`docs/DEPLOYMENT.md`](docs/DEPLOYMENT.md) — release process and CDN
161
- - [`docs/FAQ.md`](docs/FAQ.md) — common questions
126
+ Both scripts require a clean git working tree. After pushing, semantic-release publishes from `dist/` when CI runs on the release branch.
162
127
 
163
128
  ---
164
129
 
165
- ## Support
166
-
167
- - GitHub Issues: https://github.com/qrati-labs/qrati-connect-ts/issues
168
- - Email: support@qrati.com
169
-
170
- ---
171
-
172
- ## License
173
-
174
- Proprietary © Qrati Labs — https://qrati.com. All rights reserved.
130
+ Built with Preact, Vite, Tailwind, and a little bit of Shadow DOM magic.
@@ -1,4 +1,4 @@
1
- import{d as e,s as r,t,v as o}from"./DrrpB4Om.js";import{D as l,n as s}from"./CaX2xgrP.js";import{l as i}from"./ChJXhA9c.js";import"./h4ZjZXfe2.js";var n=e(()=>import("./BKDqpSN62.js")),a=e(()=>import("./DN26AtHL2.js")),c=e(()=>import("./kiL9JENf2.js")),d=e(()=>import("./CHTzn6mh2.js")),p=()=>/* @__PURE__ */t("div",{class:"flex h-full items-center justify-center",children:/* @__PURE__ */t("div",{class:"text-center",children:[
1
+ import{d as e,s as r,t,v as o}from"./DrrpB4Om.js";import{D as l,n as s}from"./CaX2xgrP.js";import{l as i}from"./ChJXhA9c.js";import"./h4ZjZXfe2.js";var n=e(()=>import("./C9kBlCZx2.js")),a=e(()=>import("./CZbEGemi2.js")),c=e(()=>import("./D340VADc2.js")),d=e(()=>import("./CQBd8iaX2.js")),p=()=>/* @__PURE__ */t("div",{class:"flex h-full items-center justify-center",children:/* @__PURE__ */t("div",{class:"text-center",children:[
2
2
  /* @__PURE__ */t("svg",{xmlns:"http://www.w3.org/2000/svg",class:"text-muted-foreground mx-auto mb-3 size-10",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor","stroke-width":"1.5",children:[/* @__PURE__ */t("path",{d:"M12 2C8.13 2 5 5.13 5 9c0 5.25 7 13 7 13s7-7.75 7-13c0-3.87-3.13-7-7-7z"}),/* @__PURE__ */t("circle",{cx:"12",cy:"9",r:"2.5"})]}),
3
3
  /* @__PURE__ */t("p",{class:"text-foreground",children:"No location data available."}),
4
4
  /* @__PURE__ */t("p",{class:"text-muted-foreground mt-1 text-xs",children:"Events need location data to appear on the map."})]})}),m=()=>/* @__PURE__ */t("div",{class:"flex h-full items-center justify-center",children:/* @__PURE__ */t("div",{class:"border-primary size-8 animate-spin rounded-full border-4 border-t-transparent"})}),g=({events:e,isLoading:g=!1})=>{const{organization:x}=s(),f=i(),h=x?.integrationSettings??{},u=h.mapProvider??"openstreetmap",v=o(e=>{f(l.GALLERY(e))},[f]);if("openstreetmap_free"===u)/* @__PURE__ */return t("div",{class:"relative mt-3 h-screen sm:mt-6",children:/* @__PURE__ */t(r,{fallback:/* @__PURE__ */t(m,{}),children:/* @__PURE__ */t(n,{onExplore:v,logoUrl:x?.logoUrl})})});const y=h.mapTilerApiKey??"",b=h.googleMapsApiKey??"",w=h.mapboxApiKey??"",j=e.filter(e=>"number"==typeof e.location?.x&&"number"==typeof e.location?.y);/* @__PURE__ */