@saasquatch/component-environment 1.0.0-2 → 1.0.0-5

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 +1,46 @@
1
1
  Provides the environment for running SaaSquatch web components.
2
+
3
+ SaaSquatch web components can run in a number of different environments, including:
4
+
5
+ - in a widget via `squatch-js`
6
+ - in a microsite (portal)
7
+ - in a mobile SDK (i.e. `squatch-android`)
8
+ - in the admin portal
9
+
10
+ In each environment, a different set of context information about the tenant, user and program are provided, and the goal of this package is to normalize the differences in environments to provide a common API.
11
+
12
+ The environment is provided in a set of contexts through `dom-context`, which provides vanilla global context providers. They can be accessed through a raw `ContextListener` or via `useDomContext` in `dom-context-hooks`.
13
+
14
+ ## General environment
15
+
16
+ ### `getEnvironment()`
17
+
18
+ Get the environment type. The current possible values are: `SquatchJS2`, `SquatchAndroid`, `SquatchPortal`, `SquatchAdmin` or `None`.
19
+
20
+ ### `isDemo()`
21
+
22
+ Returns whether components should run in demo/preview mode.
23
+
24
+ ### `getTenantAlias()`
25
+
26
+ Get the current tenant alias.
27
+
28
+ ### `getAppDomain()`
29
+
30
+ Get the SaaSquatch app domain.
31
+
32
+ ### `getEngagementMedium()`
33
+
34
+ Get the current engagement medium. This is particularly important in widgets rendered by `squatch-js` for informing metadata about share link clicks.
35
+
36
+ ## User identity
37
+
38
+ The user identity context name is exported in a constant `USER_CONTEXT_NAME`. The current value can be retrieved with `getUserIdentity()` and set with `setUserIdentity(identity)`.
39
+
40
+ ## Locale
41
+
42
+ The locale context name is exported in a constnat `LOCALE_CONTEXT_NAME`. The current value can be retrieved with `getLocale()` and set with `setLocal(locale)`.
43
+
44
+ ## Program ID
45
+
46
+ The program ID context name is exported in a constant `PROGRAM_CONTEXT_NAME`. The current value can be retrieved with `getProgramId()` and set with `setProgramId(programId)`.
package/dist/index.d.ts CHANGED
@@ -162,6 +162,72 @@ declare function getTenantAlias(): string;
162
162
  declare function getAppDomain(): string;
163
163
  declare function getEngagementMedium(): EngagementMedium;
164
164
 
165
+ interface PartialPath {
166
+ pathname: string;
167
+ search?: string;
168
+ hash?: string;
169
+ }
170
+ interface HistoryEntry extends PartialPath {
171
+ state?: object;
172
+ }
173
+ declare type To = string | PartialPath;
174
+ interface ListenableHistory {
175
+ listen(fn: () => void): () => void;
176
+ push(to: To, state?: object): void;
177
+ replace(to: To, state?: object): void;
178
+ back(): void;
179
+ forward(): void;
180
+ go(delta?: number): void;
181
+ location: HistoryEntry;
182
+ }
183
+ declare global {
184
+ interface Window {
185
+ squatchHistory: ListenableHistory;
186
+ }
187
+ }
188
+ declare class BrowserHistory implements ListenableHistory {
189
+ private listeners;
190
+ constructor();
191
+ listen(fn: () => void): () => void;
192
+ private notify;
193
+ get location(): {
194
+ pathname: string;
195
+ search: string;
196
+ hash: string;
197
+ state: any;
198
+ };
199
+ back(): void;
200
+ forward(): void;
201
+ go(delta: number): void;
202
+ push(to: To, state?: object): void;
203
+ replace(to: To, state?: object): void;
204
+ }
205
+ declare class MemoryHistory implements ListenableHistory {
206
+ private history;
207
+ private index;
208
+ private listeners;
209
+ listen(fn: () => void): () => void;
210
+ private current;
211
+ get state(): object | undefined;
212
+ notify(): void;
213
+ get location(): HistoryEntry;
214
+ back(): void;
215
+ forward(): void;
216
+ go(delta: number): void;
217
+ push(to: To, state?: object): void;
218
+ replace(to: To, state?: object): void;
219
+ }
220
+ declare class LazyHistory implements ListenableHistory {
221
+ get location(): HistoryEntry;
222
+ listen(fn: () => void): () => void;
223
+ back(): void;
224
+ forward(): void;
225
+ go(delta: number): void;
226
+ push(to: To, state?: object): void;
227
+ replace(to: To, state?: object): void;
228
+ }
229
+ declare const _default: LazyHistory;
230
+
165
231
  /**
166
232
  * Lazily start the user context provider. If it already exists, the existing provider is
167
233
  * returned. This function is safe to call multiple times.
@@ -223,4 +289,4 @@ declare function setProgramId(programId: string | undefined): void;
223
289
  */
224
290
  declare function getProgramId(): string | undefined;
225
291
 
226
- export { DEFAULT_MEDIUM, DecodedSquatchJWT, DecodedWidgetAPIJWT, EngagementMedium, Environment, EnvironmentSDK, LOCALE_CONTEXT_NAME, LocaleContextName, PROGRAM_CONTEXT_NAME, PortalEnv, ProgramContextName, SquatchAdmin, SquatchAndroid, SquatchJS2, USER_CONTEXT_NAME, UserContextName, UserId, UserIdentity, WidgetIdent, getAppDomain, getEngagementMedium, getEnvironment, getEnvironmentSDK, getLocale, getProgramId, getTenantAlias, getUserIdentity, isDemo, lazilyStartLocaleContext, lazilyStartProgramContext, lazilyStartUserContext, setLocale, setProgramId, setUserIdentity, userIdentityFromJwt };
292
+ export { BrowserHistory, DEFAULT_MEDIUM, DecodedSquatchJWT, DecodedWidgetAPIJWT, EngagementMedium, Environment, EnvironmentSDK, HistoryEntry, LOCALE_CONTEXT_NAME, LazyHistory, LocaleContextName, MemoryHistory, PROGRAM_CONTEXT_NAME, PortalEnv, ProgramContextName, SquatchAdmin, SquatchAndroid, SquatchJS2, USER_CONTEXT_NAME, UserContextName, UserId, UserIdentity, WidgetIdent, getAppDomain, getEngagementMedium, getEnvironment, getEnvironmentSDK, getLocale, getProgramId, getTenantAlias, getUserIdentity, _default as history, isDemo, lazilyStartLocaleContext, lazilyStartProgramContext, lazilyStartUserContext, setLocale, setProgramId, setUserIdentity, userIdentityFromJwt };
package/dist/index.js CHANGED
@@ -1,7 +1,9 @@
1
1
  "use strict";
2
2
  var __create = Object.create;
3
3
  var __defProp = Object.defineProperty;
4
+ var __defProps = Object.defineProperties;
4
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
5
7
  var __getOwnPropNames = Object.getOwnPropertyNames;
6
8
  var __getOwnPropSymbols = Object.getOwnPropertySymbols;
7
9
  var __getProtoOf = Object.getPrototypeOf;
@@ -19,6 +21,7 @@ var __spreadValues = (a, b) => {
19
21
  }
20
22
  return a;
21
23
  };
24
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
22
25
  var __export = (target, all) => {
23
26
  for (var name in all)
24
27
  __defProp(target, name, { get: all[name], enumerable: true });
@@ -37,8 +40,11 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
37
40
  // src/index.ts
38
41
  var src_exports = {};
39
42
  __export(src_exports, {
43
+ BrowserHistory: () => BrowserHistory,
40
44
  DEFAULT_MEDIUM: () => DEFAULT_MEDIUM,
41
45
  LOCALE_CONTEXT_NAME: () => LOCALE_CONTEXT_NAME,
46
+ LazyHistory: () => LazyHistory,
47
+ MemoryHistory: () => MemoryHistory,
42
48
  PROGRAM_CONTEXT_NAME: () => PROGRAM_CONTEXT_NAME,
43
49
  USER_CONTEXT_NAME: () => USER_CONTEXT_NAME,
44
50
  getAppDomain: () => getAppDomain,
@@ -49,6 +55,7 @@ __export(src_exports, {
49
55
  getProgramId: () => getProgramId,
50
56
  getTenantAlias: () => getTenantAlias,
51
57
  getUserIdentity: () => getUserIdentity,
58
+ history: () => history_default,
52
59
  isDemo: () => isDemo,
53
60
  lazilyStartLocaleContext: () => lazilyStartLocaleContext,
54
61
  lazilyStartProgramContext: () => lazilyStartProgramContext,
@@ -148,6 +155,199 @@ function getEngagementMedium() {
148
155
  }
149
156
  }
150
157
 
158
+ // src/debug.ts
159
+ var debugEnabled = (() => {
160
+ var _a;
161
+ try {
162
+ return (_a = window == null ? void 0 : window.localStorage) == null ? void 0 : _a.getItem("debug");
163
+ } catch (e) {
164
+ return false;
165
+ }
166
+ })();
167
+ function debug(ns, ...args) {
168
+ if (debugEnabled) {
169
+ console.debug(`sq:environment:${ns}`, ...args);
170
+ }
171
+ }
172
+
173
+ // src/history.ts
174
+ var debug2 = (...args) => debug("history", ...args);
175
+ function normalizeTo(to) {
176
+ if (typeof to === "string")
177
+ return to;
178
+ const url = new URL(to.pathname, window.origin);
179
+ if (to.search)
180
+ url.search = to.search;
181
+ if (to.hash)
182
+ url.hash = to.hash;
183
+ return url;
184
+ }
185
+ var BrowserHistory = class {
186
+ constructor() {
187
+ this.listeners = /* @__PURE__ */ new Set();
188
+ window.addEventListener("popstate", this.notify.bind(this));
189
+ window.addEventListener("pushState", this.notify.bind(this));
190
+ window.addEventListener("replaceState", this.notify.bind(this));
191
+ }
192
+ listen(fn) {
193
+ this.listeners.add(fn);
194
+ return () => {
195
+ this.listeners.delete(fn);
196
+ };
197
+ }
198
+ notify() {
199
+ debug2("notifying listeners of route change", this.location);
200
+ if (this.listeners) {
201
+ this.listeners.forEach((listener) => listener());
202
+ }
203
+ }
204
+ get location() {
205
+ return {
206
+ pathname: window.location.pathname,
207
+ search: window.location.search,
208
+ hash: window.location.hash,
209
+ state: window.history.state
210
+ };
211
+ }
212
+ back() {
213
+ this.go(-1);
214
+ }
215
+ forward() {
216
+ this.go(1);
217
+ }
218
+ go(delta) {
219
+ window.history.go(delta);
220
+ }
221
+ push(to, state) {
222
+ const url = normalizeTo(to);
223
+ window.history.pushState(state, "", url);
224
+ }
225
+ replace(to, state) {
226
+ const url = normalizeTo(to);
227
+ window.history.replaceState(state, "", url);
228
+ }
229
+ };
230
+ var MemoryHistory = class {
231
+ constructor() {
232
+ this.history = [{ pathname: "/", search: "", hash: "" }];
233
+ this.index = 0;
234
+ this.listeners = /* @__PURE__ */ new Set();
235
+ }
236
+ listen(fn) {
237
+ this.listeners.add(fn);
238
+ return () => {
239
+ this.listeners.delete(fn);
240
+ };
241
+ }
242
+ current() {
243
+ return this.history[this.index];
244
+ }
245
+ get state() {
246
+ return this.current().state;
247
+ }
248
+ notify() {
249
+ debug2("notifying listeners of route change", this.location);
250
+ this.listeners.forEach((listener) => listener());
251
+ }
252
+ get location() {
253
+ return this.history[this.index];
254
+ }
255
+ back() {
256
+ this.go(-1);
257
+ }
258
+ forward() {
259
+ this.go(1);
260
+ }
261
+ go(delta) {
262
+ this.index += delta;
263
+ if (this.index < 0)
264
+ this.index = 0;
265
+ if (this.index >= this.history.length)
266
+ this.index = this.history.length - 1;
267
+ this.notify();
268
+ }
269
+ push(to, state) {
270
+ let entry;
271
+ if (typeof to === "string") {
272
+ entry = {
273
+ pathname: to,
274
+ search: this.history[this.index].search,
275
+ hash: this.history[this.index].hash,
276
+ state
277
+ };
278
+ } else {
279
+ entry = __spreadProps(__spreadValues({}, to), {
280
+ state
281
+ });
282
+ }
283
+ this.index++;
284
+ this.history.splice(this.index, this.history.length, entry);
285
+ this.notify();
286
+ }
287
+ replace(to, state) {
288
+ if (typeof to === "string") {
289
+ this.history[this.index] = {
290
+ pathname: to,
291
+ search: this.history[this.index].search,
292
+ hash: this.history[this.index].hash,
293
+ state
294
+ };
295
+ } else {
296
+ this.history[this.index] = __spreadProps(__spreadValues({}, to), {
297
+ state
298
+ });
299
+ }
300
+ this.notify();
301
+ }
302
+ };
303
+ function createHistory() {
304
+ if (getEnvironment() === "SquatchPortal") {
305
+ let wrapHistoryFunction2 = function(functionName) {
306
+ const orig = window.history[functionName];
307
+ return function(...args) {
308
+ const returnValue = orig.apply(window.history, args);
309
+ const event = new Event(functionName);
310
+ window.dispatchEvent(event);
311
+ return returnValue;
312
+ };
313
+ };
314
+ var wrapHistoryFunction = wrapHistoryFunction2;
315
+ window.history.pushState = wrapHistoryFunction2("pushState");
316
+ window.history.replaceState = wrapHistoryFunction2("replaceState");
317
+ return new BrowserHistory();
318
+ } else {
319
+ return new MemoryHistory();
320
+ }
321
+ }
322
+ function lazyHistory() {
323
+ window.squatchHistory = window.squatchHistory || createHistory();
324
+ return window.squatchHistory;
325
+ }
326
+ var LazyHistory = class {
327
+ get location() {
328
+ return lazyHistory().location;
329
+ }
330
+ listen(fn) {
331
+ return lazyHistory().listen(fn);
332
+ }
333
+ back() {
334
+ lazyHistory().back();
335
+ }
336
+ forward() {
337
+ lazyHistory().forward();
338
+ }
339
+ go(delta) {
340
+ lazyHistory().go(delta);
341
+ }
342
+ push(to, state) {
343
+ lazyHistory().push(to, state);
344
+ }
345
+ replace(to, state) {
346
+ lazyHistory().replace(to, state);
347
+ }
348
+ };
349
+ var history_default = new LazyHistory();
350
+
151
351
  // src/contexts/UserIdentityContext.ts
152
352
  var import_jwt_decode = __toESM(require("jwt-decode"));
153
353
  var import_dom_context3 = require("dom-context");
@@ -158,22 +358,12 @@ var import_dom_context2 = require("dom-context");
158
358
 
159
359
  // src/contexts/LocaleContext.ts
160
360
  var import_dom_context = require("dom-context");
161
-
162
- // src/debug.ts
163
- var debugEnabled = localStorage.getItem("debug");
164
- function debug(ns, ...args) {
165
- if (debugEnabled) {
166
- console.debug(`sq:environment:${ns}`, ...args);
167
- }
168
- }
169
-
170
- // src/contexts/LocaleContext.ts
171
- var debug2 = (...args) => debug(LOCALE_CONTEXT_NAME, ...args);
361
+ var debug3 = (...args) => debug(LOCALE_CONTEXT_NAME, ...args);
172
362
  function lazilyStartLocaleContext() {
173
363
  var _a;
174
364
  let globalProvider = window.squatchLocale;
175
365
  if (!globalProvider) {
176
- debug2("Creating locale context provider");
366
+ debug3("Creating locale context provider");
177
367
  globalProvider = new import_dom_context.ContextProvider({
178
368
  element: document.documentElement,
179
369
  initialState: ((_a = window.widgetIdent) == null ? void 0 : _a.locale) || navigator.language.replace("-", "_"),
@@ -186,7 +376,7 @@ function lazilyStartLocaleContext() {
186
376
  function setLocale(locale) {
187
377
  const globalProvider = lazilyStartLocaleContext();
188
378
  if (globalProvider.context !== locale) {
189
- debug2(`Setting locale context value [${locale}]`);
379
+ debug3(`Setting locale context value [${locale}]`);
190
380
  globalProvider.context = locale;
191
381
  }
192
382
  }
@@ -196,7 +386,7 @@ function getLocale() {
196
386
  }
197
387
 
198
388
  // src/fetchLocale.ts
199
- var debug3 = (...args) => debug(LOCALE_CONTEXT_NAME, ...args);
389
+ var debug4 = (...args) => debug(LOCALE_CONTEXT_NAME, ...args);
200
390
  var GET_LOCALE = `
201
391
  query {
202
392
  viewer {
@@ -208,7 +398,7 @@ var GET_LOCALE = `
208
398
  `;
209
399
  async function fetchLocale() {
210
400
  var _a;
211
- debug3("Fetching locale from GraphQL for current user");
401
+ debug4("Fetching locale from GraphQL for current user");
212
402
  try {
213
403
  const result = await fetch(`${getAppDomain()}/api/v1/${getTenantAlias()}/graphql`, {
214
404
  method: "POST",
@@ -229,13 +419,13 @@ async function fetchLocale() {
229
419
  }
230
420
  return json.data.viewer.locale || void 0;
231
421
  } catch (e) {
232
- debug3(`Failed to fetch locale for current user`, e.message);
422
+ debug4(`Failed to fetch locale for current user`, e.message);
233
423
  return void 0;
234
424
  }
235
425
  }
236
426
 
237
427
  // src/listeners.ts
238
- var debug4 = (...args) => debug(LOCALE_CONTEXT_NAME, ...args);
428
+ var debug5 = (...args) => debug(LOCALE_CONTEXT_NAME, ...args);
239
429
  var userContextListenerDiv = (() => {
240
430
  const id = "__environment_context_listener";
241
431
  let div = document.getElementById(id);
@@ -255,31 +445,30 @@ var userContextListenerForLocale = new import_dom_context2.ContextListener({
255
445
  const defaultLocale = ((_a = window.widgetIdent) == null ? void 0 : _a.locale) || navigator.language.replace("-", "_");
256
446
  let newLocale;
257
447
  if (next) {
258
- debug4("User context changed, refetching locale");
448
+ debug5("User context changed, refetching locale");
259
449
  const locale = await fetchLocale();
260
450
  if (localeProvider.context !== locale) {
261
- debug4(`New value fetched from GraphQL [${locale}]`);
451
+ debug5(`New value fetched from GraphQL [${locale}]`);
262
452
  newLocale = locale || defaultLocale;
263
453
  }
264
454
  } else {
265
455
  newLocale = defaultLocale;
266
456
  }
267
- debug4(`Setting locale context to [${newLocale}]`);
457
+ debug5(`Setting locale context to [${newLocale}]`);
268
458
  localeProvider.context = newLocale;
269
- },
270
- onStatus: (status) => debug4("STATUS", status)
459
+ }
271
460
  });
272
461
  function startUserContextListenerForLocale() {
273
- debug4("Starting user context listener for locale updates");
462
+ debug5("Starting user context listener for locale updates");
274
463
  userContextListenerForLocale.start();
275
464
  }
276
465
 
277
466
  // src/contexts/UserIdentityContext.ts
278
- var debug5 = (...args) => debug(USER_CONTEXT_NAME, ...args);
467
+ var debug6 = (...args) => debug(USER_CONTEXT_NAME, ...args);
279
468
  function lazilyStartUserContext() {
280
469
  let globalProvider = window.squatchUserIdentity;
281
470
  if (!globalProvider) {
282
- debug5("Creating user context provider");
471
+ debug6("Creating user context provider");
283
472
  globalProvider = new import_dom_context3.ContextProvider({
284
473
  element: document.documentElement,
285
474
  initialState: _getInitialValue(),
@@ -365,7 +554,7 @@ function _getInitialValue() {
365
554
  function setUserIdentity(identity) {
366
555
  const globalProvider = lazilyStartUserContext();
367
556
  if (!(0, import_equality.equal)(globalProvider.context, identity)) {
368
- debug5(`Setting user context value [${JSON.stringify(identity)}]`);
557
+ debug6(`Setting user context value [${JSON.stringify(identity)}]`);
369
558
  globalProvider.context = identity;
370
559
  }
371
560
  if (identity && getEnvironmentSDK().type === "SquatchPortal") {
@@ -381,12 +570,12 @@ function getUserIdentity() {
381
570
 
382
571
  // src/contexts/ProgramContext.ts
383
572
  var import_dom_context4 = require("dom-context");
384
- var debug6 = (...args) => debug(PROGRAM_CONTEXT_NAME, ...args);
573
+ var debug7 = (...args) => debug(PROGRAM_CONTEXT_NAME, ...args);
385
574
  function lazilyStartProgramContext() {
386
575
  var _a;
387
576
  let globalProvider = window.squatchProgramId;
388
577
  if (!globalProvider) {
389
- debug6("Creating program context provider");
578
+ debug7("Creating program context provider");
390
579
  globalProvider = new import_dom_context4.ContextProvider({
391
580
  element: document.documentElement,
392
581
  initialState: ((_a = window.widgetIdent) == null ? void 0 : _a.programId) || void 0,
@@ -399,7 +588,7 @@ function lazilyStartProgramContext() {
399
588
  function setProgramId(programId) {
400
589
  const globalProvider = lazilyStartProgramContext();
401
590
  if (globalProvider.context !== programId) {
402
- debug6(`Setting program context value [${programId}]`);
591
+ debug7(`Setting program context value [${programId}]`);
403
592
  globalProvider.context = programId;
404
593
  }
405
594
  }
@@ -409,8 +598,11 @@ function getProgramId() {
409
598
  }
410
599
  // Annotate the CommonJS export names for ESM import in node:
411
600
  0 && (module.exports = {
601
+ BrowserHistory,
412
602
  DEFAULT_MEDIUM,
413
603
  LOCALE_CONTEXT_NAME,
604
+ LazyHistory,
605
+ MemoryHistory,
414
606
  PROGRAM_CONTEXT_NAME,
415
607
  USER_CONTEXT_NAME,
416
608
  getAppDomain,
@@ -421,6 +613,7 @@ function getProgramId() {
421
613
  getProgramId,
422
614
  getTenantAlias,
423
615
  getUserIdentity,
616
+ history,
424
617
  isDemo,
425
618
  lazilyStartLocaleContext,
426
619
  lazilyStartProgramContext,