@fast-china/utils 2.1.10 → 2.1.11

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 (70) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/README.md +5 -2
  3. package/README.zh.md +5 -2
  4. package/dist/array/index.mjs +21 -21
  5. package/dist/array/index.mjs.map +1 -1
  6. package/dist/async/index.mjs +32 -32
  7. package/dist/async/index.mjs.map +1 -1
  8. package/dist/base64/index.mjs +44 -51
  9. package/dist/base64/index.mjs.map +1 -1
  10. package/dist/color/index.mjs +33 -33
  11. package/dist/color/index.mjs.map +1 -1
  12. package/dist/crypto/index.mjs +153 -155
  13. package/dist/crypto/index.mjs.map +1 -1
  14. package/dist/date/index.mjs +79 -46
  15. package/dist/date/index.mjs.map +1 -1
  16. package/dist/dom/style.mjs +7 -7
  17. package/dist/dom/style.mjs.map +1 -1
  18. package/dist/env/index.mjs +9 -14
  19. package/dist/env/index.mjs.map +1 -1
  20. package/dist/function/index.mjs +4 -4
  21. package/dist/function/index.mjs.map +1 -1
  22. package/dist/identity/index.mjs +7 -7
  23. package/dist/identity/index.mjs.map +1 -1
  24. package/dist/index.d.mts +371 -366
  25. package/dist/index.global.min.js +2 -2
  26. package/dist/index.global.min.js.map +1 -1
  27. package/dist/internal/text.mjs +70 -26
  28. package/dist/internal/text.mjs.map +1 -1
  29. package/dist/logger/index.mjs +12 -13
  30. package/dist/logger/index.mjs.map +1 -1
  31. package/dist/number/index.mjs +63 -42
  32. package/dist/number/index.mjs.map +1 -1
  33. package/dist/object/index.mjs +32 -31
  34. package/dist/object/index.mjs.map +1 -1
  35. package/dist/storage/index.mjs +58 -63
  36. package/dist/storage/index.mjs.map +1 -1
  37. package/dist/string/index.mjs +60 -64
  38. package/dist/string/index.mjs.map +1 -1
  39. package/dist/vue/breakpoints.mjs +14 -10
  40. package/dist/vue/breakpoints.mjs.map +1 -1
  41. package/dist/vue/element-size.mjs +4 -4
  42. package/dist/vue/element-size.mjs.map +1 -1
  43. package/dist/vue/emits.mjs +7 -7
  44. package/dist/vue/emits.mjs.map +1 -1
  45. package/dist/vue/event-listener.mjs +5 -5
  46. package/dist/vue/event-listener.mjs.map +1 -1
  47. package/dist/vue/expose.mjs +3 -3
  48. package/dist/vue/expose.mjs.map +1 -1
  49. package/dist/vue/func.mjs +2 -2
  50. package/dist/vue/func.mjs.map +1 -1
  51. package/dist/vue/install.mjs +24 -24
  52. package/dist/vue/install.mjs.map +1 -1
  53. package/dist/vue/now.mjs +4 -5
  54. package/dist/vue/now.mjs.map +1 -1
  55. package/dist/vue/props.mjs +5 -5
  56. package/dist/vue/props.mjs.map +1 -1
  57. package/dist/vue/render.mjs +2 -2
  58. package/dist/vue/render.mjs.map +1 -1
  59. package/dist/vue/resize-observer.mjs +4 -6
  60. package/dist/vue/resize-observer.mjs.map +1 -1
  61. package/dist/vue/slots.mjs.map +1 -1
  62. package/dist/vue/transition.mjs +5 -7
  63. package/dist/vue/transition.mjs.map +1 -1
  64. package/dist/vue/window-size.mjs +2 -4
  65. package/dist/vue/window-size.mjs.map +1 -1
  66. package/dist/vue/with.mjs +1 -1
  67. package/dist/vue/with.mjs.map +1 -1
  68. package/package.json +2 -1
  69. package/dist/internal/runtime.mjs +0 -32
  70. package/dist/internal/runtime.mjs.map +0 -1
@@ -4,10 +4,10 @@ import { readonly, shallowRef } from "vue";
4
4
  /**
5
5
  * 响应式读取元素 Content Rect 尺寸。
6
6
  *
7
- * @param target - 原生元素、Ref 或 Getter。
8
- * @param initialSize - 收到首次观察结果前的尺寸,默认均为 `0`。
9
- * @param options - 原生元素观察选项。
10
- * @returns 只读宽度、高度和手动停止函数。
7
+ * @param target - 原生元素、Ref 或 Getter
8
+ * @param initialSize - 收到首次观察结果前的尺寸,默认均为 `0`
9
+ * @param options - 原生元素观察选项
10
+ * @returns 只读宽度、高度和手动停止函数
11
11
  */
12
12
  function useElementSize(target, initialSize = {
13
13
  height: 0,
@@ -1 +1 @@
1
- {"version":3,"file":"element-size.mjs","names":[],"sources":["../../src/vue/element-size.ts"],"sourcesContent":["import { readonly, shallowRef } from \"vue\";\nimport { useResizeObserver } from \"./resize-observer\";\nimport type { ShallowRef } from \"vue\";\nimport type { ResizeObserverTarget } from \"./resize-observer\";\n\n/** 元素的二维尺寸。 */\nexport interface ElementSize {\n\treadonly width: number;\n\treadonly height: number;\n}\n\n/** `useElementSize` 返回的响应式尺寸和停止函数。 */\nexport interface UseElementSizeReturn {\n\treadonly width: Readonly<ShallowRef<number>>;\n\treadonly height: Readonly<ShallowRef<number>>;\n\treadonly stop: () => void;\n}\n\n/**\n * 响应式读取元素 Content Rect 尺寸。\n *\n * @param target - 原生元素、Ref 或 Getter。\n * @param initialSize - 收到首次观察结果前的尺寸,默认均为 `0`。\n * @param options - 原生元素观察选项。\n * @returns 只读宽度、高度和手动停止函数。\n */\nexport function useElementSize(\n\ttarget: ResizeObserverTarget,\n\tinitialSize: ElementSize = { height: 0, width: 0 },\n\toptions?: ResizeObserverOptions\n): UseElementSizeReturn {\n\tconst width = shallowRef(initialSize.width);\n\tconst height = shallowRef(initialSize.height);\n\tconst stop = useResizeObserver(\n\t\ttarget,\n\t\t(entries) => {\n\t\t\tconst entry = entries[0];\n\t\t\tif (entry === undefined) return;\n\t\t\twidth.value = entry.contentRect.width;\n\t\t\theight.value = entry.contentRect.height;\n\t\t},\n\t\toptions\n\t);\n\treturn { height: readonly(height), stop, width: readonly(width) };\n}\n"],"mappings":";;;;;;;;;;;AA0BA,SAAgB,eACf,QACA,cAA2B;CAAE,QAAQ;CAAG,OAAO;AAAE,GACjD,SACuB;CACvB,MAAM,QAAQ,WAAW,YAAY,KAAK;CAC1C,MAAM,SAAS,WAAW,YAAY,MAAM;CAC5C,MAAM,OAAO,kBACZ,SACC,YAAY;EACZ,MAAM,QAAQ,QAAQ;EACtB,IAAI,UAAU,KAAA,GAAW;EACzB,MAAM,QAAQ,MAAM,YAAY;EAChC,OAAO,QAAQ,MAAM,YAAY;CAClC,GACA,OACD;CACA,OAAO;EAAE,QAAQ,SAAS,MAAM;EAAG;EAAM,OAAO,SAAS,KAAK;CAAE;AACjE"}
1
+ {"version":3,"file":"element-size.mjs","names":[],"sources":["../../src/vue/element-size.ts"],"sourcesContent":["import { readonly, shallowRef } from \"vue\";\nimport { useResizeObserver } from \"./resize-observer\";\nimport type { ShallowRef } from \"vue\";\nimport type { ResizeObserverTarget } from \"./resize-observer\";\n\n/** 元素的二维尺寸 */\nexport interface ElementSize {\n\treadonly width: number;\n\treadonly height: number;\n}\n\n/** `useElementSize` 返回的响应式尺寸和停止函数。 */\nexport interface UseElementSizeReturn {\n\treadonly width: Readonly<ShallowRef<number>>;\n\treadonly height: Readonly<ShallowRef<number>>;\n\treadonly stop: () => void;\n}\n\n/**\n * 响应式读取元素 Content Rect 尺寸。\n *\n * @param target - 原生元素、Ref 或 Getter\n * @param initialSize - 收到首次观察结果前的尺寸,默认均为 `0`\n * @param options - 原生元素观察选项\n * @returns 只读宽度、高度和手动停止函数\n */\nexport function useElementSize(\n\ttarget: ResizeObserverTarget,\n\tinitialSize: ElementSize = { height: 0, width: 0 },\n\toptions?: ResizeObserverOptions\n): UseElementSizeReturn {\n\tconst width = shallowRef(initialSize.width);\n\tconst height = shallowRef(initialSize.height);\n\tconst stop = useResizeObserver(\n\t\ttarget,\n\t\t(entries) => {\n\t\t\tconst entry = entries[0];\n\t\t\tif (entry === undefined) return;\n\t\t\twidth.value = entry.contentRect.width;\n\t\t\theight.value = entry.contentRect.height;\n\t\t},\n\t\toptions\n\t);\n\treturn { height: readonly(height), stop, width: readonly(width) };\n}\n"],"mappings":";;;;;;;;;;;AA0BA,SAAgB,eACf,QACA,cAA2B;CAAE,QAAQ;CAAG,OAAO;AAAE,GACjD,SACuB;CACvB,MAAM,QAAQ,WAAW,YAAY,KAAK;CAC1C,MAAM,SAAS,WAAW,YAAY,MAAM;CAC5C,MAAM,OAAO,kBACZ,SACC,YAAY;EACZ,MAAM,QAAQ,QAAQ;EACtB,IAAI,UAAU,KAAA,GAAW;EACzB,MAAM,QAAQ,MAAM,YAAY;EAChC,OAAO,QAAQ,MAAM,YAAY;CAClC,GACA,OACD;CACA,OAAO;EAAE,QAAQ,SAAS,MAAM;EAAG;EAAM,OAAO,SAAS,KAAK;CAAE;AACjE"}
@@ -4,7 +4,7 @@ import { computed } from "vue";
4
4
  * 把事件名转换为 Vue Handler Prop 名称。
5
5
  *
6
6
  * @param eventName - Emits 对象中的原始事件名,可使用 kebab-case。
7
- * @returns `onPascalCase` 形式的属性名。
7
+ * @returns `onPascalCase` 形式的属性名
8
8
  * @throws `TypeError` 当事件名包含空片段或无法生成有效 Handler 名称。
9
9
  */
10
10
  const toHandlerName = (eventName) => {
@@ -13,10 +13,10 @@ const toHandlerName = (eventName) => {
13
13
  /**
14
14
  * 构建响应式 Vue 事件处理器。
15
15
  *
16
- * @param emits - Vue emits 配置对象。
17
- * @param emit - `setup` 上下文提供的 emit 函数。
18
- * @param ignoredEvents - 不需要向子组件透传的事件名。
19
- * @returns 随配置重新计算的事件处理器对象。
16
+ * @param emits - Vue emits 配置对象
17
+ * @param emit - `setup` 上下文提供的 emit 函数
18
+ * @param ignoredEvents - 不需要向子组件透传的事件名
19
+ * @returns 随配置重新计算的事件处理器对象
20
20
  */
21
21
  function useEmits(emits, emit, ignoredEvents = []) {
22
22
  const ignored = new Set(ignoredEvents);
@@ -26,9 +26,9 @@ function useEmits(emits, emit, ignoredEvents = []) {
26
26
  const handlerNames = /* @__PURE__ */ new Set();
27
27
  for (const eventName of Object.keys(emits)) {
28
28
  if (ignored.has(eventName)) continue;
29
- if (eventName.length === 0 || /\s/u.test(eventName)) throw new TypeError(`无效的 Vue 事件名称:“${eventName}”。`);
29
+ if (eventName.length === 0 || /\s/u.test(eventName)) throw new TypeError(`Invalid Vue event name: "${eventName}".`);
30
30
  const handlerName = toHandlerName(eventName);
31
- if (handlerNames.has(handlerName)) throw new TypeError(`多个 Vue 事件映射到同一处理器属性:“${handlerName}”。`);
31
+ if (handlerNames.has(handlerName)) throw new TypeError(`Multiple Vue events map to the same handler property: "${handlerName}".`);
32
32
  handlerNames.add(handlerName);
33
33
  Object.defineProperty(handlers, handlerName, {
34
34
  enumerable: true,
@@ -1 +1 @@
1
- {"version":3,"file":"emits.mjs","names":[],"sources":["../../src/vue/emits.ts"],"sourcesContent":["import { computed } from \"vue\";\nimport type { ComputedRef } from \"vue\";\n\n/** Vue Emits 对象中允许的校验器形状。 */\ntype EmitValidator = ((...arguments_: never[]) => unknown) | null;\n/** 事件名到可选参数校验器的内部映射。 */\ntype EmitsOptions = Record<string, EmitValidator>;\n/** 从校验器中提取事件参数;无校验器时保留未知参数。 */\ntype EventArguments<Validator> = Validator extends (...arguments_: infer Arguments) => unknown ? Arguments : unknown[];\n/** 在类型层递归把 kebab-case 事件名转换为 PascalCase。 */\ntype PascalEventName<Value extends string> = Value extends `${infer Head}-${infer Tail}`\n\t? `${Capitalize<Head>}${PascalEventName<Tail>}`\n\t: Capitalize<Value>;\n\n/** 把事件配置映射为 Vue `onXxx` 属性。 */\nexport type EmitHandlers<Emits extends EmitsOptions> = {\n\t[Name in keyof Emits as Name extends string ? `on${PascalEventName<Name>}` : never]: (...arguments_: EventArguments<Emits[Name]>) => void;\n};\n\n/**\n * 把事件名转换为 Vue Handler Prop 名称。\n *\n * @param eventName - Emits 对象中的原始事件名,可使用 kebab-case。\n * @returns `onPascalCase` 形式的属性名。\n * @throws `TypeError` 当事件名包含空片段或无法生成有效 Handler 名称。\n */\nconst toHandlerName = (eventName: string): string => {\n\treturn `on${eventName\n\t\t.split(\"-\")\n\t\t.map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n\t\t.join(\"\")}`;\n};\n\n/**\n * 构建响应式 Vue 事件处理器。\n *\n * @param emits - Vue emits 配置对象。\n * @param emit - `setup` 上下文提供的 emit 函数。\n * @param ignoredEvents - 不需要向子组件透传的事件名。\n * @returns 随配置重新计算的事件处理器对象。\n */\nexport function useEmits<Emits extends EmitsOptions>(\n\temits: Emits,\n\temit: (...arguments_: never[]) => unknown,\n\tignoredEvents: readonly (keyof Emits)[] = []\n): ComputedRef<Partial<EmitHandlers<Emits>>> {\n\tconst ignored = new Set<PropertyKey>(ignoredEvents);\n\tconst emitEvent = emit as (eventName: string, ...arguments_: unknown[]) => void;\n\treturn computed<Partial<EmitHandlers<Emits>>>(() => {\n\t\tconst handlers = {} as Partial<EmitHandlers<Emits>>;\n\t\tconst handlerNames = new Set<string>();\n\t\tfor (const eventName of Object.keys(emits)) {\n\t\t\tif (ignored.has(eventName)) continue;\n\t\t\tif (eventName.length === 0 || /\\s/u.test(eventName)) throw new TypeError(`无效的 Vue 事件名称:“${eventName}”。`);\n\t\t\tconst handlerName = toHandlerName(eventName);\n\t\t\tif (handlerNames.has(handlerName)) {\n\t\t\t\tthrow new TypeError(`多个 Vue 事件映射到同一处理器属性:“${handlerName}”。`);\n\t\t\t}\n\t\t\thandlerNames.add(handlerName);\n\t\t\tObject.defineProperty(handlers, handlerName, {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: (...arguments_: unknown[]) => {\n\t\t\t\t\temitEvent(eventName, ...arguments_);\n\t\t\t\t},\n\t\t\t\twritable: true,\n\t\t\t});\n\t\t}\n\t\treturn handlers;\n\t});\n}\n"],"mappings":";;;;;;;;;AA0BA,MAAM,iBAAiB,cAA8B;CACpD,OAAO,KAAK,UACV,MAAM,GAAG,CAAC,CACV,KAAK,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAC3D,KAAK,EAAE;AACV;;;;;;;;;AAUA,SAAgB,SACf,OACA,MACA,gBAA0C,CAAC,GACC;CAC5C,MAAM,UAAU,IAAI,IAAiB,aAAa;CAClD,MAAM,YAAY;CAClB,OAAO,eAA6C;EACnD,MAAM,WAAW,CAAC;EAClB,MAAM,+BAAe,IAAI,IAAY;EACrC,KAAK,MAAM,aAAa,OAAO,KAAK,KAAK,GAAG;GAC3C,IAAI,QAAQ,IAAI,SAAS,GAAG;GAC5B,IAAI,UAAU,WAAW,KAAK,MAAM,KAAK,SAAS,GAAG,MAAM,IAAI,UAAU,iBAAiB,UAAU,GAAG;GACvG,MAAM,cAAc,cAAc,SAAS;GAC3C,IAAI,aAAa,IAAI,WAAW,GAC/B,MAAM,IAAI,UAAU,wBAAwB,YAAY,GAAG;GAE5D,aAAa,IAAI,WAAW;GAC5B,OAAO,eAAe,UAAU,aAAa;IAC5C,YAAY;IACZ,QAAQ,GAAG,eAA0B;KACpC,UAAU,WAAW,GAAG,UAAU;IACnC;IACA,UAAU;GACX,CAAC;EACF;EACA,OAAO;CACR,CAAC;AACF"}
1
+ {"version":3,"file":"emits.mjs","names":[],"sources":["../../src/vue/emits.ts"],"sourcesContent":["import { computed } from \"vue\";\nimport type { ComputedRef } from \"vue\";\n\n/** Vue Emits 对象中允许的校验器形状 */\ntype EmitValidator = ((...arguments_: never[]) => unknown) | null;\n/** 事件名到可选参数校验器的内部映射 */\ntype EmitsOptions = Record<string, EmitValidator>;\n/** 从校验器中提取事件参数;无校验器时保留未知参数。 */\ntype EventArguments<Validator> = Validator extends (...arguments_: infer Arguments) => unknown ? Arguments : unknown[];\n/** 在类型层递归把 kebab-case 事件名转换为 PascalCase */\ntype PascalEventName<Value extends string> = Value extends `${infer Head}-${infer Tail}`\n\t? `${Capitalize<Head>}${PascalEventName<Tail>}`\n\t: Capitalize<Value>;\n\n/** 把事件配置映射为 Vue `onXxx` 属性 */\nexport type EmitHandlers<Emits extends EmitsOptions> = {\n\t[Name in keyof Emits as Name extends string ? `on${PascalEventName<Name>}` : never]: (...arguments_: EventArguments<Emits[Name]>) => void;\n};\n\n/**\n * 把事件名转换为 Vue Handler Prop 名称。\n *\n * @param eventName - Emits 对象中的原始事件名,可使用 kebab-case。\n * @returns `onPascalCase` 形式的属性名\n * @throws `TypeError` 当事件名包含空片段或无法生成有效 Handler 名称。\n */\nconst toHandlerName = (eventName: string): string => {\n\treturn `on${eventName\n\t\t.split(\"-\")\n\t\t.map((part) => part.charAt(0).toUpperCase() + part.slice(1))\n\t\t.join(\"\")}`;\n};\n\n/**\n * 构建响应式 Vue 事件处理器。\n *\n * @param emits - Vue emits 配置对象\n * @param emit - `setup` 上下文提供的 emit 函数\n * @param ignoredEvents - 不需要向子组件透传的事件名\n * @returns 随配置重新计算的事件处理器对象\n */\nexport function useEmits<Emits extends EmitsOptions>(\n\temits: Emits,\n\temit: (...arguments_: never[]) => unknown,\n\tignoredEvents: readonly (keyof Emits)[] = []\n): ComputedRef<Partial<EmitHandlers<Emits>>> {\n\tconst ignored = new Set<PropertyKey>(ignoredEvents);\n\tconst emitEvent = emit as (eventName: string, ...arguments_: unknown[]) => void;\n\treturn computed<Partial<EmitHandlers<Emits>>>(() => {\n\t\tconst handlers = {} as Partial<EmitHandlers<Emits>>;\n\t\tconst handlerNames = new Set<string>();\n\t\tfor (const eventName of Object.keys(emits)) {\n\t\t\tif (ignored.has(eventName)) continue;\n\t\t\tif (eventName.length === 0 || /\\s/u.test(eventName)) throw new TypeError(`Invalid Vue event name: \"${eventName}\".`);\n\t\t\tconst handlerName = toHandlerName(eventName);\n\t\t\tif (handlerNames.has(handlerName)) {\n\t\t\t\tthrow new TypeError(`Multiple Vue events map to the same handler property: \"${handlerName}\".`);\n\t\t\t}\n\t\t\thandlerNames.add(handlerName);\n\t\t\tObject.defineProperty(handlers, handlerName, {\n\t\t\t\tenumerable: true,\n\t\t\t\tvalue: (...arguments_: unknown[]) => {\n\t\t\t\t\temitEvent(eventName, ...arguments_);\n\t\t\t\t},\n\t\t\t\twritable: true,\n\t\t\t});\n\t\t}\n\t\treturn handlers;\n\t});\n}\n"],"mappings":";;;;;;;;;AA0BA,MAAM,iBAAiB,cAA8B;CACpD,OAAO,KAAK,UACV,MAAM,GAAG,CAAC,CACV,KAAK,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,YAAY,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,CAC3D,KAAK,EAAE;AACV;;;;;;;;;AAUA,SAAgB,SACf,OACA,MACA,gBAA0C,CAAC,GACC;CAC5C,MAAM,UAAU,IAAI,IAAiB,aAAa;CAClD,MAAM,YAAY;CAClB,OAAO,eAA6C;EACnD,MAAM,WAAW,CAAC;EAClB,MAAM,+BAAe,IAAI,IAAY;EACrC,KAAK,MAAM,aAAa,OAAO,KAAK,KAAK,GAAG;GAC3C,IAAI,QAAQ,IAAI,SAAS,GAAG;GAC5B,IAAI,UAAU,WAAW,KAAK,MAAM,KAAK,SAAS,GAAG,MAAM,IAAI,UAAU,4BAA4B,UAAU,GAAG;GAClH,MAAM,cAAc,cAAc,SAAS;GAC3C,IAAI,aAAa,IAAI,WAAW,GAC/B,MAAM,IAAI,UAAU,0DAA0D,YAAY,GAAG;GAE9F,aAAa,IAAI,WAAW;GAC5B,OAAO,eAAe,UAAU,aAAa;IAC5C,YAAY;IACZ,QAAQ,GAAG,eAA0B;KACpC,UAAU,WAAW,GAAG,UAAU;IACnC;IACA,UAAU;GACX,CAAC;EACF;EACA,OAAO;CACR,CAAC;AACF"}
@@ -3,11 +3,11 @@ import { onScopeDispose, toValue, watch } from "vue";
3
3
  /**
4
4
  * 注册原生事件监听器,并在目标变化或 Vue 作用域销毁时自动移除。
5
5
  *
6
- * @param target - 原生事件目标、Ref 或 Getter。
7
- * @param event - 原生事件名称。
8
- * @param listener - 事件回调。
9
- * @param options - 原生事件监听选项。
10
- * @returns 可提前移除监听器的停止函数。
6
+ * @param target - 原生事件目标、Ref 或 Getter
7
+ * @param event - 原生事件名称
8
+ * @param listener - 事件回调
9
+ * @param options - 原生事件监听选项
10
+ * @returns 可提前移除监听器的停止函数
11
11
  */
12
12
  function useEventListener(target, event, listener, options) {
13
13
  const eventListener = listener;
@@ -1 +1 @@
1
- {"version":3,"file":"event-listener.mjs","names":[],"sources":["../../src/vue/event-listener.ts"],"sourcesContent":["import { onScopeDispose, toValue, watch } from \"vue\";\nimport type { MaybeRefOrGetter } from \"vue\";\n\n/** `useEventListener` 接受的原生事件目标或响应式事件目标。 */\nexport type EventTargetSource = MaybeRefOrGetter<EventTarget | null | undefined>;\n\n/**\n * 注册原生事件监听器,并在目标变化或 Vue 作用域销毁时自动移除。\n *\n * @param target - 原生事件目标、Ref 或 Getter。\n * @param event - 原生事件名称。\n * @param listener - 事件回调。\n * @param options - 原生事件监听选项。\n * @returns 可提前移除监听器的停止函数。\n */\nexport function useEventListener<EventType extends Event = Event>(\n\ttarget: EventTargetSource,\n\tevent: string,\n\tlistener: (event: EventType) => void,\n\toptions?: boolean | AddEventListenerOptions\n): () => void {\n\tconst eventListener = listener as EventListener;\n\tconst stop = watch(\n\t\t() => toValue(target),\n\t\t(currentTarget, _previousTarget, onCleanup) => {\n\t\t\tif (currentTarget === null || currentTarget === undefined) return;\n\t\t\tcurrentTarget.addEventListener(event, eventListener, options);\n\t\t\tonCleanup(() => {\n\t\t\t\tcurrentTarget.removeEventListener(event, eventListener, options);\n\t\t\t});\n\t\t},\n\t\t{ flush: \"sync\", immediate: true }\n\t);\n\tonScopeDispose(stop, true);\n\treturn stop;\n}\n"],"mappings":";;;;;;;;;;;AAeA,SAAgB,iBACf,QACA,OACA,UACA,SACa;CACb,MAAM,gBAAgB;CACtB,MAAM,OAAO,YACN,QAAQ,MAAM,IACnB,eAAe,iBAAiB,cAAc;EAC9C,IAAI,kBAAkB,QAAQ,kBAAkB,KAAA,GAAW;EAC3D,cAAc,iBAAiB,OAAO,eAAe,OAAO;EAC5D,gBAAgB;GACf,cAAc,oBAAoB,OAAO,eAAe,OAAO;EAChE,CAAC;CACF,GACA;EAAE,OAAO;EAAQ,WAAW;CAAK,CAClC;CACA,eAAe,MAAM,IAAI;CACzB,OAAO;AACR"}
1
+ {"version":3,"file":"event-listener.mjs","names":[],"sources":["../../src/vue/event-listener.ts"],"sourcesContent":["import { onScopeDispose, toValue, watch } from \"vue\";\nimport type { MaybeRefOrGetter } from \"vue\";\n\n/** `useEventListener` 接受的原生事件目标或响应式事件目标 */\nexport type EventTargetSource = MaybeRefOrGetter<EventTarget | null | undefined>;\n\n/**\n * 注册原生事件监听器,并在目标变化或 Vue 作用域销毁时自动移除。\n *\n * @param target - 原生事件目标、Ref 或 Getter\n * @param event - 原生事件名称\n * @param listener - 事件回调\n * @param options - 原生事件监听选项\n * @returns 可提前移除监听器的停止函数\n */\nexport function useEventListener<EventType extends Event = Event>(\n\ttarget: EventTargetSource,\n\tevent: string,\n\tlistener: (event: EventType) => void,\n\toptions?: boolean | AddEventListenerOptions\n): () => void {\n\tconst eventListener = listener as EventListener;\n\tconst stop = watch(\n\t\t() => toValue(target),\n\t\t(currentTarget, _previousTarget, onCleanup) => {\n\t\t\tif (currentTarget === null || currentTarget === undefined) return;\n\t\t\tcurrentTarget.addEventListener(event, eventListener, options);\n\t\t\tonCleanup(() => {\n\t\t\t\tcurrentTarget.removeEventListener(event, eventListener, options);\n\t\t\t});\n\t\t},\n\t\t{ flush: \"sync\", immediate: true }\n\t);\n\tonScopeDispose(stop, true);\n\treturn stop;\n}\n"],"mappings":";;;;;;;;;;;AAeA,SAAgB,iBACf,QACA,OACA,UACA,SACa;CACb,MAAM,gBAAgB;CACtB,MAAM,OAAO,YACN,QAAQ,MAAM,IACnB,eAAe,iBAAiB,cAAc;EAC9C,IAAI,kBAAkB,QAAQ,kBAAkB,KAAA,GAAW;EAC3D,cAAc,iBAAiB,OAAO,eAAe,OAAO;EAC5D,gBAAgB;GACf,cAAc,oBAAoB,OAAO,eAAe,OAAO;EAChE,CAAC;CACF,GACA;EAAE,OAAO;EAAQ,WAAW;CAAK,CAClC;CACA,eAAe,MAAM,IAAI;CACzB,OAAO;AACR"}
@@ -2,9 +2,9 @@
2
2
  /**
3
3
  * 同时暴露组件实例能力并返回同一个对象,便于 `setup` 返回状态供 Vue Devtools 查看。
4
4
  *
5
- * @param expose - `setup` 上下文提供的 expose 函数。
6
- * @param exposed - 需要暴露的状态和方法。
7
- * @returns 原始 exposed 对象。
5
+ * @param expose - `setup` 上下文提供的 expose 函数
6
+ * @param exposed - 需要暴露的状态和方法
7
+ * @returns 原始 exposed 对象
8
8
  */
9
9
  function useExpose(expose, exposed) {
10
10
  expose(exposed);
@@ -1 +1 @@
1
- {"version":3,"file":"expose.mjs","names":[],"sources":["../../src/vue/expose.ts"],"sourcesContent":["/**\n * 同时暴露组件实例能力并返回同一个对象,便于 `setup` 返回状态供 Vue Devtools 查看。\n *\n * @param expose - `setup` 上下文提供的 expose 函数。\n * @param exposed - 需要暴露的状态和方法。\n * @returns 原始 exposed 对象。\n */\nexport function useExpose<Exposed extends object>(expose: (exposed?: Exposed) => void, exposed: Exposed): Exposed {\n\texpose(exposed);\n\treturn exposed;\n}\n"],"mappings":";;;;;;;;AAOA,SAAgB,UAAkC,QAAqC,SAA2B;CACjH,OAAO,OAAO;CACd,OAAO;AACR"}
1
+ {"version":3,"file":"expose.mjs","names":[],"sources":["../../src/vue/expose.ts"],"sourcesContent":["/**\n * 同时暴露组件实例能力并返回同一个对象,便于 `setup` 返回状态供 Vue Devtools 查看。\n *\n * @param expose - `setup` 上下文提供的 expose 函数\n * @param exposed - 需要暴露的状态和方法\n * @returns 原始 exposed 对象\n */\nexport function useExpose<Exposed extends object>(expose: (exposed?: Exposed) => void, exposed: Exposed): Exposed {\n\texpose(exposed);\n\treturn exposed;\n}\n"],"mappings":";;;;;;;;AAOA,SAAgB,UAAkC,QAAqC,SAA2B;CACjH,OAAO,OAAO;CACd,OAAO;AACR"}
package/dist/vue/func.mjs CHANGED
@@ -2,8 +2,8 @@
2
2
  /**
3
3
  * 统一执行同步或异步函数,异常保持原样向调用方传播。
4
4
  *
5
- * @param function_ - 可选的待执行函数。
6
- * @param arguments_ - 原样传入函数的参数。
5
+ * @param function_ - 可选的待执行函数
6
+ * @param arguments_ - 原样传入函数的参数
7
7
  * @returns 函数结果;未传函数时返回 `undefined`。
8
8
  */
9
9
  async function callOptionalFunction(function_, ...arguments_) {
@@ -1 +1 @@
1
- {"version":3,"file":"func.mjs","names":[],"sources":["../../src/vue/func.ts"],"sourcesContent":["/** 可同步或异步返回结果的函数。 */\nexport type AwaitableFunction<Arguments extends readonly unknown[], Result> = (...arguments_: Arguments) => Result | PromiseLike<Result>;\n\n/**\n * 统一执行同步或异步函数,异常保持原样向调用方传播。\n *\n * @param function_ - 可选的待执行函数。\n * @param arguments_ - 原样传入函数的参数。\n * @returns 函数结果;未传函数时返回 `undefined`。\n */\nexport async function callOptionalFunction<Arguments extends readonly unknown[], Result>(\n\tfunction_: AwaitableFunction<Arguments, Result> | null | undefined,\n\t...arguments_: Arguments\n): Promise<Awaited<Result> | undefined> {\n\tif (function_ === null || function_ === undefined) return undefined;\n\treturn Promise.resolve(function_(...arguments_));\n}\n"],"mappings":";;;;;;;;AAUA,eAAsB,qBACrB,WACA,GAAG,YACoC;CACvC,IAAI,cAAc,QAAQ,cAAc,KAAA,GAAW,OAAO,KAAA;CAC1D,OAAO,QAAQ,QAAQ,UAAU,GAAG,UAAU,CAAC;AAChD"}
1
+ {"version":3,"file":"func.mjs","names":[],"sources":["../../src/vue/func.ts"],"sourcesContent":["/** 可同步或异步返回结果的函数。 */\nexport type AwaitableFunction<Arguments extends readonly unknown[], Result> = (...arguments_: Arguments) => Result | PromiseLike<Result>;\n\n/**\n * 统一执行同步或异步函数,异常保持原样向调用方传播。\n *\n * @param function_ - 可选的待执行函数\n * @param arguments_ - 原样传入函数的参数\n * @returns 函数结果;未传函数时返回 `undefined`。\n */\nexport async function callOptionalFunction<Arguments extends readonly unknown[], Result>(\n\tfunction_: AwaitableFunction<Arguments, Result> | null | undefined,\n\t...arguments_: Arguments\n): Promise<Awaited<Result> | undefined> {\n\tif (function_ === null || function_ === undefined) return undefined;\n\treturn Promise.resolve(function_(...arguments_));\n}\n"],"mappings":";;;;;;;;AAUA,eAAsB,qBACrB,WACA,GAAG,YACoC;CACvC,IAAI,cAAc,QAAQ,cAAc,KAAA,GAAW,OAAO,KAAA;CAC1D,OAAO,QAAQ,QAAQ,UAAU,GAAG,UAAU,CAAC;AAChD"}
@@ -2,41 +2,41 @@
2
2
  /**
3
3
  * 校验 Vue 3 插件安装目标。
4
4
  *
5
- * @param value - Vue 3 App 实例。
6
- * @returns 只包含组件和指令注册能力的 App。
5
+ * @param value - Vue 3 App 实例
6
+ * @returns 只包含组件和指令注册能力的 App
7
7
  * @throws `TypeError` 当目标不是对象或缺少 `component`、`directive` 方法。
8
8
  */
9
9
  const assertApp = (value) => {
10
- if (typeof value !== "object" || value === null) throw new TypeError("安装 Vue 插件需要 Vue 3 App 实例。");
10
+ if (typeof value !== "object" || value === null) throw new TypeError("Installing a Vue plugin requires a Vue 3 App instance.");
11
11
  const app = value;
12
- if (typeof app.component !== "function" || typeof app.directive !== "function") throw new TypeError("安装 Vue 插件需要 `component()` 和 `directive()` 注册方法。");
12
+ if (typeof app.component !== "function" || typeof app.directive !== "function") throw new TypeError("Installing a Vue plugin requires `component()` and `directive()` registration methods.");
13
13
  return app;
14
14
  };
15
15
  /**
16
16
  * 提取组件的全局注册名称。
17
17
  *
18
- * @param component - 待注册组件。
19
- * @returns 经过校验的显式名称。
18
+ * @param component - 待注册组件
19
+ * @returns 经过校验的显式名称
20
20
  * @throws `TypeError` 当组件没有非空字符串名称,或名称包含空白。
21
21
  */
22
22
  const getComponentName = (component) => {
23
23
  const name = component.name;
24
- if (typeof name !== "string" || name.length === 0 || /\s/u.test(name)) throw new TypeError("可安装的 Vue 组件必须公开不含空白的非空名称。");
24
+ if (typeof name !== "string" || name.length === 0 || /\s/u.test(name)) throw new TypeError("An installable Vue component must expose a nonempty name without whitespace.");
25
25
  return name;
26
26
  };
27
27
  /**
28
28
  * 预检单个组件注册。
29
29
  *
30
30
  * @remarks 先读取同名组件并完成冲突判断,再返回延迟执行动作;调用方可以在所有组件预检通过后统一提交。
31
- * @param app - 已校验的 Vue 3 App 注册目标。
32
- * @param component - 待注册组件。
31
+ * @param app - 已校验的 Vue 3 App 注册目标
32
+ * @param component - 待注册组件
33
33
  * @returns 已校验的组件引用、名称和目标中是否已经存在同一引用。
34
34
  * @throws `Error` 当同名位置已由其他组件占用。
35
35
  */
36
36
  const prepareComponentRegistration = (app, component) => {
37
37
  const name = getComponentName(component);
38
38
  const existing = app.component(name);
39
- if (existing !== void 0 && existing !== component) throw new Error(`Vue 组件名称“${name}”已被其他组件注册。`);
39
+ if (existing !== void 0 && existing !== component) throw new Error(`The Vue component name "${name}" is already registered to another component.`);
40
40
  return {
41
41
  component,
42
42
  name,
@@ -48,22 +48,22 @@ const prepareComponentRegistration = (app, component) => {
48
48
  *
49
49
  * @remarks 函数会直接为 `main` 定义附属组件属性和 `install`。所有组件名称、附属属性
50
50
  * 冲突会在修改 `main` 前完成校验;安装到 App 时也会先预检全部全局名称,再统一注册。
51
- * @param main - 具有非空 `name` 的组件。
52
- * @param extras - 同时注册并以可枚举属性挂到主组件的附属组件映射。
51
+ * @param main - 具有非空 `name` 的组件
52
+ * @param extras - 同时注册并以可枚举属性挂到主组件的附属组件映射
53
53
  * @returns 原始 `main` 引用,并附加类型化的 `install` 与 `extras` 属性。
54
54
  * @throws `TypeError` 当组件缺少合法名称、已有 `install`、附属键或名称发生冲突。
55
55
  * @throws `Error` 当 App 中同名位置已经注册其他组件。
56
56
  */
57
57
  function withInstall(main, extras) {
58
58
  const componentNames = /* @__PURE__ */ new Set([getComponentName(main)]);
59
- if ("install" in Object(main)) throw new TypeError("Vue 组件已定义 `install` 属性。");
59
+ if ("install" in Object(main)) throw new TypeError("The Vue component already defines an `install` property.");
60
60
  const extraEntries = Object.entries(extras ?? {});
61
- if (extras !== void 0 && Object.getOwnPropertySymbols(extras).some((key) => Object.prototype.propertyIsEnumerable.call(extras, key))) throw new TypeError("Vue 组件附属项必须使用字符串属性名。");
61
+ if (extras !== void 0 && Object.getOwnPropertySymbols(extras).some((key) => Object.prototype.propertyIsEnumerable.call(extras, key))) throw new TypeError("Vue component extras must use string property names.");
62
62
  for (const [key, component] of extraEntries) {
63
63
  const componentName = getComponentName(component);
64
- if (componentNames.has(componentName)) throw new TypeError(`Vue 组件名称“${componentName}”被重复注册。`);
64
+ if (componentNames.has(componentName)) throw new TypeError(`The Vue component name "${componentName}" is registered more than once.`);
65
65
  componentNames.add(componentName);
66
- if (key === "install" || key in Object(main)) throw new TypeError(`Vue 组件附属项“${key}”会覆盖主组件上的属性。`);
66
+ if (key === "install" || key in Object(main)) throw new TypeError(`The Vue component extra "${key}" would overwrite a property on the main component.`);
67
67
  }
68
68
  const installable = main;
69
69
  for (const [key, component] of extraEntries) Object.defineProperty(installable, key, {
@@ -84,12 +84,12 @@ function withInstall(main, extras) {
84
84
  *
85
85
  * @remarks 适用于只能作为主组件附属属性使用、但仍需满足 Vue Plugin 类型的组件。
86
86
  * 函数直接修改并返回传入组件,不会向 Vue 3 App 注册内容。
87
- * @param component - 尚未定义或继承 `install` 属性的组件。
88
- * @returns 原组件引用及无副作用的 `install` 方法。
87
+ * @param component - 尚未定义或继承 `install` 属性的组件
88
+ * @returns 原组件引用及无副作用的 `install` 方法
89
89
  * @throws `TypeError` 当组件自身或原型链已经存在 `install`。
90
90
  */
91
91
  function withNoopInstall(component) {
92
- if ("install" in Object(component)) throw new TypeError("Vue 组件已定义 `install` 属性。");
92
+ if ("install" in Object(component)) throw new TypeError("The Vue component already defines an `install` property.");
93
93
  const installable = component;
94
94
  installable.install = () => void 0;
95
95
  return installable;
@@ -99,20 +99,20 @@ function withNoopInstall(component) {
99
99
  *
100
100
  * @remarks 函数直接修改并返回指令。安装时重复注册同一引用保持幂等,不会覆盖同名的
101
101
  * 其他指令。名称只传给 `directive()`,不得包含 `v-` 前缀。
102
- * @param directive - 尚未定义或继承 `install` 属性的 Vue 指令对象。
103
- * @param name - 非空、无空白且不以 `v-` 开头的全局指令名。
102
+ * @param directive - 尚未定义或继承 `install` 属性的 Vue 指令对象
103
+ * @param name - 非空、无空白且不以 `v-` 开头的全局指令名
104
104
  * @returns 原指令引用及 Vue Plugin `install` 方法。
105
105
  * @throws `TypeError` 当名称非法、指令已有 `install`,或安装目标无效。
106
106
  * @throws `Error` 当 App 中同名位置已经注册其他指令。
107
107
  */
108
108
  function withInstallDirective(directive, name) {
109
- if (name.length === 0 || /\s/u.test(name) || name.startsWith("v-")) throw new TypeError("可安装的 Vue 指令名称不能包含空白或 `v-` 前缀。");
110
- if ("install" in Object(directive)) throw new TypeError("Vue 指令已定义 `install` 属性。");
109
+ if (name.length === 0 || /\s/u.test(name) || name.startsWith("v-")) throw new TypeError("An installable Vue directive name must not contain whitespace or the `v-` prefix.");
110
+ if ("install" in Object(directive)) throw new TypeError("The Vue directive already defines an `install` property.");
111
111
  const installable = directive;
112
112
  installable.install = (value) => {
113
113
  const app = assertApp(value);
114
114
  const existing = app.directive(name);
115
- if (existing !== void 0 && existing !== directive) throw new Error(`Vue 指令名称“${name}”已被其他指令注册。`);
115
+ if (existing !== void 0 && existing !== directive) throw new Error(`The Vue directive name "${name}" is already registered to another directive.`);
116
116
  if (existing !== directive) app.directive(name, directive);
117
117
  };
118
118
  return installable;
@@ -1 +1 @@
1
- {"version":3,"file":"install.mjs","names":[],"sources":["../../src/vue/install.ts"],"sourcesContent":["import type { App } from \"vue\";\n\n/** Vue 组件对象、函数组件或指令对象可接受的最小结构类型。 */\nexport type VueInstallValue = object | ((...arguments_: never[]) => unknown);\n\n/** 为 Vue 组件或指令附加供 Vue 3 `app.use()` 调用的安装能力。 */\nexport type Installable<Value> = Value & {\n\t/**\n\t * 把当前组件或指令安装到 Vue 3 App。\n\t * @param app - Vue 3 App 实例。\n\t */\n\tinstall: (app: App) => void;\n};\n\n/** TSX 组件安装类型;与 {@link Installable} 保持同一运行时契约。 */\nexport type TSXWithInstall<Value> = Installable<Value>;\n\n/** 组件、指令注册所需的 Vue 3 App 能力。 */\ninterface VueAppRegistrationTarget {\n\t/**\n\t * 读取或注册全局组件。\n\t *\n\t * @param name - 全局组件名。\n\t * @param component - 注册时传入的组件;省略时读取现有组件。\n\t * @returns Vue App 返回的现有组件、注册结果或 App 自身。\n\t */\n\tcomponent: (name: string, component?: unknown) => unknown;\n\t/**\n\t * 读取或注册全局指令。\n\t *\n\t * @param name - 不带 `v-` 的全局指令名。\n\t * @param directive - 注册时传入的指令;省略时读取现有指令。\n\t * @returns Vue App 返回的现有指令、注册结果或 App 自身。\n\t */\n\tdirective: (name: string, directive?: unknown) => unknown;\n}\n\n/**\n * 校验 Vue 3 插件安装目标。\n *\n * @param value - Vue 3 App 实例。\n * @returns 只包含组件和指令注册能力的 App。\n * @throws `TypeError` 当目标不是对象或缺少 `component`、`directive` 方法。\n */\nconst assertApp = (value: unknown): VueAppRegistrationTarget => {\n\tif (typeof value !== \"object\" || value === null) {\n\t\tthrow new TypeError(\"安装 Vue 插件需要 Vue 3 App 实例。\");\n\t}\n\tconst app = value as Partial<VueAppRegistrationTarget>;\n\tif (typeof app.component !== \"function\" || typeof app.directive !== \"function\") {\n\t\tthrow new TypeError(\"安装 Vue 插件需要 `component()` 和 `directive()` 注册方法。\");\n\t}\n\treturn app as VueAppRegistrationTarget;\n};\n\n/**\n * 提取组件的全局注册名称。\n *\n * @param component - 待注册组件。\n * @returns 经过校验的显式名称。\n * @throws `TypeError` 当组件没有非空字符串名称,或名称包含空白。\n */\nconst getComponentName = (component: VueInstallValue): string => {\n\tconst name = (component as { name?: unknown }).name;\n\tif (typeof name !== \"string\" || name.length === 0 || /\\s/u.test(name)) {\n\t\tthrow new TypeError(\"可安装的 Vue 组件必须公开不含空白的非空名称。\");\n\t}\n\treturn name;\n};\n\n/**\n * 预检单个组件注册。\n *\n * @remarks 先读取同名组件并完成冲突判断,再返回延迟执行动作;调用方可以在所有组件预检通过后统一提交。\n * @param app - 已校验的 Vue 3 App 注册目标。\n * @param component - 待注册组件。\n * @returns 已校验的组件引用、名称和目标中是否已经存在同一引用。\n * @throws `Error` 当同名位置已由其他组件占用。\n */\nconst prepareComponentRegistration = (app: VueAppRegistrationTarget, component: VueInstallValue) => {\n\tconst name = getComponentName(component);\n\tconst existing = app.component(name);\n\tif (existing !== undefined && existing !== component) {\n\t\tthrow new Error(`Vue 组件名称“${name}”已被其他组件注册。`);\n\t}\n\treturn { component, name, registered: existing === component };\n};\n\n/**\n * 为主组件附加 Vue 3 `app.use()` 安装能力。\n *\n * @remarks 函数会直接为 `main` 定义附属组件属性和 `install`。所有组件名称、附属属性\n * 冲突会在修改 `main` 前完成校验;安装到 App 时也会先预检全部全局名称,再统一注册。\n * @param main - 具有非空 `name` 的组件。\n * @param extras - 同时注册并以可枚举属性挂到主组件的附属组件映射。\n * @returns 原始 `main` 引用,并附加类型化的 `install` 与 `extras` 属性。\n * @throws `TypeError` 当组件缺少合法名称、已有 `install`、附属键或名称发生冲突。\n * @throws `Error` 当 App 中同名位置已经注册其他组件。\n */\nexport function withInstall<Main extends VueInstallValue, Extras extends Record<string, VueInstallValue> = Record<never, never>>(\n\tmain: Main,\n\textras?: Extras\n): Installable<Main> & Extras {\n\tconst componentNames = new Set([getComponentName(main)]);\n\tif (\"install\" in Object(main)) throw new TypeError(\"Vue 组件已定义 `install` 属性。\");\n\tconst extraEntries = Object.entries(extras ?? {});\n\tif (extras !== undefined && Object.getOwnPropertySymbols(extras).some((key) => Object.prototype.propertyIsEnumerable.call(extras, key))) {\n\t\tthrow new TypeError(\"Vue 组件附属项必须使用字符串属性名。\");\n\t}\n\tfor (const [key, component] of extraEntries) {\n\t\tconst componentName = getComponentName(component);\n\t\tif (componentNames.has(componentName)) throw new TypeError(`Vue 组件名称“${componentName}”被重复注册。`);\n\t\tcomponentNames.add(componentName);\n\t\tif (key === \"install\" || key in Object(main)) {\n\t\t\tthrow new TypeError(`Vue 组件附属项“${key}”会覆盖主组件上的属性。`);\n\t\t}\n\t}\n\tconst installable = main as Installable<Main> & Extras;\n\tfor (const [key, component] of extraEntries) {\n\t\tObject.defineProperty(installable, key, { configurable: true, enumerable: true, value: component, writable: true });\n\t}\n\tinstallable.install = (value: App) => {\n\t\tconst app = assertApp(value);\n\t\t// 先完成全部冲突检查,再统一注册,避免安装到一半留下部分全局组件。\n\t\tconst registrations = [main, ...extraEntries.map(([, component]) => component)].map((component) =>\n\t\t\tprepareComponentRegistration(app, component)\n\t\t);\n\t\tfor (const registration of registrations) {\n\t\t\tif (!registration.registered) app.component(registration.name, registration.component);\n\t\t}\n\t};\n\treturn installable;\n}\n\n/**\n * 为不需要单独注册的附属组件附加空安装函数。\n *\n * @remarks 适用于只能作为主组件附属属性使用、但仍需满足 Vue Plugin 类型的组件。\n * 函数直接修改并返回传入组件,不会向 Vue 3 App 注册内容。\n * @param component - 尚未定义或继承 `install` 属性的组件。\n * @returns 原组件引用及无副作用的 `install` 方法。\n * @throws `TypeError` 当组件自身或原型链已经存在 `install`。\n */\nexport function withNoopInstall<Value extends VueInstallValue>(component: Value): TSXWithInstall<Value> {\n\tif (\"install\" in Object(component)) throw new TypeError(\"Vue 组件已定义 `install` 属性。\");\n\tconst installable = component as TSXWithInstall<Value>;\n\tinstallable.install = () => undefined;\n\treturn installable;\n}\n\n/**\n * 为 Vue 3 指令附加插件安装能力。\n *\n * @remarks 函数直接修改并返回指令。安装时重复注册同一引用保持幂等,不会覆盖同名的\n * 其他指令。名称只传给 `directive()`,不得包含 `v-` 前缀。\n * @param directive - 尚未定义或继承 `install` 属性的 Vue 指令对象。\n * @param name - 非空、无空白且不以 `v-` 开头的全局指令名。\n * @returns 原指令引用及 Vue Plugin `install` 方法。\n * @throws `TypeError` 当名称非法、指令已有 `install`,或安装目标无效。\n * @throws `Error` 当 App 中同名位置已经注册其他指令。\n */\nexport function withInstallDirective<Value extends VueInstallValue>(directive: Value, name: string): Installable<Value> {\n\tif (name.length === 0 || /\\s/u.test(name) || name.startsWith(\"v-\")) {\n\t\tthrow new TypeError(\"可安装的 Vue 指令名称不能包含空白或 `v-` 前缀。\");\n\t}\n\tif (\"install\" in Object(directive)) throw new TypeError(\"Vue 指令已定义 `install` 属性。\");\n\tconst installable = directive as Installable<Value>;\n\tinstallable.install = (value: App) => {\n\t\tconst app = assertApp(value);\n\t\tconst existing = app.directive(name);\n\t\tif (existing !== undefined && existing !== directive) {\n\t\t\tthrow new Error(`Vue 指令名称“${name}”已被其他指令注册。`);\n\t\t}\n\t\tif (existing !== directive) app.directive(name, directive);\n\t};\n\treturn installable;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"install.mjs","names":[],"sources":["../../src/vue/install.ts"],"sourcesContent":["import type { App } from \"vue\";\n\n/** Vue 组件对象、函数组件或指令对象可接受的最小结构类型 */\nexport type VueInstallValue = object | ((...arguments_: never[]) => unknown);\n\n/** 为 Vue 组件或指令附加供 Vue 3 `app.use()` 调用的安装能力 */\nexport type Installable<Value> = Value & {\n\t/**\n\t * 把当前组件或指令安装到 Vue 3 App。\n\t * @param app - Vue 3 App 实例\n\t */\n\tinstall: (app: App) => void;\n};\n\n/** TSX 组件安装类型;与 {@link Installable} 保持同一运行时契约。 */\nexport type TSXWithInstall<Value> = Installable<Value>;\n\n/** 组件、指令注册所需的 Vue 3 App 能力 */\ninterface VueAppRegistrationTarget {\n\t/**\n\t * 读取或注册全局组件。\n\t *\n\t * @param name - 全局组件名\n\t * @param component - 注册时传入的组件;省略时读取现有组件。\n\t * @returns Vue App 返回的现有组件、注册结果或 App 自身。\n\t */\n\tcomponent: (name: string, component?: unknown) => unknown;\n\t/**\n\t * 读取或注册全局指令。\n\t *\n\t * @param name - 不带 `v-` 的全局指令名\n\t * @param directive - 注册时传入的指令;省略时读取现有指令。\n\t * @returns Vue App 返回的现有指令、注册结果或 App 自身。\n\t */\n\tdirective: (name: string, directive?: unknown) => unknown;\n}\n\n/**\n * 校验 Vue 3 插件安装目标。\n *\n * @param value - Vue 3 App 实例\n * @returns 只包含组件和指令注册能力的 App\n * @throws `TypeError` 当目标不是对象或缺少 `component`、`directive` 方法。\n */\nconst assertApp = (value: unknown): VueAppRegistrationTarget => {\n\tif (typeof value !== \"object\" || value === null) {\n\t\tthrow new TypeError(\"Installing a Vue plugin requires a Vue 3 App instance.\");\n\t}\n\tconst app = value as Partial<VueAppRegistrationTarget>;\n\tif (typeof app.component !== \"function\" || typeof app.directive !== \"function\") {\n\t\tthrow new TypeError(\"Installing a Vue plugin requires `component()` and `directive()` registration methods.\");\n\t}\n\treturn app as VueAppRegistrationTarget;\n};\n\n/**\n * 提取组件的全局注册名称。\n *\n * @param component - 待注册组件\n * @returns 经过校验的显式名称\n * @throws `TypeError` 当组件没有非空字符串名称,或名称包含空白。\n */\nconst getComponentName = (component: VueInstallValue): string => {\n\tconst name = (component as { name?: unknown }).name;\n\tif (typeof name !== \"string\" || name.length === 0 || /\\s/u.test(name)) {\n\t\tthrow new TypeError(\"An installable Vue component must expose a nonempty name without whitespace.\");\n\t}\n\treturn name;\n};\n\n/**\n * 预检单个组件注册。\n *\n * @remarks 先读取同名组件并完成冲突判断,再返回延迟执行动作;调用方可以在所有组件预检通过后统一提交。\n * @param app - 已校验的 Vue 3 App 注册目标\n * @param component - 待注册组件\n * @returns 已校验的组件引用、名称和目标中是否已经存在同一引用。\n * @throws `Error` 当同名位置已由其他组件占用。\n */\nconst prepareComponentRegistration = (app: VueAppRegistrationTarget, component: VueInstallValue) => {\n\tconst name = getComponentName(component);\n\tconst existing = app.component(name);\n\tif (existing !== undefined && existing !== component) {\n\t\tthrow new Error(`The Vue component name \"${name}\" is already registered to another component.`);\n\t}\n\treturn { component, name, registered: existing === component };\n};\n\n/**\n * 为主组件附加 Vue 3 `app.use()` 安装能力。\n *\n * @remarks 函数会直接为 `main` 定义附属组件属性和 `install`。所有组件名称、附属属性\n * 冲突会在修改 `main` 前完成校验;安装到 App 时也会先预检全部全局名称,再统一注册。\n * @param main - 具有非空 `name` 的组件\n * @param extras - 同时注册并以可枚举属性挂到主组件的附属组件映射\n * @returns 原始 `main` 引用,并附加类型化的 `install` 与 `extras` 属性。\n * @throws `TypeError` 当组件缺少合法名称、已有 `install`、附属键或名称发生冲突。\n * @throws `Error` 当 App 中同名位置已经注册其他组件。\n */\nexport function withInstall<Main extends VueInstallValue, Extras extends Record<string, VueInstallValue> = Record<never, never>>(\n\tmain: Main,\n\textras?: Extras\n): Installable<Main> & Extras {\n\tconst componentNames = new Set([getComponentName(main)]);\n\tif (\"install\" in Object(main)) throw new TypeError(\"The Vue component already defines an `install` property.\");\n\tconst extraEntries = Object.entries(extras ?? {});\n\tif (extras !== undefined && Object.getOwnPropertySymbols(extras).some((key) => Object.prototype.propertyIsEnumerable.call(extras, key))) {\n\t\tthrow new TypeError(\"Vue component extras must use string property names.\");\n\t}\n\tfor (const [key, component] of extraEntries) {\n\t\tconst componentName = getComponentName(component);\n\t\tif (componentNames.has(componentName)) throw new TypeError(`The Vue component name \"${componentName}\" is registered more than once.`);\n\t\tcomponentNames.add(componentName);\n\t\tif (key === \"install\" || key in Object(main)) {\n\t\t\tthrow new TypeError(`The Vue component extra \"${key}\" would overwrite a property on the main component.`);\n\t\t}\n\t}\n\tconst installable = main as Installable<Main> & Extras;\n\tfor (const [key, component] of extraEntries) {\n\t\tObject.defineProperty(installable, key, { configurable: true, enumerable: true, value: component, writable: true });\n\t}\n\tinstallable.install = (value: App) => {\n\t\tconst app = assertApp(value);\n\t\t// 先完成全部冲突检查,再统一注册,避免安装到一半留下部分全局组件。\n\t\tconst registrations = [main, ...extraEntries.map(([, component]) => component)].map((component) =>\n\t\t\tprepareComponentRegistration(app, component)\n\t\t);\n\t\tfor (const registration of registrations) {\n\t\t\tif (!registration.registered) app.component(registration.name, registration.component);\n\t\t}\n\t};\n\treturn installable;\n}\n\n/**\n * 为不需要单独注册的附属组件附加空安装函数。\n *\n * @remarks 适用于只能作为主组件附属属性使用、但仍需满足 Vue Plugin 类型的组件。\n * 函数直接修改并返回传入组件,不会向 Vue 3 App 注册内容。\n * @param component - 尚未定义或继承 `install` 属性的组件\n * @returns 原组件引用及无副作用的 `install` 方法\n * @throws `TypeError` 当组件自身或原型链已经存在 `install`。\n */\nexport function withNoopInstall<Value extends VueInstallValue>(component: Value): TSXWithInstall<Value> {\n\tif (\"install\" in Object(component)) throw new TypeError(\"The Vue component already defines an `install` property.\");\n\tconst installable = component as TSXWithInstall<Value>;\n\tinstallable.install = () => undefined;\n\treturn installable;\n}\n\n/**\n * 为 Vue 3 指令附加插件安装能力。\n *\n * @remarks 函数直接修改并返回指令。安装时重复注册同一引用保持幂等,不会覆盖同名的\n * 其他指令。名称只传给 `directive()`,不得包含 `v-` 前缀。\n * @param directive - 尚未定义或继承 `install` 属性的 Vue 指令对象\n * @param name - 非空、无空白且不以 `v-` 开头的全局指令名\n * @returns 原指令引用及 Vue Plugin `install` 方法。\n * @throws `TypeError` 当名称非法、指令已有 `install`,或安装目标无效。\n * @throws `Error` 当 App 中同名位置已经注册其他指令。\n */\nexport function withInstallDirective<Value extends VueInstallValue>(directive: Value, name: string): Installable<Value> {\n\tif (name.length === 0 || /\\s/u.test(name) || name.startsWith(\"v-\")) {\n\t\tthrow new TypeError(\"An installable Vue directive name must not contain whitespace or the `v-` prefix.\");\n\t}\n\tif (\"install\" in Object(directive)) throw new TypeError(\"The Vue directive already defines an `install` property.\");\n\tconst installable = directive as Installable<Value>;\n\tinstallable.install = (value: App) => {\n\t\tconst app = assertApp(value);\n\t\tconst existing = app.directive(name);\n\t\tif (existing !== undefined && existing !== directive) {\n\t\t\tthrow new Error(`The Vue directive name \"${name}\" is already registered to another directive.`);\n\t\t}\n\t\tif (existing !== directive) app.directive(name, directive);\n\t};\n\treturn installable;\n}\n"],"mappings":"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"}
package/dist/vue/now.mjs CHANGED
@@ -1,19 +1,18 @@
1
- import { getRuntimeUni, runtimeGlobals } from "../internal/runtime.mjs";
2
1
  import { getCurrentScope, onScopeDispose, readonly, shallowRef } from "vue";
3
2
  //#region src/vue/now.ts
4
3
  /**
5
4
  * 按固定间隔提供响应式当前时间。
6
5
  *
7
- * @param intervalMilliseconds - 更新时间间隔,默认 `1000` 毫秒。
6
+ * @param intervalMilliseconds - 更新时间间隔,默认 `1000` 毫秒
8
7
  * @returns 当前 Date 的只读 ShallowRef;SSR 环境只返回调用时的时间。
9
8
  * @throws `Error` 当浏览器或 uni-app 环境中不存在可用于自动清理的 Vue 响应式作用域。
10
9
  * @throws `RangeError` 当间隔不是平台计时器支持的非负有限整数。
11
10
  */
12
11
  function useNow(intervalMilliseconds = 1e3) {
13
- if (!Number.isInteger(intervalMilliseconds) || intervalMilliseconds < 0 || intervalMilliseconds > 2147483647) throw new RangeError("`intervalMilliseconds` 必须是 0 至 2,147,483,647 的整数。");
12
+ if (!Number.isInteger(intervalMilliseconds) || intervalMilliseconds < 0 || intervalMilliseconds > 2147483647) throw new RangeError("`intervalMilliseconds` must be an integer between 0 and 2,147,483,647.");
14
13
  const now = shallowRef(/* @__PURE__ */ new Date());
15
- if (runtimeGlobals.window !== void 0 || getRuntimeUni() !== void 0) {
16
- if (getCurrentScope() === void 0) throw new Error("`useNow` 必须在 Vue 响应式作用域内调用。");
14
+ if (typeof window !== "undefined" || typeof uni !== "undefined") {
15
+ if (getCurrentScope() === void 0) throw new Error("`useNow` must be called within a Vue reactive scope.");
17
16
  const timer = setInterval(() => {
18
17
  now.value = /* @__PURE__ */ new Date();
19
18
  }, intervalMilliseconds);
@@ -1 +1 @@
1
- {"version":3,"file":"now.mjs","names":[],"sources":["../../src/vue/now.ts"],"sourcesContent":["import { getCurrentScope, onScopeDispose, readonly, shallowRef } from \"vue\";\nimport { getRuntimeUni, runtimeGlobals } from \"../internal/runtime\";\nimport type { ShallowRef } from \"vue\";\n\n/**\n * 按固定间隔提供响应式当前时间。\n *\n * @param intervalMilliseconds - 更新时间间隔,默认 `1000` 毫秒。\n * @returns 当前 Date 的只读 ShallowRef;SSR 环境只返回调用时的时间。\n * @throws `Error` 当浏览器或 uni-app 环境中不存在可用于自动清理的 Vue 响应式作用域。\n * @throws `RangeError` 当间隔不是平台计时器支持的非负有限整数。\n */\nexport function useNow(intervalMilliseconds = 1000): Readonly<ShallowRef<Date>> {\n\tif (!Number.isInteger(intervalMilliseconds) || intervalMilliseconds < 0 || intervalMilliseconds > 2_147_483_647) {\n\t\tthrow new RangeError(\"`intervalMilliseconds` 必须是 0 至 2,147,483,647 的整数。\");\n\t}\n\tconst now = shallowRef(new Date());\n\tif (runtimeGlobals.window !== undefined || getRuntimeUni() !== undefined) {\n\t\tif (getCurrentScope() === undefined) throw new Error(\"`useNow` 必须在 Vue 响应式作用域内调用。\");\n\t\tconst timer = setInterval(() => {\n\t\t\tnow.value = new Date();\n\t\t}, intervalMilliseconds);\n\t\tonScopeDispose(() => {\n\t\t\tclearInterval(timer);\n\t\t});\n\t}\n\treturn readonly(now);\n}\n"],"mappings":";;;;;;;;;;;AAYA,SAAgB,OAAO,uBAAuB,KAAkC;CAC/E,IAAI,CAAC,OAAO,UAAU,oBAAoB,KAAK,uBAAuB,KAAK,uBAAuB,YACjG,MAAM,IAAI,WAAW,mDAAmD;CAEzE,MAAM,MAAM,2BAAW,IAAI,KAAK,CAAC;CACjC,IAAI,eAAe,WAAW,KAAA,KAAa,cAAc,MAAM,KAAA,GAAW;EACzE,IAAI,gBAAgB,MAAM,KAAA,GAAW,MAAM,IAAI,MAAM,6BAA6B;EAClF,MAAM,QAAQ,kBAAkB;GAC/B,IAAI,wBAAQ,IAAI,KAAK;EACtB,GAAG,oBAAoB;EACvB,qBAAqB;GACpB,cAAc,KAAK;EACpB,CAAC;CACF;CACA,OAAO,SAAS,GAAG;AACpB"}
1
+ {"version":3,"file":"now.mjs","names":[],"sources":["../../src/vue/now.ts"],"sourcesContent":["import { getCurrentScope, onScopeDispose, readonly, shallowRef } from \"vue\";\nimport type { ShallowRef } from \"vue\";\n\n/**\n * 按固定间隔提供响应式当前时间。\n *\n * @param intervalMilliseconds - 更新时间间隔,默认 `1000` 毫秒\n * @returns 当前 Date 的只读 ShallowRef;SSR 环境只返回调用时的时间。\n * @throws `Error` 当浏览器或 uni-app 环境中不存在可用于自动清理的 Vue 响应式作用域。\n * @throws `RangeError` 当间隔不是平台计时器支持的非负有限整数。\n */\nexport function useNow(intervalMilliseconds = 1000): Readonly<ShallowRef<Date>> {\n\tif (!Number.isInteger(intervalMilliseconds) || intervalMilliseconds < 0 || intervalMilliseconds > 2_147_483_647) {\n\t\tthrow new RangeError(\"`intervalMilliseconds` must be an integer between 0 and 2,147,483,647.\");\n\t}\n\tconst now = shallowRef(new Date());\n\tif (typeof window !== \"undefined\" || typeof uni !== \"undefined\") {\n\t\tif (getCurrentScope() === undefined) throw new Error(\"`useNow` must be called within a Vue reactive scope.\");\n\t\tconst timer = setInterval(() => {\n\t\t\tnow.value = new Date();\n\t\t}, intervalMilliseconds);\n\t\tonScopeDispose(() => {\n\t\t\tclearInterval(timer);\n\t\t});\n\t}\n\treturn readonly(now);\n}\n"],"mappings":";;;;;;;;;;AAWA,SAAgB,OAAO,uBAAuB,KAAkC;CAC/E,IAAI,CAAC,OAAO,UAAU,oBAAoB,KAAK,uBAAuB,KAAK,uBAAuB,YACjG,MAAM,IAAI,WAAW,wEAAwE;CAE9F,MAAM,MAAM,2BAAW,IAAI,KAAK,CAAC;CACjC,IAAI,OAAO,WAAW,eAAe,OAAO,QAAQ,aAAa;EAChE,IAAI,gBAAgB,MAAM,KAAA,GAAW,MAAM,IAAI,MAAM,sDAAsD;EAC3G,MAAM,QAAQ,kBAAkB;GAC/B,IAAI,wBAAQ,IAAI,KAAK;EACtB,GAAG,oBAAoB;EACvB,qBAAqB;GACpB,cAAc,KAAK;EACpB,CAAC;CACF;CACA,OAAO,SAAS,GAAG;AACpB"}
@@ -5,7 +5,7 @@ import { computed } from "vue";
5
5
  *
6
6
  * @remarks 该函数只帮助 TypeScript 建模,不验证运行时值与 `Value` 一致;调用方仍应
7
7
  * 传入 Vue 支持的构造器或构造器数组。
8
- * @param runtimeType - Vue 支持的运行时构造器或构造器数组。
8
+ * @param runtimeType - Vue 支持的运行时构造器或构造器数组
9
9
  * @returns 同一引用,仅在类型层收窄为 `PropType<Value>`。
10
10
  */
11
11
  function definePropType(runtimeType) {
@@ -14,9 +14,9 @@ function definePropType(runtimeType) {
14
14
  /**
15
15
  * 构建需要透传给子组件的响应式 Props。
16
16
  *
17
- * @param props - Vue `setup` 接收的只读响应式 Props 对象。
18
- * @param rawProps - 子组件的运行时 Props 配置。
19
- * @param ignoredProps - 不需要透传的 Props 名称。
17
+ * @param props - Vue `setup` 接收的只读响应式 Props 对象
18
+ * @param rawProps - 子组件的运行时 Props 配置
19
+ * @param ignoredProps - 不需要透传的 Props 名称
20
20
  * @returns 只包含 `rawProps` 声明键且随 Props 更新的 ComputedRef。
21
21
  */
22
22
  function useProps(props, rawProps, ignoredProps = []) {
@@ -24,7 +24,7 @@ function useProps(props, rawProps, ignoredProps = []) {
24
24
  return computed(() => {
25
25
  const result = {};
26
26
  for (const key of Reflect.ownKeys(rawProps)) {
27
- if (ignored.has(key) || !Object.hasOwn(props, key)) continue;
27
+ if (ignored.has(key) || !Object.prototype.hasOwnProperty.call(props, key)) continue;
28
28
  Object.defineProperty(result, key, {
29
29
  configurable: true,
30
30
  enumerable: true,
@@ -1 +1 @@
1
- {"version":3,"file":"props.mjs","names":[],"sources":["../../src/vue/props.ts"],"sourcesContent":["import { computed } from \"vue\";\nimport type { ComputedRef, PropType } from \"vue\";\n\n/**\n * 为 Vue 运行时 Props 构造器附加泛型类型。\n *\n * @remarks 该函数只帮助 TypeScript 建模,不验证运行时值与 `Value` 一致;调用方仍应\n * 传入 Vue 支持的构造器或构造器数组。\n * @param runtimeType - Vue 支持的运行时构造器或构造器数组。\n * @returns 同一引用,仅在类型层收窄为 `PropType<Value>`。\n */\nexport function definePropType<Value>(runtimeType: unknown): PropType<Value> {\n\treturn runtimeType as PropType<Value>;\n}\n\n/**\n * 构建需要透传给子组件的响应式 Props。\n *\n * @param props - Vue `setup` 接收的只读响应式 Props 对象。\n * @param rawProps - 子组件的运行时 Props 配置。\n * @param ignoredProps - 不需要透传的 Props 名称。\n * @returns 只包含 `rawProps` 声明键且随 Props 更新的 ComputedRef。\n */\nexport function useProps<Props extends object, RawProps extends object, IgnoredProp extends keyof RawProps = never>(\n\tprops: Props,\n\trawProps: RawProps,\n\tignoredProps: readonly IgnoredProp[] = []\n): ComputedRef<Omit<Pick<Props, Extract<keyof Props, keyof RawProps>>, Extract<IgnoredProp, keyof Props>>> {\n\tconst ignored = new Set<PropertyKey>(ignoredProps);\n\ttype Result = Omit<Pick<Props, Extract<keyof Props, keyof RawProps>>, Extract<IgnoredProp, keyof Props>>;\n\treturn computed<Result>(() => {\n\t\tconst result = {} as Result;\n\t\tfor (const key of Reflect.ownKeys(rawProps)) {\n\t\t\tif (ignored.has(key) || !Object.hasOwn(props, key)) continue;\n\t\t\tObject.defineProperty(result, key, { configurable: true, enumerable: true, value: Reflect.get(props, key), writable: true });\n\t\t}\n\t\treturn result;\n\t});\n}\n"],"mappings":";;;;;;;;;;AAWA,SAAgB,eAAsB,aAAuC;CAC5E,OAAO;AACR;;;;;;;;;AAUA,SAAgB,SACf,OACA,UACA,eAAuC,CAAC,GACkE;CAC1G,MAAM,UAAU,IAAI,IAAiB,YAAY;CAEjD,OAAO,eAAuB;EAC7B,MAAM,SAAS,CAAC;EAChB,KAAK,MAAM,OAAO,QAAQ,QAAQ,QAAQ,GAAG;GAC5C,IAAI,QAAQ,IAAI,GAAG,KAAK,CAAC,OAAO,OAAO,OAAO,GAAG,GAAG;GACpD,OAAO,eAAe,QAAQ,KAAK;IAAE,cAAc;IAAM,YAAY;IAAM,OAAO,QAAQ,IAAI,OAAO,GAAG;IAAG,UAAU;GAAK,CAAC;EAC5H;EACA,OAAO;CACR,CAAC;AACF"}
1
+ {"version":3,"file":"props.mjs","names":[],"sources":["../../src/vue/props.ts"],"sourcesContent":["import { computed } from \"vue\";\nimport type { ComputedRef, PropType } from \"vue\";\n\n/**\n * 为 Vue 运行时 Props 构造器附加泛型类型。\n *\n * @remarks 该函数只帮助 TypeScript 建模,不验证运行时值与 `Value` 一致;调用方仍应\n * 传入 Vue 支持的构造器或构造器数组。\n * @param runtimeType - Vue 支持的运行时构造器或构造器数组\n * @returns 同一引用,仅在类型层收窄为 `PropType<Value>`。\n */\nexport function definePropType<Value>(runtimeType: unknown): PropType<Value> {\n\treturn runtimeType as PropType<Value>;\n}\n\n/**\n * 构建需要透传给子组件的响应式 Props。\n *\n * @param props - Vue `setup` 接收的只读响应式 Props 对象\n * @param rawProps - 子组件的运行时 Props 配置\n * @param ignoredProps - 不需要透传的 Props 名称\n * @returns 只包含 `rawProps` 声明键且随 Props 更新的 ComputedRef。\n */\nexport function useProps<Props extends object, RawProps extends object, IgnoredProp extends keyof RawProps = never>(\n\tprops: Props,\n\trawProps: RawProps,\n\tignoredProps: readonly IgnoredProp[] = []\n): ComputedRef<Omit<Pick<Props, Extract<keyof Props, keyof RawProps>>, Extract<IgnoredProp, keyof Props>>> {\n\tconst ignored = new Set<PropertyKey>(ignoredProps);\n\ttype Result = Omit<Pick<Props, Extract<keyof Props, keyof RawProps>>, Extract<IgnoredProp, keyof Props>>;\n\treturn computed<Result>(() => {\n\t\tconst result = {} as Result;\n\t\tfor (const key of Reflect.ownKeys(rawProps)) {\n\t\t\tif (ignored.has(key) || !Object.prototype.hasOwnProperty.call(props, key)) continue;\n\t\t\tObject.defineProperty(result, key, { configurable: true, enumerable: true, value: Reflect.get(props, key), writable: true });\n\t\t}\n\t\treturn result;\n\t});\n}\n"],"mappings":";;;;;;;;;;AAWA,SAAgB,eAAsB,aAAuC;CAC5E,OAAO;AACR;;;;;;;;;AAUA,SAAgB,SACf,OACA,UACA,eAAuC,CAAC,GACkE;CAC1G,MAAM,UAAU,IAAI,IAAiB,YAAY;CAEjD,OAAO,eAAuB;EAC7B,MAAM,SAAS,CAAC;EAChB,KAAK,MAAM,OAAO,QAAQ,QAAQ,QAAQ,GAAG;GAC5C,IAAI,QAAQ,IAAI,GAAG,KAAK,CAAC,OAAO,UAAU,eAAe,KAAK,OAAO,GAAG,GAAG;GAC3E,OAAO,eAAe,QAAQ,KAAK;IAAE,cAAc;IAAM,YAAY;IAAM,OAAO,QAAQ,IAAI,OAAO,GAAG;IAAG,UAAU;GAAK,CAAC;EAC5H;EACA,OAAO;CACR,CAAC;AACF"}
@@ -3,12 +3,12 @@ import { getCurrentInstance } from "vue";
3
3
  /**
4
4
  * 在当前 Vue 3 组件实例上安装 TSX 渲染函数。
5
5
  * @remarks `setup` 仍可返回状态对象,因此状态能够显示在 Vue Devtools 中。
6
- * @param render - 当前组件的渲染函数。
6
+ * @param render - 当前组件的渲染函数
7
7
  * @throws 不在组件 `setup` 调用栈中使用时抛出 `Error`。
8
8
  */
9
9
  function useRender(render) {
10
10
  const instance = getCurrentInstance();
11
- if (instance === null) throw new Error("`useRender` 必须在 `setup` 函数内部调用。");
11
+ if (instance === null) throw new Error("`useRender` must be called inside `setup`.");
12
12
  instance.render = render;
13
13
  }
14
14
  //#endregion
@@ -1 +1 @@
1
- {"version":3,"file":"render.mjs","names":[],"sources":["../../src/vue/render.ts"],"sourcesContent":["import { getCurrentInstance } from \"vue\";\nimport type { VNode } from \"vue\";\n\n/** `useRender` 需要写入的 Vue 3 内部组件实例字段。 */\ninterface MutableVueComponentInstance {\n\trender?: () => VNode;\n}\n\n/**\n * 在当前 Vue 3 组件实例上安装 TSX 渲染函数。\n * @remarks `setup` 仍可返回状态对象,因此状态能够显示在 Vue Devtools 中。\n * @param render - 当前组件的渲染函数。\n * @throws 不在组件 `setup` 调用栈中使用时抛出 `Error`。\n */\nexport function useRender(render: () => VNode): void {\n\tconst instance = getCurrentInstance();\n\tif (instance === null) throw new Error(\"`useRender` 必须在 `setup` 函数内部调用。\");\n\t(instance as MutableVueComponentInstance).render = render;\n}\n"],"mappings":";;;;;;;;AAcA,SAAgB,UAAU,QAA2B;CACpD,MAAM,WAAW,mBAAmB;CACpC,IAAI,aAAa,MAAM,MAAM,IAAI,MAAM,iCAAiC;CACxE,SAA0C,SAAS;AACpD"}
1
+ {"version":3,"file":"render.mjs","names":[],"sources":["../../src/vue/render.ts"],"sourcesContent":["import { getCurrentInstance } from \"vue\";\nimport type { VNode } from \"vue\";\n\n/** `useRender` 需要写入的 Vue 3 内部组件实例字段 */\ninterface MutableVueComponentInstance {\n\trender?: () => VNode;\n}\n\n/**\n * 在当前 Vue 3 组件实例上安装 TSX 渲染函数。\n * @remarks `setup` 仍可返回状态对象,因此状态能够显示在 Vue Devtools 中。\n * @param render - 当前组件的渲染函数\n * @throws 不在组件 `setup` 调用栈中使用时抛出 `Error`。\n */\nexport function useRender(render: () => VNode): void {\n\tconst instance = getCurrentInstance();\n\tif (instance === null) throw new Error(\"`useRender` must be called inside `setup`.\");\n\t(instance as MutableVueComponentInstance).render = render;\n}\n"],"mappings":";;;;;;;;AAcA,SAAgB,UAAU,QAA2B;CACpD,MAAM,WAAW,mBAAmB;CACpC,IAAI,aAAa,MAAM,MAAM,IAAI,MAAM,4CAA4C;CACnF,SAA0C,SAAS;AACpD"}
@@ -1,18 +1,16 @@
1
- import { runtimeGlobals } from "../internal/runtime.mjs";
2
1
  import { onScopeDispose, toValue, watch } from "vue";
3
2
  //#region src/vue/resize-observer.ts
4
3
  /**
5
4
  * 监听元素尺寸变化,并随响应式目标切换和 Vue 作用域销毁自动断开。
6
5
  *
7
- * @param target - 原生元素、Ref 或 Getter。
8
- * @param callback - 原生 ResizeObserver 回调。
9
- * @param options - 原生元素观察选项。
6
+ * @param target - 原生元素、Ref 或 Getter
7
+ * @param callback - 原生 ResizeObserver 回调
8
+ * @param options - 原生元素观察选项
10
9
  * @returns 可提前断开观察的停止函数;运行时不支持 ResizeObserver 时为空操作。
11
10
  */
12
11
  function useResizeObserver(target, callback, options) {
13
12
  const stop = watch(() => toValue(target), (currentTarget, _previousTarget, onCleanup) => {
14
- const ResizeObserver = runtimeGlobals.ResizeObserver;
15
- if (currentTarget === null || currentTarget === void 0 || ResizeObserver === void 0) return;
13
+ if (currentTarget === null || currentTarget === void 0 || typeof ResizeObserver === "undefined") return;
16
14
  const observer = new ResizeObserver(callback);
17
15
  observer.observe(currentTarget, options);
18
16
  onCleanup(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"resize-observer.mjs","names":[],"sources":["../../src/vue/resize-observer.ts"],"sourcesContent":["import { onScopeDispose, toValue, watch } from \"vue\";\nimport { runtimeGlobals } from \"../internal/runtime\";\nimport type { MaybeRefOrGetter } from \"vue\";\n\n/** `useResizeObserver` 接受的元素或响应式元素。 */\nexport type ResizeObserverTarget = MaybeRefOrGetter<Element | null | undefined>;\n\n/**\n * 监听元素尺寸变化,并随响应式目标切换和 Vue 作用域销毁自动断开。\n *\n * @param target - 原生元素、Ref 或 Getter。\n * @param callback - 原生 ResizeObserver 回调。\n * @param options - 原生元素观察选项。\n * @returns 可提前断开观察的停止函数;运行时不支持 ResizeObserver 时为空操作。\n */\nexport function useResizeObserver(target: ResizeObserverTarget, callback: ResizeObserverCallback, options?: ResizeObserverOptions): () => void {\n\tconst stop = watch(\n\t\t() => toValue(target),\n\t\t(currentTarget, _previousTarget, onCleanup) => {\n\t\t\tconst ResizeObserver = runtimeGlobals.ResizeObserver;\n\t\t\tif (currentTarget === null || currentTarget === undefined || ResizeObserver === undefined) return;\n\t\t\tconst observer = new ResizeObserver(callback);\n\t\t\tobserver.observe(currentTarget, options);\n\t\t\tonCleanup(() => {\n\t\t\t\tobserver.disconnect();\n\t\t\t});\n\t\t},\n\t\t{ flush: \"sync\", immediate: true }\n\t);\n\tonScopeDispose(stop, true);\n\treturn stop;\n}\n"],"mappings":";;;;;;;;;;;AAeA,SAAgB,kBAAkB,QAA8B,UAAkC,SAA6C;CAC9I,MAAM,OAAO,YACN,QAAQ,MAAM,IACnB,eAAe,iBAAiB,cAAc;EAC9C,MAAM,iBAAiB,eAAe;EACtC,IAAI,kBAAkB,QAAQ,kBAAkB,KAAA,KAAa,mBAAmB,KAAA,GAAW;EAC3F,MAAM,WAAW,IAAI,eAAe,QAAQ;EAC5C,SAAS,QAAQ,eAAe,OAAO;EACvC,gBAAgB;GACf,SAAS,WAAW;EACrB,CAAC;CACF,GACA;EAAE,OAAO;EAAQ,WAAW;CAAK,CAClC;CACA,eAAe,MAAM,IAAI;CACzB,OAAO;AACR"}
1
+ {"version":3,"file":"resize-observer.mjs","names":[],"sources":["../../src/vue/resize-observer.ts"],"sourcesContent":["import { onScopeDispose, toValue, watch } from \"vue\";\nimport type { MaybeRefOrGetter } from \"vue\";\n\n/** `useResizeObserver` 接受的元素或响应式元素 */\nexport type ResizeObserverTarget = MaybeRefOrGetter<Element | null | undefined>;\n\n/**\n * 监听元素尺寸变化,并随响应式目标切换和 Vue 作用域销毁自动断开。\n *\n * @param target - 原生元素、Ref 或 Getter\n * @param callback - 原生 ResizeObserver 回调\n * @param options - 原生元素观察选项\n * @returns 可提前断开观察的停止函数;运行时不支持 ResizeObserver 时为空操作。\n */\nexport function useResizeObserver(target: ResizeObserverTarget, callback: ResizeObserverCallback, options?: ResizeObserverOptions): () => void {\n\tconst stop = watch(\n\t\t() => toValue(target),\n\t\t(currentTarget, _previousTarget, onCleanup) => {\n\t\t\tif (currentTarget === null || currentTarget === undefined || typeof ResizeObserver === \"undefined\") return;\n\t\t\tconst observer = new ResizeObserver(callback);\n\t\t\tobserver.observe(currentTarget, options);\n\t\t\tonCleanup(() => {\n\t\t\t\tobserver.disconnect();\n\t\t\t});\n\t\t},\n\t\t{ flush: \"sync\", immediate: true }\n\t);\n\tonScopeDispose(stop, true);\n\treturn stop;\n}\n"],"mappings":";;;;;;;;;;AAcA,SAAgB,kBAAkB,QAA8B,UAAkC,SAA6C;CAC9I,MAAM,OAAO,YACN,QAAQ,MAAM,IACnB,eAAe,iBAAiB,cAAc;EAC9C,IAAI,kBAAkB,QAAQ,kBAAkB,KAAA,KAAa,OAAO,mBAAmB,aAAa;EACpG,MAAM,WAAW,IAAI,eAAe,QAAQ;EAC5C,SAAS,QAAQ,eAAe,OAAO;EACvC,gBAAgB;GACf,SAAS,WAAW;EACrB,CAAC;CACF,GACA;EAAE,OAAO;EAAQ,WAAW;CAAK,CAClC;CACA,eAAe,MAAM,IAAI;CACzB,OAAO;AACR"}
@@ -1 +1 @@
1
- {"version":3,"file":"slots.mjs","names":[],"sources":["../../src/vue/slots.ts"],"sourcesContent":["import type { SlotsType, VNode } from \"vue\";\n\n/** Slot 名到 Props 类型的内部声明映射。 */\ntype RawSlots = Record<string, unknown>;\n/** 根据 Slot Props 是否为 never 生成无参数或有参数的 Slot 签名。 */\ntype VueSlot<Properties> = [Properties] extends [never] ? () => VNode[] : (properties: Properties) => VNode[];\n\n/** 把 Slot 名称与作用域参数映射为 Vue 3 Slot 函数。 */\nexport type TypedSlots<Slots extends RawSlots> = {\n\t[Name in keyof Slots]: VueSlot<Slots[Name]>;\n};\n\n/** Vue 3 `slots` 选项接受的运行时声明与官方静态类型标记。 */\nexport type TypedSlotsDeclaration<Slots extends RawSlots> = SlotsType<Partial<TypedSlots<Slots>>>;\n\n/**\n * 为 Options API 的 `slots` 选项创建带作用域参数的类型声明。\n *\n * @returns 运行时 `Object` 构造器,并携带仅供 TypeScript 使用的 Slot 类型标记。\n */\nexport function makeSlots<Slots extends RawSlots>(): TypedSlotsDeclaration<Slots> {\n\treturn Object as TypedSlotsDeclaration<Slots>;\n}\n"],"mappings":";;;;;;AAoBA,SAAgB,YAAkE;CACjF,OAAO;AACR"}
1
+ {"version":3,"file":"slots.mjs","names":[],"sources":["../../src/vue/slots.ts"],"sourcesContent":["import type { SlotsType, VNode } from \"vue\";\n\n/** Slot 名到 Props 类型的内部声明映射 */\ntype RawSlots = Record<string, unknown>;\n/** 根据 Slot Props 是否为 never 生成无参数或有参数的 Slot 签名 */\ntype VueSlot<Properties> = [Properties] extends [never] ? () => VNode[] : (properties: Properties) => VNode[];\n\n/** 把 Slot 名称与作用域参数映射为 Vue 3 Slot 函数 */\nexport type TypedSlots<Slots extends RawSlots> = {\n\t[Name in keyof Slots]: VueSlot<Slots[Name]>;\n};\n\n/** Vue 3 `slots` 选项接受的运行时声明与官方静态类型标记 */\nexport type TypedSlotsDeclaration<Slots extends RawSlots> = SlotsType<Partial<TypedSlots<Slots>>>;\n\n/**\n * 为 Options API 的 `slots` 选项创建带作用域参数的类型声明。\n *\n * @returns 运行时 `Object` 构造器,并携带仅供 TypeScript 使用的 Slot 类型标记。\n */\nexport function makeSlots<Slots extends RawSlots>(): TypedSlotsDeclaration<Slots> {\n\treturn Object as TypedSlotsDeclaration<Slots>;\n}\n"],"mappings":";;;;;;AAoBA,SAAgB,YAAkE;CACjF,OAAO;AACR"}
@@ -1,4 +1,3 @@
1
- import { runtimeGlobals } from "../internal/runtime.mjs";
2
1
  import { computed, getCurrentScope, readonly, shallowRef, toValue, watch } from "vue";
3
2
  //#region src/vue/transition.ts
4
3
  /**
@@ -15,16 +14,15 @@ import { computed, getCurrentScope, readonly, shallowRef, toValue, watch } from
15
14
  */
16
15
  function useTransition(source, options = {}) {
17
16
  const { duration = 300, transition = (progress) => progress } = options;
18
- if (!Number.isFinite(duration) || duration < 0) throw new RangeError("`duration` 必须是非负有限数。");
17
+ if (!Number.isFinite(duration) || duration < 0) throw new RangeError("`duration` must be a nonnegative finite number.");
19
18
  const readSource = () => {
20
19
  const value = toValue(source);
21
- if (!Number.isFinite(value)) throw new RangeError("`source` 必须是有限数值。");
20
+ if (!Number.isFinite(value)) throw new RangeError("`source` must be a finite number.");
22
21
  return value;
23
22
  };
24
23
  const output = shallowRef(readSource());
25
- const window = runtimeGlobals.window;
26
- if (window === void 0 || typeof window.requestAnimationFrame !== "function" || typeof window.cancelAnimationFrame !== "function") return computed(readSource);
27
- if (getCurrentScope() === void 0) throw new Error("`useTransition` 必须在 Vue 响应式作用域内调用。");
24
+ if (typeof window === "undefined" || typeof window.requestAnimationFrame !== "function" || typeof window.cancelAnimationFrame !== "function") return computed(readSource);
25
+ if (getCurrentScope() === void 0) throw new Error("`useTransition` must be called within a Vue reactive scope.");
28
26
  watch(readSource, (target, _previous, onCleanup) => {
29
27
  let frame;
30
28
  let active = true;
@@ -45,7 +43,7 @@ function useTransition(source, options = {}) {
45
43
  const progress = Math.min(1, Math.max(0, (timestamp - startedAt) / duration));
46
44
  const weight = progress === 1 ? 1 : transition(progress);
47
45
  const value = progress === 1 ? target : from * (1 - weight) + target * weight;
48
- if (!Number.isFinite(weight) || !Number.isFinite(value)) throw new RangeError("缓动结果必须是有限数值。");
46
+ if (!Number.isFinite(weight) || !Number.isFinite(value)) throw new RangeError("The easing result must be a finite number.");
49
47
  if (!active) return;
50
48
  output.value = value;
51
49
  if (active && progress < 1) frame = window.requestAnimationFrame(tick);
@@ -1 +1 @@
1
- {"version":3,"file":"transition.mjs","names":[],"sources":["../../src/vue/transition.ts"],"sourcesContent":["import { computed, getCurrentScope, readonly, shallowRef, toValue, watch } from \"vue\";\nimport { runtimeGlobals } from \"../internal/runtime\";\nimport type { MaybeRefOrGetter, ShallowRef } from \"vue\";\n\n/** 数值过渡选项 */\nexport interface UseTransitionOptions {\n\t/** 过渡时长,单位为毫秒;必须是非负有限数。默认 `300`。 */\n\tduration?: number;\n\t/** 将 `[0, 1]` 的进度映射为有限插值系数,默认线性;允许超出区间以实现回弹。 */\n\ttransition?: (progress: number) => number;\n}\n\n/**\n * 将响应式数值的变化平滑过渡为只读数值。\n *\n * @param source - 有限数值、Ref 或 getter;初值直接显示,不执行入场动画。\n * @param options - 创建时读取的时长与缓动选项\n * @returns 只读数值 Ref;SSR 或缺少动画帧 API 时直接跟随输入。\n * @remarks 浏览器动画必须在 Vue 响应式作用域内创建,停止作用域时自动取消。\n * 新目标从当前显示值继续过渡,首个动画帧开始计时,完成时精确落到目标值。\n * `duration: 0` 直接同步目标。选项不响应后续修改;仅支持单个数值。\n * @throws `Error` 当支持动画帧的环境中不存在 Vue 响应式作用域。\n * @throws `RangeError` 当输入或时长非法;后续非法输入由 Vue watcher 报错,非法缓动结果在动画帧中抛错。\n */\nexport function useTransition(source: MaybeRefOrGetter<number>, options: UseTransitionOptions = {}): Readonly<ShallowRef<number>> {\n\tconst { duration = 300, transition = (progress: number) => progress } = options;\n\tif (!Number.isFinite(duration) || duration < 0) throw new RangeError(\"`duration` 必须是非负有限数。\");\n\tconst readSource = () => {\n\t\tconst value = toValue(source);\n\t\tif (!Number.isFinite(value)) throw new RangeError(\"`source` 必须是有限数值。\");\n\t\treturn value;\n\t};\n\tconst output = shallowRef(readSource());\n\tconst window = runtimeGlobals.window;\n\tif (window === undefined || typeof window.requestAnimationFrame !== \"function\" || typeof window.cancelAnimationFrame !== \"function\") {\n\t\treturn computed(readSource);\n\t}\n\tif (getCurrentScope() === undefined) throw new Error(\"`useTransition` 必须在 Vue 响应式作用域内调用。\");\n\twatch(\n\t\treadSource,\n\t\t(target, _previous, onCleanup) => {\n\t\t\tlet frame: number | undefined;\n\t\t\tlet active = true;\n\t\t\tonCleanup(() => {\n\t\t\t\tactive = false;\n\t\t\t\tif (frame !== undefined) window.cancelAnimationFrame(frame);\n\t\t\t});\n\t\t\tif (duration === 0 || output.value === target) {\n\t\t\t\toutput.value = target;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst from = output.value;\n\t\t\tlet startedAt: number | undefined;\n\t\t\tconst tick = (timestamp: number) => {\n\t\t\t\tframe = undefined;\n\t\t\t\tif (!active) return;\n\t\t\t\tstartedAt ??= timestamp;\n\t\t\t\tconst progress = Math.min(1, Math.max(0, (timestamp - startedAt) / duration));\n\t\t\t\tconst weight = progress === 1 ? 1 : transition(progress);\n\t\t\t\tconst value = progress === 1 ? target : from * (1 - weight) + target * weight;\n\t\t\t\tif (!Number.isFinite(weight) || !Number.isFinite(value)) throw new RangeError(\"缓动结果必须是有限数值。\");\n\t\t\t\tif (!active) return;\n\t\t\t\toutput.value = value;\n\t\t\t\tif (active && progress < 1) frame = window.requestAnimationFrame(tick);\n\t\t\t};\n\t\t\tframe = window.requestAnimationFrame(tick);\n\t\t},\n\t\t{ flush: \"sync\" }\n\t);\n\treturn readonly(output);\n}\n"],"mappings":";;;;;;;;;;;;;;;AAwBA,SAAgB,cAAc,QAAkC,UAAgC,CAAC,GAAiC;CACjI,MAAM,EAAE,WAAW,KAAK,cAAc,aAAqB,aAAa;CACxE,IAAI,CAAC,OAAO,SAAS,QAAQ,KAAK,WAAW,GAAG,MAAM,IAAI,WAAW,sBAAsB;CAC3F,MAAM,mBAAmB;EACxB,MAAM,QAAQ,QAAQ,MAAM;EAC5B,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG,MAAM,IAAI,WAAW,mBAAmB;EACrE,OAAO;CACR;CACA,MAAM,SAAS,WAAW,WAAW,CAAC;CACtC,MAAM,SAAS,eAAe;CAC9B,IAAI,WAAW,KAAA,KAAa,OAAO,OAAO,0BAA0B,cAAc,OAAO,OAAO,yBAAyB,YACxH,OAAO,SAAS,UAAU;CAE3B,IAAI,gBAAgB,MAAM,KAAA,GAAW,MAAM,IAAI,MAAM,oCAAoC;CACzF,MACC,aACC,QAAQ,WAAW,cAAc;EACjC,IAAI;EACJ,IAAI,SAAS;EACb,gBAAgB;GACf,SAAS;GACT,IAAI,UAAU,KAAA,GAAW,OAAO,qBAAqB,KAAK;EAC3D,CAAC;EACD,IAAI,aAAa,KAAK,OAAO,UAAU,QAAQ;GAC9C,OAAO,QAAQ;GACf;EACD;EACA,MAAM,OAAO,OAAO;EACpB,IAAI;EACJ,MAAM,QAAQ,cAAsB;GACnC,QAAQ,KAAA;GACR,IAAI,CAAC,QAAQ;GACb,cAAc;GACd,MAAM,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,YAAY,aAAa,QAAQ,CAAC;GAC5E,MAAM,SAAS,aAAa,IAAI,IAAI,WAAW,QAAQ;GACvD,MAAM,QAAQ,aAAa,IAAI,SAAS,QAAQ,IAAI,UAAU,SAAS;GACvE,IAAI,CAAC,OAAO,SAAS,MAAM,KAAK,CAAC,OAAO,SAAS,KAAK,GAAG,MAAM,IAAI,WAAW,cAAc;GAC5F,IAAI,CAAC,QAAQ;GACb,OAAO,QAAQ;GACf,IAAI,UAAU,WAAW,GAAG,QAAQ,OAAO,sBAAsB,IAAI;EACtE;EACA,QAAQ,OAAO,sBAAsB,IAAI;CAC1C,GACA,EAAE,OAAO,OAAO,CACjB;CACA,OAAO,SAAS,MAAM;AACvB"}
1
+ {"version":3,"file":"transition.mjs","names":[],"sources":["../../src/vue/transition.ts"],"sourcesContent":["import { computed, getCurrentScope, readonly, shallowRef, toValue, watch } from \"vue\";\nimport type { MaybeRefOrGetter, ShallowRef } from \"vue\";\n\n/** 数值过渡选项 */\nexport interface UseTransitionOptions {\n\t/** 过渡时长,单位为毫秒;必须是非负有限数。默认 `300`。 */\n\tduration?: number;\n\t/** 将 `[0, 1]` 的进度映射为有限插值系数,默认线性;允许超出区间以实现回弹。 */\n\ttransition?: (progress: number) => number;\n}\n\n/**\n * 将响应式数值的变化平滑过渡为只读数值。\n *\n * @param source - 有限数值、Ref 或 getter;初值直接显示,不执行入场动画。\n * @param options - 创建时读取的时长与缓动选项\n * @returns 只读数值 Ref;SSR 或缺少动画帧 API 时直接跟随输入。\n * @remarks 浏览器动画必须在 Vue 响应式作用域内创建,停止作用域时自动取消。\n * 新目标从当前显示值继续过渡,首个动画帧开始计时,完成时精确落到目标值。\n * `duration: 0` 直接同步目标。选项不响应后续修改;仅支持单个数值。\n * @throws `Error` 当支持动画帧的环境中不存在 Vue 响应式作用域。\n * @throws `RangeError` 当输入或时长非法;后续非法输入由 Vue watcher 报错,非法缓动结果在动画帧中抛错。\n */\nexport function useTransition(source: MaybeRefOrGetter<number>, options: UseTransitionOptions = {}): Readonly<ShallowRef<number>> {\n\tconst { duration = 300, transition = (progress: number) => progress } = options;\n\tif (!Number.isFinite(duration) || duration < 0) throw new RangeError(\"`duration` must be a nonnegative finite number.\");\n\tconst readSource = () => {\n\t\tconst value = toValue(source);\n\t\tif (!Number.isFinite(value)) throw new RangeError(\"`source` must be a finite number.\");\n\t\treturn value;\n\t};\n\tconst output = shallowRef(readSource());\n\tif (typeof window === \"undefined\" || typeof window.requestAnimationFrame !== \"function\" || typeof window.cancelAnimationFrame !== \"function\") {\n\t\treturn computed(readSource);\n\t}\n\tif (getCurrentScope() === undefined) throw new Error(\"`useTransition` must be called within a Vue reactive scope.\");\n\twatch(\n\t\treadSource,\n\t\t(target, _previous, onCleanup) => {\n\t\t\tlet frame: number | undefined;\n\t\t\tlet active = true;\n\t\t\tonCleanup(() => {\n\t\t\t\tactive = false;\n\t\t\t\tif (frame !== undefined) window.cancelAnimationFrame(frame);\n\t\t\t});\n\t\t\tif (duration === 0 || output.value === target) {\n\t\t\t\toutput.value = target;\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tconst from = output.value;\n\t\t\tlet startedAt: number | undefined;\n\t\t\tconst tick = (timestamp: number) => {\n\t\t\t\tframe = undefined;\n\t\t\t\tif (!active) return;\n\t\t\t\tstartedAt ??= timestamp;\n\t\t\t\tconst progress = Math.min(1, Math.max(0, (timestamp - startedAt) / duration));\n\t\t\t\tconst weight = progress === 1 ? 1 : transition(progress);\n\t\t\t\tconst value = progress === 1 ? target : from * (1 - weight) + target * weight;\n\t\t\t\tif (!Number.isFinite(weight) || !Number.isFinite(value)) throw new RangeError(\"The easing result must be a finite number.\");\n\t\t\t\tif (!active) return;\n\t\t\t\toutput.value = value;\n\t\t\t\tif (active && progress < 1) frame = window.requestAnimationFrame(tick);\n\t\t\t};\n\t\t\tframe = window.requestAnimationFrame(tick);\n\t\t},\n\t\t{ flush: \"sync\" }\n\t);\n\treturn readonly(output);\n}\n"],"mappings":";;;;;;;;;;;;;;AAuBA,SAAgB,cAAc,QAAkC,UAAgC,CAAC,GAAiC;CACjI,MAAM,EAAE,WAAW,KAAK,cAAc,aAAqB,aAAa;CACxE,IAAI,CAAC,OAAO,SAAS,QAAQ,KAAK,WAAW,GAAG,MAAM,IAAI,WAAW,iDAAiD;CACtH,MAAM,mBAAmB;EACxB,MAAM,QAAQ,QAAQ,MAAM;EAC5B,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG,MAAM,IAAI,WAAW,mCAAmC;EACrF,OAAO;CACR;CACA,MAAM,SAAS,WAAW,WAAW,CAAC;CACtC,IAAI,OAAO,WAAW,eAAe,OAAO,OAAO,0BAA0B,cAAc,OAAO,OAAO,yBAAyB,YACjI,OAAO,SAAS,UAAU;CAE3B,IAAI,gBAAgB,MAAM,KAAA,GAAW,MAAM,IAAI,MAAM,6DAA6D;CAClH,MACC,aACC,QAAQ,WAAW,cAAc;EACjC,IAAI;EACJ,IAAI,SAAS;EACb,gBAAgB;GACf,SAAS;GACT,IAAI,UAAU,KAAA,GAAW,OAAO,qBAAqB,KAAK;EAC3D,CAAC;EACD,IAAI,aAAa,KAAK,OAAO,UAAU,QAAQ;GAC9C,OAAO,QAAQ;GACf;EACD;EACA,MAAM,OAAO,OAAO;EACpB,IAAI;EACJ,MAAM,QAAQ,cAAsB;GACnC,QAAQ,KAAA;GACR,IAAI,CAAC,QAAQ;GACb,cAAc;GACd,MAAM,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,YAAY,aAAa,QAAQ,CAAC;GAC5E,MAAM,SAAS,aAAa,IAAI,IAAI,WAAW,QAAQ;GACvD,MAAM,QAAQ,aAAa,IAAI,SAAS,QAAQ,IAAI,UAAU,SAAS;GACvE,IAAI,CAAC,OAAO,SAAS,MAAM,KAAK,CAAC,OAAO,SAAS,KAAK,GAAG,MAAM,IAAI,WAAW,4CAA4C;GAC1H,IAAI,CAAC,QAAQ;GACb,OAAO,QAAQ;GACf,IAAI,UAAU,WAAW,GAAG,QAAQ,OAAO,sBAAsB,IAAI;EACtE;EACA,QAAQ,OAAO,sBAAsB,IAAI;CAC1C,GACA,EAAE,OAAO,OAAO,CACjB;CACA,OAAO,SAAS,MAAM;AACvB"}
@@ -1,4 +1,3 @@
1
- import { runtimeGlobals } from "../internal/runtime.mjs";
2
1
  import { useEventListener } from "./event-listener.mjs";
3
2
  import { getCurrentScope, readonly, shallowRef } from "vue";
4
3
  //#region src/vue/window-size.ts
@@ -11,9 +10,8 @@ import { getCurrentScope, readonly, shallowRef } from "vue";
11
10
  function useWindowSize() {
12
11
  const width = shallowRef(0);
13
12
  const height = shallowRef(0);
14
- const window = runtimeGlobals.window;
15
- if (window !== void 0) {
16
- if (getCurrentScope() === void 0) throw new Error("`useWindowSize` 必须在 Vue 响应式作用域内调用。");
13
+ if (typeof window !== "undefined") {
14
+ if (getCurrentScope() === void 0) throw new Error("`useWindowSize` must be called within a Vue reactive scope.");
17
15
  const update = () => {
18
16
  width.value = window.innerWidth;
19
17
  height.value = window.innerHeight;
@@ -1 +1 @@
1
- {"version":3,"file":"window-size.mjs","names":[],"sources":["../../src/vue/window-size.ts"],"sourcesContent":["import { getCurrentScope, readonly, shallowRef } from \"vue\";\nimport { runtimeGlobals } from \"../internal/runtime\";\nimport { useEventListener } from \"./event-listener\";\nimport type { ShallowRef } from \"vue\";\n\n/** `useWindowSize` 返回的只读窗口尺寸。 */\nexport interface UseWindowSizeReturn {\n\treadonly width: Readonly<ShallowRef<number>>;\n\treadonly height: Readonly<ShallowRef<number>>;\n}\n\n/**\n * 响应式读取浏览器窗口内部尺寸。\n *\n * @returns 随原生 `resize` 事件更新的只读宽度和高度;非浏览器环境均为 `0`。\n * @throws `Error` 当浏览器环境中不存在可用于自动清理的 Vue 响应式作用域。\n */\nexport function useWindowSize(): UseWindowSizeReturn {\n\tconst width = shallowRef(0);\n\tconst height = shallowRef(0);\n\tconst window = runtimeGlobals.window;\n\tif (window !== undefined) {\n\t\tif (getCurrentScope() === undefined) throw new Error(\"`useWindowSize` 必须在 Vue 响应式作用域内调用。\");\n\t\tconst update = () => {\n\t\t\twidth.value = window.innerWidth;\n\t\t\theight.value = window.innerHeight;\n\t\t};\n\t\tupdate();\n\t\tuseEventListener(window, \"resize\", update, { passive: true });\n\t}\n\treturn { height: readonly(height), width: readonly(width) };\n}\n"],"mappings":";;;;;;;;;;AAiBA,SAAgB,gBAAqC;CACpD,MAAM,QAAQ,WAAW,CAAC;CAC1B,MAAM,SAAS,WAAW,CAAC;CAC3B,MAAM,SAAS,eAAe;CAC9B,IAAI,WAAW,KAAA,GAAW;EACzB,IAAI,gBAAgB,MAAM,KAAA,GAAW,MAAM,IAAI,MAAM,oCAAoC;EACzF,MAAM,eAAe;GACpB,MAAM,QAAQ,OAAO;GACrB,OAAO,QAAQ,OAAO;EACvB;EACA,OAAO;EACP,iBAAiB,QAAQ,UAAU,QAAQ,EAAE,SAAS,KAAK,CAAC;CAC7D;CACA,OAAO;EAAE,QAAQ,SAAS,MAAM;EAAG,OAAO,SAAS,KAAK;CAAE;AAC3D"}
1
+ {"version":3,"file":"window-size.mjs","names":[],"sources":["../../src/vue/window-size.ts"],"sourcesContent":["import { getCurrentScope, readonly, shallowRef } from \"vue\";\nimport { useEventListener } from \"./event-listener\";\nimport type { ShallowRef } from \"vue\";\n\n/** `useWindowSize` 返回的只读窗口尺寸。 */\nexport interface UseWindowSizeReturn {\n\treadonly width: Readonly<ShallowRef<number>>;\n\treadonly height: Readonly<ShallowRef<number>>;\n}\n\n/**\n * 响应式读取浏览器窗口内部尺寸。\n *\n * @returns 随原生 `resize` 事件更新的只读宽度和高度;非浏览器环境均为 `0`。\n * @throws `Error` 当浏览器环境中不存在可用于自动清理的 Vue 响应式作用域。\n */\nexport function useWindowSize(): UseWindowSizeReturn {\n\tconst width = shallowRef(0);\n\tconst height = shallowRef(0);\n\tif (typeof window !== \"undefined\") {\n\t\tif (getCurrentScope() === undefined) throw new Error(\"`useWindowSize` must be called within a Vue reactive scope.\");\n\t\tconst update = () => {\n\t\t\twidth.value = window.innerWidth;\n\t\t\theight.value = window.innerHeight;\n\t\t};\n\t\tupdate();\n\t\tuseEventListener(window, \"resize\", update, { passive: true });\n\t}\n\treturn { height: readonly(height), width: readonly(width) };\n}\n"],"mappings":";;;;;;;;;AAgBA,SAAgB,gBAAqC;CACpD,MAAM,QAAQ,WAAW,CAAC;CAC1B,MAAM,SAAS,WAAW,CAAC;CAC3B,IAAI,OAAO,WAAW,aAAa;EAClC,IAAI,gBAAgB,MAAM,KAAA,GAAW,MAAM,IAAI,MAAM,6DAA6D;EAClH,MAAM,eAAe;GACpB,MAAM,QAAQ,OAAO;GACrB,OAAO,QAAQ,OAAO;EACvB;EACA,OAAO;EACP,iBAAiB,QAAQ,UAAU,QAAQ,EAAE,SAAS,KAAK,CAAC;CAC7D;CACA,OAAO;EAAE,QAAQ,SAAS,MAAM;EAAG,OAAO,SAAS,KAAK;CAAE;AAC3D"}