@splendidlabz/utils 1.5.0 → 1.5.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 (156) hide show
  1. package/CHANGELOG.md +71 -1
  2. package/dist/dom/accessibility.d.ts +28 -0
  3. package/dist/dom/actions/index.d.ts +3 -0
  4. package/dist/dom/actions/masonry.d.ts +3 -0
  5. package/dist/dom/actions/prefer-horizontal-scroll.d.ts +3 -0
  6. package/dist/dom/actions/sticky.d.ts +3 -0
  7. package/dist/dom/bounding-box.d.ts +39 -0
  8. package/dist/dom/clipboard.d.ts +5 -0
  9. package/dist/dom/cookie.d.ts +11 -0
  10. package/dist/dom/css-vars.d.ts +4 -0
  11. package/dist/dom/events.d.ts +18 -0
  12. package/dist/dom/focusable.d.ts +76 -0
  13. package/dist/dom/font-size.d.ts +5 -0
  14. package/dist/dom/get-element.d.ts +100 -0
  15. package/dist/dom/hash.d.ts +1 -0
  16. package/dist/dom/index.d.ts +22 -0
  17. package/dist/dom/keyboard.d.ts +30 -0
  18. package/dist/dom/local-store.d.ts +29 -0
  19. package/dist/dom/media.d.ts +3 -0
  20. package/dist/dom/observers/index.d.ts +3 -0
  21. package/dist/dom/observers/intersection-observer.d.ts +8 -0
  22. package/dist/dom/observers/mutation-observer.d.ts +7 -0
  23. package/dist/dom/observers/observer.d.ts +1 -0
  24. package/dist/dom/observers/resize-observer.d.ts +38 -0
  25. package/dist/dom/pkce.d.ts +6 -0
  26. package/dist/dom/query-params.d.ts +4 -0
  27. package/dist/dom/random-string.d.ts +7 -0
  28. package/dist/dom/sanitize.d.ts +8 -0
  29. package/dist/dom/session-store.d.ts +5 -0
  30. package/dist/dom/trap-focus.d.ts +28 -0
  31. package/dist/dom/ui/aria-current.d.ts +5 -0
  32. package/dist/dom/ui/inconsistent-button-fix.d.ts +12 -0
  33. package/dist/dom/ui/index.d.ts +4 -0
  34. package/dist/dom/ui/scroll-container.d.ts +1 -0
  35. package/dist/dom/ui/traverse-and-scramble.d.ts +19 -0
  36. package/dist/lib/arrays/index.d.ts +5 -0
  37. package/dist/lib/arrays/item-position.d.ts +14 -0
  38. package/dist/lib/arrays/join.d.ts +13 -0
  39. package/dist/lib/arrays/shuffle.d.ts +1 -0
  40. package/dist/lib/arrays/sort.d.ts +30 -0
  41. package/dist/lib/arrays/unique.d.ts +1 -0
  42. package/dist/lib/auth/index.d.ts +1 -0
  43. package/dist/lib/auth/route-manager.d.ts +25 -0
  44. package/dist/lib/checks.d.ts +29 -0
  45. package/dist/lib/date/days.d.ts +5 -0
  46. package/dist/lib/date/index.d.ts +3 -0
  47. package/dist/lib/date/months.d.ts +9 -0
  48. package/dist/lib/date/time.d.ts +8 -0
  49. package/dist/lib/form/form-data.d.ts +7 -0
  50. package/dist/lib/form/index.d.ts +2 -0
  51. package/dist/lib/form/sanitize.d.ts +58 -0
  52. package/dist/lib/functions/debounce.d.ts +1 -0
  53. package/dist/lib/functions/env.d.ts +1 -0
  54. package/dist/lib/functions/functional.d.ts +4 -0
  55. package/dist/lib/functions/index.d.ts +5 -0
  56. package/dist/lib/functions/throttle.d.ts +1 -0
  57. package/dist/lib/functions/timeout.d.ts +3 -0
  58. package/dist/lib/index.d.ts +13 -0
  59. package/dist/lib/numbers/index.d.ts +2 -0
  60. package/dist/lib/numbers/math.d.ts +2 -0
  61. package/dist/lib/objects/camelcase-keys.d.ts +1 -0
  62. package/dist/lib/objects/empty.d.ts +2 -0
  63. package/dist/lib/objects/equal.d.ts +2 -0
  64. package/dist/lib/objects/extend.d.ts +4 -0
  65. package/dist/lib/objects/flatten.d.ts +4 -0
  66. package/dist/lib/objects/index.d.ts +13 -0
  67. package/dist/lib/objects/json.d.ts +1 -0
  68. package/dist/lib/objects/loop.d.ts +2 -0
  69. package/dist/lib/objects/mix/mix.d.ts +1 -0
  70. package/dist/lib/objects/nested-property.d.ts +22 -0
  71. package/dist/lib/objects/normalize-object.d.ts +1 -0
  72. package/dist/lib/objects/omit-empty.d.ts +1 -0
  73. package/dist/lib/objects/size.d.ts +1 -0
  74. package/dist/lib/objects/split.d.ts +10 -0
  75. package/dist/lib/promises/index.d.ts +1 -0
  76. package/dist/lib/promises/reject.d.ts +3 -0
  77. package/dist/lib/sse.d.ts +16 -0
  78. package/dist/lib/strings/convert-case/convert-case.d.ts +8 -0
  79. package/dist/lib/strings/index.d.ts +4 -0
  80. package/dist/lib/strings/markdown.d.ts +23 -0
  81. package/dist/lib/strings/pluralize.d.ts +1 -0
  82. package/dist/lib/strings/query-string.d.ts +8 -0
  83. package/dist/lib/style/index.d.ts +1 -0
  84. package/dist/lib/symbols/index.d.ts +1 -0
  85. package/dist/lib/symbols/symbols.d.ts +2 -0
  86. package/dist/node/common.d.ts +1 -0
  87. package/dist/node/dirname.d.ts +7 -0
  88. package/dist/node/file-cache.d.ts +54 -0
  89. package/dist/node/file.d.ts +2 -0
  90. package/dist/node/hash.d.ts +1 -0
  91. package/dist/node/index.d.ts +7 -0
  92. package/dist/node/pkce.d.ts +6 -0
  93. package/dist/node/random-string.d.ts +2 -0
  94. package/dist/node/sanitize.d.ts +8 -0
  95. package/dom/accessibility.js +46 -13
  96. package/{actions → dom/actions}/index.js +0 -2
  97. package/dom/actions/masonry.js +42 -0
  98. package/{actions → dom/actions}/prefer-horizontal-scroll.js +8 -8
  99. package/{actions → dom/actions}/sticky.js +3 -6
  100. package/dom/bounding-box.js +35 -7
  101. package/dom/css-vars.js +8 -0
  102. package/dom/events.js +2 -1
  103. package/dom/focusable.js +119 -10
  104. package/dom/font-size.js +21 -10
  105. package/dom/get-element.js +112 -5
  106. package/dom/index.js +3 -0
  107. package/dom/keyboard.js +13 -8
  108. package/dom/local-store.js +37 -0
  109. package/dom/media.js +1 -0
  110. package/dom/observers/index.js +3 -0
  111. package/dom/observers/intersection-observer.js +43 -0
  112. package/dom/observers/mutation-observer.js +51 -0
  113. package/dom/observers/observer.js +18 -0
  114. package/dom/observers/resize-observer.js +64 -0
  115. package/dom/sanitize.js +16 -0
  116. package/dom/trap-focus.js +18 -3
  117. package/dom/ui/inconsistent-button-fix.js +14 -2
  118. package/dom/ui/traverse-and-scramble.js +29 -8
  119. package/eslint.config.js +2 -0
  120. package/lib/arrays/index.js +5 -62
  121. package/lib/arrays/item-position.js +23 -0
  122. package/lib/arrays/join.js +20 -0
  123. package/lib/arrays/shuffle.js +21 -0
  124. package/lib/arrays/sort.js +88 -0
  125. package/lib/arrays/sort.spec.js +123 -0
  126. package/lib/arrays/unique.js +3 -0
  127. package/lib/checks.js +26 -0
  128. package/lib/date/index.js +2 -1
  129. package/lib/date/time.js +50 -0
  130. package/lib/form/sanitize.js +68 -35
  131. package/lib/form/sanitize.spec.js +126 -0
  132. package/lib/index.js +1 -0
  133. package/lib/numbers/index.js +2 -0
  134. package/lib/numbers/math.js +9 -0
  135. package/lib/objects/equal.js +9 -0
  136. package/lib/objects/index.js +1 -0
  137. package/lib/objects/mix/mix.js +2 -0
  138. package/lib/objects/mix/mix.test.js +16 -0
  139. package/lib/objects/nested-property.js +5 -0
  140. package/lib/sse.js +61 -0
  141. package/lib/strings/markdown.js +29 -10
  142. package/node/dirname.js +1 -1
  143. package/node/file-cache.js +46 -7
  144. package/node/index.js +1 -0
  145. package/node/sanitize.js +13 -0
  146. package/node/sanitize.spec.js +142 -0
  147. package/package.json +38 -13
  148. package/tsconfig.json +23 -0
  149. package/.eslintrc.cjs +0 -3
  150. package/.turbo/turbo-lint.log +0 -10
  151. package/.turbo/turbo-test.log +0 -10
  152. package/actions/intersection-observer.js +0 -37
  153. package/actions/masonry.js +0 -75
  154. package/actions/mutation-observer.js +0 -42
  155. package/actions/resize-observer.js +0 -33
  156. package/lib/index.test.js +0 -9
@@ -3,7 +3,18 @@ import glob from 'glob-promise'
3
3
  import path from 'node:path'
4
4
  import { sort } from '../lib/arrays/index.js'
5
5
 
6
- // Newer and nicer API
6
+ /**
7
+ * Creates a file cache instance for managing cached files in a directory
8
+ * @param {string} dir - Relative path to cache directory
9
+ * @returns {Promise<object>} Cache instance
10
+ * @property {function(string): Promise<number>} cacheAt - Returns the cached file's modified timestamp, or directory's last modified time if no file specified
11
+ * @property {function(string): string} getAbsPath - Returns absolute path for a file in cache
12
+ * @property {function(string): Promise<boolean>} hasFile - Checks if a file exists in cache
13
+ * @property {function(string): Promise<Buffer|undefined>} loadFile - Loads file contents from cache
14
+ * @property {function(string, string|Buffer): Promise<void>} saveFile - Saves data to cache file
15
+ * @property {function(string): Promise<object>} loadJSON - Loads and parses JSON from cache file
16
+ * @property {function(string, object): Promise<void>} saveJSON - Saves object as JSON to cache file
17
+ */
7
18
  export async function createCache(dir) {
8
19
  const absDirpath = path.join(process.cwd(), dir)
9
20
  await fs.mkdir(absDirpath, { recursive: true })
@@ -56,7 +67,7 @@ export async function createCache(dir) {
56
67
  async loadJSON(file) {
57
68
  const data = await this.loadFile(file)
58
69
  try {
59
- return JSON.parse(data)
70
+ return JSON.parse(data.toString())
60
71
  } catch (err) {
61
72
  console.warn(`Error parsing JSON: ${file}`)
62
73
  return {}
@@ -69,7 +80,19 @@ export async function createCache(dir) {
69
80
  }
70
81
  }
71
82
 
72
- // Legacy, not so nice API
83
+ /**
84
+ * Legacy file cache API for managing a single cached file
85
+ * @param {Object} options
86
+ * @param {string} options.dir - Relative path to cache directory
87
+ * @param {string} options.file - Filename to cache
88
+ * @returns {Promise<{
89
+ * modifiedAt: number,
90
+ * load: () => Promise<Buffer>,
91
+ * save: (data: string|Buffer) => Promise<void>,
92
+ * loadJSON: () => Promise<object>,
93
+ * saveJSON: (data: object) => Promise<void>
94
+ * }>}
95
+ */
73
96
  export async function fileCache({ dir, file }) {
74
97
  // Makes the path if it doesn't exist
75
98
  await fs.mkdir(path.join(process.cwd(), dir), { recursive: true })
@@ -94,7 +117,8 @@ export async function fileCache({ dir, file }) {
94
117
  },
95
118
 
96
119
  async loadJSON() {
97
- return JSON.parse(await fs.readFile(cachePath))
120
+ const data = await fs.readFile(cachePath)
121
+ return JSON.parse(data.toString())
98
122
  },
99
123
  async saveJSON(data) {
100
124
  await fs.writeFile(cachePath, JSON.stringify(data))
@@ -102,6 +126,11 @@ export async function fileCache({ dir, file }) {
102
126
  }
103
127
  }
104
128
 
129
+ /**
130
+ * Gets the most recent modification time of files matching the glob pattern
131
+ * @param {string|string[]} globPath - Glob pattern(s) to match files
132
+ * @returns {Promise<number>} Timestamp of most recently modified file, or 0 if no files found
133
+ */
105
134
  export async function getLastModifiedTime(globPath) {
106
135
  let files
107
136
 
@@ -116,13 +145,18 @@ export async function getLastModifiedTime(globPath) {
116
145
  files = a.flat()
117
146
  }
118
147
 
119
- files = await Promise.all(files.map(fs.stat))
120
- files = files.map(file => file.mtimeMs)
148
+ const stats = await Promise.all(files.map(file => fs.stat(file)))
149
+ const timestamps = stats.map(stat => Number(stat.mtimeMs))
121
150
 
122
- const sorted = sort(files, { sortBy: 'mtimeMs', order: 'desc' })
151
+ const sorted = sort(timestamps, { props: 'mtimeMs', reverse: true })
123
152
  return sorted[0] || 0
124
153
  }
125
154
 
155
+ /**
156
+ * @deprecated Use getLastModifiedTime instead
157
+ * @param {string|string[]} globPath - Glob pattern(s) to match files
158
+ * @returns {Promise<number>} Timestamp of most recently modified file, or 0 if no files found
159
+ */
126
160
  export async function getLatestModifiedTime(globPath) {
127
161
  console.warn(
128
162
  '`getLatestModifiedTime` has been renamed to `getLastModifiedTime` and will be deprecated in future versions. Please use `getLastModifiedTime` instead.',
@@ -130,6 +164,11 @@ export async function getLatestModifiedTime(globPath) {
130
164
  return getLastModifiedTime(globPath)
131
165
  }
132
166
 
167
+ /**
168
+ * Removes leading slash from a path string
169
+ * @param {string} x - Path string to process
170
+ * @returns {string} Path without leading slash
171
+ */
133
172
  export function removeFirstSlash(x) {
134
173
  return x.startsWith('/') ? x.slice(1) : x
135
174
  }
package/node/index.js CHANGED
@@ -4,3 +4,4 @@ export * from './file-cache.js'
4
4
  export * from './hash.js'
5
5
  export * from './pkce.js'
6
6
  export * from './random-string.js'
7
+ export * from './sanitize.js'
@@ -0,0 +1,13 @@
1
+ import sanitizeHtml from 'sanitize-html'
2
+ import { sanitize as sanitizeLib } from '../lib/form/sanitize.js'
3
+
4
+ /**
5
+ * Sanitizes values using sanitize-html
6
+ * @param {*} value - Value to sanitize (string, array, or object)
7
+ * @param {Object} [options={}] - sanitize-html options
8
+ * @returns {*} Sanitized value
9
+ * @throws {Error} If input is a string but sanitize-html fails
10
+ */
11
+ export function sanitize(value, options = {}) {
12
+ return sanitizeLib(value, { sanitizer: sanitizeHtml, ...options })
13
+ }
@@ -0,0 +1,142 @@
1
+ import { describe, expect, it } from 'vitest'
2
+ import { sanitize } from './sanitize.js'
3
+
4
+ describe('node sanitize', () => {
5
+ describe('sanitize', () => {
6
+ it('removes script tags', () => {
7
+ const input = '<script>alert("xss")</script>Hello'
8
+ expect(sanitize(input)).toBe('Hello')
9
+ })
10
+
11
+ it('allows safe HTML tags', () => {
12
+ const input = '<p>Hello <b>World</b></p>'
13
+ expect(sanitize(input, { allowedTags: ['b'] })).toBe('Hello <b>World</b>')
14
+ })
15
+
16
+ it('sanitizes unsafe attributes', () => {
17
+ const input = '<a href="javascript:alert(1)">Click me</a>'
18
+ expect(
19
+ sanitize(input, {
20
+ allowedTags: ['a'],
21
+ allowedAttributes: { a: ['href'] },
22
+ }),
23
+ ).toBe('<a>Click me</a>')
24
+ })
25
+
26
+ it('allows safe attributes', () => {
27
+ const input = '<a href="https://example.com">Safe link</a>'
28
+ expect(
29
+ sanitize(input, {
30
+ allowedTags: ['a'],
31
+ allowedAttributes: { a: ['href'] },
32
+ }),
33
+ ).toBe('<a href="https://example.com">Safe link</a>')
34
+ })
35
+
36
+ it('sanitizes HTML in string values', () => {
37
+ const input = {
38
+ name: '<script>alert("xss")</script>John',
39
+ bio: '<p>Hello <b>World</b> <script>alert("xss")</script></p>',
40
+ link: '<a href="javascript:alert(1)">Click me</a>',
41
+ safeLink: '<a href="https://example.com">Safe link</a>',
42
+ }
43
+
44
+ const expected = {
45
+ name: 'John',
46
+ bio: 'Hello <b>World</b> ',
47
+ link: '<a>Click me</a>',
48
+ safeLink: '<a href="https://example.com">Safe link</a>',
49
+ }
50
+
51
+ expect(
52
+ sanitize(input, {
53
+ allowedTags: ['b', 'i', 'em', 'strong', 'a'],
54
+ allowedAttributes: { a: ['href'] },
55
+ }),
56
+ ).toEqual(expected)
57
+ })
58
+
59
+ it('sanitizes nested objects with HTML', () => {
60
+ const input = {
61
+ user: {
62
+ name: '<script>alert("xss")</script>John',
63
+ profile: {
64
+ bio: '<p>Hello <b>World</b></p>',
65
+ links: [
66
+ '<a href="javascript:alert(1)">Bad</a>',
67
+ '<a href="https://good.com">Good</a>',
68
+ ],
69
+ },
70
+ },
71
+ }
72
+
73
+ const expected = {
74
+ user: {
75
+ name: 'John',
76
+ profile: {
77
+ bio: 'Hello <b>World</b>',
78
+ links: ['<a>Bad</a>', '<a href="https://good.com">Good</a>'],
79
+ },
80
+ },
81
+ }
82
+
83
+ expect(
84
+ sanitize(input, {
85
+ allowedTags: ['b', 'i', 'em', 'strong', 'a'],
86
+ allowedAttributes: { a: ['href'] },
87
+ }),
88
+ ).toEqual(expected)
89
+ })
90
+
91
+ it('preserves non-string values and sanitizes arrays correctly', () => {
92
+ const input = {
93
+ name: '<script>alert("xss")</script>John',
94
+ age: 25,
95
+ active: true,
96
+ email: null,
97
+ role: undefined,
98
+ tags: ['<script>alert(1)</script>admin', 'user'],
99
+ numbers: [1, 2, 3],
100
+ mixed: ['<b>bold</b>', 42, null, '<script>alert(1)</script>text'],
101
+ }
102
+
103
+ const expected = {
104
+ name: 'John',
105
+ age: 25,
106
+ active: true,
107
+ email: null,
108
+ role: undefined,
109
+ tags: ['admin', 'user'],
110
+ numbers: [1, 2, 3],
111
+ mixed: ['<b>bold</b>', 42, null, 'text'],
112
+ }
113
+
114
+ expect(
115
+ sanitize(input, {
116
+ allowedTags: ['b', 'i', 'em', 'strong', 'a'],
117
+ allowedAttributes: { a: ['href'] },
118
+ }),
119
+ ).toEqual(expected)
120
+ })
121
+
122
+ it('allows custom sanitizer options', () => {
123
+ const input = {
124
+ content: '<p>Hello <span>World</span> <script>alert(1)</script></p>',
125
+ }
126
+
127
+ // Test with custom allowed tags
128
+ const withSpan = sanitize(input, {
129
+ allowedTags: ['b', 'i', 'em', 'strong', 'a', 'span'],
130
+ allowedAttributes: { a: ['href'] },
131
+ })
132
+ expect(withSpan.content).toBe('Hello <span>World</span> ')
133
+
134
+ // Test with no allowed tags
135
+ const noTags = sanitize(input, {
136
+ allowedTags: [],
137
+ allowedAttributes: { a: ['href'] },
138
+ })
139
+ expect(noTags.content).toBe('Hello World ')
140
+ })
141
+ })
142
+ })
package/package.json CHANGED
@@ -1,35 +1,60 @@
1
1
  {
2
2
  "name": "@splendidlabz/utils",
3
- "version": "1.5.0",
3
+ "version": "1.5.1",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "sideEffects": false,
7
7
  "exports": {
8
- ".": "./lib/index.js",
9
- "./lib/*": "./lib/*.js",
10
- "./dom": "./dom/index.js",
11
- "./dom/*": "./dom/*.js",
12
- "./actions": "./actions/index.js",
13
- "./actions/*": "./actions/*.js",
14
- "./node": "./node/index.js",
15
- "./node/*": "./node/*.js"
8
+ ".": {
9
+ "types": "./dist/index.d.ts",
10
+ "import": "./lib/index.js"
11
+ },
12
+ "./lib/*": {
13
+ "types": "./dist/lib/*.d.ts",
14
+ "import": "./lib/*.js"
15
+ },
16
+ "./dom": {
17
+ "types": "./dist/dom/index.d.ts",
18
+ "import": "./dom/index.js"
19
+ },
20
+ "./dom/*": {
21
+ "types": "./dist/dom/*.d.ts",
22
+ "import": "./dom/*.js"
23
+ },
24
+ "./node": {
25
+ "types": "./dist/node/index.d.ts",
26
+ "import": "./node/index.js"
27
+ },
28
+ "./node/*": {
29
+ "types": "./dist/node/*.d.ts",
30
+ "import": "./node/*.js"
31
+ }
16
32
  },
17
33
  "scripts": {
18
34
  "lint": "eslint . --fix",
19
- "test": "vitest run",
20
- "test:watch": "vitest"
35
+ "test": "npm run type-check && vitest run",
36
+ "test:watch": "vitest",
37
+ "type-check": "tsc --noEmit",
38
+ "build": "tsc",
39
+ "prepublishOnly": "npm run build"
21
40
  },
22
41
  "author": "Zell Liew <zellwk@gmail.com>",
23
42
  "dependencies": {
43
+ "deep-eql": "^5.0.2",
24
44
  "dompurify": "^3.2.4",
25
45
  "glob-promise": "^6.0.7",
46
+ "marked": "^15.0.7",
47
+ "marked-gfm-heading-id": "^4.1.1",
48
+ "marked-mangle": "^1.1.10",
26
49
  "pluralize": "^8.0.0",
50
+ "sanitize-html": "^2.17.0",
27
51
  "statuses": "^2.0.1"
28
52
  },
29
53
  "devDependencies": {
30
- "@splendidlabz/eslint-config": "*",
54
+ "@splendidlabz/eslint-config": "2.0.0",
31
55
  "jsdom": "^26.0.0",
32
56
  "np": "^10.2.0",
33
- "vitest": "^3.0.7"
57
+ "typescript": "^5.4.2",
58
+ "vitest": "^3.1.1"
34
59
  }
35
60
  }
package/tsconfig.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2020",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "allowJs": true,
7
+ "checkJs": true,
8
+ "declaration": true,
9
+ "emitDeclarationOnly": true,
10
+ "outDir": "./dist",
11
+ "strict": false,
12
+ "noImplicitAny": false,
13
+ "skipLibCheck": true,
14
+ "forceConsistentCasingInFileNames": true,
15
+ "resolveJsonModule": true,
16
+ "isolatedModules": true,
17
+ "noEmit": false,
18
+ "esModuleInterop": true,
19
+ "allowSyntheticDefaultImports": true
20
+ },
21
+ "include": ["lib/**/*", "dom/**/*", "node/**/*"],
22
+ "exclude": ["node_modules", "**/*.test.js", "**/*.spec.js"]
23
+ }
package/.eslintrc.cjs DELETED
@@ -1,3 +0,0 @@
1
- module.exports = {
2
- extends: ['@splendidlabz/eslint-config'],
3
- }
@@ -1,10 +0,0 @@
1
-
2
- > @splendidlabs/utils@1.0.3 lint
3
- > eslint . --fix
4
-
5
- 
6
- /Users/zellwk/projects/@splendidlabs/packages/utils/lib/index.test.js
7
-  4:10 error 'expect' is defined but never used no-unused-vars
8
- 
9
- ✖ 1 problem (1 error, 0 warnings)
10
- 
@@ -1,10 +0,0 @@
1
-
2
- > @splendidlabs/utils@1.0.3 test
3
- > vitest run
4
-
5
- sh: vitest: command not found
6
- npm ERR! Lifecycle script `test` failed with error:
7
- npm ERR! Error: command failed
8
- npm ERR!  in workspace: @splendidlabs/utils@1.0.3
9
- npm ERR!  at location: /Users/zellwk/projects/@splendidlabs/packages/utils
10
- 
@@ -1,37 +0,0 @@
1
- // See https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/IntersectionObserver#options for options
2
- const options = {}
3
-
4
- export function intersectionObserver(node, options) {
5
- const { callback, opts } = options
6
- const observer = new IntersectionObserver(observerFn, opts)
7
-
8
- function observerFn(entries, observer) {
9
- entries.forEach(entry => {
10
- for (const entry of entries) {
11
- // Needs testing to see what's in entry
12
- if (callback) callback({ node, entry, observer })
13
- else {
14
- node.dispatchEvent(
15
- new CustomEvent('intersect', {
16
- detail: { node, entry, observer },
17
- }),
18
- )
19
- }
20
- }
21
- })
22
- }
23
-
24
- observer.observe(node)
25
-
26
- return {
27
- observer,
28
- disconnect() {
29
- observer.disconnect()
30
- },
31
-
32
- // Destroy is used for Svelte actions
33
- destroy() {
34
- observer.disconnect()
35
- },
36
- }
37
- }
@@ -1,75 +0,0 @@
1
- import { getChildrenElements, mediaLoaded } from '../dom'
2
-
3
- import { resizeObserver } from './resize-observer'
4
-
5
- export async function masonry(node) {
6
- if (nativeMasonrySupport(node)) return
7
-
8
- const colGap = parseFloat(getComputedStyle(node).columnGap)
9
- const items = getChildrenElements(node)
10
-
11
- node.style.setProperty('row-gap', '1px', 'important')
12
- node.style.gridAutoRows = '0px'
13
-
14
- try {
15
- await mediaLoaded(node)
16
- } catch (e) {}
17
-
18
- layout({ colGap, items })
19
-
20
- const obs = resizeObserver(node, {
21
- async callback(opts) {
22
- layout({ colGap, items })
23
- },
24
- })
25
-
26
- async function layout({ colGap, items }) {
27
- items.forEach(item => {
28
- const ib = item.getBoundingClientRect()
29
- item.style.gridRowEnd = `span ${Math.round(ib.height + colGap)}`
30
- })
31
- }
32
-
33
- return {
34
- destroy() {
35
- obs.disconnect()
36
- },
37
- }
38
- }
39
-
40
- // export async function masonry(node) {
41
- // if (typeof window === 'undefined') return
42
- // if (nativeMasonrySupport(node)) return
43
-
44
- // let items
45
- // let gap
46
-
47
- // node.style.setProperty('row-gap', '1px', 'important')
48
- // node.style.gridAutoRows = '0px'
49
- // // await mediaLoaded(node)
50
-
51
- // const obs = resizeObserver(node, {
52
- // async callback(opts) {
53
- // items = getChildrenElements(node)
54
- // gap = parseFloat(getComputedStyle(node).columnGap)
55
- // layout(node)
56
- // },
57
- // })
58
-
59
- // async function layout() {
60
- // items.forEach(item => {
61
- // const itemBox = item.getBoundingClientRect()
62
- // // item.style.gridRowEnd = `span ${Math.round(itemBox.height + gap)}`
63
- // })
64
- // }
65
-
66
- // return {
67
- // destroy() {
68
- // obs.disconnect()
69
- // },
70
- // }
71
- // }
72
-
73
- function nativeMasonrySupport(node) {
74
- return getComputedStyle(node).gridTemplateRows === 'masonry'
75
- }
@@ -1,42 +0,0 @@
1
- /* eslint-env browser */
2
- // https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe
3
-
4
- // These are simply options that will often be used. Check the docs for other options.
5
- const defaultOptions = {
6
- attributes: false,
7
- childList: false,
8
- subtree: false,
9
- }
10
-
11
- export function mutationObserver(node, options) {
12
- options = { ...defaultOptions, ...options }
13
- const { callback, ...opts } = options
14
- const observer = new MutationObserver(observerFn)
15
-
16
- function observerFn(entries) {
17
- for (const entry of entries) {
18
- if (callback) callback({ node, entry, observer })
19
- else {
20
- node.dispatchEvent(
21
- new CustomEvent('mutate', {
22
- detail: { node, entry, observer },
23
- }),
24
- )
25
- }
26
- }
27
- }
28
-
29
- if (node === window) node = document.body
30
- observer.observe(node, opts)
31
-
32
- return {
33
- disconnect() {
34
- observer.disconnect()
35
- },
36
-
37
- // Destroy is used for Svelte actions
38
- destroy() {
39
- observer.disconnect()
40
- },
41
- }
42
- }
@@ -1,33 +0,0 @@
1
- /* eslint-env browser */
2
- export function resizeObserver(node, options) {
3
- // We set the option here to prevent observer from being created unless necessary.
4
- options = { observe: true, ...options }
5
- if (!options.observe) return
6
-
7
- const observer = new ResizeObserver(observerFn)
8
-
9
- function observerFn(entries) {
10
- for (const entry of entries) {
11
- if (options.callback) options.callback({ node, entry, entries, observer })
12
- else {
13
- node.dispatchEvent(
14
- new CustomEvent('resize-obs', {
15
- detail: { node, entry, entries, observer },
16
- }),
17
- )
18
- }
19
- }
20
- }
21
-
22
- observer.observe(node)
23
-
24
- return {
25
- disconnect() {
26
- observer.unobserve(node)
27
- },
28
-
29
- destroy() {
30
- observer.unobserve(node)
31
- },
32
- }
33
- }
package/lib/index.test.js DELETED
@@ -1,9 +0,0 @@
1
- // Possible to test???
2
- import * as test from './index.js'
3
-
4
- import { expect, it } from 'vitest'
5
-
6
- it('Import Test', () => {
7
- console.log(test)
8
- console.log('hello')
9
- })