@builder.io/sdk-svelte 4.0.9 → 4.0.10

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 (34) hide show
  1. package/lib/browser/blocks/form/form/form.svelte +34 -12
  2. package/lib/browser/blocks/personalization-container/helpers.js +2 -2
  3. package/lib/browser/blocks/personalization-container/personalization-container.svelte +2 -0
  4. package/lib/browser/constants/sdk-version.d.ts +1 -1
  5. package/lib/browser/constants/sdk-version.js +1 -1
  6. package/lib/browser/helpers/no-serialize-wrapper.d.ts +1 -0
  7. package/lib/browser/helpers/no-serialize-wrapper.js +3 -0
  8. package/lib/browser/helpers/user-attributes.d.ts +6 -2
  9. package/lib/browser/helpers/user-attributes.js +19 -4
  10. package/lib/edge/blocks/form/form/form.svelte +34 -12
  11. package/lib/edge/blocks/personalization-container/helpers.js +2 -2
  12. package/lib/edge/blocks/personalization-container/personalization-container.svelte +2 -0
  13. package/lib/edge/constants/sdk-version.d.ts +1 -1
  14. package/lib/edge/constants/sdk-version.js +1 -1
  15. package/lib/edge/helpers/no-serialize-wrapper.d.ts +1 -0
  16. package/lib/edge/helpers/no-serialize-wrapper.js +3 -0
  17. package/lib/edge/helpers/user-attributes.d.ts +6 -2
  18. package/lib/edge/helpers/user-attributes.js +19 -4
  19. package/lib/node/blocks/form/form/form.svelte +34 -12
  20. package/lib/node/blocks/personalization-container/helpers.js +2 -2
  21. package/lib/node/blocks/personalization-container/personalization-container.svelte +2 -0
  22. package/lib/node/constants/sdk-version.d.ts +1 -1
  23. package/lib/node/constants/sdk-version.js +1 -1
  24. package/lib/node/helpers/no-serialize-wrapper.d.ts +1 -0
  25. package/lib/node/helpers/no-serialize-wrapper.js +3 -0
  26. package/lib/node/helpers/user-attributes.d.ts +6 -2
  27. package/lib/node/helpers/user-attributes.js +19 -4
  28. package/package.json +1 -1
  29. package/src/blocks/form/form/form.svelte +37 -12
  30. package/src/blocks/personalization-container/helpers.ts +2 -2
  31. package/src/blocks/personalization-container/personalization-container.svelte +3 -0
  32. package/src/constants/sdk-version.ts +1 -1
  33. package/src/helpers/no-serialize-wrapper.ts +3 -0
  34. package/src/helpers/user-attributes.ts +22 -4
@@ -144,6 +144,16 @@ function onSubmit(event) {
144
144
  }
145
145
  }
146
146
  formState = "sending";
147
+ if (sendSubmissionsTo === "email" &&
148
+ (sendSubmissionsToEmail === "your@email.com" || !sendSubmissionsToEmail)) {
149
+ const message = "SubmissionsToEmail is required when sendSubmissionsTo is set to email";
150
+ console.error(message);
151
+ formState = "error";
152
+ mergeNewRootState({
153
+ formErrorMessage: message,
154
+ });
155
+ return;
156
+ }
147
157
  const formUrl = `${getEnv() === "dev" ? "http://localhost:5000" : "https://builder.io"}/api/v1/form-submit?apiKey=${$builderContext.apiKey}&to=${btoa(sendSubmissionsToEmail || "")}&name=${encodeURIComponent(name || "")}`;
148
158
  const url = sendSubmissionsTo === "email"
149
159
  ? formUrl
@@ -162,20 +172,32 @@ function onSubmit(event) {
162
172
  else {
163
173
  body = await res.text();
164
174
  }
165
- if (!res.ok && errorMessagePath) {
166
- /* TODO: allow supplying an error formatter function */
167
- let message = get(body, errorMessagePath);
168
- if (message) {
169
- if (typeof message !== "string") {
170
- /* TODO: ideally convert json to yaml so it woul dbe like
171
- error: - email has been taken */
172
- message = JSON.stringify(message);
175
+ if (!res.ok) {
176
+ const submitErrorEvent = new CustomEvent("submit:error", {
177
+ detail: {
178
+ error: body,
179
+ status: res.status,
180
+ },
181
+ });
182
+ if (formRef?.nativeElement) {
183
+ formRef?.nativeElement.dispatchEvent(submitErrorEvent);
184
+ if (submitErrorEvent.defaultPrevented) {
185
+ return;
173
186
  }
174
- formErrorMessage = message;
175
- mergeNewRootState({
176
- formErrorMessage: message,
177
- });
178
187
  }
188
+ responseData = body;
189
+ formState = "error";
190
+ let message = errorMessagePath
191
+ ? get(body, errorMessagePath)
192
+ : body.message || body.error || body;
193
+ if (typeof message !== "string") {
194
+ message = JSON.stringify(message);
195
+ }
196
+ formErrorMessage = message;
197
+ mergeNewRootState({
198
+ formErrorMessage: message,
199
+ });
200
+ return;
179
201
  }
180
202
  responseData = body;
181
203
  formState = res.ok ? "success" : "error";
@@ -9,7 +9,7 @@ const UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME = 'updateVisibilityStylesScript';
9
9
  /**
10
10
  * SDKs that support Variant Containers
11
11
  */
12
- export const SDKS_SUPPORTING_PERSONALIZATION = ['react', 'vue', 'svelte'];
12
+ export const SDKS_SUPPORTING_PERSONALIZATION = ['react', 'vue', 'svelte', 'qwik'];
13
13
  /**
14
14
  * After hydration, we reset the tree
15
15
  * These SDKs handle Personalization Container in a special way:
@@ -19,7 +19,7 @@ export const SDKS_SUPPORTING_PERSONALIZATION = ['react', 'vue', 'svelte'];
19
19
  * This helps us to avoid flicker and show the correct / winning variant initially and then once we've hydrated we show the winning variant
20
20
  * and keep a track of the cookies to update to the correct variant dynamically when the cookie updates.
21
21
  */
22
- export const SDKS_REQUIRING_RESET_APPROACH = ['vue', 'svelte'];
22
+ export const SDKS_REQUIRING_RESET_APPROACH = ['vue', 'svelte', 'qwik'];
23
23
  export function checkShouldRenderVariants(variants, canTrack) {
24
24
  const hasVariants = variants && variants.length > 0;
25
25
  if (TARGET === 'reactNative')
@@ -61,6 +61,8 @@ onMount(() => {
61
61
  shouldResetVariants = true;
62
62
  const unsub = userAttributesService.subscribeOnUserAttributesChange((attrs) => {
63
63
  userAttributes = attrs;
64
+ }, {
65
+ fireImmediately: TARGET === "qwik",
64
66
  });
65
67
  if (!(isEditing() || isPreviewing())) {
66
68
  const variant = filteredVariants()[0];
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "4.0.9";
1
+ export declare const SDK_VERSION = "4.0.10";
@@ -1 +1 @@
1
- export const SDK_VERSION = "4.0.9";
1
+ export const SDK_VERSION = "4.0.10";
@@ -0,0 +1 @@
1
+ export declare function noSerializeWrapper(fn: () => void): () => void;
@@ -0,0 +1,3 @@
1
+ export function noSerializeWrapper(fn) {
2
+ return fn;
3
+ }
@@ -5,13 +5,17 @@ export declare const USER_ATTRIBUTES_COOKIE_NAME = "builder.userAttributes";
5
5
  export declare function createUserAttributesService(): {
6
6
  setUserAttributes(newAttrs: UserAttributes): void;
7
7
  getUserAttributes(): any;
8
- subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void): () => void;
8
+ subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void, { fireImmediately }?: {
9
+ fireImmediately?: boolean | undefined;
10
+ }): () => void;
9
11
  setCanTrack(value: boolean): void;
10
12
  };
11
13
  export declare const userAttributesService: {
12
14
  setUserAttributes(newAttrs: UserAttributes): void;
13
15
  getUserAttributes(): any;
14
- subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void): () => void;
16
+ subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void, { fireImmediately }?: {
17
+ fireImmediately?: boolean | undefined;
18
+ }): () => void;
15
19
  setCanTrack(value: boolean): void;
16
20
  };
17
21
  export declare const setClientUserAttributes: (attributes: UserAttributes) => void;
@@ -1,5 +1,7 @@
1
+ import { TARGET } from '../constants/target';
1
2
  import { isBrowser } from '../functions/is-browser';
2
3
  import { getCookieSync, setCookie } from './cookie';
4
+ import { noSerializeWrapper } from './no-serialize-wrapper';
3
5
  export const USER_ATTRIBUTES_COOKIE_NAME = 'builder.userAttributes';
4
6
  export function createUserAttributesService() {
5
7
  let canTrack = true;
@@ -29,18 +31,31 @@ export function createUserAttributesService() {
29
31
  canTrack
30
32
  }) || '{}');
31
33
  },
32
- subscribeOnUserAttributesChange(callback) {
34
+ subscribeOnUserAttributesChange(callback, { fireImmediately } = {}) {
33
35
  subscribers.add(callback);
34
- return () => {
36
+ if (fireImmediately) {
37
+ callback(this.getUserAttributes());
38
+ }
39
+ return noSerializeWrapper(function () {
35
40
  subscribers.delete(callback);
36
- };
41
+ });
37
42
  },
38
43
  setCanTrack(value) {
39
44
  canTrack = value;
40
45
  }
41
46
  };
42
47
  }
43
- export const userAttributesService = createUserAttributesService();
48
+ let _userAttributesService;
49
+ if (isBrowser() && TARGET === 'qwik') {
50
+ if (!window.__BUILDER_USER_ATTRIBUTES_SERVICE__) {
51
+ window.__BUILDER_USER_ATTRIBUTES_SERVICE__ = createUserAttributesService();
52
+ }
53
+ _userAttributesService = window.__BUILDER_USER_ATTRIBUTES_SERVICE__;
54
+ }
55
+ else {
56
+ _userAttributesService = createUserAttributesService();
57
+ }
58
+ export const userAttributesService = _userAttributesService;
44
59
  export const setClientUserAttributes = (attributes) => {
45
60
  userAttributesService.setUserAttributes(attributes);
46
61
  };
@@ -144,6 +144,16 @@ function onSubmit(event) {
144
144
  }
145
145
  }
146
146
  formState = "sending";
147
+ if (sendSubmissionsTo === "email" &&
148
+ (sendSubmissionsToEmail === "your@email.com" || !sendSubmissionsToEmail)) {
149
+ const message = "SubmissionsToEmail is required when sendSubmissionsTo is set to email";
150
+ console.error(message);
151
+ formState = "error";
152
+ mergeNewRootState({
153
+ formErrorMessage: message,
154
+ });
155
+ return;
156
+ }
147
157
  const formUrl = `${getEnv() === "dev" ? "http://localhost:5000" : "https://builder.io"}/api/v1/form-submit?apiKey=${$builderContext.apiKey}&to=${btoa(sendSubmissionsToEmail || "")}&name=${encodeURIComponent(name || "")}`;
148
158
  const url = sendSubmissionsTo === "email"
149
159
  ? formUrl
@@ -162,20 +172,32 @@ function onSubmit(event) {
162
172
  else {
163
173
  body = await res.text();
164
174
  }
165
- if (!res.ok && errorMessagePath) {
166
- /* TODO: allow supplying an error formatter function */
167
- let message = get(body, errorMessagePath);
168
- if (message) {
169
- if (typeof message !== "string") {
170
- /* TODO: ideally convert json to yaml so it woul dbe like
171
- error: - email has been taken */
172
- message = JSON.stringify(message);
175
+ if (!res.ok) {
176
+ const submitErrorEvent = new CustomEvent("submit:error", {
177
+ detail: {
178
+ error: body,
179
+ status: res.status,
180
+ },
181
+ });
182
+ if (formRef?.nativeElement) {
183
+ formRef?.nativeElement.dispatchEvent(submitErrorEvent);
184
+ if (submitErrorEvent.defaultPrevented) {
185
+ return;
173
186
  }
174
- formErrorMessage = message;
175
- mergeNewRootState({
176
- formErrorMessage: message,
177
- });
178
187
  }
188
+ responseData = body;
189
+ formState = "error";
190
+ let message = errorMessagePath
191
+ ? get(body, errorMessagePath)
192
+ : body.message || body.error || body;
193
+ if (typeof message !== "string") {
194
+ message = JSON.stringify(message);
195
+ }
196
+ formErrorMessage = message;
197
+ mergeNewRootState({
198
+ formErrorMessage: message,
199
+ });
200
+ return;
179
201
  }
180
202
  responseData = body;
181
203
  formState = res.ok ? "success" : "error";
@@ -9,7 +9,7 @@ const UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME = 'updateVisibilityStylesScript';
9
9
  /**
10
10
  * SDKs that support Variant Containers
11
11
  */
12
- export const SDKS_SUPPORTING_PERSONALIZATION = ['react', 'vue', 'svelte'];
12
+ export const SDKS_SUPPORTING_PERSONALIZATION = ['react', 'vue', 'svelte', 'qwik'];
13
13
  /**
14
14
  * After hydration, we reset the tree
15
15
  * These SDKs handle Personalization Container in a special way:
@@ -19,7 +19,7 @@ export const SDKS_SUPPORTING_PERSONALIZATION = ['react', 'vue', 'svelte'];
19
19
  * This helps us to avoid flicker and show the correct / winning variant initially and then once we've hydrated we show the winning variant
20
20
  * and keep a track of the cookies to update to the correct variant dynamically when the cookie updates.
21
21
  */
22
- export const SDKS_REQUIRING_RESET_APPROACH = ['vue', 'svelte'];
22
+ export const SDKS_REQUIRING_RESET_APPROACH = ['vue', 'svelte', 'qwik'];
23
23
  export function checkShouldRenderVariants(variants, canTrack) {
24
24
  const hasVariants = variants && variants.length > 0;
25
25
  if (TARGET === 'reactNative')
@@ -61,6 +61,8 @@ onMount(() => {
61
61
  shouldResetVariants = true;
62
62
  const unsub = userAttributesService.subscribeOnUserAttributesChange((attrs) => {
63
63
  userAttributes = attrs;
64
+ }, {
65
+ fireImmediately: TARGET === "qwik",
64
66
  });
65
67
  if (!(isEditing() || isPreviewing())) {
66
68
  const variant = filteredVariants()[0];
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "4.0.9";
1
+ export declare const SDK_VERSION = "4.0.10";
@@ -1 +1 @@
1
- export const SDK_VERSION = "4.0.9";
1
+ export const SDK_VERSION = "4.0.10";
@@ -0,0 +1 @@
1
+ export declare function noSerializeWrapper(fn: () => void): () => void;
@@ -0,0 +1,3 @@
1
+ export function noSerializeWrapper(fn) {
2
+ return fn;
3
+ }
@@ -5,13 +5,17 @@ export declare const USER_ATTRIBUTES_COOKIE_NAME = "builder.userAttributes";
5
5
  export declare function createUserAttributesService(): {
6
6
  setUserAttributes(newAttrs: UserAttributes): void;
7
7
  getUserAttributes(): any;
8
- subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void): () => void;
8
+ subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void, { fireImmediately }?: {
9
+ fireImmediately?: boolean | undefined;
10
+ }): () => void;
9
11
  setCanTrack(value: boolean): void;
10
12
  };
11
13
  export declare const userAttributesService: {
12
14
  setUserAttributes(newAttrs: UserAttributes): void;
13
15
  getUserAttributes(): any;
14
- subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void): () => void;
16
+ subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void, { fireImmediately }?: {
17
+ fireImmediately?: boolean | undefined;
18
+ }): () => void;
15
19
  setCanTrack(value: boolean): void;
16
20
  };
17
21
  export declare const setClientUserAttributes: (attributes: UserAttributes) => void;
@@ -1,5 +1,7 @@
1
+ import { TARGET } from '../constants/target';
1
2
  import { isBrowser } from '../functions/is-browser';
2
3
  import { getCookieSync, setCookie } from './cookie';
4
+ import { noSerializeWrapper } from './no-serialize-wrapper';
3
5
  export const USER_ATTRIBUTES_COOKIE_NAME = 'builder.userAttributes';
4
6
  export function createUserAttributesService() {
5
7
  let canTrack = true;
@@ -29,18 +31,31 @@ export function createUserAttributesService() {
29
31
  canTrack
30
32
  }) || '{}');
31
33
  },
32
- subscribeOnUserAttributesChange(callback) {
34
+ subscribeOnUserAttributesChange(callback, { fireImmediately } = {}) {
33
35
  subscribers.add(callback);
34
- return () => {
36
+ if (fireImmediately) {
37
+ callback(this.getUserAttributes());
38
+ }
39
+ return noSerializeWrapper(function () {
35
40
  subscribers.delete(callback);
36
- };
41
+ });
37
42
  },
38
43
  setCanTrack(value) {
39
44
  canTrack = value;
40
45
  }
41
46
  };
42
47
  }
43
- export const userAttributesService = createUserAttributesService();
48
+ let _userAttributesService;
49
+ if (isBrowser() && TARGET === 'qwik') {
50
+ if (!window.__BUILDER_USER_ATTRIBUTES_SERVICE__) {
51
+ window.__BUILDER_USER_ATTRIBUTES_SERVICE__ = createUserAttributesService();
52
+ }
53
+ _userAttributesService = window.__BUILDER_USER_ATTRIBUTES_SERVICE__;
54
+ }
55
+ else {
56
+ _userAttributesService = createUserAttributesService();
57
+ }
58
+ export const userAttributesService = _userAttributesService;
44
59
  export const setClientUserAttributes = (attributes) => {
45
60
  userAttributesService.setUserAttributes(attributes);
46
61
  };
@@ -144,6 +144,16 @@ function onSubmit(event) {
144
144
  }
145
145
  }
146
146
  formState = "sending";
147
+ if (sendSubmissionsTo === "email" &&
148
+ (sendSubmissionsToEmail === "your@email.com" || !sendSubmissionsToEmail)) {
149
+ const message = "SubmissionsToEmail is required when sendSubmissionsTo is set to email";
150
+ console.error(message);
151
+ formState = "error";
152
+ mergeNewRootState({
153
+ formErrorMessage: message,
154
+ });
155
+ return;
156
+ }
147
157
  const formUrl = `${getEnv() === "dev" ? "http://localhost:5000" : "https://builder.io"}/api/v1/form-submit?apiKey=${$builderContext.apiKey}&to=${btoa(sendSubmissionsToEmail || "")}&name=${encodeURIComponent(name || "")}`;
148
158
  const url = sendSubmissionsTo === "email"
149
159
  ? formUrl
@@ -162,20 +172,32 @@ function onSubmit(event) {
162
172
  else {
163
173
  body = await res.text();
164
174
  }
165
- if (!res.ok && errorMessagePath) {
166
- /* TODO: allow supplying an error formatter function */
167
- let message = get(body, errorMessagePath);
168
- if (message) {
169
- if (typeof message !== "string") {
170
- /* TODO: ideally convert json to yaml so it woul dbe like
171
- error: - email has been taken */
172
- message = JSON.stringify(message);
175
+ if (!res.ok) {
176
+ const submitErrorEvent = new CustomEvent("submit:error", {
177
+ detail: {
178
+ error: body,
179
+ status: res.status,
180
+ },
181
+ });
182
+ if (formRef?.nativeElement) {
183
+ formRef?.nativeElement.dispatchEvent(submitErrorEvent);
184
+ if (submitErrorEvent.defaultPrevented) {
185
+ return;
173
186
  }
174
- formErrorMessage = message;
175
- mergeNewRootState({
176
- formErrorMessage: message,
177
- });
178
187
  }
188
+ responseData = body;
189
+ formState = "error";
190
+ let message = errorMessagePath
191
+ ? get(body, errorMessagePath)
192
+ : body.message || body.error || body;
193
+ if (typeof message !== "string") {
194
+ message = JSON.stringify(message);
195
+ }
196
+ formErrorMessage = message;
197
+ mergeNewRootState({
198
+ formErrorMessage: message,
199
+ });
200
+ return;
179
201
  }
180
202
  responseData = body;
181
203
  formState = res.ok ? "success" : "error";
@@ -9,7 +9,7 @@ const UPDATE_VARIANT_VISIBILITY_SCRIPT_FN_NAME = 'updateVisibilityStylesScript';
9
9
  /**
10
10
  * SDKs that support Variant Containers
11
11
  */
12
- export const SDKS_SUPPORTING_PERSONALIZATION = ['react', 'vue', 'svelte'];
12
+ export const SDKS_SUPPORTING_PERSONALIZATION = ['react', 'vue', 'svelte', 'qwik'];
13
13
  /**
14
14
  * After hydration, we reset the tree
15
15
  * These SDKs handle Personalization Container in a special way:
@@ -19,7 +19,7 @@ export const SDKS_SUPPORTING_PERSONALIZATION = ['react', 'vue', 'svelte'];
19
19
  * This helps us to avoid flicker and show the correct / winning variant initially and then once we've hydrated we show the winning variant
20
20
  * and keep a track of the cookies to update to the correct variant dynamically when the cookie updates.
21
21
  */
22
- export const SDKS_REQUIRING_RESET_APPROACH = ['vue', 'svelte'];
22
+ export const SDKS_REQUIRING_RESET_APPROACH = ['vue', 'svelte', 'qwik'];
23
23
  export function checkShouldRenderVariants(variants, canTrack) {
24
24
  const hasVariants = variants && variants.length > 0;
25
25
  if (TARGET === 'reactNative')
@@ -61,6 +61,8 @@ onMount(() => {
61
61
  shouldResetVariants = true;
62
62
  const unsub = userAttributesService.subscribeOnUserAttributesChange((attrs) => {
63
63
  userAttributes = attrs;
64
+ }, {
65
+ fireImmediately: TARGET === "qwik",
64
66
  });
65
67
  if (!(isEditing() || isPreviewing())) {
66
68
  const variant = filteredVariants()[0];
@@ -1 +1 @@
1
- export declare const SDK_VERSION = "4.0.9";
1
+ export declare const SDK_VERSION = "4.0.10";
@@ -1 +1 @@
1
- export const SDK_VERSION = "4.0.9";
1
+ export const SDK_VERSION = "4.0.10";
@@ -0,0 +1 @@
1
+ export declare function noSerializeWrapper(fn: () => void): () => void;
@@ -0,0 +1,3 @@
1
+ export function noSerializeWrapper(fn) {
2
+ return fn;
3
+ }
@@ -5,13 +5,17 @@ export declare const USER_ATTRIBUTES_COOKIE_NAME = "builder.userAttributes";
5
5
  export declare function createUserAttributesService(): {
6
6
  setUserAttributes(newAttrs: UserAttributes): void;
7
7
  getUserAttributes(): any;
8
- subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void): () => void;
8
+ subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void, { fireImmediately }?: {
9
+ fireImmediately?: boolean | undefined;
10
+ }): () => void;
9
11
  setCanTrack(value: boolean): void;
10
12
  };
11
13
  export declare const userAttributesService: {
12
14
  setUserAttributes(newAttrs: UserAttributes): void;
13
15
  getUserAttributes(): any;
14
- subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void): () => void;
16
+ subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void, { fireImmediately }?: {
17
+ fireImmediately?: boolean | undefined;
18
+ }): () => void;
15
19
  setCanTrack(value: boolean): void;
16
20
  };
17
21
  export declare const setClientUserAttributes: (attributes: UserAttributes) => void;
@@ -1,5 +1,7 @@
1
+ import { TARGET } from '../constants/target';
1
2
  import { isBrowser } from '../functions/is-browser';
2
3
  import { getCookieSync, setCookie } from './cookie';
4
+ import { noSerializeWrapper } from './no-serialize-wrapper';
3
5
  export const USER_ATTRIBUTES_COOKIE_NAME = 'builder.userAttributes';
4
6
  export function createUserAttributesService() {
5
7
  let canTrack = true;
@@ -29,18 +31,31 @@ export function createUserAttributesService() {
29
31
  canTrack
30
32
  }) || '{}');
31
33
  },
32
- subscribeOnUserAttributesChange(callback) {
34
+ subscribeOnUserAttributesChange(callback, { fireImmediately } = {}) {
33
35
  subscribers.add(callback);
34
- return () => {
36
+ if (fireImmediately) {
37
+ callback(this.getUserAttributes());
38
+ }
39
+ return noSerializeWrapper(function () {
35
40
  subscribers.delete(callback);
36
- };
41
+ });
37
42
  },
38
43
  setCanTrack(value) {
39
44
  canTrack = value;
40
45
  }
41
46
  };
42
47
  }
43
- export const userAttributesService = createUserAttributesService();
48
+ let _userAttributesService;
49
+ if (isBrowser() && TARGET === 'qwik') {
50
+ if (!window.__BUILDER_USER_ATTRIBUTES_SERVICE__) {
51
+ window.__BUILDER_USER_ATTRIBUTES_SERVICE__ = createUserAttributesService();
52
+ }
53
+ _userAttributesService = window.__BUILDER_USER_ATTRIBUTES_SERVICE__;
54
+ }
55
+ else {
56
+ _userAttributesService = createUserAttributesService();
57
+ }
58
+ export const userAttributesService = _userAttributesService;
44
59
  export const setClientUserAttributes = (attributes) => {
45
60
  userAttributesService.setUserAttributes(attributes);
46
61
  };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@builder.io/sdk-svelte",
3
3
  "description": "Builder.io SDK for Svelte",
4
- "version": "4.0.9",
4
+ "version": "4.0.10",
5
5
  "type": "module",
6
6
  "files": [
7
7
  "lib",
@@ -188,6 +188,19 @@
188
188
  }
189
189
  }
190
190
  formState = "sending";
191
+ if (
192
+ sendSubmissionsTo === "email" &&
193
+ (sendSubmissionsToEmail === "your@email.com" || !sendSubmissionsToEmail)
194
+ ) {
195
+ const message =
196
+ "SubmissionsToEmail is required when sendSubmissionsTo is set to email";
197
+ console.error(message);
198
+ formState = "error";
199
+ mergeNewRootState({
200
+ formErrorMessage: message,
201
+ });
202
+ return;
203
+ }
191
204
  const formUrl = `${
192
205
  getEnv() === "dev" ? "http://localhost:5000" : "https://builder.io"
193
206
  }/api/v1/form-submit?apiKey=${$builderContext.apiKey}&to=${btoa(
@@ -212,20 +225,32 @@
212
225
  } else {
213
226
  body = await res.text();
214
227
  }
215
- if (!res.ok && errorMessagePath) {
216
- /* TODO: allow supplying an error formatter function */
217
- let message = get(body, errorMessagePath);
218
- if (message) {
219
- if (typeof message !== "string") {
220
- /* TODO: ideally convert json to yaml so it woul dbe like
221
- error: - email has been taken */
222
- message = JSON.stringify(message);
228
+ if (!res.ok) {
229
+ const submitErrorEvent = new CustomEvent("submit:error", {
230
+ detail: {
231
+ error: body,
232
+ status: res.status,
233
+ },
234
+ });
235
+ if (formRef?.nativeElement) {
236
+ formRef?.nativeElement.dispatchEvent(submitErrorEvent);
237
+ if (submitErrorEvent.defaultPrevented) {
238
+ return;
223
239
  }
224
- formErrorMessage = message;
225
- mergeNewRootState({
226
- formErrorMessage: message,
227
- });
228
240
  }
241
+ responseData = body;
242
+ formState = "error";
243
+ let message = errorMessagePath
244
+ ? get(body, errorMessagePath)
245
+ : body.message || body.error || body;
246
+ if (typeof message !== "string") {
247
+ message = JSON.stringify(message);
248
+ }
249
+ formErrorMessage = message;
250
+ mergeNewRootState({
251
+ formErrorMessage: message,
252
+ });
253
+ return;
229
254
  }
230
255
  responseData = body;
231
256
  formState = res.ok ? "success" : "error";
@@ -30,7 +30,7 @@ type BlocksToRenderReturnType = {
30
30
  /**
31
31
  * SDKs that support Variant Containers
32
32
  */
33
- export const SDKS_SUPPORTING_PERSONALIZATION = (['react', 'vue', 'svelte'] as Target[]);
33
+ export const SDKS_SUPPORTING_PERSONALIZATION = (['react', 'vue', 'svelte', 'qwik'] as Target[]);
34
34
 
35
35
  /**
36
36
  * After hydration, we reset the tree
@@ -41,7 +41,7 @@ export const SDKS_SUPPORTING_PERSONALIZATION = (['react', 'vue', 'svelte'] as Ta
41
41
  * This helps us to avoid flicker and show the correct / winning variant initially and then once we've hydrated we show the winning variant
42
42
  * and keep a track of the cookies to update to the correct variant dynamically when the cookie updates.
43
43
  */
44
- export const SDKS_REQUIRING_RESET_APPROACH = (['vue', 'svelte'] as Target[]);
44
+ export const SDKS_REQUIRING_RESET_APPROACH = (['vue', 'svelte', 'qwik'] as Target[]);
45
45
  export function checkShouldRenderVariants(variants: PersonalizationContainerProps['variants'], canTrack: boolean) {
46
46
  const hasVariants = variants && variants.length > 0;
47
47
  if (TARGET === 'reactNative') return false;
@@ -101,6 +101,9 @@
101
101
  const unsub = userAttributesService.subscribeOnUserAttributesChange(
102
102
  (attrs) => {
103
103
  userAttributes = attrs;
104
+ },
105
+ {
106
+ fireImmediately: TARGET === "qwik",
104
107
  }
105
108
  );
106
109
  if (!(isEditing() || isPreviewing())) {
@@ -1 +1 @@
1
- export const SDK_VERSION = "4.0.9"
1
+ export const SDK_VERSION = "4.0.10"
@@ -0,0 +1,3 @@
1
+ export function noSerializeWrapper(fn: () => void) {
2
+ return fn;
3
+ }
@@ -1,5 +1,7 @@
1
+ import { TARGET } from '../constants/target';
1
2
  import { isBrowser } from '../functions/is-browser';
2
3
  import { getCookieSync, setCookie } from './cookie';
4
+ import { noSerializeWrapper } from './no-serialize-wrapper';
3
5
  export interface UserAttributes {
4
6
  [key: string]: any;
5
7
  }
@@ -32,18 +34,34 @@ export function createUserAttributesService() {
32
34
  canTrack
33
35
  }) || '{}');
34
36
  },
35
- subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void) {
37
+ subscribeOnUserAttributesChange(callback: (attrs: UserAttributes) => void, {
38
+ fireImmediately
39
+ }: {
40
+ fireImmediately?: boolean;
41
+ } = {}) {
36
42
  subscribers.add(callback);
37
- return () => {
43
+ if (fireImmediately) {
44
+ callback(this.getUserAttributes());
45
+ }
46
+ return noSerializeWrapper(function () {
38
47
  subscribers.delete(callback);
39
- };
48
+ });
40
49
  },
41
50
  setCanTrack(value: boolean) {
42
51
  canTrack = value;
43
52
  }
44
53
  };
45
54
  }
46
- export const userAttributesService = createUserAttributesService();
55
+ let _userAttributesService: ReturnType<typeof createUserAttributesService>;
56
+ if (isBrowser() && TARGET === 'qwik') {
57
+ if (!(window as any).__BUILDER_USER_ATTRIBUTES_SERVICE__) {
58
+ (window as any).__BUILDER_USER_ATTRIBUTES_SERVICE__ = createUserAttributesService();
59
+ }
60
+ _userAttributesService = (window as any).__BUILDER_USER_ATTRIBUTES_SERVICE__;
61
+ } else {
62
+ _userAttributesService = createUserAttributesService();
63
+ }
64
+ export const userAttributesService = _userAttributesService;
47
65
  export const setClientUserAttributes = (attributes: UserAttributes) => {
48
66
  userAttributesService.setUserAttributes(attributes);
49
67
  }