@stacksjs/utils 0.64.6 → 0.65.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.
@@ -0,0 +1 @@
1
+ export { Macroable } from "macroable";
@@ -0,0 +1,2 @@
1
+ export declare const components: unknown;
2
+ export declare const functions: unknown;
@@ -0,0 +1,2 @@
1
+ import { version } from "../package.json";
2
+ export { version };
package/package.json CHANGED
@@ -1,11 +1,12 @@
1
1
  {
2
2
  "name": "@stacksjs/utils",
3
3
  "type": "module",
4
- "version": "0.64.6",
4
+ "version": "0.65.0",
5
5
  "description": "The Stacks helper functions.",
6
6
  "author": "Chris Breuer",
7
- "funding": "https://github.com/sponsors/chrisbbreuer",
7
+ "contributors": ["Chris Breuer <chris@stacksjs.org>"],
8
8
  "license": "MIT",
9
+ "funding": "https://github.com/sponsors/chrisbbreuer",
9
10
  "homepage": "https://github.com/stacksjs/stacks/tree/main/storage/framework/core/helpers#readme",
10
11
  "repository": {
11
12
  "type": "git",
@@ -37,34 +38,28 @@
37
38
  },
38
39
  "module": "dist/index.js",
39
40
  "types": "dist/index.d.ts",
40
- "contributors": [
41
- "Chris Breuer <chris@stacksjs.org>"
42
- ],
43
- "files": [
44
- "README.md",
45
- "dist",
46
- "src"
47
- ],
41
+ "files": ["README.md", "dist", "src"],
48
42
  "scripts": {
49
- "build": "bun --bun build.ts",
50
- "typecheck": "bun --bun tsc --noEmit",
43
+ "build": "bun build.ts",
44
+ "typecheck": "bun tsc --noEmit",
51
45
  "prepublishOnly": "bun run build",
52
46
  "size": "bun scripts/export-size.ts"
53
47
  },
54
48
  "dependencies": {
55
- "@stacksjs/actions": "latest",
56
- "@stacksjs/arrays": "latest",
57
- "@stacksjs/cli": "latest",
58
- "@stacksjs/config": "latest",
59
- "@stacksjs/lint": "latest",
60
- "@stacksjs/path": "latest",
61
- "@stacksjs/storage": "latest",
62
- "@stacksjs/strings": "latest",
63
- "@stacksjs/types": "latest",
64
- "@vueuse/core": "^11.0.3",
49
+ "@stacksjs/actions": "0.64.6",
50
+ "@stacksjs/arrays": "0.64.6",
51
+ "@stacksjs/cli": "0.64.6",
52
+ "@stacksjs/config": "0.64.6",
53
+ "@stacksjs/lint": "0.64.6",
54
+ "@stacksjs/path": "0.64.6",
55
+ "@stacksjs/storage": "0.64.6",
56
+ "@stacksjs/strings": "0.64.6",
57
+ "@stacksjs/types": "0.64.6",
58
+ "@vueuse/core": "^11.1.0",
65
59
  "@vueuse/head": "^2.0.0",
66
- "@vueuse/math": "^11.0.3",
67
- "@vueuse/shared": "^11.0.3",
60
+ "@vueuse/math": "^11.1.0",
61
+ "@vueuse/shared": "^11.1.0",
62
+ "ace-builds": "^1.36.2",
68
63
  "bun-plugin-env": "^0.4.1",
69
64
  "bun-plugin-yml": "^0.3.1",
70
65
  "defu": "^6.1.4",
@@ -77,13 +72,12 @@
77
72
  "magic-regexp": "^0.8.0",
78
73
  "perfect-debounce": "^1.0.0",
79
74
  "pretty-bytes": "^6.1.1",
80
- "ace-builds": "^1.36.0",
81
75
  "resize-observer-polyfill": "^1.5.1",
82
76
  "vue3-ace-editor": "^2.2.4",
83
- "yaml": "^2.5.0"
77
+ "yaml": "^2.5.1"
84
78
  },
85
79
  "devDependencies": {
86
- "@stacksjs/development": "latest",
80
+ "@stacksjs/development": "0.64.6",
87
81
  "@types/js-yaml": "^4.0.9",
88
82
  "markdown-table": "^3.0.3",
89
83
  "vue-starport": "^0.4.0"
package/src/clean.ts CHANGED
@@ -11,5 +11,5 @@ export async function cleanProject() {
11
11
  await $`rm -rf ${p.frameworkPath('**/node_modules')}`
12
12
  await $`rm -rf ${p.frameworkCloudPath('cdk.out/')}`
13
13
  await $`rm -rf ${p.frameworkCloudPath('cdk.context.json')}`
14
- await $`rm -rf ${p.frameworkCloudPath('dist.zip')}`
14
+ await $`rm -rf ${p.cloudPath('dist.zip')}`
15
15
  }
package/src/config.ts CHANGED
@@ -1,25 +1,25 @@
1
1
  export {
2
2
  defineApp,
3
3
  defineCache,
4
- defineCli,
5
4
  defineCdn,
5
+ defineChat,
6
+ defineCli,
6
7
  defineCronJob,
7
- defineJob,
8
- defineDependencies,
9
8
  defineDatabase,
9
+ defineDependencies,
10
10
  defineDns,
11
+ defineEmail,
11
12
  defineEmailConfig,
12
13
  defineGit,
13
14
  defineHashing,
15
+ defineJob,
14
16
  defineLibrary,
15
17
  defineNotification,
16
- defineSms,
17
- defineEmail,
18
- defineChat,
19
18
  definePayment,
20
19
  defineQueue,
21
20
  defineSearchEngine,
22
21
  defineServices,
22
+ defineSms,
23
23
  defineStorage,
24
24
  defineUi,
25
25
  } from '@stacksjs/config'
package/src/equal.ts CHANGED
@@ -3,10 +3,12 @@ import { getTypeName } from '@stacksjs/types'
3
3
  export function isDeepEqual(value1: any, value2: any): boolean {
4
4
  const type1 = getTypeName(value1)
5
5
  const type2 = getTypeName(value2)
6
- if (type1 !== type2) return false
6
+ if (type1 !== type2)
7
+ return false
7
8
 
8
9
  if (type1 === 'array') {
9
- if (value1.length !== value2.length) return false
10
+ if (value1.length !== value2.length)
11
+ return false
10
12
 
11
13
  return value1.every((item: any, i: number) => {
12
14
  return isDeepEqual(item, value2[i])
@@ -14,7 +16,8 @@ export function isDeepEqual(value1: any, value2: any): boolean {
14
16
  }
15
17
  if (type1 === 'object') {
16
18
  const keyArr = Object.keys(value1)
17
- if (keyArr.length !== Object.keys(value2).length) return false
19
+ if (keyArr.length !== Object.keys(value2).length)
20
+ return false
18
21
 
19
22
  return keyArr.every((key: string) => {
20
23
  return isDeepEqual(value1[key], value2[key])
package/src/find.ts CHANGED
@@ -1,3 +1,4 @@
1
+ /* eslint no-console: 0 */
1
2
  import type { Dirent } from 'node:fs'
2
3
  import fs from 'node:fs/promises'
3
4
  import os from 'node:os'
@@ -11,11 +12,12 @@ const excludePatterns = [
11
12
  'node_modules',
12
13
  'dist',
13
14
  'vendor',
15
+ 'storage/framework',
14
16
  `${os.homedir()}/Documents`,
15
17
  `${os.homedir()}/Pictures`,
16
18
  `${os.homedir()}/Library`,
17
19
  `${os.homedir()}/.Trash`,
18
- /.*out.*|.*\.out.*|out-.*/, // exclude any folder with 'out' in the name
20
+ /.*out.*/, // exclude any folder with 'out' in the name
19
21
  /.*\/\..*/, // exclude any folder that starts with a dot
20
22
  ]
21
23
 
@@ -38,25 +40,31 @@ export async function findStacksProjects(dir?: string, options?: FindStacksProje
38
40
 
39
41
  const foundProjects = await searchDirectory(dir)
40
42
 
41
- if (!foundProjects) throw new Error('No Stacks projects found')
43
+ if (!foundProjects)
44
+ throw new Error('No Stacks projects found')
42
45
 
43
46
  return foundProjects
44
47
  }
45
48
 
46
- async function searchDirectory(directory: string) {
49
+ // this searches a dir for Stacks projects which we define
50
+ // as a dir that contains a 'buddy' file and a 'storage'
51
+ // dir with a 'framework/core/buddy' structure
52
+ async function searchDirectory(directory: string): Promise<string[]> {
47
53
  const foundProjects: string[] = []
48
-
49
- const isExcluded = excludePatterns.some((pattern) =>
54
+ const isExcluded = excludePatterns.some(pattern =>
50
55
  typeof pattern === 'string' ? directory.includes(pattern) : pattern.test(directory),
51
56
  )
52
- if (isExcluded) return
57
+
58
+ if (isExcluded)
59
+ return foundProjects
53
60
 
54
61
  let items: Dirent[]
55
62
  try {
56
63
  items = await fs.readdir(directory, { withFileTypes: true })
57
- } catch (error) {
64
+ }
65
+ catch (error) {
58
66
  console.error(`Error reading directory ${directory}:`, error)
59
- return
67
+ return foundProjects
60
68
  }
61
69
 
62
70
  let buddyFileFound = false
@@ -65,24 +73,30 @@ async function searchDirectory(directory: string) {
65
73
  for (const item of items) {
66
74
  if (item.isFile() && item.name === targetFileName) {
67
75
  buddyFileFound = true
68
- } else if (item.isDirectory()) {
69
- // Recursively search in directories
76
+ }
77
+
78
+ if (item.isDirectory()) {
70
79
  const fullPath = path.join(directory, item.name)
71
80
  if (item.name === 'storage') {
72
- // Check if the 'storage/framework/core/buddy/' structure exists within this directory
81
+ const storagePath = path.join(fullPath, 'framework/core/buddy')
73
82
  try {
74
- const storagePath = path.join(fullPath, 'framework/core/buddy')
75
83
  await fs.access(storagePath)
76
84
  storageDirFound = true
77
- } catch (error) {
78
- // The specific directory structure does not exist
85
+ }
86
+ catch (error) {
87
+ console.error(`Error accessing directory ${storagePath}:`, error)
79
88
  }
80
89
  }
81
- await searchDirectory(fullPath)
90
+
91
+ // Accumulate results from recursive calls
92
+ const subDirProjects = await searchDirectory(fullPath)
93
+ foundProjects.push(...subDirProjects)
82
94
  }
83
95
  }
84
96
 
85
- if (buddyFileFound && storageDirFound) foundProjects.push(directory) // Both conditions are met
97
+ if (buddyFileFound && storageDirFound) {
98
+ foundProjects.push(directory)
99
+ }
86
100
 
87
101
  return foundProjects
88
102
  }
package/src/git.ts CHANGED
@@ -1,10 +1,13 @@
1
1
  import { execSync } from 'node:child_process'
2
+ import { handleError } from '@stacksjs/error-handling'
2
3
 
3
- export function isGitClean() {
4
+ export function isGitClean(): boolean {
4
5
  try {
5
6
  execSync('git diff-index --quiet HEAD --')
6
7
  return true
7
- } catch (error) {
8
+ }
9
+ catch (error) {
10
+ handleError(error)
8
11
  return false
9
12
  }
10
13
  }
package/src/hash.ts CHANGED
@@ -6,15 +6,17 @@ import { hashPaths } from '@stacksjs/storage'
6
6
  export function originRequestFunctionHash() {
7
7
  try {
8
8
  return hashPaths(p.cloudPath('src/edge'))
9
- } catch (error: any) {
9
+ }
10
+ catch (error: any) {
10
11
  log.error('Are we in a Docker container? Failed to hash paths. Error below:')
11
12
  log.error(error)
12
13
  return undefined
13
14
  }
14
15
  }
15
16
 
17
+ const docsSrc = [p.projectPath('docs'), p.frameworkPath('docs/dist')]
18
+
16
19
  export function websiteSourceHash() {
17
- const docsSrc = [p.projectPath('docs')]
18
20
  const websiteSrc = [
19
21
  p.projectPath('resources/views'),
20
22
  p.projectPath('resources/assets'),
@@ -23,13 +25,12 @@ export function websiteSourceHash() {
23
25
  p.projectPath('resources/components'),
24
26
  p.projectPath('resources/modules'),
25
27
  p.projectPath('resources/stores'),
28
+ p.frameworkPath('views/web'),
26
29
  ]
27
30
 
28
31
  return config.app.docMode === true ? hashPaths(docsSrc) : hashPaths(websiteSrc)
29
32
  }
30
33
 
31
34
  export function docsSourceHash() {
32
- const docsSrc = [p.projectPath('docs')]
33
-
34
35
  return hashPaths(docsSrc)
35
36
  }
package/src/helpers.ts CHANGED
@@ -1,14 +1,14 @@
1
+ import type { NpmScript } from '@stacksjs/enums'
2
+ import type { Result } from '@stacksjs/error-handling'
3
+ import type { CliOptions, Manifest, Subprocess } from '@stacksjs/types'
1
4
  import type { AddressInfo } from 'node:net'
2
5
  import { runAction } from '@stacksjs/actions'
3
6
  import { log, runCommand } from '@stacksjs/cli'
4
7
  import { app, ui } from '@stacksjs/config'
5
- import type { NpmScript } from '@stacksjs/enums'
6
8
  import { Action } from '@stacksjs/enums'
7
- import type { Result } from '@stacksjs/error-handling'
8
9
  import { err, handleError, ok } from '@stacksjs/error-handling'
9
10
  import { frameworkPath, projectPath } from '@stacksjs/path'
10
11
  import * as storage from '@stacksjs/storage'
11
- import type { CliOptions, Manifest, Subprocess } from '@stacksjs/types'
12
12
  import { parse } from 'yaml'
13
13
 
14
14
  // import { semver } from './versions'
@@ -19,12 +19,14 @@ export async function packageManager() {
19
19
  }
20
20
 
21
21
  export async function initProject(): Promise<Result<Subprocess, Error>> {
22
- if (app.env !== 'production') log.info('Project not yet initialized, generating application key...')
22
+ if (app.env !== 'production')
23
+ log.info('Project not yet initialized, generating application key...')
23
24
  else handleError('Please run `buddy key:generate` to generate an application key')
24
25
 
25
26
  const result = await runAction(Action.KeyGenerate, { cwd: projectPath() })
26
27
 
27
- if (result.isErr()) return err(handleError(result.error))
28
+ if (result.isErr())
29
+ return err(handleError(result.error))
28
30
 
29
31
  log.info('Application key generated.')
30
32
 
@@ -32,10 +34,12 @@ export async function initProject(): Promise<Result<Subprocess, Error>> {
32
34
  }
33
35
 
34
36
  export async function ensureProjectIsInitialized() {
35
- if (storage.isFile(projectPath('.env'))) return await isAppKeySet()
37
+ if (storage.isFile(projectPath('.env')))
38
+ return await isAppKeySet()
36
39
 
37
40
  // copy the .env.example file to .env
38
- if (storage.isFile(projectPath('.env.example'))) await runCommand('cp .env.example .env', { cwd: projectPath() })
41
+ if (storage.isFile(projectPath('.env.example')))
42
+ await runCommand('cp .env.example .env', { cwd: projectPath() })
39
43
  else console.error('no .env.example file found')
40
44
 
41
45
  return await isAppKeySet()
@@ -57,7 +61,7 @@ export async function frameworkVersion(): Promise<string> {
57
61
  export async function isAppKeySet() {
58
62
  const env = await storage.readTextFile('.env', projectPath())
59
63
  const lines = env.data.split('\n')
60
- const appKey = lines.find((line) => line.startsWith('APP_KEY='))
64
+ const appKey = lines.find(line => line.startsWith('APP_KEY='))
61
65
 
62
66
  return !!(appKey && appKey.length > 16)
63
67
  }
@@ -69,18 +73,23 @@ export async function isAppKeySet() {
69
73
  * @param preset
70
74
  */
71
75
  export function determineResetPreset(preset?: string) {
72
- if (ui.reset) preset = ui.reset
76
+ if (ui.reset)
77
+ preset = ui.reset
73
78
 
74
- if (preset === 'tailwind') return ["import '@unocss/reset/tailwind.css'"]
79
+ if (preset === 'tailwind')
80
+ return ['import \'@unocss/reset/tailwind.css\'']
75
81
 
76
- if (preset === 'normalize') return ["import '@unocss/reset/normalize.css'"]
82
+ if (preset === 'normalize')
83
+ return ['import \'@unocss/reset/normalize.css\'']
77
84
 
78
85
  if (preset === 'sanitize')
79
- return ["import '@unocss/reset/sanitize/sanitize.css'", "import '@unocss/reset/sanitize/assets.css"]
86
+ return ['import \'@unocss/reset/sanitize/sanitize.css\'', 'import \'@unocss/reset/sanitize/assets.css']
80
87
 
81
- if (preset === 'eric-meyer') return ["import '@unocss/reset/eric-meyer.css'"]
88
+ if (preset === 'eric-meyer')
89
+ return ['import \'@unocss/reset/eric-meyer.css\'']
82
90
 
83
- if (preset === 'antfu') return ["import '@unocss/reset/antfu.css'"]
91
+ if (preset === 'antfu')
92
+ return ['import \'@unocss/reset/antfu.css\'']
84
93
 
85
94
  return []
86
95
  }
@@ -90,11 +99,11 @@ export function determineResetPreset(preset?: string) {
90
99
  */
91
100
  export function isManifest(obj: any): obj is Manifest {
92
101
  return (
93
- obj &&
94
- typeof obj === 'object' &&
95
- isOptionalString(obj.name) &&
96
- isOptionalString(obj.version) &&
97
- isOptionalString(obj.description)
102
+ obj
103
+ && typeof obj === 'object'
104
+ && isOptionalString(obj.name)
105
+ && isOptionalString(obj.version)
106
+ && isOptionalString(obj.description)
98
107
  )
99
108
  }
100
109
 
@@ -122,7 +131,8 @@ export async function runNpmScript(script: NpmScript, options?: CliOptions): Pro
122
131
  const { data: manifest } = await storage.readJsonFile('package.json', frameworkPath())
123
132
 
124
133
  // simple, yet effective check to see if the script exists
125
- if (isManifest(manifest) && hasScript(manifest, script)) return await runCommand(`bun --bun run ${script}`, options)
134
+ if (isManifest(manifest) && hasScript(manifest, script))
135
+ return await runCommand(`bun run ${script}`, options)
126
136
 
127
137
  return err(handleError(`The ${script} script does not exist in the package.json file.`))
128
138
  }
@@ -133,7 +143,8 @@ export async function runNpmScript(script: NpmScript, options?: CliOptions): Pro
133
143
  export function hasScript(manifest: Manifest, script: NpmScript): boolean {
134
144
  const scripts = manifest.scripts as Record<NpmScript, string> | undefined
135
145
 
136
- if (scripts && typeof scripts === 'object') return Boolean(scripts[script])
146
+ if (scripts && typeof scripts === 'object')
147
+ return Boolean(scripts[script])
137
148
 
138
149
  return false
139
150
  }
@@ -155,19 +166,20 @@ export function parseYaml(content: any) {
155
166
  * @param options
156
167
  */
157
168
  export function determineDebugLevel(options?: CliOptions) {
158
- if (options?.verbose === true) return true
169
+ if (options?.verbose === true)
170
+ return true
159
171
 
160
172
  return app.debug === true
161
173
  }
162
174
 
163
175
  export function isIpv6(address: AddressInfo): boolean {
164
176
  return (
165
- address.family === 'IPv6' ||
177
+ address.family === 'IPv6'
166
178
  // in node >=18.0 <18.4 this was an integer value. This was changed in a minor version.
167
179
  // See: https://github.com/laravel/vite-plugin/issues/103
168
180
 
169
181
  // @ts-expect-error-next-line
170
- address.family === 6
182
+ || address.family === 6
171
183
  )
172
184
  }
173
185
 
package/src/index.ts CHANGED
@@ -1,21 +1,12 @@
1
- export * from './base'
2
1
  export * from './clean'
2
+
3
3
  export * from './config'
4
- export * from './debounce'
5
4
  export * from './equal'
6
5
  export * from './export-size'
7
6
  export * from './find'
8
- export * from './function'
9
7
  export * from './git'
10
- export * from './guards'
11
8
  export * from './hash'
12
9
  export * from './helpers'
13
10
  export * from './macroable'
14
- export * from './math'
15
- export * from './promise'
16
- export * from './regex'
17
- export * from './retry'
18
- export * from './sleep'
19
- export * from './throttle'
20
- export * from './vendors'
21
11
  export * from './versions'
12
+ export * from '@stacksjs/browser'
package/src/utils.ts CHANGED
@@ -6,10 +6,10 @@ const ignore = ['readme-md']
6
6
 
7
7
  export const components = fs
8
8
  .readdirSync(resolve(__dirname, './resources/components'))
9
- .map((item) => kebabCase(item.replace(/\.(stx|vue)/g, '')))
10
- .filter((item) => !ignore.includes(item))
9
+ .map(item => kebabCase(item.replace(/\.(stx|vue)/g, '')))
10
+ .filter(item => !ignore.includes(item))
11
11
 
12
12
  export const functions = fs
13
13
  .readdirSync(resolve(__dirname, './resources/functions'))
14
- .map((item) => kebabCase(item.replace(/.ts/g, '')))
15
- .filter((item) => !ignore.includes(item))
14
+ .map(item => kebabCase(item.replace(/.ts/g, '')))
15
+ .filter(item => !ignore.includes(item))
package/src/base.ts DELETED
@@ -1,12 +0,0 @@
1
- export { toString } from '@stacksjs/strings'
2
-
3
- // export function assert(condition: boolean, message: string): asserts condition {
4
- // if (!condition)
5
- // throw new Error(message)
6
- // }
7
-
8
- // export function noop() {}
9
-
10
- export async function loop(times: number, callback: any) {
11
- ;[...Array(times)].forEach(async (item, i) => await callback(i))
12
- }
package/src/debounce.ts DELETED
@@ -1 +0,0 @@
1
- export { debounce } from 'perfect-debounce'
package/src/function.ts DELETED
@@ -1,32 +0,0 @@
1
- import type { Fn, Nullable } from '@stacksjs/types'
2
-
3
- /**
4
- * Call every function in an array
5
- */
6
- export function batchInvoke(functions: Nullable<Fn>[]) {
7
- functions.forEach((fn) => fn?.())
8
- }
9
-
10
- // /**
11
- // * Call the function
12
- // */
13
- // export function invoke(fn: Fn) {
14
- // return fn()
15
- // }
16
-
17
- /**
18
- * Pass the value through the callback, and return the value
19
- *
20
- * @example
21
- * ```
22
- * function createUser(name: string): User {
23
- * return tap(new User, user => {
24
- * user.name = name
25
- * })
26
- * }
27
- * ```
28
- */
29
- export function tap<T>(value: T, callback: (value: T) => void): T {
30
- callback(value)
31
- return value
32
- }
package/src/guards.ts DELETED
@@ -1,39 +0,0 @@
1
- /**
2
- * Type guard to filter out null-ish values
3
- *
4
- * @category Guards
5
- * @example array.filter(notNullish)
6
- */
7
- export function notNullish<T>(v: T | null | undefined): v is NonNullable<T> {
8
- return v != null
9
- }
10
-
11
- /**
12
- * Type guard to filter out null values
13
- *
14
- * @category Guards
15
- * @example array.filter(noNull)
16
- */
17
- export function noNull<T>(v: T | null): v is Exclude<T, null> {
18
- return v !== null
19
- }
20
-
21
- /**
22
- * Type guard to filter out null-ish values
23
- *
24
- * @category Guards
25
- * @example array.filter(notUndefined)
26
- */
27
- export function notUndefined<T>(v: T): v is Exclude<T, undefined> {
28
- return v !== undefined
29
- }
30
-
31
- /**
32
- * Type guard to filter out falsy values
33
- *
34
- * @category Guards
35
- * @example array.filter(isTruthy)
36
- */
37
- export function isTruthy<T>(v: T): v is NonNullable<T> {
38
- return Boolean(v)
39
- }
package/src/math.ts DELETED
@@ -1,30 +0,0 @@
1
- export const clamp = (n: number, min: number, max: number) => Math.min(max, Math.max(min, n))
2
-
3
- export function rand(min: number, max: number) {
4
- min = Math.ceil(min)
5
- max = Math.floor(max)
6
- return Math.floor(Math.random() * (max - min + 1)) + min
7
- }
8
-
9
- // not, -> exported as well in ../regex
10
- export {
11
- and,
12
- createGenericProjection,
13
- createProjection,
14
- logicNot,
15
- logicOr,
16
- or,
17
- useAbs,
18
- useAverage,
19
- useCeil,
20
- useClamp,
21
- useFloor,
22
- useMath,
23
- useMax,
24
- useMin,
25
- usePrecision,
26
- useProjection,
27
- useRound,
28
- useSum,
29
- useTrunc,
30
- } from '@vueuse/math'