@owlmeans/web-inquiry 0.0.0-stage → 0.1.18-rc.1

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,3 +1,85 @@
1
- # Temporary Holding Version
1
+ # @owlmeans/web-inquiry
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ The lightweight browser SDK of the OwlMeans customer inquiry widget. It carries no widget code and
4
+ no React: it injects the widget runtime served by the CRM (`<crm>/inquiry.js`) once per page, waits
5
+ for the runtime of the version it was built for, and opens the dialog from a link, a button, a
6
+ menu entry or a floating button. Every dialog open is reported once as an analytics event.
7
+
8
+ ## Installation
9
+
10
+ ```bash
11
+ bun add @owlmeans/web-inquiry@^0.1.18-rc.1 @owlmeans/common-inquiry@^0.1.18-rc.1
12
+ ```
13
+
14
+ ## Usage
15
+
16
+ ```ts
17
+ import { makeInquiryClient, type InquiryWidgetConfig } from '@owlmeans/web-inquiry'
18
+
19
+ const inquiry = makeInquiryClient({
20
+ url: 'https://platform.owlmeans.com/crm', // the CRM base, no trailing slash needed
21
+ language: () => document.documentElement.lang, // read at every open
22
+ })
23
+
24
+ const quote: InquiryWidgetConfig = {
25
+ id: 'owlmeans-quote',
26
+ tabs: [{ alias: 'quote', title: 'Get a quote' }], // one tab: no tab strip
27
+ legal: { terms: '/legal/terms', privacy: '/legal/privacy' },
28
+ }
29
+
30
+ // A trigger keeps its href: when the widget cannot load, the click follows it.
31
+ const unbind = inquiry.bind('[data-inquiry="quote"]', quote, { source: 'pricing-card' })
32
+
33
+ await inquiry.open(quote, { source: 'menu' }) // from code
34
+ const fab = await inquiry.button(quote) // a floating button, bottom-right
35
+ fab.unmount()
36
+ ```
37
+
38
+ Nothing is fetched until the first `load`, `open`, `button` or bound click — a page that must not
39
+ contact a third party before an interaction stays clean.
40
+
41
+ ## Analytics
42
+
43
+ Each open is logged once through `@owlmeans/log` as an analytics-only call:
44
+
45
+ ```ts
46
+ logger('inquiry').info('Inquiry dialog opened',
47
+ { inquiry_widget, inquiry_tab, inquiry_source },
48
+ { analytics: 'inquiry_dialog_open', console: false })
49
+ ```
50
+
51
+ The event reaches a tag manager when the host registers the consent-gated plugin of
52
+ `@owlmeans/web-log` — without analytics consent it is dropped:
53
+
54
+ ```ts
55
+ import { addLogPlugin } from '@owlmeans/log'
56
+ import { gtmAnalyticsPlugin } from '@owlmeans/web-log'
57
+ import { INQUIRY_OPEN_EVENT } from '@owlmeans/web-inquiry'
58
+
59
+ addLogPlugin(gtmAnalyticsPlugin({ allow: [INQUIRY_OPEN_EVENT] }))
60
+ // → window.dataLayer.push({ event: 'inquiry_dialog_open', inquiry_widget, inquiry_tab, inquiry_source })
61
+ ```
62
+
63
+ In the tag manager, a Custom Event trigger on `inquiry_dialog_open` forwards it to GA4.
64
+ `analytics: 'name'` renames the event; `analytics: false` reports nothing (`onOpen` still runs).
65
+
66
+ ## Related
67
+
68
+ - [`@owlmeans/common-inquiry`](../common-inquiry): the runtime contract, config, limits and schemas
69
+ - [`@owlmeans/web-log`](../web-log): the consent-gated analytics plugins
70
+
71
+ <!-- owlmeans:agent-guidance:start -->
72
+ ## Agent guidance
73
+
74
+ This package ships embedded agent skills under `agent-meta/`. After installing your
75
+ `@owlmeans/*` packages, run the OwlMeans agent-skills installer to place them into
76
+ your project's skill store (`.agents/skills/`):
77
+
78
+ ```sh
79
+ npx @owlmeans/agent-skills@^0.1.18-rc.53
80
+ ```
81
+
82
+ The embedded files are version-matched to this package release. Do not edit them
83
+ directly — they are regenerated on each publish. To contribute guidance edits,
84
+ open a PR against the source monorepo.
85
+ <!-- owlmeans:agent-guidance:end -->
@@ -0,0 +1,16 @@
1
+ {
2
+ "schemaVersion": 2,
3
+ "package": "@owlmeans/web-inquiry",
4
+ "version": "0.1.18-rc.1",
5
+ "generatedAt": "2026-10-09T11:30:42.748Z",
6
+ "canonicalRepo": "https://github.com/owlmeans/common",
7
+ "entries": [
8
+ {
9
+ "kind": "skill",
10
+ "name": "web-inquiry",
11
+ "category": "package-specific",
12
+ "file": "skills/web-inquiry/SKILL.md",
13
+ "canonicalPath": ".agents/skills/web-inquiry/SKILL.md"
14
+ }
15
+ ]
16
+ }
@@ -0,0 +1,124 @@
1
+ ---
2
+ name: web-inquiry
3
+ description: How to use @owlmeans/web-inquiry — the lightweight browser SDK of the OwlMeans customer inquiry widget. makeInquiryClient injects the widget runtime (<crm>/inquiry.js) once per page, checks its version, and opens the contact dialog from code (open), from triggers that keep their href as a fallback (bind) or from a floating button (button); every open is reported once as the analytics event inquiry_dialog_open through @owlmeans/log, which web-log's gtmAnalyticsPlugin forwards to a tag manager under consent. Auto-invoked when adding a contact/feedback dialog, a "Contact us" or "Get a quote" trigger to a page, importing makeInquiryClient or InquiryLoadError, or wiring the inquiry open event into GTM.
4
+ user-invocable: false
5
+ ---
6
+ <!-- AUTO-GENERATED — do not edit. Regenerate via sync-agent-meta. -->
7
+
8
+ # @owlmeans/web-inquiry
9
+
10
+ **Layer:** Web (depends on `@owlmeans/common-inquiry` and `@owlmeans/log`; no React, no widget code)
11
+ **Install:** `"@owlmeans/web-inquiry": "^0.1.18-rc.1"` in `dependencies`
12
+
13
+ The host half of the inquiry widget. The dialog itself — React, styles, reCAPTCHA, the upload — is
14
+ a bundle the CRM serves; this package only loads it, opens it and reports the opens. A page pays
15
+ for the widget on the first interaction, never at load.
16
+
17
+ ## Use it
18
+
19
+ ```ts
20
+ import { makeInquiryClient } from '@owlmeans/web-inquiry'
21
+
22
+ const inquiry = makeInquiryClient({
23
+ url: `${platformWeb}/crm`, // the CRM base; a trailing slash is dropped
24
+ language: () => i18n.language, // a string, or a function read at every open
25
+ email: () => accountEmail(), // optional string or lazy sync/async reply address
26
+ })
27
+
28
+ inquiry.bind('[data-inquiry="quote"]', quoteConfig, { source: 'pricing-card' }) // returns unbind
29
+ await inquiry.open(viableConfig, { tab: 'payment', source: 'menu' })
30
+ const fab = await inquiry.button(viableConfig, { position: 'bottom-right' }) // InquiryHandle
31
+ ```
32
+
33
+ One client per page and CRM is the usual shape. More are safe: the script is injected once per
34
+ URL, and each open is routed to the client that claimed its widget id (the latest claimant takes
35
+ the opens of an unclaimed widget). The last client to act sets the runtime's language.
36
+
37
+ | Option | Meaning |
38
+ |---|---|
39
+ | `url` | the CRM base, e.g. `https://platform.owlmeans.com/crm` |
40
+ | `language` | the widget's language — string or function; default: the runtime's own choice |
41
+ | `email` | optional string or function returning `string \| null \| undefined`, directly or in a Promise; applied on each open |
42
+ | `analytics` | the open event's name; default `INQUIRY_OPEN_EVENT`; `false` reports nothing |
43
+ | `onOpen(event)` | called once per open, after the analytics event |
44
+ | `timeoutMs` | how long `load` waits; default `INQUIRY_LOAD_TIMEOUT` (10 000) |
45
+
46
+ The client passes the email source to the widget; neither creating a client, binding triggers nor
47
+ `load()` invokes it. Supply `email` in `open`, `bind` or `button` options to override the client's
48
+ default. A floating button's handle carries the same default into its `open` unless overridden.
49
+ The widget resolves it when the dialog opens, so an async lookup can show its spinner immediately
50
+ and disable the email field and Send while leaving other fields editable. Do not await the lookup
51
+ in the host before opening. A failure or missing result leaves an empty editable address; omitting
52
+ `email` preserves the manual draft. Each subsequent open reapplies the supplied preset.
53
+
54
+ Cache identity lookups in the host when needed, scoped to the authenticated session and held in
55
+ memory. Return a string or null synchronously once cached to avoid showing a spinner again. Share
56
+ pending requests, invalidate the cache when authentication changes, and discard results belonging
57
+ to an earlier session. The SDK and widget do not store identity information.
58
+
59
+ ## Loading
60
+
61
+ `load()` (and every `open`, `button` or bound click before it) injects
62
+ `<script src="<url>/inquiry.js?v=<INQUIRY_RUNTIME_VERSION>" async data-owlmeans-inquiry>` — unless
63
+ the page already holds that script, which a second copy of the package would have injected — and
64
+ waits for `window.__owlmeansInquiry`. It resolves when the runtime's `version` equals
65
+ `INQUIRY_RUNTIME_VERSION` and then calls `runtime.configure({ url, language, onOpen })`.
66
+
67
+ It rejects with an `InquiryLoadError` whose `failure` says why: `network` (the script failed, or
68
+ loaded without installing the runtime), `timeout`, `version` (another runtime version) or
69
+ `environment` (no document). A failed load removes the script it injected, so the next call
70
+ retries.
71
+
72
+ ## Triggers keep their links
73
+
74
+ `bind(target, config, opts?)` takes an element or a selector (every element it matches now). A
75
+ click is taken over and opens the dialog; if the widget cannot load, an anchor follows its own
76
+ `href` (never `#…` or `javascript:`). A modified click on an anchor — ctrl/cmd/shift/alt or a
77
+ non-primary button — is left to the browser, so "open in a new tab" still reaches the page behind
78
+ the link. Keep a real `href` on every trigger: it is the fallback and what a crawler sees.
79
+
80
+ ## Analytics
81
+
82
+ Each open, whatever opened it, is reported once:
83
+
84
+ ```ts
85
+ logger('inquiry').info('Inquiry dialog opened',
86
+ { inquiry_widget, inquiry_tab, inquiry_source },
87
+ { analytics: 'inquiry_dialog_open', console: false })
88
+ ```
89
+
90
+ The SDK reports from the runtime's `onOpen` only — `open()` itself emits nothing — so an open from
91
+ code, a bound trigger or the floating button is counted exactly once. `inquiry_source` is the
92
+ trigger's `source` (the floating button's defaults to `fab`) and is sent even when undefined, so a
93
+ tag manager's data layer does not keep the previous open's value.
94
+
95
+ To send it to GTM, the host registers the consent-gated plugin once at startup:
96
+
97
+ ```ts
98
+ import { addLogPlugin } from '@owlmeans/log'
99
+ import { gtmAnalyticsPlugin } from '@owlmeans/web-log'
100
+ import { INQUIRY_OPEN_EVENT } from '@owlmeans/web-inquiry'
101
+
102
+ addLogPlugin(gtmAnalyticsPlugin({ allow: [INQUIRY_OPEN_EVENT] }))
103
+ ```
104
+
105
+ Without analytics consent the event is dropped, never queued (`web-log`). In the container, a
106
+ Custom Event trigger on `inquiry_dialog_open` forwards it to a GA4 event tag.
107
+
108
+ ## Re-exports
109
+
110
+ For a host that depends on this package alone: `INQUIRY_OPEN_EVENT` and the types
111
+ `InquiryWidgetConfig`, `InquiryTab`, `LocalizedText`, `InquiryOpenOptions`, `InquiryButtonOptions`,
112
+ `InquiryEmailOptions`, `InquiryEmailPreset`, `InquiryEmailValue`, `InquiryOpenEvent`, `InquiryHandle`,
113
+ `InquiryRuntime` from `@owlmeans/common-inquiry`.
114
+
115
+ ## Testing
116
+
117
+ The SDK runs against a minimal fake `window`/`document` (attributes, listeners, `head.appendChild`,
118
+ `querySelectorAll`, timers, `location.assign`) and a fake runtime that calls `onOpen` once per open;
119
+ the loader is page-wide state, so each spec uses a CRM URL of its own.
120
+
121
+ ## Related
122
+
123
+ - `common-inquiry` — the config, the runtime contract, limits and schemas
124
+ - `web-log`, `log` — the analytics routing the open event takes
@@ -0,0 +1,12 @@
1
+ import type { InquiryClient, InquiryClientOptions } from './types.js';
2
+ /**
3
+ * A host page's inquiry client. Building it costs nothing: the widget runtime is fetched on the
4
+ * first `load`, `open`, `button` or bound click.
5
+ *
6
+ * ```ts
7
+ * const inquiry = makeInquiryClient({ url: 'https://platform.owlmeans.com/crm', language: () => i18n.language })
8
+ * inquiry.bind('[data-inquiry="quote"]', quoteConfig, { source: 'pricing-card' })
9
+ * ```
10
+ */
11
+ export declare const makeInquiryClient: (options: InquiryClientOptions) => InquiryClient;
12
+ //# sourceMappingURL=client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAA;AAGrE;;;;;;;;GAQG;AACH,eAAO,MAAM,iBAAiB,YAAa,oBAAoB,KAAG,aAqEjE,CAAA"}
@@ -0,0 +1,74 @@
1
+ import { INQUIRY_OPEN_EVENT } from '@owlmeans/common-inquiry';
2
+ import { logger } from '@owlmeans/log';
3
+ import { INQUIRY_LOAD_TIMEOUT } from './consts.js';
4
+ import { LOG_SCOPE, NO_DESTINATION } from './consts.local.js';
5
+ import { inquiryLoaderUtils } from './utils/loader.js';
6
+ /**
7
+ * A host page's inquiry client. Building it costs nothing: the widget runtime is fetched on the
8
+ * first `load`, `open`, `button` or bound click.
9
+ *
10
+ * ```ts
11
+ * const inquiry = makeInquiryClient({ url: 'https://platform.owlmeans.com/crm', language: () => i18n.language })
12
+ * inquiry.bind('[data-inquiry="quote"]', quoteConfig, { source: 'pricing-card' })
13
+ * ```
14
+ */
15
+ export const makeInquiryClient = (options) => {
16
+ const url = options.url.replace(/\/+$/, '');
17
+ const timeoutMs = options.timeoutMs ?? INQUIRY_LOAD_TIMEOUT;
18
+ const eventName = options.analytics === false ? null : options.analytics ?? INQUIRY_OPEN_EVENT;
19
+ const log = logger(LOG_SCOPE);
20
+ /** The one place an open is reported — the runtime calls it once per open, whatever opened it. */
21
+ const opened = (event) => {
22
+ if (eventName != null) {
23
+ log.info('Inquiry dialog opened', {
24
+ inquiry_widget: event.widget,
25
+ inquiry_tab: event.tab,
26
+ inquiry_source: event.source,
27
+ }, { analytics: eventName, console: false });
28
+ }
29
+ options.onOpen?.(event);
30
+ };
31
+ const load = async () => {
32
+ const runtime = await inquiryLoaderUtils.load(url, timeoutMs);
33
+ runtime.configure({ url, language: options.language, onOpen: inquiryLoaderUtils.dispatcher(url) });
34
+ return runtime;
35
+ };
36
+ const open = async (config, opts) => {
37
+ const runtime = await load();
38
+ inquiryLoaderUtils.claim(url, config.id, opened);
39
+ runtime.open(config, options.email != null ? { ...opts, email: opts?.email ?? options.email } : opts);
40
+ };
41
+ const button = async (config, opts) => {
42
+ const runtime = await load();
43
+ inquiryLoaderUtils.claim(url, config.id, opened);
44
+ return runtime.button(config, options.email != null ? { ...opts, email: opts?.email ?? options.email } : opts);
45
+ };
46
+ const bind = (target, config, opts) => {
47
+ if (typeof document === 'undefined') {
48
+ return () => { };
49
+ }
50
+ const elements = typeof target === 'string' ? Array.from(document.querySelectorAll(target)) : [target];
51
+ const unbinds = elements.map(element => {
52
+ const onClick = (event) => {
53
+ const href = element.getAttribute('href');
54
+ const mouse = event;
55
+ if (href != null && (mouse.button > 0 || mouse.metaKey || mouse.ctrlKey || mouse.shiftKey || mouse.altKey)) {
56
+ return;
57
+ }
58
+ event.preventDefault();
59
+ open(config, opts).catch((error) => {
60
+ const follow = href != null && href.trim() !== '' && !NO_DESTINATION.test(href);
61
+ log.warn('Inquiry widget unavailable', { url, widget: config.id, follow, error });
62
+ if (follow) {
63
+ window.location.assign(href);
64
+ }
65
+ });
66
+ };
67
+ element.addEventListener('click', onClick);
68
+ return () => element.removeEventListener('click', onClick);
69
+ });
70
+ return () => unbinds.forEach(unbind => unbind());
71
+ };
72
+ return { url, load, open, bind, button };
73
+ };
74
+ //# sourceMappingURL=client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /** How long a client waits for the widget runtime by default, in milliseconds. */
2
+ export declare const INQUIRY_LOAD_TIMEOUT = 10000;
3
+ /** The attribute that marks the injected runtime `<script>` (and lets a second client find it). */
4
+ export declare const INQUIRY_SCRIPT_ATTRIBUTE = "data-owlmeans-inquiry";
5
+ //# sourceMappingURL=consts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.d.ts","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,eAAO,MAAM,oBAAoB,QAAS,CAAA;AAE1C,mGAAmG;AACnG,eAAO,MAAM,wBAAwB,0BAA0B,CAAA"}
@@ -0,0 +1,5 @@
1
+ /** How long a client waits for the widget runtime by default, in milliseconds. */
2
+ export const INQUIRY_LOAD_TIMEOUT = 10_000;
3
+ /** The attribute that marks the injected runtime `<script>` (and lets a second client find it). */
4
+ export const INQUIRY_SCRIPT_ATTRIBUTE = 'data-owlmeans-inquiry';
5
+ //# sourceMappingURL=consts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.js","sourceRoot":"","sources":["../src/consts.ts"],"names":[],"mappings":"AAAA,kFAAkF;AAClF,MAAM,CAAC,MAAM,oBAAoB,GAAG,MAAM,CAAA;AAE1C,mGAAmG;AACnG,MAAM,CAAC,MAAM,wBAAwB,GAAG,uBAAuB,CAAA"}
@@ -0,0 +1,7 @@
1
+ /** How often a pending load looks for the runtime global, in milliseconds. */
2
+ export declare const POLL_INTERVAL = 50;
3
+ /** The log scope of the SDK. */
4
+ export declare const LOG_SCOPE = "inquiry";
5
+ /** An `href` that is no destination to fall back to. */
6
+ export declare const NO_DESTINATION: RegExp;
7
+ //# sourceMappingURL=consts.local.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.local.d.ts","sourceRoot":"","sources":["../src/consts.local.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,eAAO,MAAM,aAAa,KAAK,CAAA;AAE/B,gCAAgC;AAChC,eAAO,MAAM,SAAS,YAAY,CAAA;AAElC,wDAAwD;AACxD,eAAO,MAAM,cAAc,QAAyB,CAAA"}
@@ -0,0 +1,7 @@
1
+ /** How often a pending load looks for the runtime global, in milliseconds. */
2
+ export const POLL_INTERVAL = 50;
3
+ /** The log scope of the SDK. */
4
+ export const LOG_SCOPE = 'inquiry';
5
+ /** An `href` that is no destination to fall back to. */
6
+ export const NO_DESTINATION = /^\s*(#|javascript:)/i;
7
+ //# sourceMappingURL=consts.local.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"consts.local.js","sourceRoot":"","sources":["../src/consts.local.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,MAAM,CAAC,MAAM,aAAa,GAAG,EAAE,CAAA;AAE/B,gCAAgC;AAChC,MAAM,CAAC,MAAM,SAAS,GAAG,SAAS,CAAA;AAElC,wDAAwD;AACxD,MAAM,CAAC,MAAM,cAAc,GAAG,sBAAsB,CAAA"}
@@ -0,0 +1,7 @@
1
+ import type { InquiryLoadFailure } from './types.js';
2
+ /** The widget runtime could not be loaded; `failure` says why. */
3
+ export declare class InquiryLoadError extends Error {
4
+ readonly failure: InquiryLoadFailure;
5
+ constructor(failure: InquiryLoadFailure, message: string);
6
+ }
7
+ //# sourceMappingURL=errors.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAA;AAEpD,kEAAkE;AAClE,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,QAAQ,CAAC,OAAO,EAAE,kBAAkB,CAAA;IAEpC,YAAY,OAAO,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,EAIvD;CACF"}
@@ -0,0 +1,10 @@
1
+ /** The widget runtime could not be loaded; `failure` says why. */
2
+ export class InquiryLoadError extends Error {
3
+ failure;
4
+ constructor(failure, message) {
5
+ super(message);
6
+ this.name = 'InquiryLoadError';
7
+ this.failure = failure;
8
+ }
9
+ }
10
+ //# sourceMappingURL=errors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAEA,kEAAkE;AAClE,MAAM,OAAO,gBAAiB,SAAQ,KAAK;IAChC,OAAO,CAAoB;IAEpC,YAAY,OAA2B,EAAE,OAAe;QACtD,KAAK,CAAC,OAAO,CAAC,CAAA;QACd,IAAI,CAAC,IAAI,GAAG,kBAAkB,CAAA;QAC9B,IAAI,CAAC,OAAO,GAAG,OAAO,CAAA;IACxB,CAAC;CACF"}
@@ -0,0 +1,7 @@
1
+ export type * from './types.js';
2
+ export * from './consts.js';
3
+ export * from './errors.js';
4
+ export * from './client.js';
5
+ export type { InquiryButtonOptions, InquiryEmailOptions, InquiryEmailPreset, InquiryEmailValue, InquiryHandle, InquiryOpenEvent, InquiryOpenOptions, InquiryRuntime, InquiryTab, InquiryWidgetConfig, LocalizedText, } from '@owlmeans/common-inquiry';
6
+ export { INQUIRY_OPEN_EVENT } from '@owlmeans/common-inquiry';
7
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,mBAAmB,YAAY,CAAA;AAC/B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,YAAY,EACV,oBAAoB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,aAAa,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,cAAc,EAAE,UAAU,EACjK,mBAAmB,EAAE,aAAa,GACnC,MAAM,0BAA0B,CAAA;AACjC,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA"}
package/build/index.js ADDED
@@ -0,0 +1,5 @@
1
+ export * from './consts.js';
2
+ export * from './errors.js';
3
+ export * from './client.js';
4
+ export { INQUIRY_OPEN_EVENT } from '@owlmeans/common-inquiry';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAC3B,cAAc,aAAa,CAAA;AAK3B,OAAO,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAA"}
@@ -0,0 +1,42 @@
1
+ import type { InquiryButtonOptions, InquiryEmailOptions, InquiryHandle, InquiryOpenEvent, InquiryOpenOptions, InquiryRuntime, InquiryWidgetConfig } from '@owlmeans/common-inquiry';
2
+ export interface InquiryClientOptions extends InquiryEmailOptions {
3
+ /** The CRM base URL the widget is served from, e.g. `https://platform.owlmeans.com/crm`; a trailing slash is dropped. */
4
+ url: string;
5
+ /** The widget's language, or a function read at every open (so a language switch is honoured). */
6
+ language?: string | (() => string);
7
+ /** The analytics event of a dialog open. Default: `INQUIRY_OPEN_EVENT`; `false` reports nothing. */
8
+ analytics?: string | false;
9
+ /** Called once per dialog open, after the analytics event. */
10
+ onOpen?: (event: InquiryOpenEvent) => void;
11
+ /** How long `load` waits for the runtime, in milliseconds. Default: `INQUIRY_LOAD_TIMEOUT`. */
12
+ timeoutMs?: number;
13
+ }
14
+ /**
15
+ * The host page's handle on the inquiry widget. Nothing is fetched until the first `load`, `open`,
16
+ * `button` or bound click; the runtime script is injected once per page whatever the number of
17
+ * clients.
18
+ */
19
+ export interface InquiryClient {
20
+ /** The normalized CRM base URL. */
21
+ readonly url: string;
22
+ /**
23
+ * The widget runtime: injects `<url>/inquiry.js` once, waits for the runtime of
24
+ * `INQUIRY_RUNTIME_VERSION` and configures it. Rejects with an `InquiryLoadError` on a network
25
+ * failure, a timeout or a runtime of another version.
26
+ */
27
+ load: () => Promise<InquiryRuntime>;
28
+ /** Load, then open the widget's dialog. */
29
+ open: (config: InquiryWidgetConfig, opts?: InquiryOpenOptions) => Promise<void>;
30
+ /**
31
+ * Open the dialog from a trigger's clicks — an element, or every element a selector matches now.
32
+ * A click is taken over (`preventDefault`) and opens the dialog; when the widget cannot load, an
33
+ * anchor trigger follows its own `href` instead. A modified click (new tab, new window) on an
34
+ * anchor is left to the browser. Returns the function that unbinds every bound element.
35
+ */
36
+ bind: (target: Element | string, config: InquiryWidgetConfig, opts?: InquiryOpenOptions) => () => void;
37
+ /** Load, then mount the widget's floating button. */
38
+ button: (config: InquiryWidgetConfig, opts?: InquiryButtonOptions) => Promise<InquiryHandle>;
39
+ }
40
+ /** Why the runtime could not be loaded. */
41
+ export type InquiryLoadFailure = 'environment' | 'network' | 'timeout' | 'version';
42
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,oBAAoB,EAAE,mBAAmB,EAAE,aAAa,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,cAAc,EAAE,mBAAmB,EACpI,MAAM,0BAA0B,CAAA;AAEjC,MAAM,WAAW,oBAAqB,SAAQ,mBAAmB;IAC/D,yHAAyH;IACzH,GAAG,EAAE,MAAM,CAAA;IACX,kGAAkG;IAClG,QAAQ,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,CAAC,CAAA;IAClC,oGAAoG;IACpG,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAA;IAC1B,8DAA8D;IAC9D,MAAM,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,CAAA;IAC1C,+FAA+F;IAC/F,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,mCAAmC;IACnC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAA;IACpB;;;;OAIG;IACH,IAAI,EAAE,MAAM,OAAO,CAAC,cAAc,CAAC,CAAA;IACnC,2CAA2C;IAC3C,IAAI,EAAE,CAAC,MAAM,EAAE,mBAAmB,EAAE,IAAI,CAAC,EAAE,kBAAkB,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC/E;;;;;OAKG;IACH,IAAI,EAAE,CAAC,MAAM,EAAE,OAAO,GAAG,MAAM,EAAE,MAAM,EAAE,mBAAmB,EAAE,IAAI,CAAC,EAAE,kBAAkB,KAAK,MAAM,IAAI,CAAA;IACtG,qDAAqD;IACrD,MAAM,EAAE,CAAC,MAAM,EAAE,mBAAmB,EAAE,IAAI,CAAC,EAAE,oBAAoB,KAAK,OAAO,CAAC,aAAa,CAAC,CAAA;CAC7F;AAED,2CAA2C;AAC3C,MAAM,MAAM,kBAAkB,GAAG,aAAa,GAAG,SAAS,GAAG,SAAS,GAAG,SAAS,CAAA"}
package/build/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,23 @@
1
+ import type { InquiryOpenEvent, InquiryRuntime } from '@owlmeans/common-inquiry';
2
+ export interface InquiryOpenHandler {
3
+ (event: InquiryOpenEvent): void;
4
+ }
5
+ /**
6
+ * The page-wide half of the SDK, shared by every client: one script per CRM url, one pending load,
7
+ * and one `onOpen` per runtime that routes each open to the client that owns the widget.
8
+ */
9
+ export interface InquiryLoaderUtils {
10
+ /** The runtime served at `url` — injected once, its version checked; a failed load can be retried. */
11
+ load: (url: string, timeoutMs: number) => Promise<InquiryRuntime>;
12
+ /** Route the opens of widget `id` (and those of any widget no client claimed) to `handler`. */
13
+ claim: (url: string, id: string, handler: InquiryOpenHandler) => void;
14
+ /** The one `onOpen` the runtime of `url` is configured with. */
15
+ dispatcher: (url: string) => InquiryOpenHandler;
16
+ }
17
+ /** Who hears the opens of one runtime: the claimant of each widget, else the latest claimant. */
18
+ export interface InquiryOpenRoute {
19
+ handlers: Map<string, InquiryOpenHandler>;
20
+ last?: InquiryOpenHandler;
21
+ dispatch: InquiryOpenHandler;
22
+ }
23
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/utils/loader/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAA;AAEhF,MAAM,WAAW,kBAAkB;IAAG,CAAC,KAAK,EAAE,gBAAgB,GAAG,IAAI,CAAA;CAAE;AAEvE;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,sGAAsG;IACtG,IAAI,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,KAAK,OAAO,CAAC,cAAc,CAAC,CAAA;IACjE,+FAA+F;IAC/F,KAAK,EAAE,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,kBAAkB,KAAK,IAAI,CAAA;IACrE,gEAAgE;IAChE,UAAU,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,kBAAkB,CAAA;CAChD;AAED,iGAAiG;AACjG,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;IACzC,IAAI,CAAC,EAAE,kBAAkB,CAAA;IACzB,QAAQ,EAAE,kBAAkB,CAAA;CAC7B"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/utils/loader/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,4 @@
1
+ import type { InquiryLoaderUtils } from './loader/types.js';
2
+ export declare const createInquiryLoaderUtils: () => InquiryLoaderUtils;
3
+ export declare const inquiryLoaderUtils: InquiryLoaderUtils;
4
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/utils/loader.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,kBAAkB,EAAoB,MAAM,mBAAmB,CAAA;AAE7E,eAAO,MAAM,wBAAwB,QAAO,kBA6H3C,CAAA;AAED,eAAO,MAAM,kBAAkB,oBAA6B,CAAA"}
@@ -0,0 +1,111 @@
1
+ import { INQUIRY_GLOBAL, INQUIRY_RUNTIME_VERSION, INQUIRY_SCRIPT, } from '@owlmeans/common-inquiry';
2
+ import { INQUIRY_SCRIPT_ATTRIBUTE } from '../consts.js';
3
+ import { POLL_INTERVAL } from '../consts.local.js';
4
+ import { InquiryLoadError } from '../errors.js';
5
+ export const createInquiryLoaderUtils = () => {
6
+ const loads = new Map();
7
+ const routes = new Map();
8
+ const globalOf = () => window[INQUIRY_GLOBAL];
9
+ const scriptUrl = (url) => `${url}/${INQUIRY_SCRIPT}?v=${INQUIRY_RUNTIME_VERSION}`;
10
+ /** A runtime script already in the page — injected by another client or another copy of this package. */
11
+ const existingScript = (src) => Array.from(document.querySelectorAll(`script[${INQUIRY_SCRIPT_ATTRIBUTE}]`))
12
+ .find(script => script.getAttribute('src') === src);
13
+ const inject = (url, timeoutMs) => new Promise((resolve, reject) => {
14
+ const src = scriptUrl(url);
15
+ const found = existingScript(src);
16
+ const script = found ?? document.createElement('script');
17
+ let settled = false;
18
+ let poll;
19
+ let timer;
20
+ const settle = (runtime, error) => {
21
+ if (settled) {
22
+ return;
23
+ }
24
+ settled = true;
25
+ window.clearInterval(poll);
26
+ window.clearTimeout(timer);
27
+ script.removeEventListener('load', loaded);
28
+ script.removeEventListener('error', failed);
29
+ if (runtime != null) {
30
+ resolve(runtime);
31
+ return;
32
+ }
33
+ loads.delete(url);
34
+ if (found == null) {
35
+ script.remove();
36
+ }
37
+ reject(error);
38
+ };
39
+ /** Whether the runtime is there — settling either way once it is. */
40
+ const check = () => {
41
+ const runtime = globalOf();
42
+ if (runtime == null) {
43
+ return false;
44
+ }
45
+ if (runtime.version !== INQUIRY_RUNTIME_VERSION) {
46
+ settle(undefined, new InquiryLoadError('version', `Inquiry runtime version ${String(runtime.version)} is not ${INQUIRY_RUNTIME_VERSION}`));
47
+ }
48
+ else {
49
+ settle(runtime);
50
+ }
51
+ return true;
52
+ };
53
+ const loaded = () => {
54
+ if (!check()) {
55
+ settle(undefined, new InquiryLoadError('network', `${src} loaded without installing the inquiry runtime`));
56
+ }
57
+ };
58
+ const failed = () => {
59
+ settle(undefined, new InquiryLoadError('network', `${src} failed to load`));
60
+ };
61
+ script.addEventListener('load', loaded);
62
+ script.addEventListener('error', failed);
63
+ poll = window.setInterval(check, POLL_INTERVAL);
64
+ timer = window.setTimeout(() => {
65
+ settle(undefined, new InquiryLoadError('timeout', `${src} did not install the inquiry runtime in ${timeoutMs} ms`));
66
+ }, timeoutMs);
67
+ if (found == null) {
68
+ script.src = src;
69
+ script.async = true;
70
+ script.setAttribute(INQUIRY_SCRIPT_ATTRIBUTE, '');
71
+ document.head.appendChild(script);
72
+ }
73
+ });
74
+ const load = (url, timeoutMs) => {
75
+ if (typeof window === 'undefined' || typeof document === 'undefined') {
76
+ return Promise.reject(new InquiryLoadError('environment', 'The inquiry widget needs a browser document'));
77
+ }
78
+ const ready = globalOf();
79
+ if (ready != null && ready.version === INQUIRY_RUNTIME_VERSION) {
80
+ return Promise.resolve(ready);
81
+ }
82
+ const pending = loads.get(url);
83
+ if (pending != null) {
84
+ return pending;
85
+ }
86
+ const loading = inject(url, timeoutMs);
87
+ loads.set(url, loading);
88
+ return loading;
89
+ };
90
+ const routeOf = (url) => {
91
+ const known = routes.get(url);
92
+ if (known != null) {
93
+ return known;
94
+ }
95
+ const route = {
96
+ handlers: new Map(),
97
+ dispatch: event => (route.handlers.get(event.widget) ?? route.last)?.(event),
98
+ };
99
+ routes.set(url, route);
100
+ return route;
101
+ };
102
+ const claim = (url, id, handler) => {
103
+ const route = routeOf(url);
104
+ route.handlers.set(id, handler);
105
+ route.last = handler;
106
+ };
107
+ const dispatcher = url => routeOf(url).dispatch;
108
+ return { load, claim, dispatcher };
109
+ };
110
+ export const inquiryLoaderUtils = createInquiryLoaderUtils();
111
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/utils/loader.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,42 @@
1
1
  {
2
2
  "name": "@owlmeans/web-inquiry",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.18-rc.1",
4
+ "license": "MIT",
5
+ "description": "Lightweight browser SDK of the OwlMeans customer inquiry widget — injects the widget runtime once, opens its dialog from any trigger and reports each open as an analytics event.",
6
+ "type": "module",
7
+ "scripts": {
8
+ "build": "tsc -b",
9
+ "dev": "sleep 2 && nodemon -e ts,json --watch src --exec \"tsc -p ./tsconfig.json\"",
10
+ "watch": "tsc -b -w --preserveWatchOutput --pretty",
11
+ "test": "bun test ./tests"
12
+ },
13
+ "main": "build/index.js",
14
+ "module": "build/index.js",
15
+ "types": "build/index.d.ts",
16
+ "exports": {
17
+ ".": {
18
+ "import": "./build/index.js",
19
+ "require": "./build/index.js",
20
+ "default": "./build/index.js",
21
+ "module": "./build/index.js",
22
+ "types": "./build/index.d.ts"
23
+ }
24
+ },
25
+ "files": [
26
+ "build",
27
+ "agent-meta"
28
+ ],
29
+ "dependencies": {
30
+ "@owlmeans/common-inquiry": "^0.1.18-rc.1",
31
+ "@owlmeans/log": "^0.1.18-rc.3"
32
+ },
33
+ "devDependencies": {
34
+ "@owlmeans/dep-config": "workspace:*",
35
+ "@types/bun": "^1.4.2",
36
+ "nodemon": "^3.1.14",
37
+ "typescript": "^7.0.2"
38
+ },
39
+ "publishConfig": {
40
+ "access": "public"
41
+ }
42
+ }