@croct/plug 0.16.5 → 0.17.0

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 (116) hide show
  1. package/api/evaluate.cjs +45 -0
  2. package/api/evaluate.d.cts +23 -0
  3. package/api/evaluate.d.ts +9 -7
  4. package/api/evaluate.js +20 -22
  5. package/api/fetchContent.cjs +53 -0
  6. package/api/fetchContent.d.cts +45 -0
  7. package/api/fetchContent.d.ts +31 -11
  8. package/api/fetchContent.js +29 -21
  9. package/api/index.cjs +23 -0
  10. package/api/index.d.cts +27 -0
  11. package/api/index.d.ts +27 -2
  12. package/api/index.js +2 -6
  13. package/component.cjs +15 -0
  14. package/component.d.cts +19 -0
  15. package/component.d.ts +12 -9
  16. package/component.js +0 -3
  17. package/constants.cjs +39 -0
  18. package/constants.d.cts +7 -0
  19. package/constants.d.ts +7 -5
  20. package/constants.js +12 -9
  21. package/index.cjs +24 -0
  22. package/index.d.cts +27 -0
  23. package/index.d.ts +26 -3
  24. package/index.js +5 -6
  25. package/package.json +33 -6
  26. package/playground.cjs +166 -0
  27. package/playground.d.cts +64 -0
  28. package/playground.d.ts +18 -8
  29. package/playground.js +130 -138
  30. package/plug.cjs +271 -0
  31. package/plug.d.cts +86 -0
  32. package/plug.d.ts +34 -17
  33. package/plug.js +243 -256
  34. package/plugin.cjs +15 -0
  35. package/plugin.d.cts +41 -0
  36. package/plugin.d.ts +18 -8
  37. package/plugin.js +0 -3
  38. package/preview.cjs +180 -0
  39. package/preview.d.cts +35 -0
  40. package/preview.d.ts +18 -6
  41. package/preview.js +143 -152
  42. package/sdk/apiKey.cjs +21 -0
  43. package/sdk/apiKey.js +1 -5
  44. package/sdk/evaluation.cjs +34 -0
  45. package/sdk/evaluation.d.cts +2 -0
  46. package/sdk/evaluation.d.ts +1 -1
  47. package/sdk/evaluation.js +8 -10
  48. package/sdk/index.cjs +33 -0
  49. package/sdk/index.d.cts +15 -0
  50. package/sdk/index.d.ts +9 -6
  51. package/sdk/index.js +8 -10
  52. package/sdk/json.cjs +15 -0
  53. package/sdk/json.d.cts +6 -0
  54. package/sdk/json.d.ts +4 -1
  55. package/sdk/json.js +0 -5
  56. package/sdk/sdkEvents.cjs +15 -0
  57. package/sdk/sdkEvents.d.cts +1 -0
  58. package/sdk/sdkEvents.js +0 -3
  59. package/sdk/token.cjs +27 -0
  60. package/sdk/token.d.cts +7 -0
  61. package/sdk/token.d.ts +7 -1
  62. package/sdk/token.js +4 -6
  63. package/sdk/tracking.cjs +27 -0
  64. package/sdk/tracking.d.cts +9 -0
  65. package/sdk/tracking.d.ts +8 -5
  66. package/sdk/tracking.js +4 -6
  67. package/sdk/validation.cjs +23 -0
  68. package/sdk/validation.js +2 -6
  69. package/slot.cjs +15 -0
  70. package/slot.d.cts +42 -0
  71. package/slot.d.ts +14 -12
  72. package/slot.js +0 -3
  73. package/versioning.cjs +15 -0
  74. package/versioning.d.cts +26 -0
  75. package/versioning.d.ts +8 -6
  76. package/versioning.js +0 -3
  77. package/api/evaluate.js.map +0 -1
  78. package/api/fetchContent.js.map +0 -1
  79. package/api/index.js.map +0 -1
  80. package/component.js.map +0 -1
  81. package/constants.js.map +0 -1
  82. package/index.js.map +0 -1
  83. package/playground.js.map +0 -1
  84. package/plug.js.map +0 -1
  85. package/plugin.js.map +0 -1
  86. package/preview.js.map +0 -1
  87. package/sdk/apiKey.js.map +0 -1
  88. package/sdk/evaluation.js.map +0 -1
  89. package/sdk/index.js.map +0 -1
  90. package/sdk/json.js.map +0 -1
  91. package/sdk/sdkEvents.js.map +0 -1
  92. package/sdk/token.js.map +0 -1
  93. package/sdk/tracking.js.map +0 -1
  94. package/sdk/validation.js.map +0 -1
  95. package/slot.js.map +0 -1
  96. package/src/api/evaluate.ts +0 -50
  97. package/src/api/fetchContent.ts +0 -70
  98. package/src/api/index.ts +0 -2
  99. package/src/component.ts +0 -19
  100. package/src/constants.ts +0 -5
  101. package/src/index.ts +0 -6
  102. package/src/playground.ts +0 -247
  103. package/src/plug.ts +0 -429
  104. package/src/plugin.ts +0 -39
  105. package/src/preview.ts +0 -226
  106. package/src/sdk/evaluation.ts +0 -2
  107. package/src/sdk/index.ts +0 -14
  108. package/src/sdk/json.ts +0 -4
  109. package/src/sdk/sdkEvents.ts +0 -1
  110. package/src/sdk/token.ts +0 -1
  111. package/src/sdk/tracking.ts +0 -14
  112. package/src/slot.ts +0 -48
  113. package/src/versioning.ts +0 -38
  114. package/versioning.js.map +0 -1
  115. /package/{src/sdk/apiKey.ts → sdk/apiKey.d.cts} +0 -0
  116. /package/{src/sdk/validation.ts → sdk/validation.d.cts} +0 -0
package/playground.js CHANGED
@@ -1,150 +1,142 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.factory = exports.PlaygroundPlugin = void 0;
4
- const error_1 = require("@croct/sdk/error");
5
- const evaluatorFacade_1 = require("@croct/sdk/facade/evaluatorFacade");
6
- const constants_1 = require("./constants");
7
- const CONNECTION_PARAMETER = '__cplay';
1
+ import { formatCause } from "@croct/sdk/error";
2
+ import { TabContextFactory } from "@croct/sdk/facade/evaluatorFacade";
3
+ import { PLAYGROUND_CONNECT_URL, PLAYGROUND_ORIGIN } from "./constants.js";
4
+ const CONNECTION_PARAMETER = "__cplay";
8
5
  class PlaygroundPlugin {
9
- constructor(configuration) {
10
- this.sdkVersion = configuration.sdkVersion;
11
- this.appId = configuration.appId;
12
- this.connectionId = configuration.connectionId;
13
- this.tab = configuration.tab;
14
- this.contextFactory = configuration.contextFactory;
15
- this.storage = configuration.storage;
16
- this.eventSubscriber = configuration.eventSubscriber;
17
- this.cidAssigner = configuration.cidAssigner;
18
- this.tokenProvider = configuration.tokenProvider;
19
- this.logger = configuration.logger;
6
+ constructor(configuration) {
7
+ this.sdkVersion = configuration.sdkVersion;
8
+ this.appId = configuration.appId;
9
+ this.connectionId = configuration.connectionId;
10
+ this.tab = configuration.tab;
11
+ this.contextFactory = configuration.contextFactory;
12
+ this.storage = configuration.storage;
13
+ this.eventSubscriber = configuration.eventSubscriber;
14
+ this.cidAssigner = configuration.cidAssigner;
15
+ this.tokenProvider = configuration.tokenProvider;
16
+ this.logger = configuration.logger;
17
+ }
18
+ enable() {
19
+ const connectionId = this.resolveConnectionId();
20
+ if (connectionId === null) {
21
+ return;
20
22
  }
21
- enable() {
22
- const connectionId = this.resolveConnectionId();
23
- if (connectionId === null) {
24
- return;
25
- }
26
- this.syncListener = () => this.cidAssigner
27
- .assignCid()
28
- .then(cid => {
29
- this.syncToken(connectionId, cid);
30
- })
31
- .catch(error => {
32
- this.logger.warn(`Sync failed: ${(0, error_1.formatCause)(error)}`);
33
- });
34
- this.eventSubscriber.addListener('tokenChanged', this.syncListener);
35
- this.tab.addListener('urlChange', this.syncListener);
36
- return this.syncListener();
23
+ this.syncListener = () => this.cidAssigner.assignCid().then((cid) => {
24
+ this.syncToken(connectionId, cid);
25
+ }).catch((error) => {
26
+ this.logger.warn(`Sync failed: ${formatCause(error)}`);
27
+ });
28
+ this.eventSubscriber.addListener("tokenChanged", this.syncListener);
29
+ this.tab.addListener("urlChange", this.syncListener);
30
+ return this.syncListener();
31
+ }
32
+ resolveConnectionId() {
33
+ if (this.connectionId !== void 0) {
34
+ this.logger.debug("Connection ID passed in configuration");
35
+ return this.connectionId;
37
36
  }
38
- resolveConnectionId() {
39
- if (this.connectionId !== undefined) {
40
- this.logger.debug('Connection ID passed in configuration');
41
- return this.connectionId;
42
- }
43
- const url = new URL(this.tab.url);
44
- let connectionId = url.searchParams.get(CONNECTION_PARAMETER);
45
- if (connectionId === null || connectionId === '') {
46
- this.logger.debug('No connection ID found in URL');
47
- connectionId = this.storage.getItem('connectionId');
48
- this.logger.debug(connectionId !== null
49
- ? 'Previous connection ID found'
50
- : 'No previous connection ID found');
51
- return connectionId;
52
- }
53
- this.logger.debug('Connection ID found in URL');
54
- this.storage.setItem('connectionId', connectionId);
55
- return connectionId;
37
+ const url = new URL(this.tab.url);
38
+ let connectionId = url.searchParams.get(CONNECTION_PARAMETER);
39
+ if (connectionId === null || connectionId === "") {
40
+ this.logger.debug("No connection ID found in URL");
41
+ connectionId = this.storage.getItem("connectionId");
42
+ this.logger.debug(
43
+ connectionId !== null ? "Previous connection ID found" : "No previous connection ID found"
44
+ );
45
+ return connectionId;
56
46
  }
57
- disable() {
58
- if (this.syncListener !== undefined) {
59
- this.eventSubscriber.removeListener('tokenChanged', this.syncListener);
60
- this.tab.removeListener('urlChange', this.syncListener);
61
- delete this.syncListener;
62
- }
47
+ this.logger.debug("Connection ID found in URL");
48
+ this.storage.setItem("connectionId", connectionId);
49
+ return connectionId;
50
+ }
51
+ disable() {
52
+ if (this.syncListener !== void 0) {
53
+ this.eventSubscriber.removeListener("tokenChanged", this.syncListener);
54
+ this.tab.removeListener("urlChange", this.syncListener);
55
+ delete this.syncListener;
63
56
  }
64
- syncToken(connectionId, cid) {
65
- const iframe = document.createElement('iframe');
66
- iframe.setAttribute('src', constants_1.PLAYGROUND_CONNECT_URL);
67
- iframe.setAttribute('sandbox', 'allow-scripts allow-same-origin');
68
- iframe.style.visibility = 'hidden';
69
- iframe.style.opacity = '0';
70
- iframe.style.border = '0';
71
- iframe.style.width = '0';
72
- iframe.style.height = '0';
73
- const context = this.createContext();
74
- iframe.onload = () => {
75
- var _a, _b;
76
- if (iframe.contentWindow === null) {
77
- if (document.body.contains(iframe)) {
78
- document.body.removeChild(iframe);
79
- }
80
- this.logger.warn('Sync handshake failed');
81
- return;
82
- }
83
- const listener = (event) => {
84
- if (event.origin !== constants_1.PLAYGROUND_ORIGIN || event.data !== connectionId) {
85
- return;
86
- }
87
- window.removeEventListener('message', listener);
88
- if (document.body.contains(iframe)) {
89
- document.body.removeChild(iframe);
90
- }
91
- this.logger.debug('Sync completed');
92
- };
93
- window.addEventListener('message', listener);
94
- const payload = {
95
- appId: this.appId,
96
- connectionId: connectionId,
97
- sdkVersion: this.sdkVersion,
98
- tabId: this.tab.id,
99
- cid: cid,
100
- token: (_b = (_a = this.tokenProvider
101
- .getToken()) === null || _a === void 0 ? void 0 : _a.toString()) !== null && _b !== void 0 ? _b : null,
102
- context: context,
103
- };
104
- iframe.contentWindow.postMessage(payload, constants_1.PLAYGROUND_ORIGIN);
105
- this.logger.debug('Waiting for sync acknowledgment...');
106
- };
107
- this.logger.debug('Sync started');
108
- const connect = () => {
109
- document.body.appendChild(iframe);
110
- };
111
- if (document.body === null) {
112
- document.addEventListener('DOMContentLoaded', connect);
113
- }
114
- else {
115
- connect();
57
+ }
58
+ syncToken(connectionId, cid) {
59
+ const iframe = document.createElement("iframe");
60
+ iframe.setAttribute("src", PLAYGROUND_CONNECT_URL);
61
+ iframe.setAttribute("sandbox", "allow-scripts allow-same-origin");
62
+ iframe.style.visibility = "hidden";
63
+ iframe.style.opacity = "0";
64
+ iframe.style.border = "0";
65
+ iframe.style.width = "0";
66
+ iframe.style.height = "0";
67
+ const context = this.createContext();
68
+ iframe.onload = () => {
69
+ if (iframe.contentWindow === null) {
70
+ if (document.body.contains(iframe)) {
71
+ document.body.removeChild(iframe);
116
72
  }
117
- }
118
- createContext() {
119
- const { page, campaign, timeZone } = this.contextFactory.createContext();
120
- const context = {};
121
- if (page !== undefined) {
122
- context.page = page;
73
+ this.logger.warn("Sync handshake failed");
74
+ return;
75
+ }
76
+ const listener = (event) => {
77
+ if (event.origin !== PLAYGROUND_ORIGIN || event.data !== connectionId) {
78
+ return;
123
79
  }
124
- if (campaign !== undefined) {
125
- context.campaign = campaign;
80
+ window.removeEventListener("message", listener);
81
+ if (document.body.contains(iframe)) {
82
+ document.body.removeChild(iframe);
126
83
  }
127
- if (timeZone !== undefined) {
128
- context.timeZone = timeZone;
129
- }
130
- return context;
84
+ this.logger.debug("Sync completed");
85
+ };
86
+ window.addEventListener("message", listener);
87
+ const payload = {
88
+ appId: this.appId,
89
+ connectionId,
90
+ sdkVersion: this.sdkVersion,
91
+ tabId: this.tab.id,
92
+ cid,
93
+ token: this.tokenProvider.getToken()?.toString() ?? null,
94
+ context
95
+ };
96
+ iframe.contentWindow.postMessage(payload, PLAYGROUND_ORIGIN);
97
+ this.logger.debug("Waiting for sync acknowledgment...");
98
+ };
99
+ this.logger.debug("Sync started");
100
+ const connect = () => {
101
+ document.body.appendChild(iframe);
102
+ };
103
+ if (document.body === null) {
104
+ document.addEventListener("DOMContentLoaded", connect);
105
+ } else {
106
+ connect();
107
+ }
108
+ }
109
+ createContext() {
110
+ const { page, campaign, timeZone } = this.contextFactory.createContext();
111
+ const context = {};
112
+ if (page !== void 0) {
113
+ context.page = page;
114
+ }
115
+ if (campaign !== void 0) {
116
+ context.campaign = campaign;
131
117
  }
118
+ if (timeZone !== void 0) {
119
+ context.timeZone = timeZone;
120
+ }
121
+ return context;
122
+ }
132
123
  }
133
- exports.PlaygroundPlugin = PlaygroundPlugin;
134
124
  const factory = (props) => {
135
- const { sdk, options } = props;
136
- return new PlaygroundPlugin({
137
- sdkVersion: sdk.version,
138
- appId: sdk.appId,
139
- connectionId: options.connectionId,
140
- tab: sdk.tab,
141
- storage: sdk.getTabStorage(),
142
- tokenProvider: sdk.userTokenStore,
143
- cidAssigner: sdk.cidAssigner,
144
- contextFactory: new evaluatorFacade_1.TabContextFactory(sdk.tab),
145
- eventSubscriber: sdk.eventManager,
146
- logger: sdk.getLogger(),
147
- });
125
+ const { sdk, options } = props;
126
+ return new PlaygroundPlugin({
127
+ sdkVersion: sdk.version,
128
+ appId: sdk.appId,
129
+ connectionId: options.connectionId,
130
+ tab: sdk.tab,
131
+ storage: sdk.getTabStorage(),
132
+ tokenProvider: sdk.userTokenStore,
133
+ cidAssigner: sdk.cidAssigner,
134
+ contextFactory: new TabContextFactory(sdk.tab),
135
+ eventSubscriber: sdk.eventManager,
136
+ logger: sdk.getLogger()
137
+ });
138
+ };
139
+ export {
140
+ PlaygroundPlugin,
141
+ factory
148
142
  };
149
- exports.factory = factory;
150
- //# sourceMappingURL=playground.js.map
package/plug.cjs ADDED
@@ -0,0 +1,271 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
+ var __getOwnPropNames = Object.getOwnPropertyNames;
4
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") {
11
+ for (let key of __getOwnPropNames(from))
12
+ if (!__hasOwnProp.call(to, key) && key !== except)
13
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
14
+ }
15
+ return to;
16
+ };
17
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
18
+ var plug_exports = {};
19
+ __export(plug_exports, {
20
+ GlobalPlug: () => GlobalPlug
21
+ });
22
+ module.exports = __toCommonJS(plug_exports);
23
+ var import_sdkFacade = require("@croct/sdk/facade/sdkFacade");
24
+ var import_error = require("@croct/sdk/error");
25
+ var import_validation = require("@croct/sdk/validation");
26
+ var import_token = require("@croct/sdk/token");
27
+ var import_sdk = require("@croct/sdk");
28
+ var import_content = require("@croct/content");
29
+ var import_constants = require('./constants.cjs');
30
+ var import_playground = require('./playground.cjs');
31
+ var import_preview = require('./preview.cjs');
32
+ const PLUGIN_NAMESPACE = "Plugin";
33
+ function detectAppId() {
34
+ const script = window.document.querySelector(`script[src^='${import_constants.CDN_URL}']`);
35
+ if (!(script instanceof HTMLScriptElement)) {
36
+ return null;
37
+ }
38
+ return new URL(script.src).searchParams.get("appId");
39
+ }
40
+ class GlobalPlug {
41
+ constructor() {
42
+ this.pluginFactories = {
43
+ playground: import_playground.factory,
44
+ preview: import_preview.factory
45
+ };
46
+ this.plugins = {};
47
+ this.ready = new Promise((resolve) => {
48
+ this.initialize = resolve;
49
+ });
50
+ }
51
+ extend(name, plugin) {
52
+ if (this.pluginFactories[name] !== void 0) {
53
+ throw new Error(`Another plugin is already registered with name "${name}".`);
54
+ }
55
+ this.pluginFactories[name] = plugin;
56
+ }
57
+ plug(configuration = {}) {
58
+ if (this.instance !== void 0) {
59
+ const logger2 = this.instance.getLogger();
60
+ logger2.info("Croct is already plugged in.");
61
+ return;
62
+ }
63
+ const detectedAppId = detectAppId();
64
+ const configuredAppId = configuration.appId ?? null;
65
+ if (detectedAppId !== null && configuredAppId !== null && detectedAppId !== configuredAppId) {
66
+ throw new Error(
67
+ 'The specified app ID and the auto-detected app ID are conflicting. There is no need to specify an app ID when using an application-specific tag. Please try again omitting the "appId" option. For help, see https://croct.help/sdk/javascript/conflicting-app-id'
68
+ );
69
+ }
70
+ const appId = detectedAppId ?? configuredAppId;
71
+ if (appId === null) {
72
+ throw new Error(
73
+ 'The app ID must be specified when it cannot be auto-detected. Please try again specifying the "appId" option.For help, see https://croct.help/sdk/javascript/missing-app-id'
74
+ );
75
+ }
76
+ const { plugins, test, ...sdkConfiguration } = configuration;
77
+ const sdk = import_sdkFacade.SdkFacade.init({
78
+ ...sdkConfiguration,
79
+ appId,
80
+ test: test ?? (typeof process === "object" && (process.env?.CROCT_TEST_MODE !== void 0 ? process.env.CROCT_TEST_MODE === "true" : process.env?.NODE_ENV === "test"))
81
+ });
82
+ this.instance = sdk;
83
+ const logger = this.instance.getLogger();
84
+ if (detectedAppId === configuredAppId) {
85
+ logger.warn(
86
+ 'It is strongly recommended omitting the "appId" option when using the application-specific tag as it is detected automatically.'
87
+ );
88
+ }
89
+ const pending = [];
90
+ const defaultEnabledPlugins = Object.fromEntries(
91
+ Object.keys(this.pluginFactories).map((name) => [name, true])
92
+ );
93
+ for (const [name, options] of Object.entries({ ...defaultEnabledPlugins, ...plugins })) {
94
+ logger.debug(`Initializing plugin "${name}"...`);
95
+ const factory = this.pluginFactories[name];
96
+ if (factory === void 0) {
97
+ logger.error(`Plugin "${name}" is not registered.`);
98
+ continue;
99
+ }
100
+ if (typeof options !== "boolean" && (options === null || typeof options !== "object")) {
101
+ logger.error(
102
+ `Invalid options for plugin "${name}", expected either boolean or object but got ${(0, import_validation.describe)(options)}`
103
+ );
104
+ continue;
105
+ }
106
+ if (options === false) {
107
+ logger.warn(`Plugin "${name}" is declared but not enabled`);
108
+ continue;
109
+ }
110
+ const args = {
111
+ options: options === true ? {} : options,
112
+ sdk: {
113
+ version: import_sdk.VERSION,
114
+ appId,
115
+ tracker: sdk.tracker,
116
+ evaluator: sdk.evaluator,
117
+ user: sdk.user,
118
+ session: sdk.session,
119
+ tab: sdk.context.getTab(),
120
+ userTokenStore: {
121
+ getToken: sdk.getToken.bind(sdk),
122
+ setToken: sdk.setToken.bind(sdk)
123
+ },
124
+ previewTokenStore: sdk.previewTokenStore,
125
+ cidAssigner: sdk.cidAssigner,
126
+ eventManager: sdk.eventManager,
127
+ getLogger: (...namespace) => sdk.getLogger(PLUGIN_NAMESPACE, name, ...namespace),
128
+ getTabStorage: (...namespace) => sdk.getTabStorage(PLUGIN_NAMESPACE, name, ...namespace),
129
+ getBrowserStorage: (...namespace) => sdk.getBrowserStorage(PLUGIN_NAMESPACE, name, ...namespace)
130
+ }
131
+ };
132
+ let plugin;
133
+ try {
134
+ plugin = factory(args);
135
+ } catch (error) {
136
+ logger.error(`Failed to initialize plugin "${name}": ${(0, import_error.formatCause)(error)}`);
137
+ continue;
138
+ }
139
+ logger.debug(`Plugin "${name}" initialized`);
140
+ if (typeof plugin !== "object") {
141
+ continue;
142
+ }
143
+ this.plugins[name] = plugin;
144
+ const promise = plugin.enable();
145
+ if (!(promise instanceof Promise)) {
146
+ logger.debug(`Plugin "${name}" enabled`);
147
+ continue;
148
+ }
149
+ pending.push(
150
+ promise.then(() => logger.debug(`Plugin "${name}" enabled`)).catch((error) => logger.error(`Failed to enable plugin "${name}": ${(0, import_error.formatCause)(error)}`))
151
+ );
152
+ }
153
+ Promise.all(pending).then(() => {
154
+ this.initialize();
155
+ logger.debug("Initialization complete");
156
+ });
157
+ }
158
+ get initialized() {
159
+ return this.instance !== void 0;
160
+ }
161
+ get plugged() {
162
+ return this.ready.then(() => this);
163
+ }
164
+ get flushed() {
165
+ return this.tracker.flushed.then(() => this);
166
+ }
167
+ get sdk() {
168
+ if (this.instance === void 0) {
169
+ throw new Error("Croct is not plugged in. For help, see https://croct.help/sdk/javascript/not-plugged-in");
170
+ }
171
+ return this.instance;
172
+ }
173
+ get tracker() {
174
+ return this.sdk.tracker;
175
+ }
176
+ get evaluator() {
177
+ return this.sdk.evaluator;
178
+ }
179
+ get user() {
180
+ return this.sdk.user;
181
+ }
182
+ get session() {
183
+ return this.sdk.session;
184
+ }
185
+ isAnonymous() {
186
+ return this.sdk.context.isAnonymous();
187
+ }
188
+ getUserId() {
189
+ return this.sdk.context.getUser();
190
+ }
191
+ identify(userId) {
192
+ if (typeof userId !== "string") {
193
+ throw new Error(
194
+ "The user ID must be a string. For help, see https://croct.help/sdk/javascript/invalid-user-id"
195
+ );
196
+ }
197
+ this.sdk.identify(userId);
198
+ }
199
+ anonymize() {
200
+ this.sdk.anonymize();
201
+ }
202
+ setToken(token) {
203
+ this.sdk.setToken(import_token.Token.parse(token));
204
+ }
205
+ unsetToken() {
206
+ this.sdk.unsetToken();
207
+ }
208
+ track(type, payload) {
209
+ return this.sdk.tracker.track(type, payload);
210
+ }
211
+ evaluate(query, options = {}) {
212
+ return this.sdk.evaluator.evaluate(query, options).catch((error) => {
213
+ const logger = this.sdk.getLogger();
214
+ const reference = query.length > 20 ? `${query.slice(0, 20)}...` : query;
215
+ logger.error(`Failed to evaluate query "${reference}": ${(0, import_error.formatCause)(error)}`);
216
+ throw error;
217
+ });
218
+ }
219
+ test(expression, options = {}) {
220
+ return this.evaluate(expression, options).then((result) => result === true);
221
+ }
222
+ fetch(slotId, { fallback, ...options } = {}) {
223
+ const [id, version = "latest"] = slotId.split("@");
224
+ const logger = this.sdk.getLogger();
225
+ return this.sdk.contentFetcher.fetch(id, version === "latest" ? options : { ...options, version }).catch(async (error) => {
226
+ logger.error(`Failed to fetch content for slot "${id}@${version}": ${(0, import_error.formatCause)(error)}`);
227
+ const resolvedFallback = fallback === void 0 ? await (0, import_content.loadSlotContent)(slotId, options.preferredLocale) ?? void 0 : fallback;
228
+ if (resolvedFallback === void 0) {
229
+ throw error;
230
+ }
231
+ return { content: resolvedFallback };
232
+ });
233
+ }
234
+ async unplug() {
235
+ if (this.instance === void 0) {
236
+ return;
237
+ }
238
+ const { instance, plugins } = this;
239
+ const logger = this.sdk.getLogger();
240
+ const pending = [];
241
+ for (const [pluginName, controller] of Object.entries(plugins)) {
242
+ if (typeof controller.disable !== "function") {
243
+ continue;
244
+ }
245
+ logger.debug(`Disabling plugin "${pluginName}"...`);
246
+ const promise = controller.disable();
247
+ if (!(promise instanceof Promise)) {
248
+ logger.debug(`Plugin "${pluginName}" disabled`);
249
+ continue;
250
+ }
251
+ pending.push(
252
+ promise.then(() => logger.debug(`Plugin "${pluginName}" disabled`)).catch((error) => logger.error(`Failed to disable "${pluginName}": ${(0, import_error.formatCause)(error)}`))
253
+ );
254
+ }
255
+ delete this.instance;
256
+ this.plugins = {};
257
+ this.ready = new Promise((resolve) => {
258
+ this.initialize = resolve;
259
+ });
260
+ await Promise.all(pending);
261
+ try {
262
+ await instance.close();
263
+ } finally {
264
+ logger.info("\u{1F50C} Croct has been unplugged.");
265
+ }
266
+ }
267
+ }
268
+ // Annotate the CommonJS export names for ESM import in node:
269
+ 0 && (module.exports = {
270
+ GlobalPlug
271
+ });
package/plug.d.cts ADDED
@@ -0,0 +1,86 @@
1
+ import { SessionFacade } from '@croct/sdk/facade/sessionFacade';
2
+ import { UserFacade } from '@croct/sdk/facade/userFacade';
3
+ import { TrackerFacade } from '@croct/sdk/facade/trackerFacade';
4
+ import { EvaluationOptions, EvaluatorFacade } from '@croct/sdk/facade/evaluatorFacade';
5
+ import { Configuration as Configuration$1 } from '@croct/sdk/facade/sdkFacade';
6
+ import { Optional } from '@croct/sdk/utilityTypes';
7
+ import { ExternalTrackingEventType, ExternalTrackingEventPayload, ExternalTrackingEvent } from '@croct/sdk/trackingEvents';
8
+ import { FetchOptions as FetchOptions$1 } from '@croct/sdk/facade/contentFetcherFacade';
9
+ import { PluginFactory } from './plugin.cjs';
10
+ import { VersionedSlotId, SlotContent } from './slot.cjs';
11
+ import { JsonValue, JsonObject } from '@croct/json/mutable';
12
+ import '@croct/sdk/token';
13
+ import './sdk/index.cjs';
14
+ import '@croct/sdk/eventManager';
15
+ import '@croct/sdk/sdkEvents';
16
+ import '@croct/sdk/logging';
17
+ import '@croct/sdk/tab';
18
+ import '@croct/sdk/cid';
19
+ import '@croct/json';
20
+ import './versioning.cjs';
21
+ import './component.cjs';
22
+
23
+ interface PluginConfigurations {
24
+ [key: string]: any;
25
+ }
26
+ type Configuration = Optional<Configuration$1, 'appId'> & {
27
+ plugins?: PluginConfigurations;
28
+ };
29
+ type FetchOptions<T> = Omit<FetchOptions$1, 'version'> & {
30
+ fallback?: T;
31
+ };
32
+ type FetchResponse<I extends VersionedSlotId, C extends JsonObject = JsonObject, F = never> = {
33
+ content: SlotContent<I, C> | F;
34
+ };
35
+ interface Plug {
36
+ readonly tracker: TrackerFacade;
37
+ readonly user: UserFacade;
38
+ readonly session: SessionFacade;
39
+ readonly initialized: boolean;
40
+ readonly flushed: Promise<this>;
41
+ readonly plugged: Promise<this>;
42
+ plug(configuration: Configuration): void;
43
+ isAnonymous(): boolean;
44
+ getUserId(): string | null;
45
+ identify(userId: string): void;
46
+ anonymize(): void;
47
+ setToken(token: string): void;
48
+ unsetToken(): void;
49
+ track<T extends ExternalTrackingEventType>(type: T, payload: ExternalTrackingEventPayload<T>): Promise<ExternalTrackingEvent<T>>;
50
+ evaluate<T extends JsonValue>(expression: string, options?: EvaluationOptions): Promise<T>;
51
+ fetch<I extends VersionedSlotId>(slotId: I, options?: FetchOptions<SlotContent<I>>): Promise<FetchResponse<I>>;
52
+ fetch<F, I extends VersionedSlotId>(slotId: I, options?: FetchOptions<SlotContent<I> | F>): Promise<FetchResponse<I, JsonObject, F>>;
53
+ unplug(): Promise<void>;
54
+ }
55
+ declare class GlobalPlug implements Plug {
56
+ private pluginFactories;
57
+ private instance?;
58
+ private plugins;
59
+ private initialize;
60
+ private ready;
61
+ constructor();
62
+ extend(name: string, plugin: PluginFactory): void;
63
+ plug(configuration?: Configuration): void;
64
+ get initialized(): boolean;
65
+ get plugged(): Promise<this>;
66
+ get flushed(): Promise<this>;
67
+ private get sdk();
68
+ get tracker(): TrackerFacade;
69
+ get evaluator(): EvaluatorFacade;
70
+ get user(): UserFacade;
71
+ get session(): SessionFacade;
72
+ isAnonymous(): boolean;
73
+ getUserId(): string | null;
74
+ identify(userId: string): void;
75
+ anonymize(): void;
76
+ setToken(token: string): void;
77
+ unsetToken(): void;
78
+ track<T extends ExternalTrackingEventType>(type: T, payload: ExternalTrackingEventPayload<T>): Promise<ExternalTrackingEvent<T>>;
79
+ evaluate<T extends JsonValue>(query: string, options?: EvaluationOptions): Promise<T>;
80
+ test(expression: string, options?: EvaluationOptions): Promise<boolean>;
81
+ fetch<I extends VersionedSlotId>(slotId: I, options?: FetchOptions<SlotContent<I>>): Promise<FetchResponse<I>>;
82
+ fetch<F, I extends VersionedSlotId>(slotId: I, options?: FetchOptions<SlotContent<I> | F>): Promise<FetchResponse<I, JsonObject, F>>;
83
+ unplug(): Promise<void>;
84
+ }
85
+
86
+ export { type Configuration, type FetchOptions, type FetchResponse, GlobalPlug, type Plug, type PluginConfigurations };