@gmickel/gno 1.46.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/THIRD_PARTY_NOTICES.md +46 -0
- package/assets/skill/SKILL.md +7 -6
- package/assets/spa-production.json.gz +0 -0
- package/browser-extension/artifacts/gno-browser-clipper-v2.0.0.zip +0 -0
- package/browser-extension/artifacts/gno-browser-clipper-v2.0.0.zip.sha256 +1 -0
- package/browser-extension/dist/chunk-4tc9v0ja.js +74 -0
- package/browser-extension/dist/manifest.json +1 -1
- package/browser-extension/dist/preview.html +1 -1
- package/browser-extension/dist/service-worker.js +32 -33
- package/bunfig.toml +2 -0
- package/package.json +40 -26
- package/spec/cli.md +21 -4
- package/spec/db/schema.sql +146 -1
- package/spec/mcp.md +26 -0
- package/src/app/context-runtime-types.ts +3 -0
- package/src/app/context-runtime.ts +2 -0
- package/src/cli/commands/ask.ts +6 -1
- package/src/cli/commands/daemon.ts +21 -8
- package/src/cli/commands/embed.ts +77 -41
- package/src/cli/detach.ts +3 -2
- package/src/config/types.ts +3 -3
- package/src/converters/adapters/markitdownTs/adapter.ts +1 -2
- package/src/converters/adapters/officeparser/adapter.ts +1 -2
- package/src/converters/versions.ts +6 -8
- package/src/core/context-evidence.ts +8 -4
- package/src/core/job-manager.ts +95 -13
- package/src/core/network-boundary-inventory.ts +10 -0
- package/src/core/shutdown-budget.ts +45 -0
- package/src/embed/backlog.ts +107 -4
- package/src/embed/batch.ts +42 -2
- package/src/embed/fingerprint.ts +16 -0
- package/src/embed/retry.ts +113 -5
- package/src/embed/variant-backlog.ts +105 -0
- package/src/embed/variant-plan.ts +62 -0
- package/src/embed/variant-retry.ts +113 -0
- package/src/ingestion/graph-reconciliation.ts +327 -0
- package/src/ingestion/sync.ts +9 -272
- package/src/llm/http-inference.ts +6 -0
- package/src/llm/httpEmbedding.ts +37 -6
- package/src/llm/httpGeneration.ts +18 -3
- package/src/llm/httpRerank.ts +23 -5
- package/src/llm/inference-cancellation.ts +168 -0
- package/src/llm/inference-scope.ts +202 -0
- package/src/llm/lazy-ports.ts +115 -0
- package/src/llm/native-worker/client.ts +541 -0
- package/src/llm/native-worker/dispatcher.ts +228 -0
- package/src/llm/native-worker/embedding-identity.ts +33 -0
- package/src/llm/native-worker/entry.ts +173 -0
- package/src/llm/native-worker/errors.ts +32 -0
- package/src/llm/native-worker/evaluation.ts +16 -0
- package/src/llm/native-worker/owned-exit.ts +108 -0
- package/src/llm/native-worker/owner.ts +141 -0
- package/src/llm/native-worker/ports.ts +317 -0
- package/src/llm/native-worker/protocol.ts +442 -0
- package/src/llm/native-worker/runtime-config.ts +92 -0
- package/src/llm/nodeLlamaCpp/adapter.ts +77 -20
- package/src/llm/nodeLlamaCpp/embedding.ts +130 -46
- package/src/llm/nodeLlamaCpp/generation.ts +34 -5
- package/src/llm/nodeLlamaCpp/lifecycle-options.ts +99 -0
- package/src/llm/nodeLlamaCpp/lifecycle.ts +209 -204
- package/src/llm/nodeLlamaCpp/rerank-capacity.ts +111 -0
- package/src/llm/nodeLlamaCpp/rerank.ts +118 -27
- package/src/llm/nodeLlamaCpp/simulator-handle.ts +73 -0
- package/src/llm/nodeLlamaCpp/simulator-install.ts +124 -0
- package/src/llm/nodeLlamaCpp/simulator-session.ts +240 -0
- package/src/llm/nodeLlamaCpp/simulator-types.ts +80 -0
- package/src/llm/types.ts +35 -5
- package/src/mcp/context.ts +27 -0
- package/src/mcp/http-transport.ts +12 -10
- package/src/mcp/server.ts +3 -0
- package/src/mcp/tool-profile.ts +30 -8
- package/src/mcp/tools/context.ts +8 -11
- package/src/mcp/tools/embed.ts +1 -1
- package/src/mcp/tools/index-cmd.ts +1 -1
- package/src/mcp/tools/index.ts +10 -8
- package/src/mcp/tools/query.ts +14 -30
- package/src/mcp/tools/vsearch.ts +1 -1
- package/src/pipeline/answer.ts +23 -3
- package/src/pipeline/claim-verifier.ts +6 -0
- package/src/pipeline/expansion.ts +43 -40
- package/src/pipeline/explain.ts +6 -2
- package/src/pipeline/filters.ts +63 -0
- package/src/pipeline/fusion.ts +29 -9
- package/src/pipeline/graph-retrieval.ts +29 -9
- package/src/pipeline/hybrid.ts +198 -55
- package/src/pipeline/hydration.ts +161 -0
- package/src/pipeline/owner-fusion.ts +87 -0
- package/src/pipeline/rerank.ts +35 -11
- package/src/pipeline/search.ts +13 -2
- package/src/pipeline/types.ts +5 -3
- package/src/pipeline/vsearch.ts +87 -7
- package/src/sdk/client.ts +47 -3
- package/src/sdk/embed.ts +63 -39
- package/src/serve/background-runtime.ts +1 -1
- package/src/serve/context.ts +41 -56
- package/src/serve/embed-scheduler.ts +58 -35
- package/src/serve/public/components/IndexingProgress.tsx +46 -60
- package/src/serve/public/globals.built.css +1 -1
- package/src/serve/public/lib/shiki-language-ids.ts +14 -0
- package/src/serve/resident-admission.ts +36 -36
- package/src/serve/resident-background-work.ts +20 -2
- package/src/serve/resident-request.ts +11 -5
- package/src/serve/resident-runtime.ts +97 -61
- package/src/serve/resident-shutdown.ts +153 -0
- package/src/serve/routes/api.ts +3 -1
- package/src/serve/server.ts +47 -26
- package/src/store/migrations/028-vector-variants.ts +54 -0
- package/src/store/migrations/029-graph-reference-state.ts +77 -0
- package/src/store/migrations/index.ts +4 -0
- package/src/store/sqlite/adapter.ts +251 -183
- package/src/store/sqlite/eligibility.ts +174 -0
- package/src/store/sqlite/graph-edge-application.ts +66 -0
- package/src/store/sqlite/graph-reference-state.ts +194 -0
- package/src/store/sqlite/legacy-vector-ownership.ts +79 -0
- package/src/store/types.ts +80 -12
- package/src/store/vector/eligibility.ts +36 -0
- package/src/store/vector/freshness.ts +33 -6
- package/src/store/vector/lazy.ts +81 -0
- package/src/store/vector/sqlite-vec.ts +106 -54
- package/src/store/vector/stats.ts +14 -3
- package/src/store/vector/types.ts +35 -2
- package/src/store/vector/variant-search.ts +192 -0
- package/src/store/vector/variants.ts +451 -0
- package/vendor/converters/markitdown-ts/LICENSE +21 -0
- package/vendor/converters/markitdown-ts/dist/index.cjs +1180 -0
- package/vendor/converters/markitdown-ts/dist/index.d.cts +46 -0
- package/vendor/converters/markitdown-ts/dist/index.d.mts +46 -0
- package/vendor/converters/markitdown-ts/dist/index.d.ts +46 -0
- package/vendor/converters/markitdown-ts/dist/index.mjs +1152 -0
- package/vendor/converters/markitdown-ts/package.json +77 -0
- package/vendor/converters/officeparser/LICENSE +21 -0
- package/vendor/converters/officeparser/dist/OfficeConverter.d.ts +47 -0
- package/vendor/converters/officeparser/dist/OfficeConverter.js +76 -0
- package/vendor/converters/officeparser/dist/OfficeGenerator.d.ts +23 -0
- package/vendor/converters/officeparser/dist/OfficeGenerator.js +73 -0
- package/vendor/converters/officeparser/dist/OfficeParser.d.ts +106 -0
- package/vendor/converters/officeparser/dist/OfficeParser.js +332 -0
- package/vendor/converters/officeparser/dist/cli.d.ts +28 -0
- package/vendor/converters/officeparser/dist/cli.js +381 -0
- package/vendor/converters/officeparser/dist/defaults.d.ts +41 -0
- package/vendor/converters/officeparser/dist/defaults.js +218 -0
- package/vendor/converters/officeparser/dist/generators/BaseGenerator.d.ts +107 -0
- package/vendor/converters/officeparser/dist/generators/BaseGenerator.js +248 -0
- package/vendor/converters/officeparser/dist/generators/ChunkingGenerator.d.ts +82 -0
- package/vendor/converters/officeparser/dist/generators/ChunkingGenerator.js +797 -0
- package/vendor/converters/officeparser/dist/generators/CsvGenerator.d.ts +38 -0
- package/vendor/converters/officeparser/dist/generators/CsvGenerator.js +245 -0
- package/vendor/converters/officeparser/dist/generators/EpubGenerator.d.ts +43 -0
- package/vendor/converters/officeparser/dist/generators/EpubGenerator.js +315 -0
- package/vendor/converters/officeparser/dist/generators/HtmlGenerator.d.ts +59 -0
- package/vendor/converters/officeparser/dist/generators/HtmlGenerator.js +1942 -0
- package/vendor/converters/officeparser/dist/generators/MarkdownGenerator.d.ts +96 -0
- package/vendor/converters/officeparser/dist/generators/MarkdownGenerator.js +1175 -0
- package/vendor/converters/officeparser/dist/generators/PdfGenerator.d.ts +22 -0
- package/vendor/converters/officeparser/dist/generators/PdfGenerator.js +194 -0
- package/vendor/converters/officeparser/dist/generators/RtfGenerator.d.ts +29 -0
- package/vendor/converters/officeparser/dist/generators/RtfGenerator.js +316 -0
- package/vendor/converters/officeparser/dist/generators/TextGenerator.d.ts +13 -0
- package/vendor/converters/officeparser/dist/generators/TextGenerator.js +201 -0
- package/vendor/converters/officeparser/dist/index.d.ts +60 -0
- package/vendor/converters/officeparser/dist/index.js +72 -0
- package/vendor/converters/officeparser/dist/index.mjs +18 -0
- package/vendor/converters/officeparser/dist/officeparser.browser.d.ts +2621 -0
- package/vendor/converters/officeparser/dist/officeparser.browser.iife.js +1336 -0
- package/vendor/converters/officeparser/dist/officeparser.browser.mjs +1335 -0
- package/vendor/converters/officeparser/dist/officeparser.browser.slim.d.ts +2621 -0
- package/vendor/converters/officeparser/dist/officeparser.browser.slim.iife.js +1336 -0
- package/vendor/converters/officeparser/dist/officeparser.browser.slim.mjs +1335 -0
- package/vendor/converters/officeparser/dist/parsers/CsvParser.d.ts +9 -0
- package/vendor/converters/officeparser/dist/parsers/CsvParser.js +115 -0
- package/vendor/converters/officeparser/dist/parsers/EpubParser.d.ts +8 -0
- package/vendor/converters/officeparser/dist/parsers/EpubParser.js +217 -0
- package/vendor/converters/officeparser/dist/parsers/ExcelParser.d.ts +32 -0
- package/vendor/converters/officeparser/dist/parsers/ExcelParser.js +736 -0
- package/vendor/converters/officeparser/dist/parsers/HtmlParser.d.ts +2 -0
- package/vendor/converters/officeparser/dist/parsers/HtmlParser.js +1287 -0
- package/vendor/converters/officeparser/dist/parsers/MarkdownParser.d.ts +2 -0
- package/vendor/converters/officeparser/dist/parsers/MarkdownParser.js +1272 -0
- package/vendor/converters/officeparser/dist/parsers/OpenOfficeParser.d.ts +31 -0
- package/vendor/converters/officeparser/dist/parsers/OpenOfficeParser.js +1819 -0
- package/vendor/converters/officeparser/dist/parsers/PdfParser.d.ts +67 -0
- package/vendor/converters/officeparser/dist/parsers/PdfParser.js +848 -0
- package/vendor/converters/officeparser/dist/parsers/PowerPointParser.d.ts +32 -0
- package/vendor/converters/officeparser/dist/parsers/PowerPointParser.js +950 -0
- package/vendor/converters/officeparser/dist/parsers/RtfParser.d.ts +187 -0
- package/vendor/converters/officeparser/dist/parsers/RtfParser.js +1801 -0
- package/vendor/converters/officeparser/dist/parsers/WordParser.d.ts +79 -0
- package/vendor/converters/officeparser/dist/parsers/WordParser.js +1177 -0
- package/vendor/converters/officeparser/dist/sbom.cdx.json +1763 -0
- package/vendor/converters/officeparser/dist/types.d.ts +2507 -0
- package/vendor/converters/officeparser/dist/types.js +107 -0
- package/vendor/converters/officeparser/dist/utils/astUtils.d.ts +16 -0
- package/vendor/converters/officeparser/dist/utils/astUtils.js +33 -0
- package/vendor/converters/officeparser/dist/utils/chartUtils.d.ts +6 -0
- package/vendor/converters/officeparser/dist/utils/chartUtils.js +257 -0
- package/vendor/converters/officeparser/dist/utils/configUtils.d.ts +44 -0
- package/vendor/converters/officeparser/dist/utils/configUtils.js +315 -0
- package/vendor/converters/officeparser/dist/utils/dateUtils.d.ts +17 -0
- package/vendor/converters/officeparser/dist/utils/dateUtils.js +69 -0
- package/vendor/converters/officeparser/dist/utils/envUtils.d.ts +29 -0
- package/vendor/converters/officeparser/dist/utils/envUtils.js +152 -0
- package/vendor/converters/officeparser/dist/utils/errorUtils.d.ts +72 -0
- package/vendor/converters/officeparser/dist/utils/errorUtils.js +245 -0
- package/vendor/converters/officeparser/dist/utils/imageUtils.d.ts +66 -0
- package/vendor/converters/officeparser/dist/utils/imageUtils.js +133 -0
- package/vendor/converters/officeparser/dist/utils/mathUtils.d.ts +42 -0
- package/vendor/converters/officeparser/dist/utils/mathUtils.js +385 -0
- package/vendor/converters/officeparser/dist/utils/moduleLoader.d.ts +18 -0
- package/vendor/converters/officeparser/dist/utils/moduleLoader.js +106 -0
- package/vendor/converters/officeparser/dist/utils/ocrUtils.d.ts +42 -0
- package/vendor/converters/officeparser/dist/utils/ocrUtils.js +428 -0
- package/vendor/converters/officeparser/dist/utils/sanitize.d.ts +148 -0
- package/vendor/converters/officeparser/dist/utils/sanitize.js +344 -0
- package/vendor/converters/officeparser/dist/utils/sheetUtils.d.ts +7 -0
- package/vendor/converters/officeparser/dist/utils/sheetUtils.js +35 -0
- package/vendor/converters/officeparser/dist/utils/styleMapper.d.ts +36 -0
- package/vendor/converters/officeparser/dist/utils/styleMapper.js +224 -0
- package/vendor/converters/officeparser/dist/utils/xmlUtils.d.ts +163 -0
- package/vendor/converters/officeparser/dist/utils/xmlUtils.js +461 -0
- package/vendor/converters/officeparser/dist/utils/zipUtils.d.ts +134 -0
- package/vendor/converters/officeparser/dist/utils/zipUtils.js +337 -0
- package/vendor/converters/officeparser/package.json +147 -0
- package/vendor/converters/upstream-manifest.json +124 -0
- package/vendor/dependency-fixes/README.md +77 -0
- package/vendor/dependency-fixes/vendor-converters.py +83 -0
- package/browser-extension/artifacts/gno-browser-clipper-v1.46.0.zip +0 -0
- package/browser-extension/artifacts/gno-browser-clipper-v1.46.0.zip.sha256 +0 -1
- package/browser-extension/dist/chunk-627emwpj.js +0 -75
- /package/browser-extension/dist/{chunk-ydfx5d7p.css → chunk-z74y8n8c.css} +0 -0
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
import { OfficeIssue, ConversionResult, FullGeneratorConfig, GeneratorConfig, OfficeContentNode, OfficeMetadata, OfficeParserAST, OfficeWarningType, UniversalGeneratorFormat } from '../types.js';
|
|
2
|
+
import { StyleMapper } from '../utils/styleMapper.js';
|
|
3
|
+
/**
|
|
4
|
+
* Base class for all document generators.
|
|
5
|
+
* Provides common traversal logic and configuration handling.
|
|
6
|
+
*/
|
|
7
|
+
export declare abstract class BaseGenerator<D extends UniversalGeneratorFormat = UniversalGeneratorFormat> {
|
|
8
|
+
protected destination: D;
|
|
9
|
+
protected config: FullGeneratorConfig;
|
|
10
|
+
protected ast: OfficeParserAST;
|
|
11
|
+
protected messages: OfficeIssue[];
|
|
12
|
+
protected styleMapper: StyleMapper;
|
|
13
|
+
protected collectedNotes: OfficeContentNode[];
|
|
14
|
+
constructor(destination: D, ast: OfficeParserAST, config?: GeneratorConfig<D> | FullGeneratorConfig);
|
|
15
|
+
/**
|
|
16
|
+
* The document metadata a generator should write out: `ast.metadata` with
|
|
17
|
+
* `config.metadataOverrides` applied on top, per field.
|
|
18
|
+
*
|
|
19
|
+
* Every generator must read metadata through here rather than touching `this.ast.metadata`
|
|
20
|
+
* directly, so an override reaches all of them uniformly instead of one format at a time.
|
|
21
|
+
*
|
|
22
|
+
* Merged rather than replaced, so overriding one field doesn't blank the rest, and computed
|
|
23
|
+
* fresh rather than cached on the AST: overrides are an output concern, and mutating
|
|
24
|
+
* `ast.metadata` would leak one generation's settings into the next use of the same AST.
|
|
25
|
+
* `custom` merges into `customProperties` so callers see one bucket regardless of origin.
|
|
26
|
+
*/
|
|
27
|
+
protected get effectiveMetadata(): OfficeMetadata;
|
|
28
|
+
/**
|
|
29
|
+
* Reports caller-supplied `metadataOverrides.custom` entries that the destination format has
|
|
30
|
+
* no way to represent (EPUB's OPF and RTF's `\info` both have fixed vocabularies).
|
|
31
|
+
*
|
|
32
|
+
* Warning rather than dropping silently: a caller who sets metadata and never sees it in the
|
|
33
|
+
* output otherwise has no way to find out. Only `custom` keys are reported - the named fields
|
|
34
|
+
* map onto something in every format that carries metadata at all.
|
|
35
|
+
*/
|
|
36
|
+
protected warnUnrepresentableCustomMetadata(format: string): void;
|
|
37
|
+
/**
|
|
38
|
+
* Retrieves the semantic mapping for a node, respecting the includeFormatting flag.
|
|
39
|
+
* Per design requirements: Style mapping is bypassed if formatting is disabled.
|
|
40
|
+
*/
|
|
41
|
+
protected getSemanticMapping(node: OfficeContentNode): {
|
|
42
|
+
tag: string;
|
|
43
|
+
classes: string[];
|
|
44
|
+
attributes: Record<string, string>;
|
|
45
|
+
fresh: boolean;
|
|
46
|
+
} | undefined;
|
|
47
|
+
/**
|
|
48
|
+
* Entry point for generation.
|
|
49
|
+
*/
|
|
50
|
+
abstract generate(): Promise<ConversionResult<D>>;
|
|
51
|
+
/**
|
|
52
|
+
* Centralized logic for handling the onNode callback.
|
|
53
|
+
* Evaluates the callback and returns a result that tells the generator how to proceed.
|
|
54
|
+
*
|
|
55
|
+
* @returns
|
|
56
|
+
* - `string`: Use this as the node's output, skip default processing.
|
|
57
|
+
* - `false`: Skip this node and its subtree.
|
|
58
|
+
* - `void`: Proceed with default processing.
|
|
59
|
+
*/
|
|
60
|
+
protected handleOnNode(node: OfficeContentNode): Promise<string | false | void>;
|
|
61
|
+
/**
|
|
62
|
+
* Recursively processes nodes and builds output.
|
|
63
|
+
*
|
|
64
|
+
* @param node - The current node being processed
|
|
65
|
+
* @param processor - A function that takes a node and its children's output and returns the node's output string.
|
|
66
|
+
* @returns The generated string for this node and its subtree.
|
|
67
|
+
*/
|
|
68
|
+
protected processNodeRecursive(node: OfficeContentNode, processor: (node: OfficeContentNode, childrenOutput: string) => string | Promise<string>): Promise<string>;
|
|
69
|
+
/**
|
|
70
|
+
* Helper to generate a unique ID (slug) from text.
|
|
71
|
+
*/
|
|
72
|
+
protected slugify(text: string): string;
|
|
73
|
+
private noteFootnoteKeys;
|
|
74
|
+
private usedFootnoteKeys;
|
|
75
|
+
private footnoteKeyCounter;
|
|
76
|
+
/**
|
|
77
|
+
* Assigns a stable, unique reference key to a footnote/endnote node, reused for both
|
|
78
|
+
* its inline reference marker and its collected definition. Source ids aren't reliably
|
|
79
|
+
* unique across a document - DOCX/ODT number footnotes and endnotes in separate
|
|
80
|
+
* sequences, so both can carry noteId "1" - so a source id is only reused when it
|
|
81
|
+
* hasn't already been claimed; otherwise a sequential counter guarantees uniqueness.
|
|
82
|
+
*/
|
|
83
|
+
protected getFootnoteKey(note: OfficeContentNode): string;
|
|
84
|
+
/**
|
|
85
|
+
* True when every content-bearing text descendant satisfies `test` - i.e. the property is
|
|
86
|
+
* uniform across the whole node and therefore says nothing the node type does not already say.
|
|
87
|
+
*
|
|
88
|
+
* Used to decide whether a heading's or header row's inherited formatting can be dropped. The
|
|
89
|
+
* distinction matters: an ODF heading whose paragraph style is bold and 14pt yields a heading
|
|
90
|
+
* where *every* run is bold and 14pt, and re-emitting that gives `# **Heading**` in Markdown
|
|
91
|
+
* and, worse in RTF/HTML, an inner font-size that overrides the heading's own and visibly
|
|
92
|
+
* shrinks it. But `# Normal **Bold** Normal` is an author contrasting one word against the
|
|
93
|
+
* rest, and dropping that would discard real meaning. Only the uniform case is safe.
|
|
94
|
+
*
|
|
95
|
+
* Returns false when there is no text to judge, so an empty or image-only node never triggers
|
|
96
|
+
* suppression.
|
|
97
|
+
*/
|
|
98
|
+
protected hasUniformFormatting(node: OfficeContentNode, test: (formatting: OfficeContentNode['formatting']) => boolean): boolean;
|
|
99
|
+
/**
|
|
100
|
+
* Recursively extracts plain text from a node and its children.
|
|
101
|
+
*/
|
|
102
|
+
protected getNodeText(node: OfficeContentNode): string;
|
|
103
|
+
/**
|
|
104
|
+
* Reports a warning to the user and collects it for the final result.
|
|
105
|
+
*/
|
|
106
|
+
protected warn(type: OfficeWarningType, info?: any, node?: OfficeContentNode): void;
|
|
107
|
+
}
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.BaseGenerator = void 0;
|
|
4
|
+
const types_js_1 = require("../types.js");
|
|
5
|
+
const configUtils_js_1 = require("../utils/configUtils.js");
|
|
6
|
+
const errorUtils_js_1 = require("../utils/errorUtils.js");
|
|
7
|
+
const styleMapper_js_1 = require("../utils/styleMapper.js");
|
|
8
|
+
/**
|
|
9
|
+
* Base class for all document generators.
|
|
10
|
+
* Provides common traversal logic and configuration handling.
|
|
11
|
+
*/
|
|
12
|
+
class BaseGenerator {
|
|
13
|
+
destination;
|
|
14
|
+
config;
|
|
15
|
+
ast;
|
|
16
|
+
messages = [];
|
|
17
|
+
styleMapper;
|
|
18
|
+
collectedNotes = [];
|
|
19
|
+
constructor(destination, ast, config) {
|
|
20
|
+
this.destination = destination;
|
|
21
|
+
this.config = (0, configUtils_js_1.resolveGeneratorConfig)(destination, ast.config, config);
|
|
22
|
+
this.ast = ast;
|
|
23
|
+
this.styleMapper = new styleMapper_js_1.StyleMapper(this.config.styleMap, this.config.ignoreDefaultStyleMap);
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* The document metadata a generator should write out: `ast.metadata` with
|
|
27
|
+
* `config.metadataOverrides` applied on top, per field.
|
|
28
|
+
*
|
|
29
|
+
* Every generator must read metadata through here rather than touching `this.ast.metadata`
|
|
30
|
+
* directly, so an override reaches all of them uniformly instead of one format at a time.
|
|
31
|
+
*
|
|
32
|
+
* Merged rather than replaced, so overriding one field doesn't blank the rest, and computed
|
|
33
|
+
* fresh rather than cached on the AST: overrides are an output concern, and mutating
|
|
34
|
+
* `ast.metadata` would leak one generation's settings into the next use of the same AST.
|
|
35
|
+
* `custom` merges into `customProperties` so callers see one bucket regardless of origin.
|
|
36
|
+
*/
|
|
37
|
+
get effectiveMetadata() {
|
|
38
|
+
const base = this.ast.metadata || {};
|
|
39
|
+
const overrides = this.config.metadataOverrides;
|
|
40
|
+
if (!overrides)
|
|
41
|
+
return base;
|
|
42
|
+
const { custom, language, ...named } = overrides;
|
|
43
|
+
const merged = { ...base };
|
|
44
|
+
// Assign only the fields actually supplied - spreading `named` wholesale would write
|
|
45
|
+
// `undefined` over parsed values for every field the caller left out.
|
|
46
|
+
for (const [key, value] of Object.entries(named)) {
|
|
47
|
+
if (value !== undefined)
|
|
48
|
+
merged[key] = value;
|
|
49
|
+
}
|
|
50
|
+
// `language` has no slot on OfficeMetadata; parsers already surface it through
|
|
51
|
+
// nativeProperties, so an override belongs in the same place rather than widening the
|
|
52
|
+
// parser-side type for a generator concern. Generators reading `nativeProperties.language`
|
|
53
|
+
// then pick it up with no change.
|
|
54
|
+
if (language !== undefined) {
|
|
55
|
+
merged.nativeProperties = { ...(base.nativeProperties || {}), language };
|
|
56
|
+
}
|
|
57
|
+
if (custom && Object.keys(custom).length > 0) {
|
|
58
|
+
merged.customProperties = { ...(base.customProperties || {}), ...custom };
|
|
59
|
+
}
|
|
60
|
+
return merged;
|
|
61
|
+
}
|
|
62
|
+
/**
|
|
63
|
+
* Reports caller-supplied `metadataOverrides.custom` entries that the destination format has
|
|
64
|
+
* no way to represent (EPUB's OPF and RTF's `\info` both have fixed vocabularies).
|
|
65
|
+
*
|
|
66
|
+
* Warning rather than dropping silently: a caller who sets metadata and never sees it in the
|
|
67
|
+
* output otherwise has no way to find out. Only `custom` keys are reported - the named fields
|
|
68
|
+
* map onto something in every format that carries metadata at all.
|
|
69
|
+
*/
|
|
70
|
+
warnUnrepresentableCustomMetadata(format) {
|
|
71
|
+
const custom = this.config.metadataOverrides?.custom;
|
|
72
|
+
if (!custom)
|
|
73
|
+
return;
|
|
74
|
+
const keys = Object.keys(custom);
|
|
75
|
+
if (keys.length === 0)
|
|
76
|
+
return;
|
|
77
|
+
this.warn(types_js_1.OfficeWarningType.METADATA_NOT_REPRESENTABLE, { keys, format });
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* Retrieves the semantic mapping for a node, respecting the includeFormatting flag.
|
|
81
|
+
* Per design requirements: Style mapping is bypassed if formatting is disabled.
|
|
82
|
+
*/
|
|
83
|
+
getSemanticMapping(node) {
|
|
84
|
+
if (this.config.includeFormatting === false) {
|
|
85
|
+
return undefined;
|
|
86
|
+
}
|
|
87
|
+
return this.styleMapper.getMapping(node);
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Centralized logic for handling the onNode callback.
|
|
91
|
+
* Evaluates the callback and returns a result that tells the generator how to proceed.
|
|
92
|
+
*
|
|
93
|
+
* @returns
|
|
94
|
+
* - `string`: Use this as the node's output, skip default processing.
|
|
95
|
+
* - `false`: Skip this node and its subtree.
|
|
96
|
+
* - `void`: Proceed with default processing.
|
|
97
|
+
*/
|
|
98
|
+
async handleOnNode(node) {
|
|
99
|
+
const result = await this.config.onNode(node);
|
|
100
|
+
if (result === false)
|
|
101
|
+
return false;
|
|
102
|
+
if (typeof result === 'string')
|
|
103
|
+
return result;
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Recursively processes nodes and builds output.
|
|
107
|
+
*
|
|
108
|
+
* @param node - The current node being processed
|
|
109
|
+
* @param processor - A function that takes a node and its children's output and returns the node's output string.
|
|
110
|
+
* @returns The generated string for this node and its subtree.
|
|
111
|
+
*/
|
|
112
|
+
async processNodeRecursive(node, processor) {
|
|
113
|
+
// Every text-based generator funnels its whole traversal through here, so one check
|
|
114
|
+
// makes `abortSignal` effective for all of them. Previously the signal was read once
|
|
115
|
+
// before generation began and never again, which meant it could decline to start work
|
|
116
|
+
// but could not stop work already underway - not much use against a document large
|
|
117
|
+
// enough to be worth aborting. The check is a property read on an optional signal, so
|
|
118
|
+
// the per-node cost is negligible.
|
|
119
|
+
(0, errorUtils_js_1.checkAbortSignal)(this.config.abortSignal);
|
|
120
|
+
const override = await this.handleOnNode(node);
|
|
121
|
+
if (override === false)
|
|
122
|
+
return '';
|
|
123
|
+
if (typeof override === 'string')
|
|
124
|
+
return override;
|
|
125
|
+
let childrenOutput = '';
|
|
126
|
+
if (node.children) {
|
|
127
|
+
for (const child of node.children) {
|
|
128
|
+
childrenOutput += await this.processNodeRecursive(child, processor);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
if (node.notes && node.notes.length > 0) {
|
|
132
|
+
if (node.type !== 'slide') {
|
|
133
|
+
this.collectedNotes.push(...node.notes);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
let result = await processor(node, childrenOutput);
|
|
137
|
+
if (node.type === 'slide' && node.notes && node.notes.length > 0) {
|
|
138
|
+
for (const note of node.notes) {
|
|
139
|
+
result += await this.processNodeRecursive(note, processor);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
return result;
|
|
143
|
+
}
|
|
144
|
+
/**
|
|
145
|
+
* Helper to generate a unique ID (slug) from text.
|
|
146
|
+
*/
|
|
147
|
+
slugify(text) {
|
|
148
|
+
return text
|
|
149
|
+
.toLowerCase()
|
|
150
|
+
.replace(/[^\w\s-]/g, '')
|
|
151
|
+
.replace(/[\s_-]+/g, '-')
|
|
152
|
+
.replace(/^-+|-+$/g, '');
|
|
153
|
+
}
|
|
154
|
+
noteFootnoteKeys = new Map();
|
|
155
|
+
usedFootnoteKeys = new Set();
|
|
156
|
+
footnoteKeyCounter = 0;
|
|
157
|
+
/**
|
|
158
|
+
* Assigns a stable, unique reference key to a footnote/endnote node, reused for both
|
|
159
|
+
* its inline reference marker and its collected definition. Source ids aren't reliably
|
|
160
|
+
* unique across a document - DOCX/ODT number footnotes and endnotes in separate
|
|
161
|
+
* sequences, so both can carry noteId "1" - so a source id is only reused when it
|
|
162
|
+
* hasn't already been claimed; otherwise a sequential counter guarantees uniqueness.
|
|
163
|
+
*/
|
|
164
|
+
getFootnoteKey(note) {
|
|
165
|
+
const cached = this.noteFootnoteKeys.get(note);
|
|
166
|
+
if (cached)
|
|
167
|
+
return cached;
|
|
168
|
+
const preferred = note.metadata?.noteId;
|
|
169
|
+
// The id is document-supplied and lands inside `[^...]` in Markdown, where the parser's
|
|
170
|
+
// own recognizer accepts everything but `]` - so a note id carrying markup round-tripped
|
|
171
|
+
// into the output verbatim. Accept it only when it looks like a label; otherwise fall
|
|
172
|
+
// through to the sequential counter, which is always safe. Real ids are numeric (DOCX),
|
|
173
|
+
// `ftn1`-shaped (ODT) or short slugs (`fn1`), and a Markdown label like `[^my note]`
|
|
174
|
+
// still qualifies, so the fallback fires only for genuinely hostile input.
|
|
175
|
+
const isLabelLike = typeof preferred === 'string' && /^[A-Za-z0-9_.:-][A-Za-z0-9 _.:-]*$/.test(preferred);
|
|
176
|
+
let key;
|
|
177
|
+
if (preferred && isLabelLike && !this.usedFootnoteKeys.has(preferred)) {
|
|
178
|
+
key = preferred;
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
do {
|
|
182
|
+
this.footnoteKeyCounter++;
|
|
183
|
+
key = String(this.footnoteKeyCounter);
|
|
184
|
+
} while (this.usedFootnoteKeys.has(key));
|
|
185
|
+
}
|
|
186
|
+
this.usedFootnoteKeys.add(key);
|
|
187
|
+
this.noteFootnoteKeys.set(note, key);
|
|
188
|
+
return key;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* True when every content-bearing text descendant satisfies `test` - i.e. the property is
|
|
192
|
+
* uniform across the whole node and therefore says nothing the node type does not already say.
|
|
193
|
+
*
|
|
194
|
+
* Used to decide whether a heading's or header row's inherited formatting can be dropped. The
|
|
195
|
+
* distinction matters: an ODF heading whose paragraph style is bold and 14pt yields a heading
|
|
196
|
+
* where *every* run is bold and 14pt, and re-emitting that gives `# **Heading**` in Markdown
|
|
197
|
+
* and, worse in RTF/HTML, an inner font-size that overrides the heading's own and visibly
|
|
198
|
+
* shrinks it. But `# Normal **Bold** Normal` is an author contrasting one word against the
|
|
199
|
+
* rest, and dropping that would discard real meaning. Only the uniform case is safe.
|
|
200
|
+
*
|
|
201
|
+
* Returns false when there is no text to judge, so an empty or image-only node never triggers
|
|
202
|
+
* suppression.
|
|
203
|
+
*/
|
|
204
|
+
hasUniformFormatting(node, test) {
|
|
205
|
+
let sawText = false;
|
|
206
|
+
const walk = (n) => {
|
|
207
|
+
if (n.type === 'text') {
|
|
208
|
+
// Whitespace-only runs carry no visible formatting either way, so they neither
|
|
209
|
+
// count as evidence nor veto - otherwise a stray unformatted space between two
|
|
210
|
+
// bold runs would defeat the check on almost every real heading.
|
|
211
|
+
if (!(n.text || '').trim())
|
|
212
|
+
return true;
|
|
213
|
+
sawText = true;
|
|
214
|
+
return test(n.formatting);
|
|
215
|
+
}
|
|
216
|
+
return (n.children ?? []).every(walk);
|
|
217
|
+
};
|
|
218
|
+
const uniform = (node.children ?? []).every(walk);
|
|
219
|
+
return sawText && uniform;
|
|
220
|
+
}
|
|
221
|
+
/**
|
|
222
|
+
* Recursively extracts plain text from a node and its children.
|
|
223
|
+
*/
|
|
224
|
+
getNodeText(node) {
|
|
225
|
+
if (node.text)
|
|
226
|
+
return node.text;
|
|
227
|
+
if (node.children) {
|
|
228
|
+
return node.children.map(c => this.getNodeText(c)).join('');
|
|
229
|
+
}
|
|
230
|
+
return '';
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Reports a warning to the user and collects it for the final result.
|
|
234
|
+
*/
|
|
235
|
+
warn(type, info, node) {
|
|
236
|
+
const message = (0, errorUtils_js_1.getWarningMessage)(type, info);
|
|
237
|
+
const issue = {
|
|
238
|
+
type: 'warning',
|
|
239
|
+
code: type,
|
|
240
|
+
message,
|
|
241
|
+
node,
|
|
242
|
+
details: info
|
|
243
|
+
};
|
|
244
|
+
this.messages.push(issue);
|
|
245
|
+
this.config.onWarning(issue);
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
exports.BaseGenerator = BaseGenerator;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { ConversionResult, GeneratorConfig, OfficeParserAST } from '../types.js';
|
|
2
|
+
import { BaseGenerator } from './BaseGenerator.js';
|
|
3
|
+
/**
|
|
4
|
+
* Generates a list of OfficeChunk objects from an AST for use in RAG pipelines.
|
|
5
|
+
* Supports three strategies: 'fixed-size', 'document-structure', and 'semantic'.
|
|
6
|
+
*/
|
|
7
|
+
export declare class ChunkingGenerator extends BaseGenerator<'chunks'> {
|
|
8
|
+
/** The resolved chunking config (with defaults applied). */
|
|
9
|
+
private chunkConfig;
|
|
10
|
+
/** Whether the user provided an explicit sentence boundary regex. */
|
|
11
|
+
private isCustomRegex;
|
|
12
|
+
constructor(ast: OfficeParserAST, config?: GeneratorConfig<'chunks'>);
|
|
13
|
+
/**
|
|
14
|
+
* Merges the user's chunking config with the appropriate defaults for the chosen strategy.
|
|
15
|
+
*/
|
|
16
|
+
private resolveChunkingConfig;
|
|
17
|
+
/**
|
|
18
|
+
* Main entry point. Routes to the correct strategy implementation.
|
|
19
|
+
* Note: ConversionResult.value is a real OfficeChunk[] array for the 'chunks' destination, not
|
|
20
|
+
* a JSON string. Consumers serialize it to JSON/JSONL themselves.
|
|
21
|
+
*/
|
|
22
|
+
generate(): Promise<ConversionResult<'chunks'>>;
|
|
23
|
+
/**
|
|
24
|
+
* Splits the full document text into fixed-size chunks with optional overlap.
|
|
25
|
+
* Attempts to split on natural separators before hard-cutting.
|
|
26
|
+
*/
|
|
27
|
+
private generateFixedSize;
|
|
28
|
+
/**
|
|
29
|
+
* Recursively tries separators to split text into chunks of at most `chunkSize`,
|
|
30
|
+
* with `chunkOverlap` characters of overlap between consecutive chunks.
|
|
31
|
+
*/
|
|
32
|
+
private splitTextRecursively;
|
|
33
|
+
/**
|
|
34
|
+
* Walks the AST and splits at the designated structural boundaries (slide, page, heading, paragraph).
|
|
35
|
+
*/
|
|
36
|
+
private generateDocumentStructure;
|
|
37
|
+
private processNodeForStructure;
|
|
38
|
+
private isStructuralBoundary;
|
|
39
|
+
/**
|
|
40
|
+
* Handles table chunking with the configured tableSplitStrategy.
|
|
41
|
+
* 'row': keeps header row attached to every chunk.
|
|
42
|
+
* 'flatten': converts table to text and splits normally.
|
|
43
|
+
*/
|
|
44
|
+
private processTableNode;
|
|
45
|
+
/**
|
|
46
|
+
* Renders a list of row nodes as a pipe-separated text string.
|
|
47
|
+
*/
|
|
48
|
+
private renderRowsAsText;
|
|
49
|
+
/**
|
|
50
|
+
* Splits document into semantically coherent chunks using cosine similarity
|
|
51
|
+
* between sentence embeddings. A new chunk begins when similarity drops
|
|
52
|
+
* below `similarityThreshold`.
|
|
53
|
+
*/
|
|
54
|
+
private generateSemantic;
|
|
55
|
+
/**
|
|
56
|
+
* Extracts all text sentences from the AST with their contextual metadata.
|
|
57
|
+
*/
|
|
58
|
+
private extractSentences;
|
|
59
|
+
/**
|
|
60
|
+
* Builds a flat text string from the entire document and a map of
|
|
61
|
+
* character offsets to AST node metadata for position-based metadata lookups.
|
|
62
|
+
*/
|
|
63
|
+
private buildFlatTextWithPositions;
|
|
64
|
+
/**
|
|
65
|
+
* Finds the closest AST metadata for a given character position.
|
|
66
|
+
*/
|
|
67
|
+
private enrichMetadataFromPosition;
|
|
68
|
+
/**
|
|
69
|
+
* Applies final post-processing: strips whitespace, sets sourceType.
|
|
70
|
+
*/
|
|
71
|
+
private finalizeChunks;
|
|
72
|
+
/**
|
|
73
|
+
* Helper to process embeddings in sequential batches to avoid API rate limits and memory issues.
|
|
74
|
+
*/
|
|
75
|
+
private batchEmbeddings;
|
|
76
|
+
private cosineSimilarity;
|
|
77
|
+
private averageEmbeddings;
|
|
78
|
+
/**
|
|
79
|
+
* Robustly splits text into sentences, respecting abbreviations and non-Western punctuation.
|
|
80
|
+
*/
|
|
81
|
+
private splitIntoSentences;
|
|
82
|
+
}
|