@symbo.ls/brender 3.8.8 → 3.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -7,7 +7,6 @@ const resolveParams = (params, mockState) => {
7
7
  try {
8
8
  const mockEl = {
9
9
  state: mockState || {},
10
- props: {},
11
10
  call: () => void 0,
12
11
  __ref: {}
13
12
  };
@@ -191,7 +190,6 @@ const preEvaluateChildren = (def, inheritedState) => {
191
190
  try {
192
191
  const mockEl = {
193
192
  state: effectiveState,
194
- props: {},
195
193
  call: (fn) => {
196
194
  if (fn === "getActiveLang" || fn === "getLang") return effectiveState?.lang || "ka";
197
195
  if (fn === "polyglot") return arguments[1] || "";
@@ -12,7 +12,7 @@ let _funcqlPlugin = null;
12
12
  const getFuncqlPlugin = async () => {
13
13
  if (_funcqlPlugin) return _funcqlPlugin;
14
14
  try {
15
- const mod = await import("@domql/funcql");
15
+ const mod = await import("@symbo.ls/funcql");
16
16
  _funcqlPlugin = mod.funcqlPlugin;
17
17
  return _funcqlPlugin;
18
18
  } catch {
@@ -20,7 +20,7 @@ const getFuncqlPlugin = async () => {
20
20
  }
21
21
  };
22
22
  import { parseHTML } from "linkedom";
23
- import createEmotionInstance from "@emotion/css/create-instance";
23
+ import { css, injectGlobal, reset as resetCss } from "@symbo.ls/css";
24
24
  const ssrResolve = (map, key) => {
25
25
  if (!map || !key) return void 0;
26
26
  if (map[key] !== void 0) return map[key];
@@ -193,7 +193,7 @@ const resolveDomqlPackage = (ws, pkg, ...subpath) => {
193
193
  if (ws.isMonorepo) {
194
194
  return resolve(ws.monorepoRoot, "packages", "domql", "packages", pkg, ...subpath);
195
195
  }
196
- const pkgJson = tryRequireResolve(ws, `@domql/${pkg}/package.json`);
196
+ const pkgJson = tryRequireResolve(ws, `@symbo.ls/${pkg}/package.json`);
197
197
  if (pkgJson) return resolve(dirname(pkgJson), ...subpath);
198
198
  return null;
199
199
  };
@@ -288,7 +288,7 @@ const bundleCreateDomql = async () => {
288
288
  }
289
289
  });
290
290
  build.onResolve({ filter: /^@domql\// }, (args) => {
291
- const pkg = args.path.replace("@domql/", "");
291
+ const pkg = args.path.replace("@symbo.ls/", "");
292
292
  if (ws.isMonorepo) {
293
293
  const src = resolve(ws.monorepoRoot, "packages", "domql", "packages", pkg, "src", "index.js");
294
294
  if (existsSync(src)) return { path: src };
@@ -386,7 +386,7 @@ export const supabaseAdapter = () => ({name:'supabase'});
386
386
  let contents = readFileSync(args.path, "utf8");
387
387
  contents = contents.replace(
388
388
  /import\s*\{\s*Link\s*\}\s*from\s*['"]smbls['"]/,
389
- `const Link = { tag: 'a', attr: { href: (el) => el.props?.href } }`
389
+ `const Link = { tag: 'a', attr: { href: (el) => el.href } }`
390
390
  );
391
391
  return { contents, loader: "js" };
392
392
  });
@@ -476,9 +476,9 @@ const UIKIT_STUBS = {
476
476
  Link: {
477
477
  tag: "a",
478
478
  attr: {
479
- href: (el) => el.props?.href,
480
- target: (el) => el.props?.target,
481
- rel: (el) => el.props?.rel
479
+ href: (el) => el.href,
480
+ target: (el) => el.target,
481
+ rel: (el) => el.rel
482
482
  }
483
483
  },
484
484
  A: { extends: "Link" },
@@ -487,14 +487,14 @@ const UIKIT_STUBS = {
487
487
  tag: "img",
488
488
  attr: {
489
489
  src: (el) => {
490
- let src = el.props?.src;
490
+ let src = el.src;
491
491
  if (typeof src === "string" && src.includes("{{")) {
492
492
  src = el.call("replaceLiteralsWithObjectFields", src, el.state);
493
493
  }
494
494
  return src;
495
495
  },
496
- alt: (el) => el.props?.alt,
497
- loading: (el) => el.props?.loading
496
+ alt: (el) => el.alt,
497
+ loading: (el) => el.loading
498
498
  }
499
499
  },
500
500
  Image: { extends: "Img" },
@@ -632,11 +632,7 @@ const render = async (data, options = {}) => {
632
632
  };
633
633
  }
634
634
  }
635
- const ssrEmotion = createEmotionInstance({
636
- key: "smbls",
637
- container: document.head,
638
- speedy: false
639
- });
635
+ resetCss();
640
636
  const ctx = {
641
637
  state: baseState,
642
638
  ...stateOverrides ? { state: { ...baseState, ...stateOverrides } } : {},
@@ -654,6 +650,7 @@ const render = async (data, options = {}) => {
654
650
  methods: data.methods || {},
655
651
  designSystem: structuredCloneDeep(data.designSystem || {}),
656
652
  files: data.files || {},
653
+ sharedLibraries: data.sharedLibraries || [],
657
654
  ...config,
658
655
  // Override polyglot with SSR-enriched version
659
656
  ...polyglotConfig ? { polyglot: polyglotConfig } : {},
@@ -661,8 +658,7 @@ const render = async (data, options = {}) => {
661
658
  document,
662
659
  window,
663
660
  parent: { node: body },
664
- // Use SSR emotion instance (non-speedy) for proper @media rule extraction
665
- initOptions: { emotion: ssrEmotion },
661
+ initOptions: {},
666
662
  // Disable sourcemap tracking in SSR — it causes stack overflows
667
663
  // when state contains large data arrays (articles, events, etc.)
668
664
  domqlOptions: { sourcemap: false },
@@ -685,38 +681,17 @@ const render = async (data, options = {}) => {
685
681
  const brRegistry = buildPathRegistry(element);
686
682
  const metadata = extractMetadata(data, route, element, element?.state);
687
683
  const emotionCSS = [];
688
- const emotionInstance = ctx.emotion || element && element.context && element.context.emotion;
689
- if (emotionInstance && emotionInstance.cache) {
690
- const cache = emotionInstance.cache;
691
- if (cache.inserted) {
692
- for (const key in cache.inserted) {
693
- const rule = cache.inserted[key];
694
- if (typeof rule === "string" && rule) emotionCSS.push(rule);
695
- }
696
- }
697
- if (cache.sheet && cache.sheet.tags) {
698
- for (const tag of cache.sheet.tags) {
699
- if (tag.sheet && tag.sheet.cssRules) {
700
- for (const rule of tag.sheet.cssRules) {
701
- if (rule.cssText) emotionCSS.push(rule.cssText);
702
- }
684
+ const head = document.head || document.querySelector("head");
685
+ if (head) {
686
+ for (const style of head.querySelectorAll("style")) {
687
+ if (style.sheet && style.sheet.cssRules) {
688
+ for (const rule of style.sheet.cssRules) {
689
+ if (rule.cssText) emotionCSS.push(rule.cssText);
703
690
  }
704
691
  }
705
- }
706
- }
707
- if (!emotionCSS.length) {
708
- const head = document.head || document.querySelector("head");
709
- if (head) {
710
- for (const style of head.querySelectorAll("style")) {
711
- if (style.sheet && style.sheet.cssRules) {
712
- for (const rule of style.sheet.cssRules) {
713
- if (rule.cssText) emotionCSS.push(rule.cssText);
714
- }
715
- }
716
- if (!emotionCSS.length) {
717
- const content = style.textContent || "";
718
- if (content) emotionCSS.push(content);
719
- }
692
+ if (!emotionCSS.length) {
693
+ const content = style.textContent || "";
694
+ if (content) emotionCSS.push(content);
720
695
  }
721
696
  }
722
697
  }
@@ -739,8 +714,8 @@ const renderElement = async (elementDef, options = {}) => {
739
714
  const { context = {} } = options;
740
715
  const { window, document } = createEnv();
741
716
  const body = document.body;
742
- const { create } = await import("@domql/element");
743
- const domqlUtils = await import("@domql/utils");
717
+ const { create } = await import("@symbo.ls/element");
718
+ const domqlUtils = await import("@symbo.ls/utils");
744
719
  const components = { ...UIKIT_STUBS, ...context.components || {} };
745
720
  const utils = {
746
721
  ...domqlUtils,
@@ -773,6 +748,36 @@ const fixSvgContent = (html) => {
773
748
  );
774
749
  };
775
750
  let _cachedGlobalCSS = null;
751
+ const SCRATCH_CONFIG_FLAGS = [
752
+ "globalTheme",
753
+ "themeStorageKey",
754
+ "themeRoot",
755
+ "useReset",
756
+ "useVariable",
757
+ "useFontImport",
758
+ "useIconSprite",
759
+ "useSvgSprite",
760
+ "useDocumentTheme",
761
+ "useDefaultConfig",
762
+ "useDefaultIcons",
763
+ "useThemeSuffixedVars",
764
+ "verbose",
765
+ "semanticIcons"
766
+ ];
767
+ const pickProjectConfig = (data) => {
768
+ if (!data || typeof data !== "object") return null;
769
+ if (data.config && typeof data.config === "object") return data.config;
770
+ const out = {};
771
+ let any = false;
772
+ for (const flag of SCRATCH_CONFIG_FLAGS) {
773
+ if (Object.prototype.hasOwnProperty.call(data, flag)) {
774
+ out[flag] = data[flag];
775
+ any = true;
776
+ }
777
+ }
778
+ if (any) return out;
779
+ return data.settings || null;
780
+ };
776
781
  const generateGlobalCSS = async (ds, config) => {
777
782
  if (_cachedGlobalCSS) return _cachedGlobalCSS;
778
783
  try {
@@ -855,7 +860,7 @@ const generateGlobalCSS = async (ds, config) => {
855
860
  }
856
861
  });
857
862
  build.onResolve({ filter: /^@domql\// }, (args) => {
858
- const pkg = args.path.replace("@domql/", "");
863
+ const pkg = args.path.replace("@symbo.ls/", "");
859
864
  if (ws.isMonorepo) {
860
865
  const src = resolve(ws.monorepoRoot, "packages", "domql", "packages", pkg, "src", "index.js");
861
866
  if (existsSync2(src)) return { path: src };
@@ -963,7 +968,7 @@ const renderRoute = async (data, options = {}) => {
963
968
  const result = await render(data, { route, pathname, prefetch: true });
964
969
  if (!result) return null;
965
970
  const ds = data.designSystem || {};
966
- const globalCSS = await generateGlobalCSS(ds, data.config || data.settings);
971
+ const globalCSS = await generateGlobalCSS(ds, pickProjectConfig(data));
967
972
  let prefetchedState = null;
968
973
  let activeLang = null;
969
974
  try {
@@ -1022,7 +1027,7 @@ const renderPage = async (data, route = "/", options = {}) => {
1022
1027
  }
1023
1028
  const emotionCSS = Array.from(_accumulatedEmotionCSS).join("\n");
1024
1029
  const ds = data.designSystem || {};
1025
- const globalCSS = await generateGlobalCSS(ds, data.config || data.settings);
1030
+ const globalCSS = await generateGlobalCSS(ds, pickProjectConfig(data));
1026
1031
  const fontLinks = generateFontLinks(ds);
1027
1032
  const brKeyCount = Object.keys(result.registry).length;
1028
1033
  let isrBody = "";
@@ -1440,32 +1445,29 @@ const getExtendsCSS = (el) => {
1440
1445
  return null;
1441
1446
  };
1442
1447
  const resolveElementProps = (el) => {
1443
- const { props } = el;
1444
- if (!props) return props;
1445
1448
  let resolved;
1446
- for (const key in props) {
1447
- if (typeof props[key] !== "function") continue;
1449
+ for (const key in el) {
1450
+ if (typeof el[key] !== "function") continue;
1448
1451
  if (NON_CSS_PROPS.has(key)) continue;
1449
1452
  if (key.charCodeAt(0) >= 65 && key.charCodeAt(0) <= 90) continue;
1450
1453
  if (key.startsWith("on")) continue;
1451
- if (!resolved) resolved = { ...props };
1454
+ if (key.startsWith("__")) continue;
1455
+ if (!resolved) resolved = {};
1452
1456
  let result;
1453
1457
  try {
1454
- result = props[key](el, el.state || {});
1458
+ result = el[key](el, el.state || {});
1455
1459
  } catch {
1456
1460
  try {
1457
1461
  const mockState = { root: {}, ...el.state || {} };
1458
- result = props[key](el, mockState);
1462
+ result = el[key](el, mockState);
1459
1463
  } catch {
1460
1464
  }
1461
1465
  }
1462
1466
  if (result !== void 0 && result !== null && result !== false) {
1463
1467
  resolved[key] = result;
1464
- } else {
1465
- delete resolved[key];
1466
1468
  }
1467
1469
  }
1468
- return resolved || props;
1470
+ return resolved || el;
1469
1471
  };
1470
1472
  const extractCSS = (element, ds) => {
1471
1473
  const mediaMap = ds?.media || {};
package/env.js CHANGED
@@ -9,7 +9,11 @@ export const createEnv = (html = '<!DOCTYPE html><html><head></head><body></body
9
9
 
10
10
  // Stub APIs that DOMQL/smbls may call during rendering
11
11
  if (!window.requestAnimationFrame) {
12
- window.requestAnimationFrame = (fn) => setTimeout(fn, 0)
12
+ window.requestAnimationFrame = (fn) => {
13
+ const id = setTimeout(fn, 0)
14
+ if (id?.unref) id.unref()
15
+ return id
16
+ }
13
17
  }
14
18
  if (!window.cancelAnimationFrame) {
15
19
  window.cancelAnimationFrame = (id) => clearTimeout(id)
@@ -58,11 +62,12 @@ export const createEnv = (html = '<!DOCTYPE html><html><head></head><body></body
58
62
  }
59
63
  }
60
64
 
61
- // Expose linkedom constructors on globalThis so @domql/utils isDOMNode
65
+ // Expose linkedom constructors on globalThis so @symbo.ls/utils isDOMNode
62
66
  // can use instanceof checks (it reads from globalThis.Node, etc.)
63
67
  globalThis.window = window
64
68
  globalThis.document = document
65
69
  globalThis.Node = window.Node || globalThis.Node
70
+ globalThis.Element = window.Element || globalThis.Element
66
71
  globalThis.HTMLElement = window.HTMLElement || globalThis.HTMLElement
67
72
  globalThis.MutationObserver = window.MutationObserver
68
73
  globalThis.Window = window.constructor
package/hydrate.js CHANGED
@@ -100,14 +100,14 @@ export const hydrate = (element, options = {}) => {
100
100
  * generates emotion class name, and applies it to the DOM node.
101
101
  */
102
102
  const renderCSS = (el, emotion, colorMap, mediaMap) => {
103
- const { node, props } = el
104
- if (!node || !props) return
103
+ const { node } = el
104
+ if (!node) return
105
105
 
106
106
  const css = {}
107
107
  let hasCss = false
108
108
 
109
- for (const key in props) {
110
- const val = props[key]
109
+ for (const key in el) {
110
+ const val = el[key]
111
111
 
112
112
  // @media breakpoint objects: @mobile, @tablet, etc.
113
113
  if (key.charCodeAt(0) === 64) {
@@ -181,7 +181,7 @@ const renderCSS = (el, emotion, colorMap, mediaMap) => {
181
181
  }
182
182
 
183
183
  // Preserve explicit class from props/attr
184
- if (props.class) classes.push(props.class)
184
+ if (el.class) classes.push(el.class)
185
185
  if (el.attr?.class) classes.push(el.attr.class)
186
186
 
187
187
  // Handle classlist
@@ -203,7 +203,7 @@ const renderCSS = (el, emotion, colorMap, mediaMap) => {
203
203
  }
204
204
 
205
205
  // Clean up CSS prop attributes that leaked into HTML
206
- for (const key in props) {
206
+ for (const key in el) {
207
207
  if (isCSS(key) && node.hasAttribute(key)) {
208
208
  node.removeAttribute(key)
209
209
  }
@@ -391,7 +391,7 @@ const CSS_PROPERTIES = new Set([
391
391
  ])
392
392
 
393
393
  /**
394
- * Binds DOM events from element.on and element.props onto the real node.
394
+ * Binds DOM events from element's onX properties onto the real node.
395
395
  */
396
396
  const DOMQL_LIFECYCLE = new Set([
397
397
  'render', 'create', 'init', 'start', 'complete', 'done',
@@ -400,56 +400,46 @@ const DOMQL_LIFECYCLE = new Set([
400
400
  ])
401
401
 
402
402
  const bindEvents = (el) => {
403
- const { node, on, props } = el
403
+ const { node } = el
404
404
  if (!node) return
405
405
 
406
- const handled = new Set()
407
-
408
- if (on) {
409
- for (const param in on) {
410
- if (DOMQL_LIFECYCLE.has(param)) continue
411
- if (typeof on[param] !== 'function') continue
412
- handled.add(param)
413
- addListener(node, param, on[param], el)
414
- }
415
- }
416
-
417
- if (props) {
418
- for (const key in props) {
419
- if (key.length <= 2 || key[0] !== 'o' || key[1] !== 'n') continue
420
- if (typeof props[key] !== 'function') continue
421
- const third = key[2]
422
- if (third !== third.toUpperCase()) continue
423
- const eventName = third.toLowerCase() + key.slice(3)
424
- if (handled.has(eventName) || DOMQL_LIFECYCLE.has(eventName)) continue
425
- addListener(node, eventName, props[key], el)
426
- }
406
+ if (!el.__ref.__eventCleanup) el.__ref.__eventCleanup = []
407
+
408
+ // v4: event handlers are flat on element as onX properties
409
+ for (const key in el) {
410
+ if (key.length <= 2 || key[0] !== 'o' || key[1] !== 'n') continue
411
+ if (typeof el[key] !== 'function') continue
412
+ const third = key[2]
413
+ if (third !== third.toUpperCase()) continue
414
+ const eventName = third.toLowerCase() + key.slice(3)
415
+ if (DOMQL_LIFECYCLE.has(eventName)) continue
416
+ addListener(node, eventName, el[key], el)
427
417
  }
428
418
  }
429
419
 
430
420
  const addListener = (node, eventName, handler, el) => {
431
- node.addEventListener(eventName, (event) => {
432
- const result = handler.call(el, event, el, el.state, el.context)
433
- if (result && typeof result.then === 'function') {
434
- result.catch(() => {})
421
+ const listener = (event) => {
422
+ try {
423
+ handler.call(el, event, el, el.state, el.context)
424
+ } catch (e) {
425
+ console.warn('[brender hydrate]', eventName, e.message)
435
426
  }
436
- })
427
+ }
428
+ node.addEventListener(eventName, listener)
429
+ el.__ref.__eventCleanup.push(() => node.removeEventListener(eventName, listener))
437
430
  }
438
431
 
439
432
  /**
440
- * Walks the tree and fires on.render, on.renderRouter, on.done, on.create
433
+ * Walks the tree and fires onRender, onRenderRouter, onDone, onCreate
441
434
  * lifecycle events — the same ones that fire during normal DOMQL create.
442
435
  */
443
436
  const fireLifecycle = (el) => {
444
437
  if (!el || !el.__ref || !el.node) return
445
438
 
446
- const on = el.on
447
- if (on) {
448
- fireEvent(on.render, el)
449
- fireEvent(on.renderRouter, el)
450
- fireEvent(on.done, el)
451
- fireEvent(on.create, el)
452
- }
439
+ fireEvent(el.onRender, el)
440
+ fireEvent(el.onRenderRouter, el)
441
+ fireEvent(el.onDone, el)
442
+ fireEvent(el.onCreate, el)
453
443
 
454
444
  if (el.__ref.__children) {
455
445
  for (const childKey of el.__ref.__children) {
package/load.js CHANGED
@@ -71,7 +71,9 @@ export const loadProject = async (projectPath) => {
71
71
  functionsModule,
72
72
  methodsModule,
73
73
  designSystemModule,
74
- filesModule
74
+ filesModule,
75
+ assetsModule,
76
+ sharedLibsModule
75
77
  ] = await Promise.all([
76
78
  bundleAndImport(join(symbolsDir, 'app.js')),
77
79
  bundleAndImport(join(symbolsDir, 'state.js')),
@@ -83,12 +85,14 @@ export const loadProject = async (projectPath) => {
83
85
  bundleAndImport(join(symbolsDir, 'functions', 'index.js')),
84
86
  bundleAndImport(join(symbolsDir, 'methods', 'index.js')),
85
87
  bundleAndImport(join(symbolsDir, 'designSystem', 'index.js')),
86
- bundleAndImport(join(symbolsDir, 'files', 'index.js'))
88
+ bundleAndImport(join(symbolsDir, 'files', 'index.js')),
89
+ bundleAndImport(join(symbolsDir, 'assets', 'index.js')).catch(() => null),
90
+ bundleAndImport(join(symbolsDir, 'sharedLibraries.js')).catch(() => null)
87
91
  ])
88
92
 
89
93
  // Spread into plain objects — ESM module namespaces are non-extensible,
90
94
  // which breaks downstream code that adds properties (e.g. polyglot functions).
91
- return {
95
+ const result = {
92
96
  app: { ...(appModule?.default || {}) },
93
97
  state: { ...(stateModule?.default || {}) },
94
98
  dependencies: { ...(depsModule?.default || {}) },
@@ -99,8 +103,23 @@ export const loadProject = async (projectPath) => {
99
103
  methods: { ...(methodsModule || {}) },
100
104
  designSystem: { ...(designSystemModule?.default || {}) },
101
105
  files: { ...(filesModule?.default || {}) },
102
- config: { ...(configModule?.default || {}) }
106
+ assets: { ...(assetsModule?.default || {}) },
107
+ config: { ...(configModule?.default || {}) },
108
+ sharedLibraries: sharedLibsModule?.default || []
103
109
  }
110
+
111
+ // Pre-resolve string library references and merge into context
112
+ // so production builds have zero runtime overhead
113
+ if (result.sharedLibraries.length) {
114
+ const { resolveSharedLibraries, mergeSharedLibraries } = await import('@symbo.ls/utils')
115
+ const hasStrings = result.sharedLibraries.some(lib => typeof lib === 'string')
116
+ if (hasStrings) {
117
+ result.sharedLibraries = await resolveSharedLibraries(result.sharedLibraries)
118
+ }
119
+ mergeSharedLibraries(result, result.sharedLibraries)
120
+ }
121
+
122
+ return result
104
123
  }
105
124
 
106
125
  /**
package/package.json CHANGED
@@ -1,21 +1,15 @@
1
1
  {
2
2
  "name": "@symbo.ls/brender",
3
- "version": "3.8.8",
3
+ "version": "3.14.0",
4
4
  "license": "CC-BY-NC-4.0",
5
5
  "type": "module",
6
- "module": "./dist/esm/index.js",
7
- "main": "./dist/cjs/index.js",
6
+ "module": "./index.js",
7
+ "main": "./index.js",
8
8
  "exports": {
9
- ".": {
10
- "import": "./index.js",
11
- "require": "./dist/cjs/index.js"
12
- },
13
- "./hydrate": {
14
- "import": "./hydrate.js"
15
- },
16
- "./load": {
17
- "import": "./load.js"
18
- }
9
+ ".": "./index.js",
10
+ "./hydrate": "./hydrate.js",
11
+ "./load": "./load.js",
12
+ "./package.json": "./package.json"
19
13
  },
20
14
  "source": "index.js",
21
15
  "files": [
@@ -24,19 +18,20 @@
24
18
  ],
25
19
  "scripts": {
26
20
  "copy:package:cjs": "cp ../../build/package-cjs.json dist/cjs/package.json",
27
- "build:esm": "cross-env NODE_ENV=$NODE_ENV esbuild *.js --target=es2020 --format=esm --outdir=dist/esm --define:process.env.NODE_ENV=process.env.NODE_ENV",
28
- "build:cjs": "cross-env NODE_ENV=$NODE_ENV esbuild *.js --target=node18 --format=cjs --outdir=dist/cjs --define:process.env.NODE_ENV=process.env.NODE_ENV",
21
+ "build:esm": "NODE_ENV=$NODE_ENV esbuild *.js --target=es2020 --format=esm --outdir=dist/esm --define:process.env.NODE_ENV=process.env.NODE_ENV",
22
+ "build:cjs": "NODE_ENV=$NODE_ENV esbuild *.js --target=node18 --format=cjs --outdir=dist/cjs --define:process.env.NODE_ENV=process.env.NODE_ENV",
29
23
  "build": "node ../../build/build.js",
30
- "prepublish": "npm run build && npm run copy:package:cjs",
24
+ "prepublish": "bun run build && bun run copy:package:cjs",
31
25
  "render:survey": "node scripts/render.js survey",
32
26
  "render:rita": "node scripts/render.js rita",
33
- "render:all": "npm run render:survey && npm run render:rita",
27
+ "render:all": "bun run render:survey && bun run render:rita",
34
28
  "liquidate:survey": "node scripts/liquidate.js survey",
35
29
  "liquidate:rita": "node scripts/liquidate.js rita",
36
30
  "dev:rita": "node examples/serve-rita.js"
37
31
  },
38
32
  "dependencies": {
39
- "@symbo.ls/helmet": "^3.8.8",
33
+ "@symbo.ls/css": "^3.14.0",
34
+ "@symbo.ls/helmet": "^3.14.0",
40
35
  "linkedom": "^0.16.8"
41
36
  },
42
37
  "devDependencies": {
package/prefetch.js CHANGED
@@ -24,7 +24,6 @@ const resolveParams = (params, mockState) => {
24
24
  // Build a mock element with basic call() support
25
25
  const mockEl = {
26
26
  state: mockState || {},
27
- props: {},
28
27
  call: () => undefined,
29
28
  __ref: {}
30
29
  }
@@ -312,8 +311,7 @@ const preEvaluateChildren = (def, inheritedState) => {
312
311
  try {
313
312
  const mockEl = {
314
313
  state: effectiveState,
315
- props: {},
316
- call: (fn) => {
314
+ call: (fn) => {
317
315
  if (fn === 'getActiveLang' || fn === 'getLang') return effectiveState?.lang || 'ka'
318
316
  if (fn === 'polyglot') return arguments[1] || ''
319
317
  return undefined