@builder.io/sdk-solid 5.0.1 → 5.1.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/lib/node/dev.jsx CHANGED
@@ -208,231 +208,365 @@ var getUserAttributes = () => {
208
208
  };
209
209
  };
210
210
 
211
- // src/functions/evaluate/helpers.ts
212
- var getFunctionArguments = ({
213
- builder,
214
- context,
215
- event,
216
- state
211
+ // src/constants/sdk-version.ts
212
+ var SDK_VERSION = "5.1.1";
213
+
214
+ // src/helpers/sdk-headers.ts
215
+ var getSdkHeaders = () => ({
216
+ "X-Builder-SDK": TARGET,
217
+ "X-Builder-SDK-GEN": "2",
218
+ "X-Builder-SDK-Version": SDK_VERSION
219
+ });
220
+
221
+ // src/helpers/nullable.ts
222
+ var checkIsDefined = (maybeT) => maybeT !== null && maybeT !== void 0;
223
+
224
+ // src/helpers/url.ts
225
+ var getTopLevelDomain = (host) => {
226
+ if (host === "localhost" || host === "127.0.0.1") {
227
+ return host;
228
+ }
229
+ const parts = host.split(".");
230
+ if (parts.length > 2) {
231
+ return parts.slice(1).join(".");
232
+ }
233
+ return host;
234
+ };
235
+
236
+ // src/helpers/cookie.ts
237
+ var getCookieSync = ({
238
+ name,
239
+ canTrack
217
240
  }) => {
218
- return Object.entries({
219
- state,
220
- Builder: builder,
221
- // legacy
222
- builder,
223
- context,
224
- event
225
- });
241
+ try {
242
+ if (!canTrack) {
243
+ return void 0;
244
+ }
245
+ return document.cookie.split("; ").find((row) => row.startsWith(`${name}=`))?.split("=")[1];
246
+ } catch (err) {
247
+ logger.warn("[COOKIE] GET error: ", err?.message || err);
248
+ return void 0;
249
+ }
226
250
  };
227
- var getBuilderGlobals = () => ({
228
- isEditing: isEditing(),
229
- isBrowser: isBrowser(),
230
- isServer: !isBrowser(),
231
- getUserAttributes: () => getUserAttributes()
232
- });
233
- var parseCode = (code, {
234
- isExpression = true
251
+ var getCookie = async (args) => getCookieSync(args);
252
+ var stringifyCookie = (cookie) => cookie.map(([key, value]) => value ? `${key}=${value}` : key).filter(checkIsDefined).join("; ");
253
+ var SECURE_CONFIG = [["secure", ""], ["SameSite", "None"]];
254
+ var createCookieString = ({
255
+ name,
256
+ value,
257
+ expires
235
258
  }) => {
236
- const useReturn = (
237
- // we disable this for cases where we definitely don't want a return
238
- isExpression && !(code.includes(";") || code.includes(" return ") || code.trim().startsWith("return "))
239
- );
240
- const useCode = useReturn ? `return (${code});` : code;
241
- return useCode;
259
+ const secure = isBrowser() ? location.protocol === "https:" : true;
260
+ const secureObj = secure ? SECURE_CONFIG : [[]];
261
+ const expiresObj = expires ? [["expires", expires.toUTCString()]] : [[]];
262
+ const cookieValue = [[name, value], ...expiresObj, ["path", "/"], ["domain", getTopLevelDomain(window.location.hostname)], ...secureObj];
263
+ const cookie = stringifyCookie(cookieValue);
264
+ return cookie;
242
265
  };
243
- function flattenState({
244
- rootState,
245
- localState,
246
- rootSetState
247
- }) {
248
- return new Proxy(rootState, {
249
- get: (target, prop) => {
250
- if (localState && prop in localState) {
251
- return localState[prop];
252
- }
253
- const val = target[prop];
254
- if (typeof val === "object" && val !== null) {
255
- return flattenState({
256
- rootState: val,
257
- localState: void 0,
258
- rootSetState: rootSetState ? (subState) => {
259
- target[prop] = subState;
260
- rootSetState(target);
261
- } : void 0
262
- });
263
- }
264
- return val;
265
- },
266
- set: (target, prop, value) => {
267
- if (localState && prop in localState) {
268
- throw new Error("Writing to local state is not allowed as it is read-only.");
269
- }
270
- target[prop] = value;
271
- rootSetState?.(target);
272
- return true;
266
+ var setCookie = async ({
267
+ name,
268
+ value,
269
+ expires,
270
+ canTrack
271
+ }) => {
272
+ try {
273
+ if (!canTrack) {
274
+ return;
273
275
  }
276
+ const cookie = createCookieString({
277
+ name,
278
+ value,
279
+ expires
280
+ });
281
+ document.cookie = cookie;
282
+ } catch (err) {
283
+ logger.warn("[COOKIE] SET error: ", err?.message || err);
284
+ }
285
+ };
286
+
287
+ // src/helpers/uuid.ts
288
+ function uuidv4() {
289
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
290
+ const r = Math.random() * 16 | 0, v = c == "x" ? r : r & 3 | 8;
291
+ return v.toString(16);
274
292
  });
275
293
  }
294
+ function uuid() {
295
+ return uuidv4().replace(/-/g, "");
296
+ }
276
297
 
277
- // src/functions/evaluate/browser-runtime/browser.ts
278
- var runInBrowser = ({
279
- code,
280
- builder,
281
- context,
282
- event,
283
- localState,
284
- rootSetState,
285
- rootState
298
+ // src/helpers/sessionId.ts
299
+ var SESSION_LOCAL_STORAGE_KEY = "builderSessionId";
300
+ var getSessionId = async ({
301
+ canTrack
286
302
  }) => {
287
- const functionArgs = getFunctionArguments({
288
- builder,
289
- context,
290
- event,
291
- state: flattenState({
292
- rootState,
293
- localState,
294
- rootSetState
295
- })
296
- });
297
- return new Function(...functionArgs.map(([name]) => name), code)(...functionArgs.map(([, value]) => value));
298
- };
299
-
300
- // src/constants/sdk-name.ts
301
- var SDK_NAME_FOR_TARGET = (() => {
302
- switch (TARGET) {
303
- case "rsc":
304
- return "react-nextjs";
305
- case "reactNative":
306
- return "react-native";
307
- default:
308
- return TARGET;
303
+ if (!canTrack) {
304
+ return void 0;
309
305
  }
310
- })();
311
- var SDK_NAME = `@builder.io/sdk-${SDK_NAME_FOR_TARGET}`;
312
-
313
- // src/functions/fast-clone.ts
314
- var fastClone = (obj) => JSON.parse(JSON.stringify(obj));
315
-
316
- // src/functions/set.ts
317
- var set = (obj, _path, value) => {
318
- if (Object(obj) !== obj) {
319
- return obj;
306
+ const sessionId = await getCookie({
307
+ name: SESSION_LOCAL_STORAGE_KEY,
308
+ canTrack
309
+ });
310
+ if (checkIsDefined(sessionId)) {
311
+ return sessionId;
312
+ } else {
313
+ const newSessionId = createSessionId();
314
+ setSessionId({
315
+ id: newSessionId,
316
+ canTrack
317
+ });
318
+ return newSessionId;
320
319
  }
321
- const path = Array.isArray(_path) ? _path : _path.toString().match(/[^.[\]]+/g);
322
- path.slice(0, -1).reduce((a, c, i) => Object(a[c]) === a[c] ? a[c] : a[c] = Math.abs(Number(path[i + 1])) >> 0 === +path[i + 1] ? [] : {}, obj)[path[path.length - 1]] = value;
323
- return obj;
324
320
  };
321
+ var createSessionId = () => uuid();
322
+ var setSessionId = ({
323
+ id,
324
+ canTrack
325
+ }) => setCookie({
326
+ name: SESSION_LOCAL_STORAGE_KEY,
327
+ value: id,
328
+ canTrack
329
+ });
325
330
 
326
- // src/functions/evaluate/node-runtime/safeDynamicRequire.ts
327
- import { createRequire } from "node:module";
328
- var noop = () => {
331
+ // src/helpers/localStorage.ts
332
+ var getLocalStorage = () => isBrowser() && typeof localStorage !== "undefined" ? localStorage : void 0;
333
+ var getLocalStorageItem = ({
334
+ key,
335
+ canTrack
336
+ }) => {
337
+ try {
338
+ if (canTrack) {
339
+ return getLocalStorage()?.getItem(key);
340
+ }
341
+ return void 0;
342
+ } catch (err) {
343
+ console.debug("[LocalStorage] GET error: ", err);
344
+ return void 0;
345
+ }
329
346
  };
330
- var safeDynamicRequire = noop;
331
- try {
332
- safeDynamicRequire = createRequire(import.meta.url);
333
- } catch (error) {
347
+ var setLocalStorageItem = ({
348
+ key,
349
+ canTrack,
350
+ value
351
+ }) => {
334
352
  try {
335
- safeDynamicRequire = eval("require");
336
- } catch (error2) {
353
+ if (canTrack) {
354
+ getLocalStorage()?.setItem(key, value);
355
+ }
356
+ } catch (err) {
357
+ console.debug("[LocalStorage] SET error: ", err);
337
358
  }
338
- }
359
+ };
339
360
 
340
- // src/functions/evaluate/node-runtime/node-runtime.ts
341
- var getSyncValName = (key) => `bldr_${key}_sync`;
342
- var BUILDER_SET_STATE_NAME = "BUILDER_SET_STATE";
343
- var INJECTED_IVM_GLOBAL = "BUILDER_IVM";
344
- var REF_TO_PROXY_FN = `
345
- var refToProxy = (obj) => {
346
- if (typeof obj !== 'object' || obj === null) {
347
- return obj;
348
- }
349
- return new Proxy({}, {
350
- get(target, key) {
351
- if (key === 'copySync') {
352
- return () => obj.copySync();
353
- }
354
- const val = obj.getSync(key);
355
- if (typeof val?.getSync === 'function') {
356
- return refToProxy(val);
357
- }
358
- return val;
359
- },
360
- set(target, key, value) {
361
- const v = typeof value === 'object' ? new ${INJECTED_IVM_GLOBAL}.Reference(value) : value;
362
- obj.setSync(key, v);
363
- ${BUILDER_SET_STATE_NAME}(key, value)
364
- },
365
- deleteProperty(target, key) {
366
- obj.deleteSync(key);
361
+ // src/helpers/visitorId.ts
362
+ var VISITOR_LOCAL_STORAGE_KEY = "builderVisitorId";
363
+ var getVisitorId = ({
364
+ canTrack
365
+ }) => {
366
+ if (!canTrack) {
367
+ return void 0;
368
+ }
369
+ const visitorId = getLocalStorageItem({
370
+ key: VISITOR_LOCAL_STORAGE_KEY,
371
+ canTrack
372
+ });
373
+ if (checkIsDefined(visitorId)) {
374
+ return visitorId;
375
+ } else {
376
+ const newVisitorId = createVisitorId();
377
+ setVisitorId({
378
+ id: newVisitorId,
379
+ canTrack
380
+ });
381
+ return newVisitorId;
382
+ }
383
+ };
384
+ var createVisitorId = () => uuid();
385
+ var setVisitorId = ({
386
+ id,
387
+ canTrack
388
+ }) => setLocalStorageItem({
389
+ key: VISITOR_LOCAL_STORAGE_KEY,
390
+ value: id,
391
+ canTrack
392
+ });
393
+
394
+ // src/functions/log-fetch.ts
395
+ function logFetch(url) {
396
+ if (typeof process !== "undefined" && process.env?.DEBUG) {
397
+ if (String(process.env.DEBUG) == "true") {
398
+ logger.log(url);
367
399
  }
368
- })
400
+ }
369
401
  }
370
- `;
371
- var processCode = ({
372
- code,
373
- args
402
+
403
+ // src/functions/track/index.ts
404
+ var getTrackingEventData = async ({
405
+ canTrack
374
406
  }) => {
375
- const fnArgs = args.map(([name]) => `var ${name} = refToProxy(${getSyncValName(name)}); `).join("");
376
- return `
377
- ${REF_TO_PROXY_FN}
378
- ${fnArgs}
379
- function theFunction() {
380
- ${code}
407
+ if (!canTrack) {
408
+ return {
409
+ visitorId: void 0,
410
+ sessionId: void 0
411
+ };
412
+ }
413
+ const sessionId = await getSessionId({
414
+ canTrack
415
+ });
416
+ const visitorId = getVisitorId({
417
+ canTrack
418
+ });
419
+ return {
420
+ sessionId,
421
+ visitorId
422
+ };
423
+ };
424
+ var createEvent = async ({
425
+ type: eventType,
426
+ canTrack,
427
+ apiKey,
428
+ metadata,
429
+ ...properties
430
+ }) => ({
431
+ type: eventType,
432
+ data: {
433
+ ...properties,
434
+ metadata: {
435
+ url: location.href,
436
+ ...metadata
437
+ },
438
+ ...await getTrackingEventData({
439
+ canTrack
440
+ }),
441
+ userAttributes: getUserAttributes(),
442
+ ownerId: apiKey
443
+ }
444
+ });
445
+ async function _track({
446
+ apiHost,
447
+ ...eventProps
448
+ }) {
449
+ if (!eventProps.apiKey) {
450
+ logger.error("Missing API key for track call. Please provide your API key.");
451
+ return;
452
+ }
453
+ if (!eventProps.canTrack) {
454
+ return;
455
+ }
456
+ if (isEditing()) {
457
+ return;
458
+ }
459
+ if (!(isBrowser() || TARGET === "reactNative")) {
460
+ return;
461
+ }
462
+ const baseUrl = apiHost || "https://cdn.builder.io";
463
+ const url = `${baseUrl}/api/v1/track`;
464
+ logFetch(url);
465
+ return fetch(url, {
466
+ method: "POST",
467
+ body: JSON.stringify({
468
+ events: [await createEvent(eventProps)]
469
+ }),
470
+ headers: {
471
+ "content-type": "application/json",
472
+ ...getSdkHeaders()
473
+ },
474
+ mode: "cors"
475
+ }).catch((err) => {
476
+ console.error("Failed to track: ", err);
477
+ });
381
478
  }
479
+ var track = (args) => _track({
480
+ ...args,
481
+ canTrack: true
482
+ });
382
483
 
383
- const output = theFunction()
384
-
385
- if (typeof output === 'object' && output !== null) {
386
- return JSON.stringify(output.copySync ? output.copySync() : output);
387
- } else {
388
- return output;
389
- }
390
- `;
484
+ // src/functions/evaluate/helpers.ts
485
+ var getFunctionArguments = ({
486
+ builder,
487
+ context,
488
+ event,
489
+ state
490
+ }) => {
491
+ return Object.entries({
492
+ state,
493
+ Builder: builder,
494
+ // legacy
495
+ builder,
496
+ context,
497
+ event
498
+ });
391
499
  };
392
- var IVM_INSTANCE = null;
393
- var IVM_CONTEXT = null;
394
- var SHOULD_MENTION_INITIALIZE_SCRIPT = SDK_NAME === "@builder.io/sdk-react-nextjs" || SDK_NAME === "@builder.io/sdk-react" || SDK_NAME === "@builder.io/sdk-qwik" || SDK_NAME === "@builder.io/sdk-vue";
395
- var getIvm = () => {
396
- try {
397
- if (IVM_INSTANCE)
398
- return IVM_INSTANCE;
399
- const dynRequiredIvm = safeDynamicRequire("isolated-vm");
400
- if (dynRequiredIvm)
401
- return dynRequiredIvm;
402
- } catch (error2) {
403
- logger.error("isolated-vm import error.", error2);
500
+ var getBuilderGlobals = (trackingContext) => ({
501
+ isEditing: isEditing(),
502
+ isBrowser: isBrowser(),
503
+ isServer: !isBrowser(),
504
+ getUserAttributes: () => getUserAttributes(),
505
+ trackConversion: (amount, customProperties) => {
506
+ if (!trackingContext?.apiKey || trackingContext?.canTrack === false) {
507
+ return;
508
+ }
509
+ _track({
510
+ type: "conversion",
511
+ apiKey: trackingContext.apiKey,
512
+ canTrack: trackingContext.canTrack ?? true,
513
+ contentId: trackingContext.contentId,
514
+ variationId: trackingContext.variationId !== trackingContext.contentId ? trackingContext.variationId : void 0,
515
+ metadata: {
516
+ ...customProperties || {},
517
+ ...amount !== void 0 ? {
518
+ amount
519
+ } : {}
520
+ }
521
+ });
404
522
  }
405
- const ERROR_MESSAGE = `${MSG_PREFIX}could not import \`isolated-vm\` module for safe script execution on a Node server.
406
-
407
- SOLUTION: In a server-only execution path within your application, do one of the following:
408
-
409
- ${SHOULD_MENTION_INITIALIZE_SCRIPT ? `- import and call \`initializeNodeRuntime()\` from "${SDK_NAME}/node/init".` : ""}
410
- - add the following import: \`await import('isolated-vm')\`.
411
-
412
- For more information, visit https://builder.io/c/docs/integration-tips#enabling-data-bindings-in-node-environments`;
413
- throw new Error(ERROR_MESSAGE);
523
+ });
524
+ var parseCode = (code, {
525
+ isExpression = true
526
+ }) => {
527
+ const useReturn = (
528
+ // we disable this for cases where we definitely don't want a return
529
+ isExpression && !(code.includes(";") || code.includes(" return ") || code.trim().startsWith("return "))
530
+ );
531
+ const useCode = useReturn ? `return (${code});` : code;
532
+ return useCode;
414
533
  };
415
- function setIsolateContext(options = {
416
- memoryLimit: 128
534
+ function flattenState({
535
+ rootState,
536
+ localState,
537
+ rootSetState
417
538
  }) {
418
- if (IVM_CONTEXT)
419
- return IVM_CONTEXT;
420
- const ivm = getIvm();
421
- const isolate = new ivm.Isolate(options);
422
- const context = isolate.createContextSync();
423
- const jail = context.global;
424
- jail.setSync("global", jail.derefInto());
425
- jail.setSync("log", function(...logArgs) {
426
- console.log(...logArgs);
539
+ return new Proxy(rootState, {
540
+ get: (target, prop) => {
541
+ if (localState && prop in localState) {
542
+ return localState[prop];
543
+ }
544
+ const val = target[prop];
545
+ if (typeof val === "object" && val !== null) {
546
+ return flattenState({
547
+ rootState: val,
548
+ localState: void 0,
549
+ rootSetState: rootSetState ? (subState) => {
550
+ target[prop] = subState;
551
+ rootSetState(target);
552
+ } : void 0
553
+ });
554
+ }
555
+ return val;
556
+ },
557
+ set: (target, prop, value) => {
558
+ if (localState && prop in localState) {
559
+ throw new Error("Writing to local state is not allowed as it is read-only.");
560
+ }
561
+ target[prop] = value;
562
+ rootSetState?.(target);
563
+ return true;
564
+ }
427
565
  });
428
- jail.setSync(INJECTED_IVM_GLOBAL, ivm);
429
- IVM_CONTEXT = context;
430
- return context;
431
566
  }
432
- var getIsolateContext = () => {
433
- return setIsolateContext();
434
- };
435
- var runInNode = ({
567
+
568
+ // src/functions/evaluate/browser-runtime/browser.ts
569
+ var runInBrowser = ({
436
570
  code,
437
571
  builder,
438
572
  context,
@@ -441,49 +575,201 @@ var runInNode = ({
441
575
  rootSetState,
442
576
  rootState
443
577
  }) => {
444
- const ivm = getIvm();
445
- const state = fastClone({
446
- ...rootState,
447
- ...localState
448
- });
449
- const args = getFunctionArguments({
578
+ const functionArgs = getFunctionArguments({
450
579
  builder,
451
580
  context,
452
581
  event,
453
- state
454
- });
455
- const isolateContext = getIsolateContext();
456
- const jail = isolateContext.global;
457
- jail.setSync(BUILDER_SET_STATE_NAME, function(key, value) {
458
- set(rootState, key, value);
459
- rootSetState?.(rootState);
460
- });
461
- args.forEach(([key, arg]) => {
462
- const val = typeof arg === "object" ? new ivm.Reference(
463
- // workaround: methods with default values for arguments is not being cloned over
464
- key === "builder" ? {
465
- ...arg,
466
- getUserAttributes: () => arg.getUserAttributes()
467
- } : arg
468
- ) : null;
469
- jail.setSync(getSyncValName(key), val);
470
- });
471
- const evalStr = processCode({
472
- code,
473
- args
582
+ state: flattenState({
583
+ rootState,
584
+ localState,
585
+ rootSetState
586
+ })
474
587
  });
475
- const resultStr = isolateContext.evalClosureSync(evalStr);
476
- try {
477
- const res = JSON.parse(resultStr);
478
- return res;
479
- } catch (_error) {
480
- return resultStr;
481
- }
588
+ return new Function(...functionArgs.map(([name]) => name), code)(...functionArgs.map(([, value]) => value));
589
+ };
590
+
591
+ // src/constants/sdk-name.ts
592
+ var SDK_NAME_FOR_TARGET = (() => {
593
+ switch (TARGET) {
594
+ case "rsc":
595
+ return "react-nextjs";
596
+ case "reactNative":
597
+ return "react-native";
598
+ default:
599
+ return TARGET;
600
+ }
601
+ })();
602
+ var SDK_NAME = `@builder.io/sdk-${SDK_NAME_FOR_TARGET}`;
603
+
604
+ // src/functions/fast-clone.ts
605
+ var fastClone = (obj) => JSON.parse(JSON.stringify(obj));
606
+
607
+ // src/functions/set.ts
608
+ var set = (obj, _path, value) => {
609
+ if (Object(obj) !== obj) {
610
+ return obj;
611
+ }
612
+ const path = Array.isArray(_path) ? _path : _path.toString().match(/[^.[\]]+/g);
613
+ path.slice(0, -1).reduce((a, c, i) => Object(a[c]) === a[c] ? a[c] : a[c] = Math.abs(Number(path[i + 1])) >> 0 === +path[i + 1] ? [] : {}, obj)[path[path.length - 1]] = value;
614
+ return obj;
615
+ };
616
+
617
+ // src/functions/evaluate/node-runtime/safeDynamicRequire.ts
618
+ import { createRequire } from "node:module";
619
+ var noop = () => {
620
+ };
621
+ var safeDynamicRequire = noop;
622
+ try {
623
+ safeDynamicRequire = createRequire(import.meta.url);
624
+ } catch (error) {
625
+ try {
626
+ safeDynamicRequire = eval("require");
627
+ } catch (error2) {
628
+ }
629
+ }
630
+
631
+ // src/functions/evaluate/node-runtime/node-runtime.ts
632
+ var getSyncValName = (key) => `bldr_${key}_sync`;
633
+ var BUILDER_SET_STATE_NAME = "BUILDER_SET_STATE";
634
+ var INJECTED_IVM_GLOBAL = "BUILDER_IVM";
635
+ var REF_TO_PROXY_FN = `
636
+ var refToProxy = (obj) => {
637
+ if (typeof obj !== 'object' || obj === null) {
638
+ return obj;
639
+ }
640
+ return new Proxy({}, {
641
+ get(target, key) {
642
+ if (key === 'copySync') {
643
+ return () => obj.copySync();
644
+ }
645
+ const val = obj.getSync(key);
646
+ if (typeof val?.getSync === 'function') {
647
+ return refToProxy(val);
648
+ }
649
+ return val;
650
+ },
651
+ set(target, key, value) {
652
+ const v = typeof value === 'object' ? new ${INJECTED_IVM_GLOBAL}.Reference(value) : value;
653
+ obj.setSync(key, v);
654
+ ${BUILDER_SET_STATE_NAME}(key, value)
655
+ },
656
+ deleteProperty(target, key) {
657
+ obj.deleteSync(key);
658
+ }
659
+ })
660
+ }
661
+ `;
662
+ var processCode = ({
663
+ code,
664
+ args
665
+ }) => {
666
+ const fnArgs = args.map(([name]) => `var ${name} = refToProxy(${getSyncValName(name)}); `).join("");
667
+ return `
668
+ ${REF_TO_PROXY_FN}
669
+ ${fnArgs}
670
+ function theFunction() {
671
+ ${code}
672
+ }
673
+
674
+ const output = theFunction()
675
+
676
+ if (typeof output === 'object' && output !== null) {
677
+ return JSON.stringify(output.copySync ? output.copySync() : output);
678
+ } else {
679
+ return output;
680
+ }
681
+ `;
682
+ };
683
+ var IVM_INSTANCE = null;
684
+ var IVM_OPTIONS = {
685
+ memoryLimit: 128
686
+ };
687
+ var SHOULD_MENTION_INITIALIZE_SCRIPT = SDK_NAME === "@builder.io/sdk-react-nextjs" || SDK_NAME === "@builder.io/sdk-react" || SDK_NAME === "@builder.io/sdk-qwik" || SDK_NAME === "@builder.io/sdk-vue";
688
+ var getIvm = () => {
689
+ try {
690
+ if (IVM_INSTANCE)
691
+ return IVM_INSTANCE;
692
+ const dynRequiredIvm = safeDynamicRequire("isolated-vm");
693
+ if (dynRequiredIvm)
694
+ return dynRequiredIvm;
695
+ } catch (error2) {
696
+ logger.error("isolated-vm import error.", error2);
697
+ }
698
+ const ERROR_MESSAGE = `${MSG_PREFIX}could not import \`isolated-vm\` module for safe script execution on a Node server.
699
+
700
+ SOLUTION: In a server-only execution path within your application, do one of the following:
701
+
702
+ ${SHOULD_MENTION_INITIALIZE_SCRIPT ? `- import and call \`initializeNodeRuntime()\` from "${SDK_NAME}/node/init".` : ""}
703
+ - add the following import: \`await import('isolated-vm')\`.
704
+
705
+ For more information, visit https://builder.io/c/docs/integration-tips#enabling-data-bindings-in-node-environments`;
706
+ throw new Error(ERROR_MESSAGE);
707
+ };
708
+ var runInNode = ({
709
+ code,
710
+ builder,
711
+ context,
712
+ event,
713
+ localState,
714
+ rootSetState,
715
+ rootState
716
+ }) => {
717
+ const ivm = getIvm();
718
+ let isolate;
719
+ try {
720
+ isolate = new ivm.Isolate(IVM_OPTIONS);
721
+ const isolateContext = isolate.createContextSync();
722
+ const jail = isolateContext.global;
723
+ jail.setSync("global", jail.derefInto());
724
+ jail.setSync("log", function(...logArgs) {
725
+ console.log(...logArgs);
726
+ });
727
+ jail.setSync(INJECTED_IVM_GLOBAL, ivm);
728
+ const state = fastClone({
729
+ ...rootState,
730
+ ...localState
731
+ });
732
+ const args = getFunctionArguments({
733
+ builder,
734
+ context,
735
+ event,
736
+ state
737
+ });
738
+ jail.setSync(BUILDER_SET_STATE_NAME, function(key, value) {
739
+ set(rootState, key, value);
740
+ rootSetState?.(rootState);
741
+ });
742
+ args.forEach(([key, arg]) => {
743
+ const val = typeof arg === "object" ? new ivm.Reference(
744
+ // workaround: methods with default values for arguments is not being cloned over
745
+ key === "builder" ? {
746
+ ...arg,
747
+ getUserAttributes: () => arg.getUserAttributes()
748
+ } : arg
749
+ ) : null;
750
+ jail.setSync(getSyncValName(key), val);
751
+ });
752
+ const evalStr = processCode({
753
+ code,
754
+ args
755
+ });
756
+ const resultStr = isolateContext.evalClosureSync(evalStr);
757
+ try {
758
+ const res = JSON.parse(resultStr);
759
+ return res;
760
+ } catch (_error) {
761
+ return resultStr;
762
+ }
763
+ } finally {
764
+ if (isolate) {
765
+ try {
766
+ isolate.dispose();
767
+ } catch (e) {
768
+ }
769
+ }
770
+ }
482
771
  };
483
772
 
484
- // src/helpers/nullable.ts
485
- var checkIsDefined = (maybeT) => maybeT !== null && maybeT !== void 0;
486
-
487
773
  // src/functions/is-node-runtime.ts
488
774
  function isNodeRuntime() {
489
775
  return typeof process !== "undefined" && checkIsDefined(process?.versions?.node);
@@ -528,7 +814,8 @@ function evaluate({
528
814
  rootState,
529
815
  rootSetState,
530
816
  event,
531
- isExpression = true
817
+ isExpression = true,
818
+ trackingContext
532
819
  }) {
533
820
  if (code.trim() === "") {
534
821
  return void 0;
@@ -544,7 +831,7 @@ function evaluate({
544
831
  code: parseCode(code, {
545
832
  isExpression
546
833
  }),
547
- builder: getBuilderGlobals(),
834
+ builder: getBuilderGlobals(trackingContext),
548
835
  context,
549
836
  event,
550
837
  rootSetState,
@@ -793,801 +1080,538 @@ function throttle(func, wait, options = {}) {
793
1080
  previous = now;
794
1081
  result = func.apply(context, args);
795
1082
  if (!timeout)
796
- context = args = null;
797
- } else if (!timeout && options.trailing !== false) {
798
- timeout = setTimeout(later, remaining);
799
- }
800
- return result;
801
- };
802
- }
803
- function assign(target, ..._args) {
804
- const to = Object(target);
805
- for (let index = 1; index < arguments.length; index++) {
806
- const nextSource = arguments[index];
807
- if (nextSource != null) {
808
- for (const nextKey in nextSource) {
809
- if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
810
- to[nextKey] = nextSource[nextKey];
811
- }
812
- }
813
- }
814
- }
815
- return to;
816
- }
817
- function bindAnimations(animations) {
818
- if (TARGET === "reactNative") {
819
- return;
820
- }
821
- for (const animation of animations) {
822
- switch (animation.trigger) {
823
- case "pageLoad":
824
- triggerAnimation(animation);
825
- break;
826
- case "scrollInView":
827
- bindScrollInViewAnimation(animation);
828
- break;
829
- }
830
- }
831
- }
832
- function warnElementNotPresent(id) {
833
- console.warn(`Cannot animate element: element with ID ${id} not found!`);
834
- }
835
- function augmentAnimation(animation, element) {
836
- const stylesUsed = getAllStylesUsed(animation);
837
- const computedStyle = getComputedStyle(element);
838
- const firstStyles = animation.steps[0].styles;
839
- const lastStyles = animation.steps[animation.steps.length - 1].styles;
840
- const bothStyles = [firstStyles, lastStyles];
841
- for (const styles of bothStyles) {
842
- for (const style of stylesUsed) {
843
- if (!(style in styles)) {
844
- styles[style] = computedStyle[style];
845
- }
846
- }
847
- }
848
- }
849
- function getAllStylesUsed(animation) {
850
- const properties = [];
851
- for (const step of animation.steps) {
852
- for (const key in step.styles) {
853
- if (properties.indexOf(key) === -1) {
854
- properties.push(key);
855
- }
856
- }
857
- }
858
- return properties;
859
- }
860
- function triggerAnimation(animation) {
861
- const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
862
- if (!elements.length) {
863
- warnElementNotPresent(animation.elementId || animation.id || "");
864
- return;
865
- }
866
- Array.from(elements).forEach((element) => {
867
- augmentAnimation(animation, element);
868
- element.style.transition = "none";
869
- element.style.transitionDelay = "0";
870
- assign(element.style, animation.steps[0].styles);
871
- setTimeout(() => {
872
- element.style.transition = `all ${animation.duration}s ${camelToKebabCase(animation.easing)}`;
873
- if (animation.delay) {
874
- element.style.transitionDelay = animation.delay + "s";
875
- }
876
- assign(element.style, animation.steps[1].styles);
877
- setTimeout(() => {
878
- element.style.transition = "";
879
- element.style.transitionDelay = "";
880
- }, (animation.delay || 0) * 1e3 + animation.duration * 1e3 + 100);
881
- });
882
- });
883
- }
884
- function bindScrollInViewAnimation(animation) {
885
- const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
886
- if (!elements.length) {
887
- warnElementNotPresent(animation.elementId || animation.id || "");
888
- return;
889
- }
890
- Array.from(elements).forEach((element) => {
891
- augmentAnimation(animation, element);
892
- let triggered = false;
893
- let pendingAnimation = false;
894
- function immediateOnScroll() {
895
- if (!triggered && isScrolledIntoView(element)) {
896
- triggered = true;
897
- pendingAnimation = true;
898
- setTimeout(() => {
899
- assign(element.style, animation.steps[1].styles);
900
- if (!animation.repeat) {
901
- document.removeEventListener("scroll", onScroll);
902
- }
903
- setTimeout(() => {
904
- pendingAnimation = false;
905
- if (!animation.repeat) {
906
- element.style.transition = "";
907
- element.style.transitionDelay = "";
908
- }
909
- }, (animation.duration + (animation.delay || 0)) * 1e3 + 100);
910
- });
911
- } else if (animation.repeat && triggered && !pendingAnimation && !isScrolledIntoView(element)) {
912
- triggered = false;
913
- assign(element.style, animation.steps[0].styles);
914
- }
915
- }
916
- const onScroll = throttle(immediateOnScroll, 200, {
917
- leading: false
918
- });
919
- function isScrolledIntoView(elem) {
920
- const rect = elem.getBoundingClientRect();
921
- const windowHeight = window.innerHeight;
922
- const thresholdPercent = (animation.thresholdPercent || 0) / 100;
923
- const threshold = thresholdPercent * windowHeight;
924
- return rect.bottom > threshold && rect.top < windowHeight - threshold;
925
- }
926
- const defaultState = animation.steps[0].styles;
927
- function attachDefaultState() {
928
- assign(element.style, defaultState);
929
- }
930
- attachDefaultState();
931
- setTimeout(() => {
932
- element.style.transition = `all ${animation.duration}s ${camelToKebabCase(animation.easing)}`;
933
- if (animation.delay) {
934
- element.style.transitionDelay = animation.delay + "s";
935
- }
936
- });
937
- document.addEventListener("scroll", onScroll, {
938
- capture: true,
939
- passive: true
940
- });
941
- immediateOnScroll();
942
- });
943
- }
944
-
945
- // src/helpers/css.ts
946
- var convertStyleMapToCSSArray = (style) => {
947
- const cssProps = Object.entries(style).map(([key, value]) => {
948
- if (typeof value === "string") {
949
- return `${camelToKebabCase(key)}: ${value};`;
950
- } else {
951
- return void 0;
952
- }
953
- });
954
- return cssProps.filter(checkIsDefined);
955
- };
956
- var convertStyleMapToCSS = (style) => convertStyleMapToCSSArray(style).join("\n");
957
- var createCssClass = ({
958
- mediaQuery,
959
- className,
960
- styles
961
- }) => {
962
- const cssClass = `.${className} {
963
- ${convertStyleMapToCSS(styles)}
964
- }`;
965
- if (mediaQuery) {
966
- return `${mediaQuery} {
967
- ${cssClass}
968
- }`;
969
- } else {
970
- return cssClass;
971
- }
972
- };
973
-
974
- // src/functions/transform-style-property.ts
975
- function transformStyleProperty({
976
- style
977
- }) {
978
- return style;
979
- }
980
-
981
- // src/functions/get-style.ts
982
- var getStyle = ({
983
- block,
984
- context
985
- }) => {
986
- return mapStyleObjToStrIfNeeded(transformStyleProperty({
987
- style: block.style || {},
988
- context,
989
- block
990
- }));
991
- };
992
- function mapStyleObjToStrIfNeeded(style) {
993
- switch (TARGET) {
994
- case "svelte":
995
- case "vue":
996
- case "solid":
997
- case "angular":
998
- return convertStyleMapToCSSArray(style).join(" ");
999
- case "qwik":
1000
- case "reactNative":
1001
- case "react":
1002
- case "rsc":
1003
- return style;
1004
- }
1005
- }
1006
-
1007
- // src/components/block/block.helpers.ts
1008
- var checkIsComponentRestricted = (component, model) => {
1009
- if (!component)
1010
- return true;
1011
- if (!model)
1012
- return false;
1013
- return component.models && component.models.length > 0 && !component.models.includes(model);
1014
- };
1015
- var getComponent = ({
1016
- block,
1017
- registeredComponents,
1018
- model
1019
- }) => {
1020
- const componentName = block.component?.name;
1021
- if (!componentName) {
1022
- return null;
1023
- }
1024
- const ref = registeredComponents[componentName];
1025
- if (!ref || checkIsComponentRestricted(ref, model)) {
1026
- console.warn(`
1027
- Could not find a registered component named "${componentName}".
1028
- If you registered it, is the file that registered it imported by the file that needs to render it?`);
1029
- return void 0;
1030
- } else {
1031
- return ref;
1032
- }
1033
- };
1034
- var getRepeatItemData = ({
1035
- block,
1036
- context
1037
- }) => {
1038
- const {
1039
- repeat,
1040
- ...blockWithoutRepeat
1041
- } = block;
1042
- if (!repeat?.collection) {
1043
- return void 0;
1044
- }
1045
- const itemsArray = evaluate({
1046
- code: repeat.collection,
1047
- localState: context.localState,
1048
- rootState: context.rootState,
1049
- rootSetState: context.rootSetState,
1050
- context: context.context
1051
- });
1052
- if (!Array.isArray(itemsArray)) {
1053
- return void 0;
1054
- }
1055
- const collectionName = repeat.collection.split(".").pop();
1056
- const itemNameToUse = repeat.itemName || (collectionName ? collectionName + "Item" : "item");
1057
- const repeatArray = itemsArray.map((item, index) => ({
1058
- context: {
1059
- ...context,
1060
- localState: {
1061
- ...context.localState,
1062
- $index: index,
1063
- $item: item,
1064
- [itemNameToUse]: item,
1065
- [`$${itemNameToUse}Index`]: index
1066
- }
1067
- },
1068
- block: blockWithoutRepeat
1069
- }));
1070
- return repeatArray;
1071
- };
1072
- var provideLinkComponent = (block, linkComponent) => {
1073
- if (block?.shouldReceiveBuilderProps?.builderLinkComponent)
1074
- return {
1075
- builderLinkComponent: linkComponent
1076
- };
1077
- return {};
1078
- };
1079
- var provideRegisteredComponents = (block, registeredComponents, model) => {
1080
- if (block?.shouldReceiveBuilderProps?.builderComponents) {
1081
- const filteredRegisteredComponents = Object.fromEntries(Object.entries(registeredComponents).filter(([_, component]) => {
1082
- return !checkIsComponentRestricted(component, model);
1083
- }));
1084
- return {
1085
- builderComponents: filteredRegisteredComponents
1086
- };
1087
- }
1088
- return {};
1089
- };
1090
- var provideBuilderBlock = (block, builderBlock) => {
1091
- if (block?.shouldReceiveBuilderProps?.builderBlock)
1092
- return {
1093
- builderBlock
1094
- };
1095
- return {};
1096
- };
1097
- var provideBuilderContext = (block, context) => {
1098
- if (block?.shouldReceiveBuilderProps?.builderContext)
1099
- return {
1100
- builderContext: context
1101
- };
1102
- return {};
1103
- };
1104
- var generateKey = (index) => {
1105
- return index.toString();
1106
- };
1107
-
1108
- // src/functions/event-handler-name.ts
1109
- function capitalizeFirstLetter(string) {
1110
- return string.charAt(0).toUpperCase() + string.slice(1);
1111
- }
1112
- var getEventHandlerName = (key) => `on${capitalizeFirstLetter(key)}`;
1113
-
1114
- // src/functions/get-block-actions-handler.ts
1115
- var createEventHandler = (value, options) => (event) => evaluate({
1116
- code: value,
1117
- context: options.context,
1118
- localState: options.localState,
1119
- rootState: options.rootState,
1120
- rootSetState: options.rootSetState,
1121
- event,
1122
- isExpression: false
1123
- });
1124
-
1125
- // src/functions/get-block-actions.ts
1126
- function getBlockActions(options) {
1127
- const obj = {};
1128
- const optionActions = options.block.actions ?? {};
1129
- for (const key in optionActions) {
1130
- if (!optionActions.hasOwnProperty(key)) {
1131
- continue;
1132
- }
1133
- const value = optionActions[key];
1134
- let eventHandlerName = getEventHandlerName(key);
1135
- if (options.stripPrefix) {
1136
- switch (TARGET) {
1137
- case "vue":
1138
- eventHandlerName = eventHandlerName.replace("v-on:", "");
1139
- break;
1140
- case "svelte":
1141
- eventHandlerName = eventHandlerName.replace("on:", "");
1142
- break;
1143
- }
1144
- }
1145
- obj[eventHandlerName] = createEventHandler(value, options);
1146
- }
1147
- return obj;
1148
- }
1149
-
1150
- // src/functions/transform-block-properties.ts
1151
- function transformBlockProperties({
1152
- properties
1153
- }) {
1154
- return properties;
1155
- }
1156
-
1157
- // src/functions/get-block-properties.ts
1158
- var extractRelevantRootBlockProperties = (block) => {
1159
- return {
1160
- href: block.href
1161
- };
1162
- };
1163
- function getBlockProperties({
1164
- block,
1165
- context
1166
- }) {
1167
- const properties = {
1168
- ...extractRelevantRootBlockProperties(block),
1169
- ...block.properties,
1170
- "builder-id": block.id,
1171
- style: getStyle({
1172
- block,
1173
- context
1174
- }),
1175
- [getClassPropName()]: [block.id, "builder-block", block.class, block.properties?.class].filter(Boolean).join(" ")
1176
- };
1177
- return transformBlockProperties({
1178
- properties,
1179
- context,
1180
- block
1181
- });
1182
- }
1183
-
1184
- // src/components/block/components/block-wrapper.tsx
1185
- function BlockWrapper(props) {
1186
- return <><Dynamic_renderer_default
1187
- TagName={props.Wrapper}
1188
- attributes={getBlockProperties({
1189
- block: props.block,
1190
- context: props.context
1191
- })}
1192
- actionAttributes={getBlockActions({
1193
- block: props.block,
1194
- rootState: props.context.rootState,
1195
- rootSetState: props.context.rootSetState,
1196
- localState: props.context.localState,
1197
- context: props.context.context,
1198
- stripPrefix: true
1199
- })}
1200
- >{props.children}</Dynamic_renderer_default></>;
1201
- }
1202
- var Block_wrapper_default = BlockWrapper;
1203
-
1204
- // src/components/block/components/component-ref/component-ref.tsx
1205
- import { Show as Show3, For, createSignal as createSignal3 } from "solid-js";
1206
- import { Dynamic as Dynamic4 } from "solid-js/web";
1207
-
1208
- // src/components/block/components/interactive-element.tsx
1209
- import { Show as Show2, on, createEffect, createMemo as createMemo2, createSignal as createSignal2 } from "solid-js";
1210
- import { Dynamic as Dynamic3 } from "solid-js/web";
1211
-
1212
- // src/functions/is-previewing.ts
1213
- function isPreviewing(search) {
1214
- const searchToUse = search || (isBrowser() ? window.location.search : void 0);
1215
- if (!searchToUse) {
1216
- return false;
1217
- }
1218
- const normalizedSearch = getSearchString(searchToUse);
1219
- return Boolean(normalizedSearch.indexOf("builder.preview=") !== -1);
1220
- }
1221
-
1222
- // src/functions/register-component.ts
1223
- var createRegisterComponentMessage = (info) => ({
1224
- type: "builder.registerComponent",
1225
- data: serializeIncludingFunctions(info)
1226
- });
1227
- var serializeFn = (fnValue) => {
1228
- const fnStr = fnValue.toString().trim();
1229
- const isArrowWithoutParens = /^[a-zA-Z0-9_]+\s*=>/i.test(fnStr);
1230
- const appendFunction = !fnStr.startsWith("function") && !fnStr.startsWith("async") && !fnStr.startsWith("(") && !isArrowWithoutParens;
1231
- return `return (${appendFunction ? "function " : ""}${fnStr}).apply(this, arguments)`;
1232
- };
1233
- function serializeIncludingFunctions(info) {
1234
- return JSON.parse(JSON.stringify(info, (key, value) => {
1235
- if (typeof value === "function") {
1236
- return serializeFn(value);
1083
+ context = args = null;
1084
+ } else if (!timeout && options.trailing !== false) {
1085
+ timeout = setTimeout(later, remaining);
1237
1086
  }
1238
- return value;
1239
- }));
1087
+ return result;
1088
+ };
1240
1089
  }
1241
-
1242
- // src/functions/register.ts
1243
- var registry = {};
1244
- function register(type, info) {
1245
- if (type === "plugin") {
1246
- info = serializeIncludingFunctions(info);
1247
- }
1248
- let typeList = registry[type];
1249
- if (!typeList) {
1250
- typeList = registry[type] = [];
1251
- }
1252
- typeList.push(info);
1253
- if (isBrowser()) {
1254
- const message = {
1255
- type: "builder.register",
1256
- data: {
1257
- type,
1258
- info
1259
- }
1260
- };
1261
- try {
1262
- parent.postMessage(message, "*");
1263
- if (parent !== window) {
1264
- window.postMessage(message, "*");
1090
+ function assign(target, ..._args) {
1091
+ const to = Object(target);
1092
+ for (let index = 1; index < arguments.length; index++) {
1093
+ const nextSource = arguments[index];
1094
+ if (nextSource != null) {
1095
+ for (const nextKey in nextSource) {
1096
+ if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
1097
+ to[nextKey] = nextSource[nextKey];
1098
+ }
1265
1099
  }
1266
- } catch (err) {
1267
- console.debug("Could not postmessage", err);
1268
1100
  }
1269
1101
  }
1102
+ return to;
1270
1103
  }
1271
- function registerAction(action) {
1272
- if (isBrowser()) {
1273
- const actionClone = JSON.parse(JSON.stringify(action));
1274
- if (action.action) {
1275
- actionClone.action = action.action.toString();
1104
+ function bindAnimations(animations) {
1105
+ if (TARGET === "reactNative") {
1106
+ return;
1107
+ }
1108
+ for (const animation of animations) {
1109
+ switch (animation.trigger) {
1110
+ case "pageLoad":
1111
+ triggerAnimation(animation);
1112
+ break;
1113
+ case "scrollInView":
1114
+ bindScrollInViewAnimation(animation);
1115
+ break;
1276
1116
  }
1277
- window.parent?.postMessage({
1278
- type: "builder.registerAction",
1279
- data: actionClone
1280
- }, "*");
1281
1117
  }
1282
1118
  }
1283
-
1284
- // src/functions/set-editor-settings.ts
1285
- var settings = {};
1286
- function setEditorSettings(newSettings) {
1287
- if (isBrowser()) {
1288
- Object.assign(settings, newSettings);
1289
- const message = {
1290
- type: "builder.settingsChange",
1291
- data: settings
1292
- };
1293
- parent.postMessage(message, "*");
1294
- }
1119
+ function warnElementNotPresent(id) {
1120
+ console.warn(`Cannot animate element: element with ID ${id} not found!`);
1295
1121
  }
1296
-
1297
- // src/functions/get-builder-search-params/index.ts
1298
- var BUILDER_SEARCHPARAMS_PREFIX = "builder.";
1299
- var BUILDER_OPTIONS_PREFIX = "options.";
1300
- var getBuilderSearchParams = (_options) => {
1301
- if (!_options) {
1302
- return {};
1122
+ function augmentAnimation(animation, element) {
1123
+ const stylesUsed = getAllStylesUsed(animation);
1124
+ const computedStyle = getComputedStyle(element);
1125
+ const firstStyles = animation.steps[0].styles;
1126
+ const lastStyles = animation.steps[animation.steps.length - 1].styles;
1127
+ const bothStyles = [firstStyles, lastStyles];
1128
+ for (const styles of bothStyles) {
1129
+ for (const style of stylesUsed) {
1130
+ if (!(style in styles)) {
1131
+ styles[style] = computedStyle[style];
1132
+ }
1133
+ }
1303
1134
  }
1304
- const options = normalizeSearchParams(_options);
1305
- const newOptions = {};
1306
- Object.keys(options).forEach((key) => {
1307
- if (key.startsWith(BUILDER_SEARCHPARAMS_PREFIX)) {
1308
- const trimmedKey = key.replace(BUILDER_SEARCHPARAMS_PREFIX, "").replace(BUILDER_OPTIONS_PREFIX, "");
1309
- newOptions[trimmedKey] = options[key];
1135
+ }
1136
+ function getAllStylesUsed(animation) {
1137
+ const properties = [];
1138
+ for (const step of animation.steps) {
1139
+ for (const key in step.styles) {
1140
+ if (properties.indexOf(key) === -1) {
1141
+ properties.push(key);
1142
+ }
1310
1143
  }
1311
- });
1312
- return newOptions;
1313
- };
1314
- var getBuilderSearchParamsFromWindow = () => {
1315
- if (!isBrowser()) {
1316
- return {};
1317
1144
  }
1318
- const searchParams = new URLSearchParams(window.location.search);
1319
- return getBuilderSearchParams(searchParams);
1320
- };
1321
-
1322
- // src/constants/sdk-version.ts
1323
- var SDK_VERSION = "5.0.1";
1324
-
1325
- // src/helpers/sdk-headers.ts
1326
- var getSdkHeaders = () => ({
1327
- "X-Builder-SDK": TARGET,
1328
- "X-Builder-SDK-GEN": "2",
1329
- "X-Builder-SDK-Version": SDK_VERSION
1330
- });
1331
-
1332
- // src/helpers/url.ts
1333
- var getTopLevelDomain = (host) => {
1334
- if (host === "localhost" || host === "127.0.0.1") {
1335
- return host;
1145
+ return properties;
1146
+ }
1147
+ function triggerAnimation(animation) {
1148
+ const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
1149
+ if (!elements.length) {
1150
+ warnElementNotPresent(animation.elementId || animation.id || "");
1151
+ return;
1336
1152
  }
1337
- const parts = host.split(".");
1338
- if (parts.length > 2) {
1339
- return parts.slice(1).join(".");
1153
+ Array.from(elements).forEach((element) => {
1154
+ augmentAnimation(animation, element);
1155
+ element.style.transition = "none";
1156
+ element.style.transitionDelay = "0";
1157
+ assign(element.style, animation.steps[0].styles);
1158
+ setTimeout(() => {
1159
+ element.style.transition = `all ${animation.duration}s ${camelToKebabCase(animation.easing)}`;
1160
+ if (animation.delay) {
1161
+ element.style.transitionDelay = animation.delay + "s";
1162
+ }
1163
+ assign(element.style, animation.steps[1].styles);
1164
+ setTimeout(() => {
1165
+ element.style.transition = "";
1166
+ element.style.transitionDelay = "";
1167
+ }, (animation.delay || 0) * 1e3 + animation.duration * 1e3 + 100);
1168
+ });
1169
+ });
1170
+ }
1171
+ function bindScrollInViewAnimation(animation) {
1172
+ const elements = Array.prototype.slice.call(document.getElementsByClassName(animation.elementId || animation.id || ""));
1173
+ if (!elements.length) {
1174
+ warnElementNotPresent(animation.elementId || animation.id || "");
1175
+ return;
1340
1176
  }
1341
- return host;
1342
- };
1343
-
1344
- // src/helpers/cookie.ts
1345
- var getCookieSync = ({
1346
- name,
1347
- canTrack
1348
- }) => {
1349
- try {
1350
- if (!canTrack) {
1351
- return void 0;
1177
+ Array.from(elements).forEach((element) => {
1178
+ augmentAnimation(animation, element);
1179
+ let triggered = false;
1180
+ let pendingAnimation = false;
1181
+ function immediateOnScroll() {
1182
+ if (!triggered && isScrolledIntoView(element)) {
1183
+ triggered = true;
1184
+ pendingAnimation = true;
1185
+ setTimeout(() => {
1186
+ assign(element.style, animation.steps[1].styles);
1187
+ if (!animation.repeat) {
1188
+ document.removeEventListener("scroll", onScroll);
1189
+ }
1190
+ setTimeout(() => {
1191
+ pendingAnimation = false;
1192
+ if (!animation.repeat) {
1193
+ element.style.transition = "";
1194
+ element.style.transitionDelay = "";
1195
+ }
1196
+ }, (animation.duration + (animation.delay || 0)) * 1e3 + 100);
1197
+ });
1198
+ } else if (animation.repeat && triggered && !pendingAnimation && !isScrolledIntoView(element)) {
1199
+ triggered = false;
1200
+ assign(element.style, animation.steps[0].styles);
1201
+ }
1352
1202
  }
1353
- return document.cookie.split("; ").find((row) => row.startsWith(`${name}=`))?.split("=")[1];
1354
- } catch (err) {
1355
- logger.warn("[COOKIE] GET error: ", err?.message || err);
1356
- return void 0;
1357
- }
1358
- };
1359
- var getCookie = async (args) => getCookieSync(args);
1360
- var stringifyCookie = (cookie) => cookie.map(([key, value]) => value ? `${key}=${value}` : key).filter(checkIsDefined).join("; ");
1361
- var SECURE_CONFIG = [["secure", ""], ["SameSite", "None"]];
1362
- var createCookieString = ({
1363
- name,
1364
- value,
1365
- expires
1366
- }) => {
1367
- const secure = isBrowser() ? location.protocol === "https:" : true;
1368
- const secureObj = secure ? SECURE_CONFIG : [[]];
1369
- const expiresObj = expires ? [["expires", expires.toUTCString()]] : [[]];
1370
- const cookieValue = [[name, value], ...expiresObj, ["path", "/"], ["domain", getTopLevelDomain(window.location.hostname)], ...secureObj];
1371
- const cookie = stringifyCookie(cookieValue);
1372
- return cookie;
1373
- };
1374
- var setCookie = async ({
1375
- name,
1376
- value,
1377
- expires,
1378
- canTrack
1379
- }) => {
1380
- try {
1381
- if (!canTrack) {
1382
- return;
1203
+ const onScroll = throttle(immediateOnScroll, 200, {
1204
+ leading: false
1205
+ });
1206
+ function isScrolledIntoView(elem) {
1207
+ const rect = elem.getBoundingClientRect();
1208
+ const windowHeight = window.innerHeight;
1209
+ const thresholdPercent = (animation.thresholdPercent || 0) / 100;
1210
+ const threshold = thresholdPercent * windowHeight;
1211
+ return rect.bottom > threshold && rect.top < windowHeight - threshold;
1383
1212
  }
1384
- const cookie = createCookieString({
1385
- name,
1386
- value,
1387
- expires
1213
+ const defaultState = animation.steps[0].styles;
1214
+ function attachDefaultState() {
1215
+ assign(element.style, defaultState);
1216
+ }
1217
+ attachDefaultState();
1218
+ setTimeout(() => {
1219
+ element.style.transition = `all ${animation.duration}s ${camelToKebabCase(animation.easing)}`;
1220
+ if (animation.delay) {
1221
+ element.style.transitionDelay = animation.delay + "s";
1222
+ }
1388
1223
  });
1389
- document.cookie = cookie;
1390
- } catch (err) {
1391
- logger.warn("[COOKIE] SET error: ", err?.message || err);
1392
- }
1393
- };
1394
-
1395
- // src/helpers/uuid.ts
1396
- function uuidv4() {
1397
- return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
1398
- const r = Math.random() * 16 | 0, v = c == "x" ? r : r & 3 | 8;
1399
- return v.toString(16);
1224
+ document.addEventListener("scroll", onScroll, {
1225
+ capture: true,
1226
+ passive: true
1227
+ });
1228
+ immediateOnScroll();
1400
1229
  });
1401
1230
  }
1402
- function uuid() {
1403
- return uuidv4().replace(/-/g, "");
1404
- }
1405
1231
 
1406
- // src/helpers/sessionId.ts
1407
- var SESSION_LOCAL_STORAGE_KEY = "builderSessionId";
1408
- var getSessionId = async ({
1409
- canTrack
1410
- }) => {
1411
- if (!canTrack) {
1412
- return void 0;
1413
- }
1414
- const sessionId = await getCookie({
1415
- name: SESSION_LOCAL_STORAGE_KEY,
1416
- canTrack
1232
+ // src/helpers/css.ts
1233
+ var convertStyleMapToCSSArray = (style) => {
1234
+ const cssProps = Object.entries(style).map(([key, value]) => {
1235
+ if (typeof value === "string") {
1236
+ return `${camelToKebabCase(key)}: ${value};`;
1237
+ } else {
1238
+ return void 0;
1239
+ }
1417
1240
  });
1418
- if (checkIsDefined(sessionId)) {
1419
- return sessionId;
1241
+ return cssProps.filter(checkIsDefined);
1242
+ };
1243
+ var convertStyleMapToCSS = (style) => convertStyleMapToCSSArray(style).join("\n");
1244
+ var createCssClass = ({
1245
+ mediaQuery,
1246
+ className,
1247
+ styles
1248
+ }) => {
1249
+ const cssClass = `.${className} {
1250
+ ${convertStyleMapToCSS(styles)}
1251
+ }`;
1252
+ if (mediaQuery) {
1253
+ return `${mediaQuery} {
1254
+ ${cssClass}
1255
+ }`;
1420
1256
  } else {
1421
- const newSessionId = createSessionId();
1422
- setSessionId({
1423
- id: newSessionId,
1424
- canTrack
1425
- });
1426
- return newSessionId;
1257
+ return cssClass;
1427
1258
  }
1428
1259
  };
1429
- var createSessionId = () => uuid();
1430
- var setSessionId = ({
1431
- id,
1432
- canTrack
1433
- }) => setCookie({
1434
- name: SESSION_LOCAL_STORAGE_KEY,
1435
- value: id,
1436
- canTrack
1437
- });
1438
1260
 
1439
- // src/helpers/localStorage.ts
1440
- var getLocalStorage = () => isBrowser() && typeof localStorage !== "undefined" ? localStorage : void 0;
1441
- var getLocalStorageItem = ({
1442
- key,
1443
- canTrack
1261
+ // src/functions/transform-style-property.ts
1262
+ function transformStyleProperty({
1263
+ style
1264
+ }) {
1265
+ return style;
1266
+ }
1267
+
1268
+ // src/functions/get-style.ts
1269
+ var getStyle = ({
1270
+ block,
1271
+ context
1444
1272
  }) => {
1445
- try {
1446
- if (canTrack) {
1447
- return getLocalStorage()?.getItem(key);
1448
- }
1449
- return void 0;
1450
- } catch (err) {
1451
- console.debug("[LocalStorage] GET error: ", err);
1452
- return void 0;
1273
+ return mapStyleObjToStrIfNeeded(transformStyleProperty({
1274
+ style: block.style || {},
1275
+ context,
1276
+ block
1277
+ }));
1278
+ };
1279
+ function mapStyleObjToStrIfNeeded(style) {
1280
+ switch (TARGET) {
1281
+ case "svelte":
1282
+ case "vue":
1283
+ case "solid":
1284
+ case "angular":
1285
+ return convertStyleMapToCSSArray(style).join(" ");
1286
+ case "qwik":
1287
+ case "reactNative":
1288
+ case "react":
1289
+ case "rsc":
1290
+ return style;
1453
1291
  }
1292
+ }
1293
+
1294
+ // src/components/block/block.helpers.ts
1295
+ var checkIsComponentRestricted = (component, model) => {
1296
+ if (!component)
1297
+ return true;
1298
+ if (!model)
1299
+ return false;
1300
+ return component.models && component.models.length > 0 && !component.models.includes(model);
1454
1301
  };
1455
- var setLocalStorageItem = ({
1456
- key,
1457
- canTrack,
1458
- value
1302
+ var getComponent = ({
1303
+ block,
1304
+ registeredComponents,
1305
+ model
1459
1306
  }) => {
1460
- try {
1461
- if (canTrack) {
1462
- getLocalStorage()?.setItem(key, value);
1463
- }
1464
- } catch (err) {
1465
- console.debug("[LocalStorage] SET error: ", err);
1307
+ const componentName = block.component?.name;
1308
+ if (!componentName) {
1309
+ return null;
1310
+ }
1311
+ const ref = registeredComponents[componentName];
1312
+ if (!ref || checkIsComponentRestricted(ref, model)) {
1313
+ console.warn(`
1314
+ Could not find a registered component named "${componentName}".
1315
+ If you registered it, is the file that registered it imported by the file that needs to render it?`);
1316
+ return void 0;
1317
+ } else {
1318
+ return ref;
1466
1319
  }
1467
1320
  };
1468
-
1469
- // src/helpers/visitorId.ts
1470
- var VISITOR_LOCAL_STORAGE_KEY = "builderVisitorId";
1471
- var getVisitorId = ({
1472
- canTrack
1321
+ var getRepeatItemData = ({
1322
+ block,
1323
+ context
1473
1324
  }) => {
1474
- if (!canTrack) {
1325
+ const {
1326
+ repeat,
1327
+ ...blockWithoutRepeat
1328
+ } = block;
1329
+ if (!repeat?.collection) {
1475
1330
  return void 0;
1476
1331
  }
1477
- const visitorId = getLocalStorageItem({
1478
- key: VISITOR_LOCAL_STORAGE_KEY,
1479
- canTrack
1332
+ const itemsArray = evaluate({
1333
+ code: repeat.collection,
1334
+ localState: context.localState,
1335
+ rootState: context.rootState,
1336
+ rootSetState: context.rootSetState,
1337
+ context: context.context
1480
1338
  });
1481
- if (checkIsDefined(visitorId)) {
1482
- return visitorId;
1483
- } else {
1484
- const newVisitorId = createVisitorId();
1485
- setVisitorId({
1486
- id: newVisitorId,
1487
- canTrack
1488
- });
1489
- return newVisitorId;
1339
+ if (!Array.isArray(itemsArray)) {
1340
+ return void 0;
1341
+ }
1342
+ const collectionName = repeat.collection.split(".").pop();
1343
+ const itemNameToUse = repeat.itemName || (collectionName ? collectionName + "Item" : "item");
1344
+ const repeatArray = itemsArray.map((item, index) => ({
1345
+ context: {
1346
+ ...context,
1347
+ localState: {
1348
+ ...context.localState,
1349
+ $index: index,
1350
+ $item: item,
1351
+ [itemNameToUse]: item,
1352
+ [`$${itemNameToUse}Index`]: index
1353
+ }
1354
+ },
1355
+ block: blockWithoutRepeat
1356
+ }));
1357
+ return repeatArray;
1358
+ };
1359
+ var provideLinkComponent = (block, linkComponent) => {
1360
+ if (block?.shouldReceiveBuilderProps?.builderLinkComponent)
1361
+ return {
1362
+ builderLinkComponent: linkComponent
1363
+ };
1364
+ return {};
1365
+ };
1366
+ var provideRegisteredComponents = (block, registeredComponents, model) => {
1367
+ if (block?.shouldReceiveBuilderProps?.builderComponents) {
1368
+ const filteredRegisteredComponents = Object.fromEntries(Object.entries(registeredComponents).filter(([_, component]) => {
1369
+ return !checkIsComponentRestricted(component, model);
1370
+ }));
1371
+ return {
1372
+ builderComponents: filteredRegisteredComponents
1373
+ };
1490
1374
  }
1375
+ return {};
1491
1376
  };
1492
- var createVisitorId = () => uuid();
1493
- var setVisitorId = ({
1494
- id,
1495
- canTrack
1496
- }) => setLocalStorageItem({
1497
- key: VISITOR_LOCAL_STORAGE_KEY,
1498
- value: id,
1499
- canTrack
1377
+ var provideBuilderBlock = (block, builderBlock) => {
1378
+ if (block?.shouldReceiveBuilderProps?.builderBlock)
1379
+ return {
1380
+ builderBlock
1381
+ };
1382
+ return {};
1383
+ };
1384
+ var provideBuilderContext = (block, context) => {
1385
+ if (block?.shouldReceiveBuilderProps?.builderContext)
1386
+ return {
1387
+ builderContext: context
1388
+ };
1389
+ return {};
1390
+ };
1391
+ var generateKey = (index) => {
1392
+ return index.toString();
1393
+ };
1394
+
1395
+ // src/functions/event-handler-name.ts
1396
+ function capitalizeFirstLetter(string) {
1397
+ return string.charAt(0).toUpperCase() + string.slice(1);
1398
+ }
1399
+ var getEventHandlerName = (key) => `on${capitalizeFirstLetter(key)}`;
1400
+
1401
+ // src/functions/get-block-actions-handler.ts
1402
+ var createEventHandler = (value, options) => (event) => evaluate({
1403
+ code: value,
1404
+ context: options.context,
1405
+ localState: options.localState,
1406
+ rootState: options.rootState,
1407
+ rootSetState: options.rootSetState,
1408
+ event,
1409
+ isExpression: false,
1410
+ trackingContext: options.trackingContext
1500
1411
  });
1501
1412
 
1502
- // src/functions/log-fetch.ts
1503
- function logFetch(url) {
1504
- if (typeof process !== "undefined" && process.env?.DEBUG) {
1505
- if (String(process.env.DEBUG) == "true") {
1506
- logger.log(url);
1413
+ // src/functions/get-block-actions.ts
1414
+ function getBlockActions(options) {
1415
+ const obj = {};
1416
+ const optionActions = options.block.actions ?? {};
1417
+ for (const key in optionActions) {
1418
+ if (!optionActions.hasOwnProperty(key)) {
1419
+ continue;
1420
+ }
1421
+ const value = optionActions[key];
1422
+ let eventHandlerName = getEventHandlerName(key);
1423
+ if (options.stripPrefix) {
1424
+ switch (TARGET) {
1425
+ case "vue":
1426
+ eventHandlerName = eventHandlerName.replace("v-on:", "");
1427
+ break;
1428
+ case "svelte":
1429
+ eventHandlerName = eventHandlerName.replace("on:", "");
1430
+ break;
1431
+ }
1507
1432
  }
1433
+ obj[eventHandlerName] = createEventHandler(value, options);
1508
1434
  }
1435
+ return obj;
1509
1436
  }
1510
1437
 
1511
- // src/functions/track/index.ts
1512
- var getTrackingEventData = async ({
1513
- canTrack
1514
- }) => {
1515
- if (!canTrack) {
1516
- return {
1517
- visitorId: void 0,
1518
- sessionId: void 0
1519
- };
1520
- }
1521
- const sessionId = await getSessionId({
1522
- canTrack
1523
- });
1524
- const visitorId = getVisitorId({
1525
- canTrack
1526
- });
1438
+ // src/functions/transform-block-properties.ts
1439
+ function transformBlockProperties({
1440
+ properties
1441
+ }) {
1442
+ return properties;
1443
+ }
1444
+
1445
+ // src/functions/get-block-properties.ts
1446
+ var extractRelevantRootBlockProperties = (block) => {
1527
1447
  return {
1528
- sessionId,
1529
- visitorId
1448
+ href: block.href
1530
1449
  };
1531
1450
  };
1532
- var createEvent = async ({
1533
- type: eventType,
1534
- canTrack,
1535
- apiKey,
1536
- metadata,
1537
- ...properties
1538
- }) => ({
1539
- type: eventType,
1540
- data: {
1541
- ...properties,
1542
- metadata: {
1543
- url: location.href,
1544
- ...metadata
1545
- },
1546
- ...await getTrackingEventData({
1547
- canTrack
1451
+ function getBlockProperties({
1452
+ block,
1453
+ context
1454
+ }) {
1455
+ const properties = {
1456
+ ...extractRelevantRootBlockProperties(block),
1457
+ ...block.properties,
1458
+ "builder-id": block.id,
1459
+ style: getStyle({
1460
+ block,
1461
+ context
1548
1462
  }),
1549
- userAttributes: getUserAttributes(),
1550
- ownerId: apiKey
1463
+ [getClassPropName()]: [block.id, "builder-block", block.class, block.properties?.class].filter(Boolean).join(" ")
1464
+ };
1465
+ return transformBlockProperties({
1466
+ properties,
1467
+ context,
1468
+ block
1469
+ });
1470
+ }
1471
+
1472
+ // src/components/block/components/block-wrapper.tsx
1473
+ function BlockWrapper(props) {
1474
+ return <><Dynamic_renderer_default
1475
+ TagName={props.Wrapper}
1476
+ attributes={getBlockProperties({
1477
+ block: props.block,
1478
+ context: props.context
1479
+ })}
1480
+ actionAttributes={getBlockActions({
1481
+ block: props.block,
1482
+ rootState: props.context.rootState,
1483
+ rootSetState: props.context.rootSetState,
1484
+ localState: props.context.localState,
1485
+ context: props.context.context,
1486
+ stripPrefix: true,
1487
+ trackingContext: {
1488
+ apiKey: props.context.apiKey,
1489
+ canTrack: props.context.canTrack ?? true,
1490
+ contentId: props.context.content?.id,
1491
+ variationId: props.context.content?.testVariationId
1492
+ }
1493
+ })}
1494
+ >{props.children}</Dynamic_renderer_default></>;
1495
+ }
1496
+ var Block_wrapper_default = BlockWrapper;
1497
+
1498
+ // src/components/block/components/component-ref/component-ref.tsx
1499
+ import { Show as Show3, For, createSignal as createSignal3 } from "solid-js";
1500
+ import { Dynamic as Dynamic4 } from "solid-js/web";
1501
+
1502
+ // src/components/block/components/interactive-element.tsx
1503
+ import { Show as Show2, on, createEffect, createMemo as createMemo2, createSignal as createSignal2 } from "solid-js";
1504
+ import { Dynamic as Dynamic3 } from "solid-js/web";
1505
+
1506
+ // src/functions/is-previewing.ts
1507
+ function isPreviewing(search) {
1508
+ const searchToUse = search || (isBrowser() ? window.location.search : void 0);
1509
+ if (!searchToUse) {
1510
+ return false;
1551
1511
  }
1512
+ const normalizedSearch = getSearchString(searchToUse);
1513
+ return Boolean(normalizedSearch.indexOf("builder.preview=") !== -1);
1514
+ }
1515
+
1516
+ // src/functions/register-component.ts
1517
+ var createRegisterComponentMessage = (info) => ({
1518
+ type: "builder.registerComponent",
1519
+ data: serializeIncludingFunctions(info)
1552
1520
  });
1553
- async function _track({
1554
- apiHost,
1555
- ...eventProps
1556
- }) {
1557
- if (!eventProps.apiKey) {
1558
- logger.error("Missing API key for track call. Please provide your API key.");
1559
- return;
1521
+ var serializeFn = (fnValue) => {
1522
+ const fnStr = fnValue.toString().trim();
1523
+ const isArrowWithoutParens = /^[a-zA-Z0-9_]+\s*=>/i.test(fnStr);
1524
+ const appendFunction = !fnStr.startsWith("function") && !fnStr.startsWith("async") && !fnStr.startsWith("(") && !isArrowWithoutParens;
1525
+ return `return (${appendFunction ? "function " : ""}${fnStr}).apply(this, arguments)`;
1526
+ };
1527
+ function serializeIncludingFunctions(info) {
1528
+ return JSON.parse(JSON.stringify(info, (key, value) => {
1529
+ if (typeof value === "function") {
1530
+ return serializeFn(value);
1531
+ }
1532
+ return value;
1533
+ }));
1534
+ }
1535
+
1536
+ // src/functions/register.ts
1537
+ var registry = {};
1538
+ function register(type, info) {
1539
+ if (type === "plugin") {
1540
+ info = serializeIncludingFunctions(info);
1560
1541
  }
1561
- if (!eventProps.canTrack) {
1562
- return;
1542
+ let typeList = registry[type];
1543
+ if (!typeList) {
1544
+ typeList = registry[type] = [];
1563
1545
  }
1564
- if (isEditing()) {
1565
- return;
1546
+ typeList.push(info);
1547
+ if (isBrowser()) {
1548
+ const message = {
1549
+ type: "builder.register",
1550
+ data: {
1551
+ type,
1552
+ info
1553
+ }
1554
+ };
1555
+ try {
1556
+ parent.postMessage(message, "*");
1557
+ if (parent !== window) {
1558
+ window.postMessage(message, "*");
1559
+ }
1560
+ } catch (err) {
1561
+ console.debug("Could not postmessage", err);
1562
+ }
1566
1563
  }
1567
- if (!(isBrowser() || TARGET === "reactNative")) {
1568
- return;
1564
+ }
1565
+ function registerAction(action) {
1566
+ if (isBrowser()) {
1567
+ const actionClone = JSON.parse(JSON.stringify(action));
1568
+ if (action.action) {
1569
+ actionClone.action = action.action.toString();
1570
+ }
1571
+ window.parent?.postMessage({
1572
+ type: "builder.registerAction",
1573
+ data: actionClone
1574
+ }, "*");
1569
1575
  }
1570
- const baseUrl = apiHost || "https://cdn.builder.io";
1571
- const url = `${baseUrl}/api/v1/track`;
1572
- logFetch(url);
1573
- return fetch(url, {
1574
- method: "POST",
1575
- body: JSON.stringify({
1576
- events: [await createEvent(eventProps)]
1577
- }),
1578
- headers: {
1579
- "content-type": "application/json",
1580
- ...getSdkHeaders()
1581
- },
1582
- mode: "cors"
1583
- }).catch((err) => {
1584
- console.error("Failed to track: ", err);
1585
- });
1586
1576
  }
1587
- var track = (args) => _track({
1588
- ...args,
1589
- canTrack: true
1590
- });
1577
+
1578
+ // src/functions/set-editor-settings.ts
1579
+ var settings = {};
1580
+ function setEditorSettings(newSettings) {
1581
+ if (isBrowser()) {
1582
+ Object.assign(settings, newSettings);
1583
+ const message = {
1584
+ type: "builder.settingsChange",
1585
+ data: settings
1586
+ };
1587
+ parent.postMessage(message, "*");
1588
+ }
1589
+ }
1590
+
1591
+ // src/functions/get-builder-search-params/index.ts
1592
+ var BUILDER_SEARCHPARAMS_PREFIX = "builder.";
1593
+ var BUILDER_OPTIONS_PREFIX = "options.";
1594
+ var getBuilderSearchParams = (_options) => {
1595
+ if (!_options) {
1596
+ return {};
1597
+ }
1598
+ const options = normalizeSearchParams(_options);
1599
+ const newOptions = {};
1600
+ Object.keys(options).forEach((key) => {
1601
+ if (key.startsWith(BUILDER_SEARCHPARAMS_PREFIX)) {
1602
+ const trimmedKey = key.replace(BUILDER_SEARCHPARAMS_PREFIX, "").replace(BUILDER_OPTIONS_PREFIX, "");
1603
+ newOptions[trimmedKey] = options[key];
1604
+ }
1605
+ });
1606
+ return newOptions;
1607
+ };
1608
+ var getBuilderSearchParamsFromWindow = () => {
1609
+ if (!isBrowser()) {
1610
+ return {};
1611
+ }
1612
+ const searchParams = new URLSearchParams(window.location.search);
1613
+ return getBuilderSearchParams(searchParams);
1614
+ };
1591
1615
 
1592
1616
  // src/functions/is-from-trusted-host.ts
1593
1617
  var DEFAULT_TRUSTED_HOSTS = ["*.beta.builder.io", "beta.builder.io", "builder.io", "localhost", "qa.builder.io"];
@@ -2331,7 +2355,13 @@ function InteractiveElement(props) {
2331
2355
  rootState: props.context.rootState,
2332
2356
  rootSetState: props.context.rootSetState,
2333
2357
  localState: props.context.localState,
2334
- context: props.context.context
2358
+ context: props.context.context,
2359
+ trackingContext: {
2360
+ apiKey: props.context.apiKey,
2361
+ canTrack: props.context.canTrack ?? true,
2362
+ contentId: props.context.content?.id,
2363
+ variationId: props.context.content?.testVariationId
2364
+ }
2335
2365
  })
2336
2366
  } : {};
2337
2367
  });