@symbo.ls/utils 3.14.0 → 3.14.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.
Files changed (88) hide show
  1. package/README.md +2 -2
  2. package/assets.js +117 -0
  3. package/cookie.js +20 -13
  4. package/dist/cjs/browser.js +2 -0
  5. package/dist/cjs/date.js +3 -1
  6. package/dist/cjs/detectHeight.js +13 -22
  7. package/dist/cjs/domqlv3hacks.js +3845 -0
  8. package/dist/cjs/fibonacci.js +3 -1
  9. package/dist/cjs/files.js +3 -1
  10. package/dist/cjs/index.js +4084 -38
  11. package/dist/cjs/load.js +7 -5
  12. package/dist/cjs/package.json +4 -0
  13. package/dist/cjs/scaling.js +23 -5
  14. package/dist/cjs/style.js +3 -1
  15. package/index.js +1 -0
  16. package/methods.js +51 -3
  17. package/object.js +36 -2
  18. package/package.json +1 -1
  19. package/dist/cjs/array.js +0 -168
  20. package/dist/cjs/cache.js +0 -26
  21. package/dist/cjs/cdn.js +0 -85
  22. package/dist/cjs/component.js +0 -45
  23. package/dist/cjs/cookie.js +0 -75
  24. package/dist/cjs/element.js +0 -136
  25. package/dist/cjs/env.js +0 -43
  26. package/dist/cjs/events.js +0 -39
  27. package/dist/cjs/extends.js +0 -434
  28. package/dist/cjs/function.js +0 -114
  29. package/dist/cjs/globals.js +0 -30
  30. package/dist/cjs/if.js +0 -48
  31. package/dist/cjs/key.js +0 -38
  32. package/dist/cjs/keys.js +0 -201
  33. package/dist/cjs/log.js +0 -34
  34. package/dist/cjs/metadata.js +0 -310
  35. package/dist/cjs/methods.js +0 -599
  36. package/dist/cjs/node.js +0 -35
  37. package/dist/cjs/object.js +0 -634
  38. package/dist/cjs/projectKeys.js +0 -35
  39. package/dist/cjs/props.js +0 -282
  40. package/dist/cjs/scope.js +0 -44
  41. package/dist/cjs/sharedLibraries.js +0 -146
  42. package/dist/cjs/state.js +0 -173
  43. package/dist/cjs/string-extra.js +0 -72
  44. package/dist/cjs/string.js +0 -183
  45. package/dist/cjs/tags.js +0 -220
  46. package/dist/cjs/triggerEvent.js +0 -112
  47. package/dist/cjs/types.js +0 -74
  48. package/dist/cjs/update.js +0 -42
  49. package/dist/esm/array.js +0 -148
  50. package/dist/esm/browser.js +0 -14
  51. package/dist/esm/cache.js +0 -6
  52. package/dist/esm/cdn.js +0 -65
  53. package/dist/esm/component.js +0 -25
  54. package/dist/esm/cookie.js +0 -55
  55. package/dist/esm/date.js +0 -11
  56. package/dist/esm/detectHeight.js +0 -42
  57. package/dist/esm/element.js +0 -116
  58. package/dist/esm/env.js +0 -23
  59. package/dist/esm/events.js +0 -19
  60. package/dist/esm/extends.js +0 -414
  61. package/dist/esm/fibonacci.js +0 -10
  62. package/dist/esm/files.js +0 -4
  63. package/dist/esm/function.js +0 -94
  64. package/dist/esm/globals.js +0 -10
  65. package/dist/esm/if.js +0 -28
  66. package/dist/esm/index.js +0 -37
  67. package/dist/esm/key.js +0 -18
  68. package/dist/esm/keys.js +0 -181
  69. package/dist/esm/load.js +0 -151
  70. package/dist/esm/log.js +0 -14
  71. package/dist/esm/metadata.js +0 -290
  72. package/dist/esm/methods.js +0 -569
  73. package/dist/esm/node.js +0 -15
  74. package/dist/esm/object.js +0 -621
  75. package/dist/esm/projectKeys.js +0 -16
  76. package/dist/esm/props.js +0 -262
  77. package/dist/esm/scaling.js +0 -15
  78. package/dist/esm/scope.js +0 -24
  79. package/dist/esm/sharedLibraries.js +0 -126
  80. package/dist/esm/state.js +0 -163
  81. package/dist/esm/string-extra.js +0 -52
  82. package/dist/esm/string.js +0 -163
  83. package/dist/esm/style.js +0 -20
  84. package/dist/esm/tags.js +0 -200
  85. package/dist/esm/triggerEvent.js +0 -92
  86. package/dist/esm/types.js +0 -54
  87. package/dist/esm/update.js +0 -22
  88. package/dist/iife/index.js +0 -5818
package/README.md CHANGED
@@ -6,7 +6,7 @@ Core utility functions for the DOMQL element system.
6
6
 
7
7
  The propertization system normalizes element definitions by classifying keys into child elements, framework keys, and CSS/design-token properties.
8
8
 
9
- In v4, properties go directly on the element (no `props:` wrapper needed). The propertization system operates internally to route properties to the atomic CSS engine (`@symbo.ls/css`).
9
+ In v3.14, properties go directly on the element (no `props:` wrapper needed). The propertization system operates internally to route properties to the atomic CSS engine (`@symbo.ls/css`).
10
10
 
11
11
  ### Two-phase process
12
12
 
@@ -15,7 +15,7 @@ In v4, properties go directly on the element (no `props:` wrapper needed). The p
15
15
 
16
16
  ### Key classification rules
17
17
 
18
- In v4, properties go directly on the element (no `props:` wrapper needed). The propertization system still operates internally for the CSS engine.
18
+ In v3.14, properties go directly on the element (no `props:` wrapper needed). The propertization system still operates internally for the CSS engine.
19
19
 
20
20
  | Pattern | Classification | Example |
21
21
  |---------|---------------|---------|
package/assets.js ADDED
@@ -0,0 +1,117 @@
1
+ 'use strict'
2
+
3
+ /**
4
+ * Asset resolution + variant emitters shared across media components
5
+ * (Img, Video, Audio, AssetPicture, …) and any plugin that reads from
6
+ * `context.assets` / `context.files`.
7
+ *
8
+ * Components don't care WHERE an asset lives — runner-discovered file,
9
+ * cloud-uploaded entry, or hand-authored URL — they call `resolveAsset`
10
+ * with the element and get back a normalized shape (or null).
11
+ */
12
+
13
+ /**
14
+ * Look up `el.src` in `el.context.assets`, falling back to
15
+ * `el.context.files`. Normalizes the two source-side shapes:
16
+ *
17
+ * - **String URL** — cloud-resolved or hand-authored bare URLs.
18
+ * Returns `{ src, type: null, variants: null }`. Components emit
19
+ * a single-source tag with no `<source>` chain and no `srcset`.
20
+ *
21
+ * - **Manifest object** — `{ src, type, category, variants[] }`.
22
+ * Shape produced by the runner's filename-based asset walker
23
+ * (and any cloud provider that exposes variant metadata). Returned
24
+ * verbatim.
25
+ *
26
+ * Anything else (object without `.src`, missing key, non-string `el.src`)
27
+ * returns null. Components fall through to plain markup using `el.src`.
28
+ */
29
+ export const resolveAsset = (el) => {
30
+ const key = el && el.src
31
+ if (!key || typeof key !== 'string') return null
32
+ const ctx = el.context
33
+ if (!ctx) return null
34
+ const found = (ctx.assets && ctx.assets[key]) || (ctx.files && ctx.files[key])
35
+ if (!found) return null
36
+ if (typeof found === 'string') {
37
+ return { src: found, type: null, variants: null }
38
+ }
39
+ if (typeof found === 'object' && typeof found.src === 'string') {
40
+ return found
41
+ }
42
+ return null
43
+ }
44
+
45
+ /**
46
+ * Render an `srcset` value from a list of variants.
47
+ *
48
+ * Width descriptors take precedence over scale when present. Bare 1x
49
+ * entries are kept or dropped based on context:
50
+ *
51
+ * - `<source srcset>` (`keepOneX: true`, default): bare 1x URLs are
52
+ * required because `<source>` has no `src` fallback — without a 1x
53
+ * entry the source can't match default-DPR clients.
54
+ * - `<img srcset>` (`keepOneX: false`): bare 1x URLs are redundant
55
+ * because the `src` attribute already covers them.
56
+ */
57
+ export const srcsetFor = (variants, { keepOneX = true } = {}) => {
58
+ if (!Array.isArray(variants) || !variants.length) return ''
59
+ const usingWidth = variants.some((v) => typeof v.width === 'number')
60
+ const parts = []
61
+ for (const v of variants) {
62
+ if (usingWidth && typeof v.width === 'number') {
63
+ parts.push(`${v.src} ${v.width}w`)
64
+ } else if (!usingWidth) {
65
+ if (v.scale === 1 && keepOneX) parts.push(v.src)
66
+ else if (v.scale && v.scale !== 1) parts.push(`${v.src} ${v.scale}x`)
67
+ }
68
+ }
69
+ return parts.join(', ')
70
+ }
71
+
72
+ /**
73
+ * Same-format srcset for an `<img>` tag — filtered to the asset's
74
+ * primary format and with `keepOneX: false`. Used by `<Img>`.
75
+ */
76
+ export const buildImgSrcset = (asset) => {
77
+ if (!asset || !Array.isArray(asset.variants)) return ''
78
+ const sameFormat = asset.variants.filter((v) => v.format === asset.type)
79
+ return srcsetFor(sameFormat, { keepOneX: false })
80
+ }
81
+
82
+ /**
83
+ * Build the children of an `<picture>` (or any format-negotiating tag)
84
+ * from an asset manifest: one `<source type="…" srcset="…">` per non-
85
+ * primary format, plus a trailing `<img>` for the primary format.
86
+ *
87
+ * Returns a list of DOMQL element configs. When the asset has no
88
+ * variants array (cloud-string URL or single-source entry), returns
89
+ * just the `<img>`.
90
+ */
91
+ export const buildSourcesAndImg = (asset, alt) => {
92
+ if (!asset || typeof asset !== 'object' || typeof asset.src !== 'string') return []
93
+ if (!Array.isArray(asset.variants) || !asset.variants.length) {
94
+ return [{ tag: 'img', attr: { src: asset.src, alt: alt || '' } }]
95
+ }
96
+ // Group by format. Format that matches `asset.type` is the fallback
97
+ // and gets emitted as the trailing `<img>` (browsers fall through to
98
+ // it when no `<source>` matches). Other formats become `<source>`.
99
+ const byFormat = new Map()
100
+ for (const v of asset.variants) {
101
+ if (!byFormat.has(v.format)) byFormat.set(v.format, [])
102
+ byFormat.get(v.format).push(v)
103
+ }
104
+ const sources = []
105
+ for (const [format, list] of byFormat) {
106
+ if (format === asset.type) continue
107
+ sources.push({
108
+ tag: 'source',
109
+ attr: { type: format, srcset: srcsetFor(list, { keepOneX: true }) }
110
+ })
111
+ }
112
+ const sameFormat = byFormat.get(asset.type) || []
113
+ const fallbackSrcset = srcsetFor(sameFormat, { keepOneX: false })
114
+ const imgAttr = { src: asset.src, alt: alt || '' }
115
+ if (fallbackSrcset) imgAttr.srcset = fallbackSrcset
116
+ return [...sources, { tag: 'img', attr: imgAttr }]
117
+ }
package/cookie.js CHANGED
@@ -38,16 +38,19 @@ export const removeCookie = cname => {
38
38
  * @returns {*} -- parsed data or undefined
39
39
  */
40
40
  export function getLocalStorage (key) {
41
- if (!window.localStorage) {
42
- return undefined
43
- }
44
-
45
- const item = window.localStorage.getItem(key)
46
-
47
- if (item === null) {
41
+ // localStorage access throws in: Safari private mode (quota), sandboxed
42
+ // iframes without `allow-storage-access-by-user-activation`, Firefox with
43
+ // `dom.storage.enabled=false`. Wrap the access itself, not just the
44
+ // JSON.parse — the existing try only covered parse and let the read
45
+ // crash the host.
46
+ let item
47
+ try {
48
+ if (!window.localStorage) return undefined
49
+ item = window.localStorage.getItem(key)
50
+ } catch (e) {
48
51
  return undefined
49
52
  }
50
-
53
+ if (item === null) return undefined
51
54
  try {
52
55
  return JSON.parse(item)
53
56
  } catch (e) {
@@ -62,10 +65,14 @@ export function getLocalStorage (key) {
62
65
  * @param data - the data to save
63
66
  */
64
67
  export function setLocalStorage (key, data) {
65
- if (!window.localStorage || data === undefined || data === null) {
66
- return
68
+ if (data === undefined || data === null) return
69
+ try {
70
+ if (!window.localStorage) return
71
+ const value = typeof data === 'object' ? JSON.stringify(data) : data
72
+ window.localStorage.setItem(key, value)
73
+ } catch (e) {
74
+ // QuotaExceededError (Safari private + over quota), SecurityError
75
+ // (sandboxed iframe / disabled storage). Silent fail — caller doesn't
76
+ // expect an exception out of a "save best-effort" helper.
67
77
  }
68
-
69
- const value = typeof data === 'object' ? JSON.stringify(data) : data
70
- window.localStorage.setItem(key, value)
71
78
  }
@@ -16,6 +16,8 @@ var __copyProps = (to, from, except, desc) => {
16
16
  return to;
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/browser.js
19
21
  var browser_exports = {};
20
22
  __export(browser_exports, {
21
23
  toggleFullscreen: () => toggleFullscreen
package/dist/cjs/date.js CHANGED
@@ -16,12 +16,14 @@ var __copyProps = (to, from, except, desc) => {
16
16
  return to;
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/date.js
19
21
  var date_exports = {};
20
22
  __export(date_exports, {
21
23
  formatDate: () => formatDate
22
24
  });
23
25
  module.exports = __toCommonJS(date_exports);
24
- const formatDate = (timestamp) => {
26
+ var formatDate = (timestamp) => {
25
27
  if (!timestamp) return "";
26
28
  const d = new Date(timestamp);
27
29
  const ye = new Intl.DateTimeFormat("en", { year: "numeric" }).format(d);
@@ -16,46 +16,37 @@ var __copyProps = (to, from, except, desc) => {
16
16
  return to;
17
17
  };
18
18
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
+
20
+ // src/detectHeight.js
19
21
  var detectHeight_exports = {};
20
22
  __export(detectHeight_exports, {
21
23
  detectHeightOnInit: () => detectHeightOnInit
22
24
  });
23
25
  module.exports = __toCommonJS(detectHeight_exports);
24
- const detectHeightOnInit = (element, state) => {
26
+ var detectHeightOnInit = (element, state) => {
25
27
  const heightTimeout = setTimeout(() => {
26
28
  const { props } = element;
27
29
  if (!state.clientHeight) {
28
- const {
29
- node: { clientHeight }
30
- } = element;
30
+ const { node: { clientHeight } } = element;
31
31
  if (clientHeight) {
32
32
  state.clientHeight = clientHeight;
33
33
  }
34
34
  }
35
35
  if (state.active) {
36
36
  if (props.height === "auto") return;
37
- element.update(
38
- {
39
- height: state.clientHeight
40
- },
41
- { preventBeforeUpdateListener: true, preventChildrenUpdate: true }
42
- );
37
+ element.update({
38
+ props: { height: state.clientHeight }
39
+ }, { preventBeforeUpdateListener: true, preventChildrenUpdate: true });
43
40
  const setAutoTimeout = setTimeout(() => {
44
- element.update(
45
- {
46
- height: "auto"
47
- },
48
- { preventBeforeUpdateListener: true, preventChildrenUpdate: true }
49
- );
41
+ element.update({
42
+ props: { height: "auto" }
43
+ }, { preventBeforeUpdateListener: true, preventChildrenUpdate: true });
50
44
  clearTimeout(setAutoTimeout);
51
45
  }, 450);
52
46
  } else {
53
- element.update(
54
- {
55
- height: "0"
56
- },
57
- { preventBeforeUpdateListener: true, preventChildrenUpdate: true }
58
- );
47
+ element.update({
48
+ props: { height: "0" }
49
+ }, { preventBeforeUpdateListener: true, preventChildrenUpdate: true });
59
50
  }
60
51
  clearTimeout(heightTimeout);
61
52
  });