@h-ai/datapipe 1.0.0-beta.17 → 1.0.0-beta.19

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.
package/dist/index.d.ts CHANGED
@@ -344,4 +344,5 @@ interface DatapipeFunctions {
344
344
  */
345
345
  declare const datapipe: DatapipeFunctions;
346
346
 
347
- export { type ChunkMode, ChunkModeSchema, type ChunkOperations, type ChunkOptions, type ChunkOptionsInput, ChunkOptionsSchema, type ChunkTransformFn, type CleanOperations, type CleanOptions, type CleanOptionsInput, CleanOptionsSchema, type DataChunk, type DatapipeFunctions, HaiDatapipeError, type PipelineBuilder, type PipelineResult, type PipelineStep, type TransformFn, datapipe };
347
+ export { ChunkModeSchema, ChunkOptionsSchema, CleanOptionsSchema, HaiDatapipeError, datapipe };
348
+ export type { ChunkMode, ChunkOperations, ChunkOptions, ChunkOptionsInput, ChunkTransformFn, CleanOperations, CleanOptions, CleanOptionsInput, DataChunk, DatapipeFunctions, PipelineBuilder, PipelineResult, PipelineStep, TransformFn };
package/dist/index.js CHANGED
@@ -51,7 +51,9 @@ var ChunkOptionsSchema = z.object({
51
51
  markdownMinLevel: z.number().int().min(1).max(6).default(2),
52
52
  /** 是否保留 Markdown 标题在分块内容中(默认 true) */
53
53
  markdownKeepTitle: z.boolean().default(true)
54
- }).refine((options) => options.overlap < options.maxSize, { path: ["overlap"] });
54
+ }).refine((options) => options.overlap < options.maxSize, {
55
+ path: ["overlap"]
56
+ });
55
57
 
56
58
  // messages/en-US.json
57
59
  var en_US_default = {
@@ -147,7 +149,9 @@ function splitCharacters(text, maxSize, overlap, expression) {
147
149
  return chunks;
148
150
  }
149
151
  function splitWords(text, maxSize, overlap) {
150
- const words = [...text.matchAll(/\S+/gu)];
152
+ const words = [
153
+ ...text.matchAll(/\S+/gu)
154
+ ];
151
155
  const chunks = [];
152
156
  for (let start = 0; start < words.length; ) {
153
157
  const end = Math.min(start + maxSize, words.length);
@@ -183,14 +187,35 @@ function markdownSections(text, minLevel) {
183
187
  end--;
184
188
  if (end < title.length && (title[end - 1] === " " || title[end - 1] === " "))
185
189
  title = title.slice(0, end).trimEnd();
186
- headings.push({ start: line.index, bodyStart: line.index + line[0].length, title, level: heading[1].length });
190
+ headings.push({
191
+ start: line.index,
192
+ bodyStart: line.index + line[0].length,
193
+ title,
194
+ level: heading[1].length
195
+ });
187
196
  }
188
197
  }
189
- if (headings.length === 0)
190
- return [{ start: 0, bodyStart: 0, end: text.length, title: "", level: 0 }];
198
+ if (headings.length === 0) {
199
+ return [
200
+ {
201
+ start: 0,
202
+ bodyStart: 0,
203
+ end: text.length,
204
+ title: "",
205
+ level: 0
206
+ }
207
+ ];
208
+ }
191
209
  const sections = [];
192
- if (headings[0].start > 0)
193
- sections.push({ start: 0, bodyStart: 0, end: headings[0].start, title: "", level: 0 });
210
+ if (headings[0].start > 0) {
211
+ sections.push({
212
+ start: 0,
213
+ bodyStart: 0,
214
+ end: headings[0].start,
215
+ title: "",
216
+ level: 0
217
+ });
218
+ }
194
219
  headings.forEach((heading, index) => sections.push({ ...heading, end: headings[index + 1]?.start ?? text.length }));
195
220
  return sections;
196
221
  }
@@ -210,8 +235,11 @@ function modeExpression(mode, separator) {
210
235
  }
211
236
  function chunkText(text, options) {
212
237
  const parsed = ChunkOptionsSchema.safeParse(options);
213
- if (!parsed.success)
214
- return err(HaiDatapipeError.CONFIG_ERROR, datapipeM("datapipe_configError", { params: { error: parsed.error.message } }), parsed.error);
238
+ if (!parsed.success) {
239
+ return err(HaiDatapipeError.CONFIG_ERROR, datapipeM("datapipe_configError", {
240
+ params: { error: parsed.error.message }
241
+ }), parsed.error);
242
+ }
215
243
  const opts = parsed.data;
216
244
  if (opts.mode === "custom" && !opts.separator)
217
245
  return err(HaiDatapipeError.MISSING_SEPARATOR, datapipeM("datapipe_missingSeparator"));
@@ -223,15 +251,28 @@ function chunkText(text, options) {
223
251
  for (const section of markdownSections(text, opts.markdownMinLevel)) {
224
252
  const content = text.slice(opts.markdownKeepTitle ? section.start : section.bodyStart, section.end);
225
253
  const parts2 = splitCharacters(content, opts.maxSize, opts.overlap, modeExpression("paragraph"));
226
- for (const part of parts2)
227
- chunks.push({ index: chunks.length, content: part, metadata: { title: section.title, level: section.level, ...parts2.length > 1 ? { subChunk: true } : {} } });
254
+ for (const part of parts2) {
255
+ chunks.push({
256
+ index: chunks.length,
257
+ content: part,
258
+ metadata: {
259
+ title: section.title,
260
+ level: section.level,
261
+ ...parts2.length > 1 ? { subChunk: true } : {}
262
+ }
263
+ });
264
+ }
228
265
  }
229
266
  return ok(chunks);
230
267
  }
231
268
  const parts = opts.mode === "word" ? splitWords(text, opts.maxSize, opts.overlap) : splitCharacters(text, opts.maxSize, opts.overlap, modeExpression(opts.mode, opts.separator));
232
269
  return ok(parts.map((content, index) => ({ index, content })));
233
270
  } catch (cause) {
234
- return err(HaiDatapipeError.CHUNK_FAILED, datapipeM("datapipe_chunkFailed", { params: { error: String(cause) } }), cause);
271
+ return err(HaiDatapipeError.CHUNK_FAILED, datapipeM("datapipe_chunkFailed", {
272
+ params: {
273
+ error: String(cause)
274
+ }
275
+ }), cause);
235
276
  }
236
277
  }
237
278
  function stripHtmlTags(text) {
@@ -257,7 +298,9 @@ var MULTI_SPACE_REGEX = /[ \t]{2,}/g;
257
298
  function cleanText(text, options) {
258
299
  const parseResult = CleanOptionsSchema.safeParse(options ?? {});
259
300
  if (!parseResult.success) {
260
- return err(HaiDatapipeError.CONFIG_ERROR, datapipeM("datapipe_configError", { params: { error: parseResult.error.message } }), parseResult.error);
301
+ return err(HaiDatapipeError.CONFIG_ERROR, datapipeM("datapipe_configError", {
302
+ params: { error: parseResult.error.message }
303
+ }), parseResult.error);
261
304
  }
262
305
  const opts = parseResult.data;
263
306
  let result = text;
@@ -277,7 +320,11 @@ function cleanText(text, options) {
277
320
  try {
278
321
  regex = new RegExp(pattern, "g");
279
322
  } catch (regexError) {
280
- return err(HaiDatapipeError.CONFIG_ERROR, datapipeM("datapipe_configError", { params: { error: String(regexError) } }), regexError);
323
+ return err(HaiDatapipeError.CONFIG_ERROR, datapipeM("datapipe_configError", {
324
+ params: {
325
+ error: String(regexError)
326
+ }
327
+ }), regexError);
281
328
  }
282
329
  result = result.replace(regex, replacement);
283
330
  }
@@ -291,7 +338,11 @@ function cleanText(text, options) {
291
338
  }
292
339
  return ok(result);
293
340
  } catch (error) {
294
- return err(HaiDatapipeError.CLEAN_FAILED, datapipeM("datapipe_cleanFailed", { params: { error: String(error) } }), error);
341
+ return err(HaiDatapipeError.CLEAN_FAILED, datapipeM("datapipe_cleanFailed", {
342
+ params: {
343
+ error: String(error)
344
+ }
345
+ }), error);
295
346
  }
296
347
  }
297
348
  function createPipelineBuilder() {
@@ -340,7 +391,11 @@ async function runPipeline(steps, text) {
340
391
  try {
341
392
  currentText = await step.fn(currentText);
342
393
  } catch (error) {
343
- return err(HaiDatapipeError.TRANSFORM_FAILED, datapipeM("datapipe_transformFailed", { params: { error: String(error) } }), error);
394
+ return err(HaiDatapipeError.TRANSFORM_FAILED, datapipeM("datapipe_transformFailed", {
395
+ params: {
396
+ error: String(error)
397
+ }
398
+ }), error);
344
399
  }
345
400
  break;
346
401
  }
@@ -349,7 +404,11 @@ async function runPipeline(steps, text) {
349
404
  try {
350
405
  chunks = await step.fn(chunks);
351
406
  } catch (error) {
352
- return err(HaiDatapipeError.PIPELINE_FAILED, datapipeM("datapipe_pipelineFailed", { params: { error: String(error) } }), error);
407
+ return err(HaiDatapipeError.PIPELINE_FAILED, datapipeM("datapipe_pipelineFailed", {
408
+ params: {
409
+ error: String(error)
410
+ }
411
+ }), error);
353
412
  }
354
413
  }
355
414
  break;
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/datapipe-config.ts","../messages/en-US.json","../messages/ja-JP.json","../messages/zh-CN.json","../src/datapipe-i18n.ts","../src/datapipe-types.ts","../src/datapipe-chunk.ts","../src/datapipe-clean.ts","../src/datapipe-pipeline.ts","../src/datapipe-main.ts"],"names":["core","parts","err","ok"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @h-ai/datapipe — 数据处理管线配置 Schema\n *\n * 本文件定义数据处理模块的错误码常量、Zod Schema 和配置类型。\n * 支持清洗(clean)、分块(chunk)、转换(transform)和管线(pipeline)。\n * @module datapipe-config\n */\n\nimport { z } from 'zod'\n\n// ─── 清洗配置 ───\n\n/**\n * 清洗选项 Schema\n *\n * 数据清洗规则配置,支持移除 HTML、URL、Email、标准化空白等。\n * @example\n * ```ts\n * import { CleanOptionsSchema } from '@h-ai/datapipe'\n * const options = CleanOptionsSchema.parse({ removeHtml: true, removeEmails: true })\n * ```\n */\nexport const CleanOptionsSchema = z.object({\n /** 移除 HTML 标签(默认 true) */\n removeHtml: z.boolean().default(true),\n /** 移除 URL(默认 false) */\n removeUrls: z.boolean().default(false),\n /** 移除 Email 地址(默认 false) */\n removeEmails: z.boolean().default(false),\n /** 标准化空白字符(多空格→单空格、去掉多余空行,默认 true) */\n normalizeWhitespace: z.boolean().default(true),\n /** 去除首尾空白(默认 true) */\n trim: z.boolean().default(true),\n /**\n * 自定义替换规则(正则→替换字符串)\n *\n * ❗ 安全提示:pattern 会通过 `new RegExp()` 构造,如果其值来源于用户输入,请在调用方先行校验以防止 ReDoS 攻击。\n */\n customReplacements: z.array(z.object({\n /** 正则表达式字符串 */\n pattern: z.string(),\n /** 替换文本 */\n replacement: z.string(),\n })).optional(),\n})\n\n/**\n * 清洗选项类型\n * @example\n * ```ts\n * import { CleanOptionsSchema, type CleanOptions } from '@h-ai/datapipe'\n * const options: CleanOptions = CleanOptionsSchema.parse({ removeHtml: true })\n * ```\n */\nexport type CleanOptions = z.infer<typeof CleanOptionsSchema>\n\n/**\n * 清洗选项输入类型\n * @example\n * ```ts\n * import type { CleanOptionsInput } from '@h-ai/datapipe'\n * const options: CleanOptionsInput = { removeHtml: true, removeUrls: true }\n * ```\n */\nexport type CleanOptionsInput = z.input<typeof CleanOptionsSchema>\n\n// ─── 分块配置 ───\n\n/**\n * 分块模式枚举\n *\n * - `sentence` — 按句子分块\n * - `paragraph` — 按段落分块\n * - `markdown` — 按 Markdown 标题分块(## / ### 等)\n * - `page` — 按分页符分块\n * - `word` — 按非空白词数分块,不截断单个词\n * - `character` — 按 Unicode code point 分块,不拆代理对\n * - `custom` — 自定义分隔符分块\n * @example\n * ```ts\n * import { ChunkModeSchema } from '@h-ai/datapipe'\n * const mode = ChunkModeSchema.parse('character')\n * ```\n */\nexport const ChunkModeSchema = z.enum([\n 'sentence',\n 'paragraph',\n 'markdown',\n 'page',\n 'word',\n 'character',\n 'custom',\n])\n\n/**\n * 分块模式类型\n * @example\n * ```ts\n * import type { ChunkMode } from '@h-ai/datapipe'\n * const options: ChunkMode = 'character'\n * ```\n */\nexport type ChunkMode = z.infer<typeof ChunkModeSchema>\n\n/**\n * 分块选项 Schema\n * datapipe 的默认 overlap 为 0;消费者可显式提供自己的默认值,例如 AI Knowledge 为 200。\n * @example\n * ```ts\n * import { ChunkOptionsSchema } from '@h-ai/datapipe'\n * const options = ChunkOptionsSchema.parse({ mode: 'markdown', maxSize: 500, overlap: 50 })\n * // maxSize 已包含重叠,overlap 必须小于 maxSize;自定义正则仅来自可信配置。\n * ```\n */\nexport const ChunkOptionsSchema = z.object({\n /** 分块模式 */\n mode: ChunkModeSchema,\n /** 每块上限包含 overlap/分隔符;word 按非空白词,其他按 Unicode code point,默认 1500。 */\n maxSize: z.number().int().positive().default(1500),\n /** 重叠使用与 maxSize 相同的单位,必须严格小于 maxSize。 */\n overlap: z.number().int().min(0).default(0),\n /**\n * 自定义分隔符正则(仅 mode='custom' 时使用)\n *\n * ❗ 安全提示:separator 会通过 `new RegExp()` 构造,如果其值来源于用户输入,请在调用方先行校验以防止 ReDoS 攻击。\n */\n separator: z.string().optional(),\n /** Markdown 标题分割深度(1-6,默认 2,即 # 和 ## 作为分块边界;设为 3 则 ### 也作为分块边界) */\n markdownMinLevel: z.number().int().min(1).max(6).default(2),\n /** 是否保留 Markdown 标题在分块内容中(默认 true) */\n markdownKeepTitle: z.boolean().default(true),\n}).refine(options => options.overlap < options.maxSize, { path: ['overlap'] })\n\n/**\n * 分块选项类型\n * @example\n * ```ts\n * import { ChunkOptionsSchema, type ChunkOptions } from '@h-ai/datapipe'\n * const options: ChunkOptions = ChunkOptionsSchema.parse({ mode: 'character', maxSize: 500 })\n * ```\n */\nexport type ChunkOptions = z.infer<typeof ChunkOptionsSchema>\n\n/**\n * 分块选项输入类型\n * @example\n * ```ts\n * import type { ChunkOptionsInput } from '@h-ai/datapipe'\n * const options: ChunkOptionsInput = { mode: 'character', maxSize: 500, overlap: 50 }\n * ```\n */\nexport type ChunkOptionsInput = z.input<typeof ChunkOptionsSchema>\n","{\n \"$schema\": \"https://inlang.com/schema/inlang-message-format\",\n \"datapipe_cleanFailed\": \"Failed to clean text: {error}\",\n \"datapipe_chunkFailed\": \"Failed to chunk text: {error}\",\n \"datapipe_transformFailed\": \"Failed to transform text: {error}\",\n \"datapipe_pipelineFailed\": \"Pipeline execution failed: {error}\",\n \"datapipe_configError\": \"Datapipe config validation failed: {error}\",\n \"datapipe_missingSeparator\": \"Custom chunk mode requires a separator parameter\"\n}\n","{\n \"$schema\": \"https://inlang.com/schema/inlang-message-format\",\n \"datapipe_cleanFailed\": \"テキストのクリーニングに失敗しました: {error}\",\n \"datapipe_chunkFailed\": \"テキストの分割に失敗しました: {error}\",\n \"datapipe_transformFailed\": \"テキストの変換に失敗しました: {error}\",\n \"datapipe_pipelineFailed\": \"パイプラインの実行に失敗しました: {error}\",\n \"datapipe_configError\": \"データパイプ設定の検証に失敗しました: {error}\",\n \"datapipe_missingSeparator\": \"カスタム分割モードにはseparatorパラメーターが必要です\"\n}\n","{\n \"$schema\": \"https://inlang.com/schema/inlang-message-format\",\n \"datapipe_cleanFailed\": \"清洗文本失败: {error}\",\n \"datapipe_chunkFailed\": \"分块文本失败: {error}\",\n \"datapipe_transformFailed\": \"转换文本失败: {error}\",\n \"datapipe_pipelineFailed\": \"管线执行失败: {error}\",\n \"datapipe_configError\": \"数据处理配置校验失败:{error}\",\n \"datapipe_missingSeparator\": \"自定义分块模式需要提供 separator 参数\"\n}\n","/**\n * @h-ai/datapipe — i18n\n *\n * 本文件提供数据处理模块的 i18n 文案访问入口。\n * @module datapipe-i18n\n */\n\nimport { core } from '@h-ai/core'\nimport messagesEnUS from '../messages/en-US.json'\nimport messagesJaJP from '../messages/ja-JP.json'\nimport messagesZhCN from '../messages/zh-CN.json'\n\n// ─── i18n ───\n\n/**\n * 数据处理模块文案 Key 类型\n * @example 模块内部上下文\n * ```ts\n * const key: DatapipeMessageKey = 'datapipe_cleanFailed'\n * const message = datapipeM(key)\n * ```\n */\ntype DatapipeMessageKey = keyof typeof messagesZhCN\n\n/**\n * 获取数据处理模块文案。\n * @param key - 文案 Key\n * @param options - 插值参数与格式化选项\n * @returns 本地化后的文案字符串\n * @example 模块内部上下文\n * ```ts\n * const message = datapipeM('datapipe_cleanFailed', { params: { error: 'invalid input' }, locale: 'en-US' })\n * ```\n */\nexport const datapipeM = core.i18n.createMessageGetter<DatapipeMessageKey>({\n 'zh-CN': messagesZhCN,\n 'en-US': messagesEnUS,\n 'ja-JP': messagesJaJP,\n})\n","/**\n * @h-ai/datapipe — 类型定义\n *\n * 本文件定义数据处理模块的核心接口和类型。\n * @module datapipe-types\n */\n\nimport type { ErrorInfo, HaiResult } from '@h-ai/core'\nimport type { ChunkOptionsInput, CleanOptionsInput } from './datapipe-config.js'\nimport { core } from '@h-ai/core'\n\n// ─── 错误定义(照 @h-ai/core 范式) ───\n\n/**\n * 数据处理错误信息映射(错误码:HTTP状态码)。\n *\n * 完整错误码将自动生成为:`hai:datapipe:NNN`\n */\nconst DatapipeErrorInfo = {\n CLEAN_FAILED: '001:500',\n CHUNK_FAILED: '002:500',\n TRANSFORM_FAILED: '003:500',\n PIPELINE_FAILED: '004:500',\n CONFIG_ERROR: '005:400',\n MISSING_SEPARATOR: '006:400',\n} as const satisfies ErrorInfo\n\n/**\n * Datapipe 模块标准错误定义对象。\n * @example\n * ```ts\n * import { HaiDatapipeError } from '@h-ai/datapipe'\n * import { err } from '@h-ai/core'\n * const result = err(HaiDatapipeError.CONFIG_ERROR, 'Invalid chunk configuration')\n * if (!result.success) result.error.httpStatus\n * ```\n */\nexport const HaiDatapipeError = core.error.buildHaiErrorsDef('datapipe', DatapipeErrorInfo)\n\n// ─── 数据块 ───\n\n/**\n * 数据块接口\n *\n * 表示经过分块处理后的单个文本片段。\n * @example\n * ```ts\n * import type { DataChunk } from '@h-ai/datapipe'\n * const options: DataChunk = { index: 0, content: '## Intro', metadata: { title: 'Intro', level: 2 } }\n * ```\n */\nexport interface DataChunk {\n /** 分块索引(从 0 开始) */\n index: number\n /** 原文切片;保留空白和分隔符。word 以词计量,其他模式以 Unicode code point 计量。 */\n content: string\n /** 分块元数据(可选) */\n metadata?: Record<string, unknown>\n}\n\n// ─── 转换函数 ───\n\n/**\n * 转换函数类型\n *\n * 自定义文本后处理函数,可以是同步或异步。\n * @example\n * ```ts\n * import type { TransformFn } from '@h-ai/datapipe'\n * const options: TransformFn = text => text.trim().toLowerCase()\n * ```\n */\nexport type TransformFn = (text: string) => string | Promise<string>\n\n/**\n * 分块转换函数类型\n *\n * 对分块列表进行后处理(如过滤、合并等)。\n * @example\n * ```ts\n * import type { ChunkTransformFn } from '@h-ai/datapipe'\n * const options: ChunkTransformFn = chunks => chunks.filter(chunk => chunk.content.trim().length > 0)\n * ```\n */\nexport type ChunkTransformFn = (chunks: DataChunk[]) => DataChunk[] | Promise<DataChunk[]>\n\n// ─── 管线步骤 ───\n\n/**\n * 管线步骤类型\n *\n * 管线由一系列步骤组成,支持清洗、分块和自定义转换。\n * @example\n * ```ts\n * import type { PipelineStep } from '@h-ai/datapipe'\n * const options: PipelineStep = { type: 'chunk', options: { mode: 'paragraph', maxSize: 500, overlap: 50 } }\n * ```\n */\nexport type PipelineStep\n = | { type: 'clean', options?: CleanOptionsInput }\n | { type: 'chunk', options: ChunkOptionsInput }\n | { type: 'transform', fn: TransformFn }\n | { type: 'chunkTransform', fn: ChunkTransformFn }\n\n// ─── 管线结果 ───\n\n/**\n * 管线执行结果\n * @example\n * ```ts\n * import type { PipelineResult } from '@h-ai/datapipe'\n * const options: PipelineResult = { text: 'One. Two.', chunks: [{ index: 0, content: 'One. Two.' }] }\n * ```\n */\nexport interface PipelineResult {\n /** 处理后的文本(分块前的最终文本) */\n text: string\n /** 分块列表(如果管线包含 chunk 步骤) */\n chunks: DataChunk[]\n}\n\n// ─── 操作接口 ───\n\n/**\n * 清洗操作接口\n *\n * 通过 `datapipe.clean()` 调用。\n * @example\n * ```ts\n * import { datapipe, type CleanOperations } from '@h-ai/datapipe'\n * const clean: CleanOperations = datapipe.clean\n * const result = clean('<p>Hello</p>')\n * if (result.success) result.data.trim()\n * ```\n */\nexport interface CleanOperations {\n /**\n * 清洗文本\n *\n * @param text - 原始文本\n * @param options - 清洗选项(可选,使用默认值)\n * @returns 清洗后的文本\n */\n (text: string, options?: CleanOptionsInput): HaiResult<string>\n}\n\n/**\n * 分块操作接口\n *\n * 通过 `datapipe.chunk()` 调用。\n * @example\n * ```ts\n * import { datapipe, type ChunkOperations } from '@h-ai/datapipe'\n * const chunk: ChunkOperations = datapipe.chunk\n * const result = chunk('One. Two.', { mode: 'sentence', maxSize: 10 })\n * if (result.success) result.data.map(item => item.index)\n * ```\n */\nexport interface ChunkOperations {\n /**\n * 对文本进行分块\n *\n * @param text - 输入文本\n * @param options - 分块选项\n * @returns 分块列表\n */\n (text: string, options: ChunkOptionsInput): HaiResult<DataChunk[]>\n}\n\n/**\n * 管线构建器接口\n *\n * 通过 `datapipe.pipeline()` 创建,链式添加步骤后执行。\n * @example\n * ```ts\n * import { datapipe } from '@h-ai/datapipe'\n * const result = await datapipe.pipeline()\n * .clean({ removeHtml: true })\n * .transform(text => text.toLowerCase())\n * .chunk({ mode: 'character', maxSize: 500, overlap: 50 })\n * .run('<p>One. Two. Three.</p>')\n * if (result.success) result.data.chunks.map(chunk => chunk.content)\n * else result.error.message\n * ```\n */\nexport interface PipelineBuilder {\n /** 添加清洗步骤 */\n clean: (options?: CleanOptionsInput) => PipelineBuilder\n /** 添加分块步骤 */\n chunk: (options: ChunkOptionsInput) => PipelineBuilder\n /** 添加文本转换步骤 */\n transform: (fn: TransformFn) => PipelineBuilder\n /** 添加分块后处理步骤 */\n chunkTransform: (fn: ChunkTransformFn) => PipelineBuilder\n /** 执行管线 */\n run: (text: string) => Promise<HaiResult<PipelineResult>>\n}\n\n/**\n * 数据处理管线服务接口\n * @example\n * ```ts\n * import { datapipe } from '@h-ai/datapipe'\n * const result = await datapipe.pipeline()\n * .clean({ removeHtml: true })\n * .transform(text => text.toLowerCase())\n * .chunk({ mode: 'character', maxSize: 500, overlap: 50 })\n * .run('<p>One. Two. Three.</p>')\n * if (result.success) result.data.chunks.map(chunk => chunk.content)\n * else result.error.message\n * ```\n */\nexport interface DatapipeFunctions {\n /** 清洗文本 */\n clean: CleanOperations\n /** 分块文本 */\n chunk: ChunkOperations\n /** 创建管线构建器 */\n pipeline: () => PipelineBuilder\n}\n","/**\n * @h-ai/datapipe — 保留源文本的有界分块。\n * word 按非空白词计数,其他模式按 Unicode code point 计数,均先计入 overlap。\n * @module datapipe-chunk\n */\nimport type { HaiResult } from '@h-ai/core'\nimport type { ChunkMode, ChunkOptionsInput } from './datapipe-config.js'\nimport type { DataChunk } from './datapipe-types.js'\nimport { err, ok } from '@h-ai/core'\nimport { ChunkOptionsSchema } from './datapipe-config.js'\nimport { datapipeM } from './datapipe-i18n.js'\nimport { HaiDatapipeError } from './datapipe-types.js'\n\n/**\n * Markdown 源区间;标题移除仅影响显式 keepTitle=false 的内容起点。\n * @example 模块内部上下文\n * ```ts\n * const section: MarkdownSection = { start: 0, bodyStart: 8, end: 12, title: 'Title', level: 1 }\n * const bodyLength = section.end - section.bodyStart\n * ```\n */\ninterface MarkdownSection {\n start: number\n bodyStart: number\n end: number\n title: string\n level: number\n}\n\n/** 找出自然边界对应的 code point 下标;保留分隔符,不通过 split/join 改写正文。 */\nfunction findBoundaries(text: string, expression?: RegExp): number[] {\n if (!expression)\n return []\n const boundaries: number[] = []\n let previousOffset = 0\n let points = 0\n for (const match of text.matchAll(expression)) {\n const offset = match.index + match[0].length\n if (offset <= previousOffset)\n continue\n points += Array.from(text.slice(previousOffset, offset)).length\n boundaries.push(points)\n previousOffset = offset\n }\n return boundaries\n}\n\n/** 取不超过预算的最后自然边界;边界至少越过 overlap,保证下轮起点严格前进。 */\nfunction boundedEnd(boundaries: number[], start: number, limit: number, overlap: number): number {\n let lower = 0\n let upper = boundaries.length\n while (lower < upper) {\n const middle = Math.floor((lower + upper) / 2)\n if (boundaries[middle]! <= limit)\n lower = middle + 1\n else\n upper = middle\n }\n const candidate = boundaries[lower - 1]\n return candidate !== undefined && candidate > start + overlap ? candidate : limit\n}\n\n/**\n * 所有字符模式共用滑窗;原文切片已包含空白、标点和分隔符,不追加隐式换行。\n * @example splitCharacters('甲😀乙丙丁', 3, 1) // ['甲😀乙', '乙丙丁']\n */\nfunction splitCharacters(text: string, maxSize: number, overlap: number, expression?: RegExp): string[] {\n const points = Array.from(text)\n const boundaries = findBoundaries(text, expression)\n const chunks: string[] = []\n for (let start = 0; start < points.length;) {\n const limit = Math.min(start + maxSize, points.length)\n const end = limit === points.length ? limit : boundedEnd(boundaries, start, limit, overlap)\n chunks.push(points.slice(start, end).join(''))\n if (end === points.length)\n break\n start = end - overlap\n }\n return chunks\n}\n\n/** 按非空白词滑窗,切片仍使用原始字符串的 offset,保留词间全部空白。 */\nfunction splitWords(text: string, maxSize: number, overlap: number): string[] {\n const words = [...text.matchAll(/\\S+/gu)]\n const chunks: string[] = []\n for (let start = 0; start < words.length;) {\n const end = Math.min(start + maxSize, words.length)\n const from = start === 0 ? 0 : words[start]!.index\n const to = end === words.length ? text.length : words[end]!.index\n chunks.push(text.slice(from, to))\n if (end === words.length)\n break\n start = end - overlap\n }\n return chunks\n}\n\n/** 匹配 # 至配置级别的标题;fenced code 内的 # 是正文,不创建虚假 section。 */\nfunction markdownSections(text: string, minLevel: number): MarkdownSection[] {\n const headings: Array<Omit<MarkdownSection, 'end'>> = []\n let fence: { character: string, length: number } | undefined\n for (const line of text.matchAll(/[^\\n]*(?:\\n|$)/g)) {\n const content = line[0].replace(/\\r?\\n$/, '')\n if (fence) {\n if (new RegExp(`^ {0,3}${fence.character}{${fence.length},}[ \\\\t]*$`).test(content))\n fence = undefined\n continue\n }\n const opening = /^ {0,3}(`{3,}|~{3,})/.exec(content)\n if (opening) {\n fence = { character: opening[1]![0]!, length: opening[1]!.length }\n continue\n }\n const heading = /^ {0,3}(#{1,6})[ \\t]/.exec(content)\n if (heading && heading[1]!.length <= minLevel) {\n let title = content.slice(heading[0].length).trim()\n let end = title.length\n while (title[end - 1] === '#')\n end--\n // 只移除空白分隔的尾部 #,按线性扫描处理,避免可交换量词造成正则回溯。\n if (end < title.length && (title[end - 1] === ' ' || title[end - 1] === '\\t'))\n title = title.slice(0, end).trimEnd()\n headings.push({ start: line.index, bodyStart: line.index + line[0].length, title, level: heading[1]!.length })\n }\n }\n if (headings.length === 0)\n return [{ start: 0, bodyStart: 0, end: text.length, title: '', level: 0 }]\n const sections: MarkdownSection[] = []\n if (headings[0]!.start > 0)\n sections.push({ start: 0, bodyStart: 0, end: headings[0]!.start, title: '', level: 0 })\n headings.forEach((heading, index) => sections.push({ ...heading, end: headings[index + 1]?.start ?? text.length }))\n return sections\n}\n\n/** 自然边界只决定优先切点,不删除分隔符或改变预算单位。 */\nfunction modeExpression(mode: ChunkMode, separator?: string): RegExp | undefined {\n switch (mode) {\n case 'sentence': return /[。!?.!?]+\\s*/gu\n case 'paragraph': return /\\r?\\n(?:[ \\t]*\\r?\\n)+/gu\n case 'page': return /\\f/gu\n case 'custom': return new RegExp(separator!, 'gu')\n default: return undefined\n }\n}\n\n/**\n * 对文本分块;word 使用词数,其他模式使用 Unicode code point,非字节/token/UTF-16 长度。\n * maxSize 包含 overlap 和分隔符,0 <= overlap < maxSize;默认不重叠。\n * 原始空白与分隔符保留,Markdown 仅在显式 keepTitle=false 时移除标题行。\n * @param text - 源文本;空或全空白输入返回空数组。\n * @param options - 模式与预算;Markdown section 之间不重叠,section 内使用相同边界算法。\n * @returns 有界且顺序连续编号的分块;配置错误或非法正则返回错误结果。\n * @example\n * ```ts\n * import { datapipe } from '@h-ai/datapipe'\n * const result = datapipe.chunk('One. Two. Three.', { mode: 'sentence', maxSize: 12, overlap: 2 })\n * if (result.success) result.data.map(chunk => chunk.content)\n * else result.error.message\n * ```\n */\nexport function chunkText(text: string, options: ChunkOptionsInput): HaiResult<DataChunk[]> {\n const parsed = ChunkOptionsSchema.safeParse(options)\n if (!parsed.success)\n return err(HaiDatapipeError.CONFIG_ERROR, datapipeM('datapipe_configError', { params: { error: parsed.error.message } }), parsed.error)\n const opts = parsed.data\n if (opts.mode === 'custom' && !opts.separator)\n return err(HaiDatapipeError.MISSING_SEPARATOR, datapipeM('datapipe_missingSeparator'))\n if (!text || text.trim().length === 0)\n return ok([])\n try {\n if (opts.mode === 'markdown') {\n const chunks: DataChunk[] = []\n for (const section of markdownSections(text, opts.markdownMinLevel)) {\n const content = text.slice(opts.markdownKeepTitle ? section.start : section.bodyStart, section.end)\n const parts = splitCharacters(content, opts.maxSize, opts.overlap, modeExpression('paragraph'))\n for (const part of parts)\n chunks.push({ index: chunks.length, content: part, metadata: { title: section.title, level: section.level, ...(parts.length > 1 ? { subChunk: true } : {}) } })\n }\n return ok(chunks)\n }\n const parts = opts.mode === 'word'\n ? splitWords(text, opts.maxSize, opts.overlap)\n : splitCharacters(text, opts.maxSize, opts.overlap, modeExpression(opts.mode, opts.separator))\n return ok(parts.map((content, index) => ({ index, content })))\n }\n catch (cause) {\n return err(HaiDatapipeError.CHUNK_FAILED, datapipeM('datapipe_chunkFailed', { params: { error: String(cause) } }), cause)\n }\n}\n","/**\n * @h-ai/datapipe — 文本清洗功能\n *\n * 提供文本清洗工具,支持移除 HTML、URL、Email、标准化空白等。\n * @module datapipe-clean\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { CleanOptionsInput } from './datapipe-config.js'\n\nimport { err, ok } from '@h-ai/core'\n\nimport { CleanOptionsSchema } from './datapipe-config.js'\nimport { datapipeM } from './datapipe-i18n.js'\nimport { HaiDatapipeError } from './datapipe-types.js'\n\n/** 按首个闭合符提取文本;仅用于清洗,不代替渲染 HTML 前的安全消毒。 */\nfunction stripHtmlTags(text: string): string {\n const parts: string[] = []\n let cursor = 0\n while (cursor < text.length) {\n const start = text.indexOf('<', cursor)\n if (start < 0)\n break\n const end = text.indexOf('>', start + 1)\n if (end < 0)\n break\n parts.push(text.slice(cursor, start))\n cursor = end + 1\n }\n parts.push(text.slice(cursor))\n return parts.join('')\n}\n\n/**\n * URL 正则(HTTP/HTTPS)\n */\nconst URL_REGEX = /https?:\\/\\/[^\\s<>\"{}|\\\\^`[\\]]+/g\n\n/**\n * Email 正则\n */\nconst EMAIL_REGEX = /(?<![\\w.%+-])[\\w.%+-]+@[a-z0-9.-]+\\.[a-z]{2,}/gi\n\n/**\n * 多空行正则(3行及以上空行 → 2行)\n */\nconst MULTI_NEWLINE_REGEX = /\\n{3,}/g\n\n/**\n * 多空格正则\n */\nconst MULTI_SPACE_REGEX = /[ \\t]{2,}/g\n\n/**\n * 清洗文本\n *\n * 根据配置选项对文本进行清洗处理。\n *\n * @param text - 原始文本\n * @param options - 清洗选项(可选)\n * @returns 清洗后的文本\n * @example\n * ```ts\n * import { datapipe } from '@h-ai/datapipe'\n * const result = datapipe.clean('<p>Hello</p>', { removeHtml: true })\n * if (result.success) result.data.toUpperCase()\n * else result.error.message\n * ```\n */\nexport function cleanText(text: string, options?: CleanOptionsInput): HaiResult<string> {\n const parseResult = CleanOptionsSchema.safeParse(options ?? {})\n if (!parseResult.success) {\n return err(HaiDatapipeError.CONFIG_ERROR, datapipeM('datapipe_configError', { params: { error: parseResult.error.message } }), parseResult.error)\n }\n\n const opts = parseResult.data\n let result = text\n\n try {\n // 移除 HTML 标签\n if (opts.removeHtml) {\n result = stripHtmlTags(result)\n }\n\n // 移除 URL\n if (opts.removeUrls) {\n result = result.replace(URL_REGEX, '')\n }\n\n // 移除 Email\n if (opts.removeEmails) {\n result = result.replace(EMAIL_REGEX, '')\n }\n\n // 自定义替换\n if (opts.customReplacements) {\n for (const { pattern, replacement } of opts.customReplacements) {\n let regex: RegExp\n try {\n regex = new RegExp(pattern, 'g')\n }\n catch (regexError) {\n return err(HaiDatapipeError.CONFIG_ERROR, datapipeM('datapipe_configError', { params: { error: String(regexError) } }), regexError)\n }\n result = result.replace(regex, replacement)\n }\n }\n\n // 标准化空白\n if (opts.normalizeWhitespace) {\n result = result.replace(MULTI_SPACE_REGEX, ' ')\n result = result.replace(MULTI_NEWLINE_REGEX, '\\n\\n')\n }\n\n // 去除首尾空白\n if (opts.trim) {\n result = result.trim()\n }\n\n return ok(result)\n }\n catch (error) {\n return err(HaiDatapipeError.CLEAN_FAILED, datapipeM('datapipe_cleanFailed', { params: { error: String(error) } }), error)\n }\n}\n","/**\n * @h-ai/datapipe — 管线构建器\n *\n * 提供可组合的管线构建器,支持链式添加清洗、分块、转换步骤后执行。\n * @module datapipe-pipeline\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { ChunkOptionsInput, CleanOptionsInput } from './datapipe-config.js'\nimport type {\n ChunkTransformFn,\n DataChunk,\n PipelineBuilder,\n PipelineResult,\n PipelineStep,\n TransformFn,\n} from './datapipe-types.js'\n\nimport { err, ok } from '@h-ai/core'\n\nimport { chunkText } from './datapipe-chunk.js'\nimport { cleanText } from './datapipe-clean.js'\nimport { datapipeM } from './datapipe-i18n.js'\nimport { HaiDatapipeError } from './datapipe-types.js'\n\n/**\n * 创建管线构建器\n *\n * @returns PipelineBuilder 实例,支持链式添加步骤后执行\n * @example\n * ```ts\n * import { datapipe } from '@h-ai/datapipe'\n * const result = await datapipe.pipeline()\n * .clean({ removeHtml: true })\n * .transform(text => text.toLowerCase())\n * .chunk({ mode: 'character', maxSize: 500, overlap: 50 })\n * .run('<p>One. Two. Three.</p>')\n * if (result.success) result.data.chunks.map(chunk => chunk.content)\n * else result.error.message\n * ```\n */\nexport function createPipelineBuilder(): PipelineBuilder {\n const steps: PipelineStep[] = []\n\n const builder: PipelineBuilder = {\n clean(options?: CleanOptionsInput): PipelineBuilder {\n steps.push({ type: 'clean', options })\n return builder\n },\n\n chunk(options: ChunkOptionsInput): PipelineBuilder {\n steps.push({ type: 'chunk', options })\n return builder\n },\n\n transform(fn: TransformFn): PipelineBuilder {\n steps.push({ type: 'transform', fn })\n return builder\n },\n\n chunkTransform(fn: ChunkTransformFn): PipelineBuilder {\n steps.push({ type: 'chunkTransform', fn })\n return builder\n },\n\n run: (text: string) => runPipeline(steps, text),\n }\n\n return builder\n}\n\n// ─── 管线执行 ───\n\n/**\n * 执行管线步骤\n */\nasync function runPipeline(\n steps: PipelineStep[],\n text: string,\n): Promise<HaiResult<PipelineResult>> {\n let currentText = text\n let chunks: DataChunk[] = []\n\n for (const step of steps) {\n switch (step.type) {\n case 'clean': {\n const result = cleanText(currentText, step.options)\n if (!result.success)\n return result\n currentText = result.data\n break\n }\n\n case 'chunk': {\n const result = chunkText(currentText, step.options)\n if (!result.success)\n return result\n chunks = result.data\n break\n }\n\n case 'transform': {\n try {\n currentText = await step.fn(currentText)\n }\n catch (error) {\n return err(HaiDatapipeError.TRANSFORM_FAILED, datapipeM('datapipe_transformFailed', { params: { error: String(error) } }), error)\n }\n break\n }\n\n case 'chunkTransform': {\n if (chunks.length > 0) {\n try {\n chunks = await step.fn(chunks)\n }\n catch (error) {\n return err(HaiDatapipeError.PIPELINE_FAILED, datapipeM('datapipe_pipelineFailed', { params: { error: String(error) } }), error)\n }\n }\n break\n }\n }\n }\n\n return ok({ text: currentText, chunks })\n}\n","/**\n * @h-ai/datapipe — 数据处理管线主入口\n *\n * 提供统一的 `datapipe` 对象,聚合清洗、分块和管线功能。\n * datapipe 为纯函数模块,无需初始化即可使用。\n * @module datapipe-main\n */\n\nimport type { DatapipeFunctions } from './datapipe-types.js'\n\nimport { chunkText } from './datapipe-chunk.js'\nimport { cleanText } from './datapipe-clean.js'\nimport { createPipelineBuilder } from './datapipe-pipeline.js'\n\n// ─── 统一服务对象 ───\n\n/**\n * 数据处理管线服务对象\n *\n * 纯函数模块,无需初始化即可使用。\n * @example\n * ```ts\n * import { datapipe } from '@h-ai/datapipe'\n * const result = await datapipe.pipeline()\n * .clean({ removeHtml: true })\n * .transform(text => text.toLowerCase())\n * .chunk({ mode: 'character', maxSize: 500, overlap: 50 })\n * .run('<p>One. Two. Three.</p>')\n * if (result.success) result.data.chunks.map(chunk => chunk.content)\n * else result.error.message\n * ```\n */\nexport const datapipe: DatapipeFunctions = {\n clean: cleanText,\n chunk: chunkText,\n pipeline: createPipelineBuilder,\n}\n"]}
1
+ {"version":3,"sources":["../src/datapipe-config.ts","../messages/en-US.json","../messages/ja-JP.json","../messages/zh-CN.json","../src/datapipe-i18n.ts","../src/datapipe-types.ts","../src/datapipe-chunk.ts","../src/datapipe-clean.ts","../src/datapipe-pipeline.ts","../src/datapipe-main.ts"],"names":["core","parts","err","ok"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * @h-ai/datapipe — 数据处理管线配置 Schema\n *\n * 本文件定义数据处理模块的错误码常量、Zod Schema 和配置类型。\n * 支持清洗(clean)、分块(chunk)、转换(transform)和管线(pipeline)。\n * @module datapipe-config\n */\n\nimport { z } from 'zod'\n\n// ─── 清洗配置 ───\n\n/**\n * 清洗选项 Schema\n *\n * 数据清洗规则配置,支持移除 HTML、URL、Email、标准化空白等。\n * @example\n * ```ts\n * import { CleanOptionsSchema } from '@h-ai/datapipe'\n * const options = CleanOptionsSchema.parse({ removeHtml: true, removeEmails: true })\n * ```\n */\nexport const CleanOptionsSchema = z.object({\n /** 移除 HTML 标签(默认 true) */\n removeHtml: z.boolean().default(true),\n /** 移除 URL(默认 false) */\n removeUrls: z.boolean().default(false),\n /** 移除 Email 地址(默认 false) */\n removeEmails: z.boolean().default(false),\n /** 标准化空白字符(多空格→单空格、去掉多余空行,默认 true) */\n normalizeWhitespace: z.boolean().default(true),\n /** 去除首尾空白(默认 true) */\n trim: z.boolean().default(true),\n /**\n * 自定义替换规则(正则→替换字符串)\n *\n * ❗ 安全提示:pattern 会通过 `new RegExp()` 构造,如果其值来源于用户输入,请在调用方先行校验以防止 ReDoS 攻击。\n */\n customReplacements: z.array(z.object({\n /** 正则表达式字符串 */\n pattern: z.string(),\n /** 替换文本 */\n replacement: z.string(),\n })).optional(),\n})\n\n/**\n * 清洗选项类型\n * @example\n * ```ts\n * import { CleanOptionsSchema, type CleanOptions } from '@h-ai/datapipe'\n * const options: CleanOptions = CleanOptionsSchema.parse({ removeHtml: true })\n * ```\n */\nexport type CleanOptions = z.infer<typeof CleanOptionsSchema>\n\n/**\n * 清洗选项输入类型\n * @example\n * ```ts\n * import type { CleanOptionsInput } from '@h-ai/datapipe'\n * const options: CleanOptionsInput = { removeHtml: true, removeUrls: true }\n * ```\n */\nexport type CleanOptionsInput = z.input<typeof CleanOptionsSchema>\n\n// ─── 分块配置 ───\n\n/**\n * 分块模式枚举\n *\n * - `sentence` — 按句子分块\n * - `paragraph` — 按段落分块\n * - `markdown` — 按 Markdown 标题分块(## / ### 等)\n * - `page` — 按分页符分块\n * - `word` — 按非空白词数分块,不截断单个词\n * - `character` — 按 Unicode code point 分块,不拆代理对\n * - `custom` — 自定义分隔符分块\n * @example\n * ```ts\n * import { ChunkModeSchema } from '@h-ai/datapipe'\n * const mode = ChunkModeSchema.parse('character')\n * ```\n */\nexport const ChunkModeSchema = z.enum([\n 'sentence',\n 'paragraph',\n 'markdown',\n 'page',\n 'word',\n 'character',\n 'custom',\n])\n\n/**\n * 分块模式类型\n * @example\n * ```ts\n * import type { ChunkMode } from '@h-ai/datapipe'\n * const options: ChunkMode = 'character'\n * ```\n */\nexport type ChunkMode = z.infer<typeof ChunkModeSchema>\n\n/**\n * 分块选项 Schema\n * datapipe 的默认 overlap 为 0;消费者可显式提供自己的默认值,例如 AI Knowledge 为 200。\n * @example\n * ```ts\n * import { ChunkOptionsSchema } from '@h-ai/datapipe'\n * const options = ChunkOptionsSchema.parse({ mode: 'markdown', maxSize: 500, overlap: 50 })\n * // maxSize 已包含重叠,overlap 必须小于 maxSize;自定义正则仅来自可信配置。\n * ```\n */\nexport const ChunkOptionsSchema = z.object({\n /** 分块模式 */\n mode: ChunkModeSchema,\n /** 每块上限包含 overlap/分隔符;word 按非空白词,其他按 Unicode code point,默认 1500。 */\n maxSize: z.number().int().positive().default(1500),\n /** 重叠使用与 maxSize 相同的单位,必须严格小于 maxSize。 */\n overlap: z.number().int().min(0).default(0),\n /**\n * 自定义分隔符正则(仅 mode='custom' 时使用)\n *\n * ❗ 安全提示:separator 会通过 `new RegExp()` 构造,如果其值来源于用户输入,请在调用方先行校验以防止 ReDoS 攻击。\n */\n separator: z.string().optional(),\n /** Markdown 标题分割深度(1-6,默认 2,即 # 和 ## 作为分块边界;设为 3 则 ### 也作为分块边界) */\n markdownMinLevel: z.number().int().min(1).max(6).default(2),\n /** 是否保留 Markdown 标题在分块内容中(默认 true) */\n markdownKeepTitle: z.boolean().default(true),\n}).refine(options => options.overlap < options.maxSize, {\n path: ['overlap'],\n})\n\n/**\n * 分块选项类型\n * @example\n * ```ts\n * import { ChunkOptionsSchema, type ChunkOptions } from '@h-ai/datapipe'\n * const options: ChunkOptions = ChunkOptionsSchema.parse({ mode: 'character', maxSize: 500 })\n * ```\n */\nexport type ChunkOptions = z.infer<typeof ChunkOptionsSchema>\n\n/**\n * 分块选项输入类型\n * @example\n * ```ts\n * import type { ChunkOptionsInput } from '@h-ai/datapipe'\n * const options: ChunkOptionsInput = { mode: 'character', maxSize: 500, overlap: 50 }\n * ```\n */\nexport type ChunkOptionsInput = z.input<typeof ChunkOptionsSchema>\n","{\n \"$schema\": \"https://inlang.com/schema/inlang-message-format\",\n \"datapipe_cleanFailed\": \"Failed to clean text: {error}\",\n \"datapipe_chunkFailed\": \"Failed to chunk text: {error}\",\n \"datapipe_transformFailed\": \"Failed to transform text: {error}\",\n \"datapipe_pipelineFailed\": \"Pipeline execution failed: {error}\",\n \"datapipe_configError\": \"Datapipe config validation failed: {error}\",\n \"datapipe_missingSeparator\": \"Custom chunk mode requires a separator parameter\"\n}\n","{\n \"$schema\": \"https://inlang.com/schema/inlang-message-format\",\n \"datapipe_cleanFailed\": \"テキストのクリーニングに失敗しました: {error}\",\n \"datapipe_chunkFailed\": \"テキストの分割に失敗しました: {error}\",\n \"datapipe_transformFailed\": \"テキストの変換に失敗しました: {error}\",\n \"datapipe_pipelineFailed\": \"パイプラインの実行に失敗しました: {error}\",\n \"datapipe_configError\": \"データパイプ設定の検証に失敗しました: {error}\",\n \"datapipe_missingSeparator\": \"カスタム分割モードにはseparatorパラメーターが必要です\"\n}\n","{\n \"$schema\": \"https://inlang.com/schema/inlang-message-format\",\n \"datapipe_cleanFailed\": \"清洗文本失败: {error}\",\n \"datapipe_chunkFailed\": \"分块文本失败: {error}\",\n \"datapipe_transformFailed\": \"转换文本失败: {error}\",\n \"datapipe_pipelineFailed\": \"管线执行失败: {error}\",\n \"datapipe_configError\": \"数据处理配置校验失败:{error}\",\n \"datapipe_missingSeparator\": \"自定义分块模式需要提供 separator 参数\"\n}\n","/**\n * @h-ai/datapipe — i18n\n *\n * 本文件提供数据处理模块的 i18n 文案访问入口。\n * @module datapipe-i18n\n */\n\nimport { core } from '@h-ai/core'\nimport messagesEnUS from '../messages/en-US.json'\nimport messagesJaJP from '../messages/ja-JP.json'\nimport messagesZhCN from '../messages/zh-CN.json'\n\n// ─── i18n ───\n\n/**\n * 数据处理模块文案 Key 类型\n * @example 模块内部上下文\n * ```ts\n * const key: DatapipeMessageKey = 'datapipe_cleanFailed'\n * const message = datapipeM(key)\n * ```\n */\ntype DatapipeMessageKey = keyof typeof messagesZhCN\n\n/**\n * 获取数据处理模块文案。\n * @param key - 文案 Key\n * @param options - 插值参数与格式化选项\n * @returns 本地化后的文案字符串\n * @example 模块内部上下文\n * ```ts\n * const message = datapipeM('datapipe_cleanFailed', { params: { error: 'invalid input' }, locale: 'en-US' })\n * ```\n */\nexport const datapipeM = core.i18n.createMessageGetter<DatapipeMessageKey>({\n 'zh-CN': messagesZhCN,\n 'en-US': messagesEnUS,\n 'ja-JP': messagesJaJP,\n})\n","/**\n * @h-ai/datapipe — 类型定义\n *\n * 本文件定义数据处理模块的核心接口和类型。\n * @module datapipe-types\n */\n\nimport type { ErrorInfo, HaiResult } from '@h-ai/core'\nimport type { ChunkOptionsInput, CleanOptionsInput } from './datapipe-config.js'\nimport { core } from '@h-ai/core'\n\n// ─── 错误定义(照 @h-ai/core 范式) ───\n\n/**\n * 数据处理错误信息映射(错误码:HTTP状态码)。\n *\n * 完整错误码将自动生成为:`hai:datapipe:NNN`\n */\nconst DatapipeErrorInfo = {\n CLEAN_FAILED: '001:500',\n CHUNK_FAILED: '002:500',\n TRANSFORM_FAILED: '003:500',\n PIPELINE_FAILED: '004:500',\n CONFIG_ERROR: '005:400',\n MISSING_SEPARATOR: '006:400',\n} as const satisfies ErrorInfo\n\n/**\n * Datapipe 模块标准错误定义对象。\n * @example\n * ```ts\n * import { HaiDatapipeError } from '@h-ai/datapipe'\n * import { err } from '@h-ai/core'\n * const result = err(HaiDatapipeError.CONFIG_ERROR, 'Invalid chunk configuration')\n * if (!result.success) result.error.httpStatus\n * ```\n */\nexport const HaiDatapipeError = core.error.buildHaiErrorsDef('datapipe', DatapipeErrorInfo)\n\n// ─── 数据块 ───\n\n/**\n * 数据块接口\n *\n * 表示经过分块处理后的单个文本片段。\n * @example\n * ```ts\n * import type { DataChunk } from '@h-ai/datapipe'\n * const options: DataChunk = { index: 0, content: '## Intro', metadata: { title: 'Intro', level: 2 } }\n * ```\n */\nexport interface DataChunk {\n /** 分块索引(从 0 开始) */\n index: number\n /** 原文切片;保留空白和分隔符。word 以词计量,其他模式以 Unicode code point 计量。 */\n content: string\n /** 分块元数据(可选) */\n metadata?: Record<string, unknown>\n}\n\n// ─── 转换函数 ───\n\n/**\n * 转换函数类型\n *\n * 自定义文本后处理函数,可以是同步或异步。\n * @example\n * ```ts\n * import type { TransformFn } from '@h-ai/datapipe'\n * const options: TransformFn = text => text.trim().toLowerCase()\n * ```\n */\nexport type TransformFn = (text: string) => string | Promise<string>\n\n/**\n * 分块转换函数类型\n *\n * 对分块列表进行后处理(如过滤、合并等)。\n * @example\n * ```ts\n * import type { ChunkTransformFn } from '@h-ai/datapipe'\n * const options: ChunkTransformFn = chunks => chunks.filter(chunk => chunk.content.trim().length > 0)\n * ```\n */\nexport type ChunkTransformFn = (chunks: DataChunk[]) => DataChunk[] | Promise<DataChunk[]>\n\n// ─── 管线步骤 ───\n\n/**\n * 管线步骤类型\n *\n * 管线由一系列步骤组成,支持清洗、分块和自定义转换。\n * @example\n * ```ts\n * import type { PipelineStep } from '@h-ai/datapipe'\n * const options: PipelineStep = { type: 'chunk', options: { mode: 'paragraph', maxSize: 500, overlap: 50 } }\n * ```\n */\nexport type PipelineStep\n = | { type: 'clean', options?: CleanOptionsInput }\n | { type: 'chunk', options: ChunkOptionsInput }\n | { type: 'transform', fn: TransformFn }\n | { type: 'chunkTransform', fn: ChunkTransformFn }\n\n// ─── 管线结果 ───\n\n/**\n * 管线执行结果\n * @example\n * ```ts\n * import type { PipelineResult } from '@h-ai/datapipe'\n * const options: PipelineResult = { text: 'One. Two.', chunks: [{ index: 0, content: 'One. Two.' }] }\n * ```\n */\nexport interface PipelineResult {\n /** 处理后的文本(分块前的最终文本) */\n text: string\n /** 分块列表(如果管线包含 chunk 步骤) */\n chunks: DataChunk[]\n}\n\n// ─── 操作接口 ───\n\n/**\n * 清洗操作接口\n *\n * 通过 `datapipe.clean()` 调用。\n * @example\n * ```ts\n * import { datapipe, type CleanOperations } from '@h-ai/datapipe'\n * const clean: CleanOperations = datapipe.clean\n * const result = clean('<p>Hello</p>')\n * if (result.success) result.data.trim()\n * ```\n */\nexport interface CleanOperations {\n /**\n * 清洗文本\n *\n * @param text - 原始文本\n * @param options - 清洗选项(可选,使用默认值)\n * @returns 清洗后的文本\n */\n (text: string, options?: CleanOptionsInput): HaiResult<string>\n}\n\n/**\n * 分块操作接口\n *\n * 通过 `datapipe.chunk()` 调用。\n * @example\n * ```ts\n * import { datapipe, type ChunkOperations } from '@h-ai/datapipe'\n * const chunk: ChunkOperations = datapipe.chunk\n * const result = chunk('One. Two.', { mode: 'sentence', maxSize: 10 })\n * if (result.success) result.data.map(item => item.index)\n * ```\n */\nexport interface ChunkOperations {\n /**\n * 对文本进行分块\n *\n * @param text - 输入文本\n * @param options - 分块选项\n * @returns 分块列表\n */\n (text: string, options: ChunkOptionsInput): HaiResult<DataChunk[]>\n}\n\n/**\n * 管线构建器接口\n *\n * 通过 `datapipe.pipeline()` 创建,链式添加步骤后执行。\n * @example\n * ```ts\n * import { datapipe } from '@h-ai/datapipe'\n * const result = await datapipe.pipeline()\n * .clean({ removeHtml: true })\n * .transform(text => text.toLowerCase())\n * .chunk({ mode: 'character', maxSize: 500, overlap: 50 })\n * .run('<p>One. Two. Three.</p>')\n * if (result.success) result.data.chunks.map(chunk => chunk.content)\n * else result.error.message\n * ```\n */\nexport interface PipelineBuilder {\n /** 添加清洗步骤 */\n clean: (options?: CleanOptionsInput) => PipelineBuilder\n /** 添加分块步骤 */\n chunk: (options: ChunkOptionsInput) => PipelineBuilder\n /** 添加文本转换步骤 */\n transform: (fn: TransformFn) => PipelineBuilder\n /** 添加分块后处理步骤 */\n chunkTransform: (fn: ChunkTransformFn) => PipelineBuilder\n /** 执行管线 */\n run: (text: string) => Promise<HaiResult<PipelineResult>>\n}\n\n/**\n * 数据处理管线服务接口\n * @example\n * ```ts\n * import { datapipe } from '@h-ai/datapipe'\n * const result = await datapipe.pipeline()\n * .clean({ removeHtml: true })\n * .transform(text => text.toLowerCase())\n * .chunk({ mode: 'character', maxSize: 500, overlap: 50 })\n * .run('<p>One. Two. Three.</p>')\n * if (result.success) result.data.chunks.map(chunk => chunk.content)\n * else result.error.message\n * ```\n */\nexport interface DatapipeFunctions {\n /** 清洗文本 */\n clean: CleanOperations\n /** 分块文本 */\n chunk: ChunkOperations\n /** 创建管线构建器 */\n pipeline: () => PipelineBuilder\n}\n","/**\n * @h-ai/datapipe — 保留源文本的有界分块。\n * word 按非空白词计数,其他模式按 Unicode code point 计数,均先计入 overlap。\n * @module datapipe-chunk\n */\nimport type { HaiResult } from '@h-ai/core'\nimport type { ChunkMode, ChunkOptionsInput } from './datapipe-config.js'\nimport type { DataChunk } from './datapipe-types.js'\nimport { err, ok } from '@h-ai/core'\nimport { ChunkOptionsSchema } from './datapipe-config.js'\nimport { datapipeM } from './datapipe-i18n.js'\nimport { HaiDatapipeError } from './datapipe-types.js'\n\n/**\n * Markdown 源区间;标题移除仅影响显式 keepTitle=false 的内容起点。\n * @example 模块内部上下文\n * ```ts\n * const section: MarkdownSection = { start: 0, bodyStart: 8, end: 12, title: 'Title', level: 1 }\n * const bodyLength = section.end - section.bodyStart\n * ```\n */\ninterface MarkdownSection {\n start: number\n bodyStart: number\n end: number\n title: string\n level: number\n}\n\n/** 找出自然边界对应的 code point 下标;保留分隔符,不通过 split/join 改写正文。 */\nfunction findBoundaries(text: string, expression?: RegExp): number[] {\n if (!expression)\n return []\n const boundaries: number[] = []\n let previousOffset = 0\n let points = 0\n for (const match of text.matchAll(expression)) {\n const offset = match.index + match[0].length\n if (offset <= previousOffset)\n continue\n points += Array.from(text.slice(previousOffset, offset)).length\n boundaries.push(points)\n previousOffset = offset\n }\n return boundaries\n}\n\n/** 取不超过预算的最后自然边界;边界至少越过 overlap,保证下轮起点严格前进。 */\nfunction boundedEnd(boundaries: number[], start: number, limit: number, overlap: number): number {\n let lower = 0\n let upper = boundaries.length\n while (lower < upper) {\n const middle = Math.floor((lower + upper) / 2)\n if (boundaries[middle]! <= limit)\n lower = middle + 1\n else\n upper = middle\n }\n const candidate = boundaries[lower - 1]\n return candidate !== undefined && candidate > start + overlap\n ? candidate\n : limit\n}\n\n/**\n * 所有字符模式共用滑窗;原文切片已包含空白、标点和分隔符,不追加隐式换行。\n * @example splitCharacters('甲😀乙丙丁', 3, 1) // ['甲😀乙', '乙丙丁']\n */\nfunction splitCharacters(text: string, maxSize: number, overlap: number, expression?: RegExp): string[] {\n const points = Array.from(text)\n const boundaries = findBoundaries(text, expression)\n const chunks: string[] = []\n for (let start = 0; start < points.length;) {\n const limit = Math.min(start + maxSize, points.length)\n const end = limit === points.length\n ? limit\n : boundedEnd(boundaries, start, limit, overlap)\n chunks.push(points.slice(start, end).join(''))\n if (end === points.length)\n break\n start = end - overlap\n }\n return chunks\n}\n\n/** 按非空白词滑窗,切片仍使用原始字符串的 offset,保留词间全部空白。 */\nfunction splitWords(text: string, maxSize: number, overlap: number): string[] {\n const words = [\n ...text.matchAll(/\\S+/gu),\n ]\n const chunks: string[] = []\n for (let start = 0; start < words.length;) {\n const end = Math.min(start + maxSize, words.length)\n const from = start === 0\n ? 0\n : words[start]!.index\n const to = end === words.length\n ? text.length\n : words[end]!.index\n chunks.push(text.slice(from, to))\n if (end === words.length)\n break\n start = end - overlap\n }\n return chunks\n}\n\n/** 匹配 # 至配置级别的标题;fenced code 内的 # 是正文,不创建虚假 section。 */\nfunction markdownSections(text: string, minLevel: number): MarkdownSection[] {\n const headings: Array<Omit<MarkdownSection, 'end'>> = []\n let fence: { character: string, length: number } | undefined\n for (const line of text.matchAll(/[^\\n]*(?:\\n|$)/g)) {\n const content = line[0].replace(/\\r?\\n$/, '')\n if (fence) {\n if (new RegExp(`^ {0,3}${fence.character}{${fence.length},}[ \\\\t]*$`).test(content))\n fence = undefined\n continue\n }\n const opening = /^ {0,3}(`{3,}|~{3,})/.exec(content)\n if (opening) {\n fence = { character: opening[1]![0]!, length: opening[1]!.length }\n continue\n }\n const heading = /^ {0,3}(#{1,6})[ \\t]/.exec(content)\n if (heading && heading[1]!.length <= minLevel) {\n let title = content.slice(heading[0].length).trim()\n let end = title.length\n while (title[end - 1] === '#')\n end--\n // 只移除空白分隔的尾部 #,按线性扫描处理,避免可交换量词造成正则回溯。\n if (end < title.length && (title[end - 1] === ' ' || title[end - 1] === '\\t'))\n title = title.slice(0, end).trimEnd()\n headings.push({\n start: line.index,\n bodyStart: line.index + line[0].length,\n title,\n level: heading[1]!.length,\n })\n }\n }\n if (headings.length === 0) {\n return [\n {\n start: 0,\n bodyStart: 0,\n end: text.length,\n title: '',\n level: 0,\n },\n ]\n }\n const sections: MarkdownSection[] = []\n if (headings[0]!.start > 0) {\n sections.push({\n start: 0,\n bodyStart: 0,\n end: headings[0]!.start,\n title: '',\n level: 0,\n })\n }\n headings.forEach((heading, index) => sections.push({ ...heading, end: headings[index + 1]?.start ?? text.length }))\n return sections\n}\n\n/** 自然边界只决定优先切点,不删除分隔符或改变预算单位。 */\nfunction modeExpression(mode: ChunkMode, separator?: string): RegExp | undefined {\n switch (mode) {\n case 'sentence': return /[。!?.!?]+\\s*/gu\n case 'paragraph': return /\\r?\\n(?:[ \\t]*\\r?\\n)+/gu\n case 'page': return /\\f/gu\n case 'custom': return new RegExp(separator!, 'gu')\n default: return undefined\n }\n}\n\n/**\n * 对文本分块;word 使用词数,其他模式使用 Unicode code point,非字节/token/UTF-16 长度。\n * maxSize 包含 overlap 和分隔符,0 <= overlap < maxSize;默认不重叠。\n * 原始空白与分隔符保留,Markdown 仅在显式 keepTitle=false 时移除标题行。\n * @param text - 源文本;空或全空白输入返回空数组。\n * @param options - 模式与预算;Markdown section 之间不重叠,section 内使用相同边界算法。\n * @returns 有界且顺序连续编号的分块;配置错误或非法正则返回错误结果。\n * @example\n * ```ts\n * import { datapipe } from '@h-ai/datapipe'\n * const result = datapipe.chunk('One. Two. Three.', { mode: 'sentence', maxSize: 12, overlap: 2 })\n * if (result.success) result.data.map(chunk => chunk.content)\n * else result.error.message\n * ```\n */\nexport function chunkText(text: string, options: ChunkOptionsInput): HaiResult<DataChunk[]> {\n const parsed = ChunkOptionsSchema.safeParse(options)\n if (!parsed.success) {\n return err(HaiDatapipeError.CONFIG_ERROR, datapipeM('datapipe_configError', {\n params: { error: parsed.error.message },\n }), parsed.error)\n }\n const opts = parsed.data\n if (opts.mode === 'custom' && !opts.separator)\n return err(HaiDatapipeError.MISSING_SEPARATOR, datapipeM('datapipe_missingSeparator'))\n if (!text || text.trim().length === 0)\n return ok([])\n try {\n if (opts.mode === 'markdown') {\n const chunks: DataChunk[] = []\n for (const section of markdownSections(text, opts.markdownMinLevel)) {\n const content = text.slice(opts.markdownKeepTitle ? section.start : section.bodyStart, section.end)\n const parts = splitCharacters(content, opts.maxSize, opts.overlap, modeExpression('paragraph'))\n for (const part of parts) {\n chunks.push({\n index: chunks.length,\n content: part,\n metadata: {\n title: section.title,\n level: section.level,\n ...(parts.length > 1\n ? { subChunk: true }\n : {}),\n },\n })\n }\n }\n return ok(chunks)\n }\n const parts = opts.mode === 'word'\n ? splitWords(text, opts.maxSize, opts.overlap)\n : splitCharacters(text, opts.maxSize, opts.overlap, modeExpression(opts.mode, opts.separator))\n return ok(parts.map((content, index) => ({ index, content })))\n }\n catch (cause) {\n return err(HaiDatapipeError.CHUNK_FAILED, datapipeM('datapipe_chunkFailed', {\n params: {\n error: String(cause),\n },\n }), cause)\n }\n}\n","/**\n * @h-ai/datapipe — 文本清洗功能\n *\n * 提供文本清洗工具,支持移除 HTML、URL、Email、标准化空白等。\n * @module datapipe-clean\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { CleanOptionsInput } from './datapipe-config.js'\n\nimport { err, ok } from '@h-ai/core'\n\nimport { CleanOptionsSchema } from './datapipe-config.js'\nimport { datapipeM } from './datapipe-i18n.js'\nimport { HaiDatapipeError } from './datapipe-types.js'\n\n/** 按首个闭合符提取文本;仅用于清洗,不代替渲染 HTML 前的安全消毒。 */\nfunction stripHtmlTags(text: string): string {\n const parts: string[] = []\n let cursor = 0\n while (cursor < text.length) {\n const start = text.indexOf('<', cursor)\n if (start < 0)\n break\n const end = text.indexOf('>', start + 1)\n if (end < 0)\n break\n parts.push(text.slice(cursor, start))\n cursor = end + 1\n }\n parts.push(text.slice(cursor))\n return parts.join('')\n}\n\n/**\n * URL 正则(HTTP/HTTPS)\n */\nconst URL_REGEX = /https?:\\/\\/[^\\s<>\"{}|\\\\^`[\\]]+/g\n\n/**\n * Email 正则\n */\nconst EMAIL_REGEX = /(?<![\\w.%+-])[\\w.%+-]+@[a-z0-9.-]+\\.[a-z]{2,}/gi\n\n/**\n * 多空行正则(3行及以上空行 → 2行)\n */\nconst MULTI_NEWLINE_REGEX = /\\n{3,}/g\n\n/**\n * 多空格正则\n */\nconst MULTI_SPACE_REGEX = /[ \\t]{2,}/g\n\n/**\n * 清洗文本\n *\n * 根据配置选项对文本进行清洗处理。\n *\n * @param text - 原始文本\n * @param options - 清洗选项(可选)\n * @returns 清洗后的文本\n * @example\n * ```ts\n * import { datapipe } from '@h-ai/datapipe'\n * const result = datapipe.clean('<p>Hello</p>', { removeHtml: true })\n * if (result.success) result.data.toUpperCase()\n * else result.error.message\n * ```\n */\nexport function cleanText(text: string, options?: CleanOptionsInput): HaiResult<string> {\n const parseResult = CleanOptionsSchema.safeParse(options ?? {})\n if (!parseResult.success) {\n return err(HaiDatapipeError.CONFIG_ERROR, datapipeM('datapipe_configError', {\n params: { error: parseResult.error.message },\n }), parseResult.error)\n }\n\n const opts = parseResult.data\n let result = text\n\n try {\n // 移除 HTML 标签\n if (opts.removeHtml) {\n result = stripHtmlTags(result)\n }\n\n // 移除 URL\n if (opts.removeUrls) {\n result = result.replace(URL_REGEX, '')\n }\n\n // 移除 Email\n if (opts.removeEmails) {\n result = result.replace(EMAIL_REGEX, '')\n }\n\n // 自定义替换\n if (opts.customReplacements) {\n for (const { pattern, replacement } of opts.customReplacements) {\n let regex: RegExp\n try {\n regex = new RegExp(pattern, 'g')\n }\n catch (regexError) {\n return err(HaiDatapipeError.CONFIG_ERROR, datapipeM('datapipe_configError', {\n params: {\n error: String(regexError),\n },\n }), regexError)\n }\n result = result.replace(regex, replacement)\n }\n }\n\n // 标准化空白\n if (opts.normalizeWhitespace) {\n result = result.replace(MULTI_SPACE_REGEX, ' ')\n result = result.replace(MULTI_NEWLINE_REGEX, '\\n\\n')\n }\n\n // 去除首尾空白\n if (opts.trim) {\n result = result.trim()\n }\n\n return ok(result)\n }\n catch (error) {\n return err(HaiDatapipeError.CLEAN_FAILED, datapipeM('datapipe_cleanFailed', {\n params: {\n error: String(error),\n },\n }), error)\n }\n}\n","/**\n * @h-ai/datapipe — 管线构建器\n *\n * 提供可组合的管线构建器,支持链式添加清洗、分块、转换步骤后执行。\n * @module datapipe-pipeline\n */\n\nimport type { HaiResult } from '@h-ai/core'\nimport type { ChunkOptionsInput, CleanOptionsInput } from './datapipe-config.js'\nimport type {\n ChunkTransformFn,\n DataChunk,\n PipelineBuilder,\n PipelineResult,\n PipelineStep,\n TransformFn,\n} from './datapipe-types.js'\n\nimport { err, ok } from '@h-ai/core'\n\nimport { chunkText } from './datapipe-chunk.js'\nimport { cleanText } from './datapipe-clean.js'\nimport { datapipeM } from './datapipe-i18n.js'\nimport { HaiDatapipeError } from './datapipe-types.js'\n\n/**\n * 创建管线构建器\n *\n * @returns PipelineBuilder 实例,支持链式添加步骤后执行\n * @example\n * ```ts\n * import { datapipe } from '@h-ai/datapipe'\n * const result = await datapipe.pipeline()\n * .clean({ removeHtml: true })\n * .transform(text => text.toLowerCase())\n * .chunk({ mode: 'character', maxSize: 500, overlap: 50 })\n * .run('<p>One. Two. Three.</p>')\n * if (result.success) result.data.chunks.map(chunk => chunk.content)\n * else result.error.message\n * ```\n */\nexport function createPipelineBuilder(): PipelineBuilder {\n const steps: PipelineStep[] = []\n\n const builder: PipelineBuilder = {\n clean(options?: CleanOptionsInput): PipelineBuilder {\n steps.push({ type: 'clean', options })\n return builder\n },\n\n chunk(options: ChunkOptionsInput): PipelineBuilder {\n steps.push({ type: 'chunk', options })\n return builder\n },\n\n transform(fn: TransformFn): PipelineBuilder {\n steps.push({ type: 'transform', fn })\n return builder\n },\n\n chunkTransform(fn: ChunkTransformFn): PipelineBuilder {\n steps.push({ type: 'chunkTransform', fn })\n return builder\n },\n\n run: (text: string) => runPipeline(steps, text),\n }\n\n return builder\n}\n\n// ─── 管线执行 ───\n\n/**\n * 执行管线步骤\n */\nasync function runPipeline(\n steps: PipelineStep[],\n text: string,\n): Promise<HaiResult<PipelineResult>> {\n let currentText = text\n let chunks: DataChunk[] = []\n\n for (const step of steps) {\n switch (step.type) {\n case 'clean': {\n const result = cleanText(currentText, step.options)\n if (!result.success)\n return result\n currentText = result.data\n break\n }\n\n case 'chunk': {\n const result = chunkText(currentText, step.options)\n if (!result.success)\n return result\n chunks = result.data\n break\n }\n\n case 'transform': {\n try {\n currentText = await step.fn(currentText)\n }\n catch (error) {\n return err(HaiDatapipeError.TRANSFORM_FAILED, datapipeM('datapipe_transformFailed', {\n params: {\n error: String(error),\n },\n }), error)\n }\n break\n }\n\n case 'chunkTransform': {\n if (chunks.length > 0) {\n try {\n chunks = await step.fn(chunks)\n }\n catch (error) {\n return err(HaiDatapipeError.PIPELINE_FAILED, datapipeM('datapipe_pipelineFailed', {\n params: {\n error: String(error),\n },\n }), error)\n }\n }\n break\n }\n }\n }\n\n return ok({ text: currentText, chunks })\n}\n","/**\n * @h-ai/datapipe — 数据处理管线主入口\n *\n * 提供统一的 `datapipe` 对象,聚合清洗、分块和管线功能。\n * datapipe 为纯函数模块,无需初始化即可使用。\n * @module datapipe-main\n */\n\nimport type { DatapipeFunctions } from './datapipe-types.js'\n\nimport { chunkText } from './datapipe-chunk.js'\nimport { cleanText } from './datapipe-clean.js'\nimport { createPipelineBuilder } from './datapipe-pipeline.js'\n\n// ─── 统一服务对象 ───\n\n/**\n * 数据处理管线服务对象\n *\n * 纯函数模块,无需初始化即可使用。\n * @example\n * ```ts\n * import { datapipe } from '@h-ai/datapipe'\n * const result = await datapipe.pipeline()\n * .clean({ removeHtml: true })\n * .transform(text => text.toLowerCase())\n * .chunk({ mode: 'character', maxSize: 500, overlap: 50 })\n * .run('<p>One. Two. Three.</p>')\n * if (result.success) result.data.chunks.map(chunk => chunk.content)\n * else result.error.message\n * ```\n */\nexport const datapipe: DatapipeFunctions = {\n clean: cleanText,\n chunk: chunkText,\n pipeline: createPipelineBuilder,\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@h-ai/datapipe",
3
3
  "type": "module",
4
- "version": "1.0.0-beta.17",
4
+ "version": "1.0.0-beta.19",
5
5
  "description": "Data processing pipeline module for hai-framework: clean, chunk, transform",
6
6
  "exports": {
7
7
  ".": {
@@ -21,11 +21,11 @@
21
21
  "node": "^22.23.4 || ^24.22.1 || ^26.12.1"
22
22
  },
23
23
  "dependencies": {
24
- "@h-ai/core": "1.0.0-beta.17",
25
- "zod": "^4.6.5"
24
+ "@h-ai/core": "1.0.0-beta.19",
25
+ "zod": "^4.6.7"
26
26
  },
27
27
  "devDependencies": {
28
- "tsup": "^8.5.1",
28
+ "tsup": "^9.0.0",
29
29
  "typescript": "^6.0.3"
30
30
  },
31
31
  "scripts": {